diff --git a/lib/SensorsLib/README.md b/lib/SensorsLib/README.md index 15c39dc..9d8b707 100644 --- a/lib/SensorsLib/README.md +++ b/lib/SensorsLib/README.md @@ -9,6 +9,7 @@ ``` +Some commonly used sensor libraries are not completed and are being added diff --git a/lib/SensorsLib/datasheet/HYM8563.pdf b/lib/SensorsLib/datasheet/HYM8563.pdf new file mode 100644 index 0000000..bcf475f Binary files /dev/null and b/lib/SensorsLib/datasheet/HYM8563.pdf differ diff --git a/lib/SensorsLib/datasheet/PCF8563 Datasheet Rev.11.pdf b/lib/SensorsLib/datasheet/PCF8563 Datasheet Rev.11.pdf new file mode 100644 index 0000000..6e600f6 Binary files /dev/null and b/lib/SensorsLib/datasheet/PCF8563 Datasheet Rev.11.pdf differ diff --git a/lib/SensorsLib/examples/PCF8563_AlarmByUnits/PCF8563_AlarmByUnits.ino b/lib/SensorsLib/examples/PCF8563_AlarmByUnits/PCF8563_AlarmByUnits.ino new file mode 100644 index 0000000..cb4f390 --- /dev/null +++ b/lib/SensorsLib/examples/PCF8563_AlarmByUnits/PCF8563_AlarmByUnits.ino @@ -0,0 +1,196 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2022 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file PCF8563_AlarmByUnits.ino + * @author Lewis He (lewishe@outlook.com) + * @date 2022-12-11 + * + */ +#include +#include +#include +#include +#include "SensorPCF8563.tpp" + +#ifdef ESP32 +#define I2C_SDA 42 +#define I2C_SCL 41 +#define RTC_IRQ 14 +#else +#define _PINNUM(port, pin) ((port)*32 + (pin)) +#define I2C_SDA _PINNUM(0,26) +#define I2C_SCL _PINNUM(0,27) +#define RTC_IRQ _PINNUM(0,16) +#endif + + +SensorPCF8563 rtc; + + +uint32_t lastMillis = 0; +uint8_t nextHour = 22; +uint8_t nextMonth = 1; +uint8_t nextDay = 1; +uint8_t nextMinute = 59; +uint8_t nextSecond = 55; + + +void setup() +{ + Serial.begin(115200); + while (!Serial); + +#ifdef LILYGO_TBEAM_SUPREME_V3_0 + extern bool setupPower(); + setupPower(); +#endif + + if (!rtc.begin(Wire, PCF8563_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) { + Serial.println("Failed to find PCF8563 - check your wiring!"); + while (1) { + delay(1000); + } + } + + pinMode(RTC_IRQ, INPUT_PULLUP); + + rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond); + + // From minute timer + rtc.setAlarmByMinutes(0); + + rtc.enableAlarm(); + +} + +void printDateTime() +{ + if (millis() - lastMillis > 1000) { + /** + /// Format output time* + Option: + DATETIME_FORMAT_HM + DATETIME_FORMAT_HMS + DATETIME_FORMAT_YYYY_MM_DD + DATETIME_FORMAT_MM_DD_YYYY + DATETIME_FORMAT_DD_MM_YYYY + DATETIME_FORMAT_YYYY_MM_DD_H_M_S + default: DATETIME_FORMAT_YYYY_MM_DD_H_M_S_WEEK + */ + Serial.println(rtc.strftime()); + + lastMillis = millis(); + } +} + +// Test minute timing +void testAlarmMinute() +{ + while (1) { + if (digitalRead(RTC_IRQ) == LOW) { + Serial.println("testAlarmMinute Interrupt .... "); + if (rtc.isAlarmActive()) { + Serial.println("Alarm active"); + rtc.resetAlarm(); + rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond); + nextHour++; + if (nextHour >= 24) { + nextHour = 23; + nextDay = 25; + rtc.setAlarmByHours(0); + Serial.println("setAlarmByHours"); + return; + } + } + } + printDateTime(); + } +} + +// Test hour timing +void testAlarmHour() +{ + while (1) { + if (digitalRead(RTC_IRQ) == LOW) { + Serial.println("testAlarmHour Interrupt .... "); + if (rtc.isAlarmActive()) { + Serial.println("Alarm active"); + rtc.resetAlarm(); + rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond); + nextDay++; + if (nextDay >= 30) { + nextMonth = 1; + nextHour = 23; + nextMinute = 59; + nextSecond = 55; + nextDay = rtc.getDaysInMonth(nextMonth, 2022); + rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond); + rtc.setAlarmByDays(1); + Serial.println("setAlarmByDays"); + return; + } + } + } + printDateTime(); + } +} + +// Test day timing +void testAlarmDay() +{ + while (1) { + if (digitalRead(RTC_IRQ) == LOW) { + Serial.println("testAlarmDay Interrupt .... "); + if (rtc.isAlarmActive()) { + Serial.println("Alarm active"); + rtc.resetAlarm(); + nextDay = rtc.getDaysInMonth(nextMonth, 2022); + rtc.setDateTime(2022, nextMonth, nextDay, nextHour, nextMinute, nextSecond); + nextMonth++; + if (nextMonth >= 12) { + return; + } + } + } + printDateTime(); + } +} + + + + +void loop() +{ + testAlarmMinute(); + testAlarmHour(); + testAlarmDay(); + + Serial.println("Test done ..."); + while (1) { + delay(100); + } +} + + + diff --git a/lib/SensorsLib/examples/PCF8563_AlarmByUnits/power.cpp b/lib/SensorsLib/examples/PCF8563_AlarmByUnits/power.cpp new file mode 100644 index 0000000..96d5804 --- /dev/null +++ b/lib/SensorsLib/examples/PCF8563_AlarmByUnits/power.cpp @@ -0,0 +1,167 @@ +/** + * @file power.cpp + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2022 + * @date 2022-10-25 + * + */ + + +#ifdef LILYGO_TBEAM_SUPREME_V3_0 +#include +#include "XPowersAXP2101.tpp" +#include "XPowersAXP192.tpp" + + + +#define I2C_SDA 42 +#define I2C_SCL 41 +#define PMU_IRQ 40 + +XPowersLibInterface *PMU = NULL; + +bool setupPower() +{ + Serial.println("setupPower"); + + if (!PMU) { + PMU = new XPowersAXP2101(Wire, I2C_SDA, I2C_SCL); + if (!PMU->init()) { + Serial.println("Warning: Failed to find AXP2101 power management"); + delete PMU; + PMU = NULL; + } else { + Serial.println("AXP2101 PMU init succeeded, using AXP2101 PMU"); + } + } + + if (!PMU) { + return false; + } + + if (PMU->getChipModel() == XPOWERS_AXP2101) { + +#if defined(LILYGO_TBEAM_V1_2) + + PMU->setProtectedChannel(XPOWERS_DCDC1); + + PMU->disablePowerOutput(XPOWERS_DCDC2); + PMU->disablePowerOutput(XPOWERS_DCDC3); + PMU->disablePowerOutput(XPOWERS_DCDC4); + PMU->disablePowerOutput(XPOWERS_DCDC5); + + // PMU->disablePowerOutput(XPOWERS_ALDO1); + // PMU->disablePowerOutput(XPOWERS_ALDO2); + // PMU->disablePowerOutput(XPOWERS_ALDO3); + PMU->disablePowerOutput(XPOWERS_ALDO4); + + PMU->disablePowerOutput(XPOWERS_BLDO1); + PMU->disablePowerOutput(XPOWERS_BLDO2); + + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + + PMU->enablePowerOutput(XPOWERS_VBACKUP); + PMU->enablePowerOutput(XPOWERS_ALDO1); + PMU->enablePowerOutput(XPOWERS_ALDO2); + PMU->enablePowerOutput(XPOWERS_ALDO3); + + PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V4); + +#elif defined(LILYGO_TBEAM_SUPREME_V3_0) + + //t-beam m.2 inface + //gps + PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO4); + + // lora + PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO3); + + // Sensor + PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO1); + + PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO2); + + //Sdcard + PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); + PMU->enablePowerOutput(XPOWERS_BLDO1); + + //face m.2 + PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC3); + + PMU->setPowerChannelVoltage(XPOWERS_DCDC4, XPOWERS_AXP2101_DCDC4_VOL2_MAX); + PMU->enablePowerOutput(XPOWERS_DCDC4); + + PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC5); + + + //not use channel + PMU->disablePowerOutput(XPOWERS_DCDC2); + // PMU->disablePowerOutput(XPOWERS_DCDC4); + // PMU->disablePowerOutput(XPOWERS_DCDC5); + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + PMU->disablePowerOutput(XPOWERS_VBACKUP); + +#endif + } + + PMU->enableSystemVoltageMeasure(); + PMU->enableVbusVoltageMeasure(); + PMU->enableBattVoltageMeasure(); + PMU->disableTSPinMeasure(); + + Serial.printf("=========================================\n"); + if (PMU->isChannelAvailable(XPOWERS_DCDC1)) { + Serial.printf("DC1 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC2)) { + Serial.printf("DC2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC3)) { + Serial.printf("DC3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC4)) { + Serial.printf("DC4 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC5)) { + Serial.printf("DC5 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC5) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC5)); + } + if (PMU->isChannelAvailable(XPOWERS_LDO2)) { + Serial.printf("LDO2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2)); + } + if (PMU->isChannelAvailable(XPOWERS_LDO3)) { + Serial.printf("LDO3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO1)) { + Serial.printf("ALDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO2)) { + Serial.printf("ALDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO3)) { + Serial.printf("ALDO3: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO4)) { + Serial.printf("ALDO4: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO1)) { + Serial.printf("BLDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO2)) { + Serial.printf("BLDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2)); + } + Serial.printf("=========================================\n"); + + + return true; +} + +#endif \ No newline at end of file diff --git a/lib/SensorsLib/examples/PCF8563_SimpleTime/PCF8563_SimpleTime.ino b/lib/SensorsLib/examples/PCF8563_SimpleTime/PCF8563_SimpleTime.ino new file mode 100644 index 0000000..8f9ccbc --- /dev/null +++ b/lib/SensorsLib/examples/PCF8563_SimpleTime/PCF8563_SimpleTime.ino @@ -0,0 +1,90 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2022 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file PCF8563_SimpleTime.ino + * @author Lewis He (lewishe@outlook.com) + * @date 2022-12-12 + * + */ +#include +#include +#include +#include "SensorPCF8563.tpp" + +// lilygo t-beam-s3-core pin +#define I2C_SDA 42 +#define I2C_SCL 41 +#define RTC_IRQ 14 + +SensorPCF8563 rtc; +uint32_t lastMillis; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + +#ifdef LILYGO_TBEAM_SUPREME_V3_0 + extern bool setupPower(); + setupPower(); +#endif + + pinMode(RTC_IRQ, INPUT_PULLUP); + + if (!rtc.begin(Wire, PCF8563_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) { + Serial.println("Failed to find PCF8563 - check your wiring!"); + while (1) { + delay(1000); + } + } + + uint16_t year = 2022; + uint8_t month = 12; + uint8_t day = 12; + uint8_t hour = 21; + uint8_t minute = 00; + uint8_t second = 30; + + rtc.setDateTime(year, month, day, hour, minute, second); + +} + + +void loop() +{ + if (millis() - lastMillis > 1000) { + lastMillis = millis(); + RTC_DateTime datetime = rtc.getDateTime(); + Serial.printf(" Year :"); Serial.print(datetime.year); + Serial.printf(" Month:"); Serial.print(datetime.month); + Serial.printf(" Day :"); Serial.print(datetime.day); + Serial.printf(" Hour:"); Serial.print(datetime.hour); + Serial.printf(" Minute:"); Serial.print(datetime.minute); + Serial.printf(" Sec :"); Serial.println(datetime.second); + + } +} + + + diff --git a/lib/SensorsLib/examples/PCF8563_SimpleTime/power.cpp b/lib/SensorsLib/examples/PCF8563_SimpleTime/power.cpp new file mode 100644 index 0000000..96d5804 --- /dev/null +++ b/lib/SensorsLib/examples/PCF8563_SimpleTime/power.cpp @@ -0,0 +1,167 @@ +/** + * @file power.cpp + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2022 + * @date 2022-10-25 + * + */ + + +#ifdef LILYGO_TBEAM_SUPREME_V3_0 +#include +#include "XPowersAXP2101.tpp" +#include "XPowersAXP192.tpp" + + + +#define I2C_SDA 42 +#define I2C_SCL 41 +#define PMU_IRQ 40 + +XPowersLibInterface *PMU = NULL; + +bool setupPower() +{ + Serial.println("setupPower"); + + if (!PMU) { + PMU = new XPowersAXP2101(Wire, I2C_SDA, I2C_SCL); + if (!PMU->init()) { + Serial.println("Warning: Failed to find AXP2101 power management"); + delete PMU; + PMU = NULL; + } else { + Serial.println("AXP2101 PMU init succeeded, using AXP2101 PMU"); + } + } + + if (!PMU) { + return false; + } + + if (PMU->getChipModel() == XPOWERS_AXP2101) { + +#if defined(LILYGO_TBEAM_V1_2) + + PMU->setProtectedChannel(XPOWERS_DCDC1); + + PMU->disablePowerOutput(XPOWERS_DCDC2); + PMU->disablePowerOutput(XPOWERS_DCDC3); + PMU->disablePowerOutput(XPOWERS_DCDC4); + PMU->disablePowerOutput(XPOWERS_DCDC5); + + // PMU->disablePowerOutput(XPOWERS_ALDO1); + // PMU->disablePowerOutput(XPOWERS_ALDO2); + // PMU->disablePowerOutput(XPOWERS_ALDO3); + PMU->disablePowerOutput(XPOWERS_ALDO4); + + PMU->disablePowerOutput(XPOWERS_BLDO1); + PMU->disablePowerOutput(XPOWERS_BLDO2); + + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + + PMU->enablePowerOutput(XPOWERS_VBACKUP); + PMU->enablePowerOutput(XPOWERS_ALDO1); + PMU->enablePowerOutput(XPOWERS_ALDO2); + PMU->enablePowerOutput(XPOWERS_ALDO3); + + PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V4); + +#elif defined(LILYGO_TBEAM_SUPREME_V3_0) + + //t-beam m.2 inface + //gps + PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO4); + + // lora + PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO3); + + // Sensor + PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO1); + + PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO2); + + //Sdcard + PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); + PMU->enablePowerOutput(XPOWERS_BLDO1); + + //face m.2 + PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC3); + + PMU->setPowerChannelVoltage(XPOWERS_DCDC4, XPOWERS_AXP2101_DCDC4_VOL2_MAX); + PMU->enablePowerOutput(XPOWERS_DCDC4); + + PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC5); + + + //not use channel + PMU->disablePowerOutput(XPOWERS_DCDC2); + // PMU->disablePowerOutput(XPOWERS_DCDC4); + // PMU->disablePowerOutput(XPOWERS_DCDC5); + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + PMU->disablePowerOutput(XPOWERS_VBACKUP); + +#endif + } + + PMU->enableSystemVoltageMeasure(); + PMU->enableVbusVoltageMeasure(); + PMU->enableBattVoltageMeasure(); + PMU->disableTSPinMeasure(); + + Serial.printf("=========================================\n"); + if (PMU->isChannelAvailable(XPOWERS_DCDC1)) { + Serial.printf("DC1 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC2)) { + Serial.printf("DC2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC3)) { + Serial.printf("DC3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC4)) { + Serial.printf("DC4 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC5)) { + Serial.printf("DC5 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC5) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC5)); + } + if (PMU->isChannelAvailable(XPOWERS_LDO2)) { + Serial.printf("LDO2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2)); + } + if (PMU->isChannelAvailable(XPOWERS_LDO3)) { + Serial.printf("LDO3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO1)) { + Serial.printf("ALDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO2)) { + Serial.printf("ALDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO3)) { + Serial.printf("ALDO3: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO4)) { + Serial.printf("ALDO4: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO1)) { + Serial.printf("BLDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO2)) { + Serial.printf("BLDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2)); + } + Serial.printf("=========================================\n"); + + + return true; +} + +#endif \ No newline at end of file diff --git a/lib/SensorsLib/examples/PCF8563_TimeLib/PCF8563_TimeLib.ino b/lib/SensorsLib/examples/PCF8563_TimeLib/PCF8563_TimeLib.ino new file mode 100644 index 0000000..1456e4f --- /dev/null +++ b/lib/SensorsLib/examples/PCF8563_TimeLib/PCF8563_TimeLib.ino @@ -0,0 +1,101 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2022 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file PCF8563_TimeLib.ino + * @author Lewis He (lewishe@outlook.com) + * @date 2022-12-12 + * + */ +#include +#include +#include +#include "SensorPCF8563.tpp" +#include + +// lilygo t-beam-s3-core pin +#define I2C_SDA 42 +#define I2C_SCL 41 +#define RTC_IRQ 14 + +SensorPCF8563 rtc; +uint32_t lastMillis; +char buf[64]; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + +#ifdef LILYGO_TBEAM_SUPREME_V3_0 + extern bool setupPower(); + setupPower(); +#endif + + pinMode(RTC_IRQ, INPUT_PULLUP); + + if (!rtc.begin(Wire, PCF8563_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) { + Serial.println("Failed to find PCF8563 - check your wiring!"); + while (1) { + delay(1000); + } + } + +} + + +void loop() +{ + if (millis() - lastMillis > 1000) { + + lastMillis = millis(); + + struct tm timeinfo; + // Get the time C library structure + rtc.getDateTime(&timeinfo); + + // Format the output using the strftime function + // For more formats, please refer to : + // https://man7.org/linux/man-pages/man3/strftime.3.html + + size_t written = strftime(buf, 64, "%A, %B %d %Y %H:%M:%S", &timeinfo); + + if (written != 0) { + Serial.println(buf); + } + + written = strftime(buf, 64, "%b %d %Y %H:%M:%S", &timeinfo); + if (written != 0) { + Serial.println(buf); + } + + + written = strftime(buf, 64, "%A, %d. %B %Y %I:%M%p", &timeinfo); + if (written != 0) { + Serial.println(buf); + } + } +} + + + diff --git a/lib/SensorsLib/examples/PCF8563_TimeLib/power.cpp b/lib/SensorsLib/examples/PCF8563_TimeLib/power.cpp new file mode 100644 index 0000000..96d5804 --- /dev/null +++ b/lib/SensorsLib/examples/PCF8563_TimeLib/power.cpp @@ -0,0 +1,167 @@ +/** + * @file power.cpp + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2022 + * @date 2022-10-25 + * + */ + + +#ifdef LILYGO_TBEAM_SUPREME_V3_0 +#include +#include "XPowersAXP2101.tpp" +#include "XPowersAXP192.tpp" + + + +#define I2C_SDA 42 +#define I2C_SCL 41 +#define PMU_IRQ 40 + +XPowersLibInterface *PMU = NULL; + +bool setupPower() +{ + Serial.println("setupPower"); + + if (!PMU) { + PMU = new XPowersAXP2101(Wire, I2C_SDA, I2C_SCL); + if (!PMU->init()) { + Serial.println("Warning: Failed to find AXP2101 power management"); + delete PMU; + PMU = NULL; + } else { + Serial.println("AXP2101 PMU init succeeded, using AXP2101 PMU"); + } + } + + if (!PMU) { + return false; + } + + if (PMU->getChipModel() == XPOWERS_AXP2101) { + +#if defined(LILYGO_TBEAM_V1_2) + + PMU->setProtectedChannel(XPOWERS_DCDC1); + + PMU->disablePowerOutput(XPOWERS_DCDC2); + PMU->disablePowerOutput(XPOWERS_DCDC3); + PMU->disablePowerOutput(XPOWERS_DCDC4); + PMU->disablePowerOutput(XPOWERS_DCDC5); + + // PMU->disablePowerOutput(XPOWERS_ALDO1); + // PMU->disablePowerOutput(XPOWERS_ALDO2); + // PMU->disablePowerOutput(XPOWERS_ALDO3); + PMU->disablePowerOutput(XPOWERS_ALDO4); + + PMU->disablePowerOutput(XPOWERS_BLDO1); + PMU->disablePowerOutput(XPOWERS_BLDO2); + + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + + PMU->enablePowerOutput(XPOWERS_VBACKUP); + PMU->enablePowerOutput(XPOWERS_ALDO1); + PMU->enablePowerOutput(XPOWERS_ALDO2); + PMU->enablePowerOutput(XPOWERS_ALDO3); + + PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V4); + +#elif defined(LILYGO_TBEAM_SUPREME_V3_0) + + //t-beam m.2 inface + //gps + PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO4); + + // lora + PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO3); + + // Sensor + PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO1); + + PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO2); + + //Sdcard + PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); + PMU->enablePowerOutput(XPOWERS_BLDO1); + + //face m.2 + PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC3); + + PMU->setPowerChannelVoltage(XPOWERS_DCDC4, XPOWERS_AXP2101_DCDC4_VOL2_MAX); + PMU->enablePowerOutput(XPOWERS_DCDC4); + + PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC5); + + + //not use channel + PMU->disablePowerOutput(XPOWERS_DCDC2); + // PMU->disablePowerOutput(XPOWERS_DCDC4); + // PMU->disablePowerOutput(XPOWERS_DCDC5); + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + PMU->disablePowerOutput(XPOWERS_VBACKUP); + +#endif + } + + PMU->enableSystemVoltageMeasure(); + PMU->enableVbusVoltageMeasure(); + PMU->enableBattVoltageMeasure(); + PMU->disableTSPinMeasure(); + + Serial.printf("=========================================\n"); + if (PMU->isChannelAvailable(XPOWERS_DCDC1)) { + Serial.printf("DC1 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC2)) { + Serial.printf("DC2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC3)) { + Serial.printf("DC3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC4)) { + Serial.printf("DC4 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC5)) { + Serial.printf("DC5 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC5) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC5)); + } + if (PMU->isChannelAvailable(XPOWERS_LDO2)) { + Serial.printf("LDO2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2)); + } + if (PMU->isChannelAvailable(XPOWERS_LDO3)) { + Serial.printf("LDO3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO1)) { + Serial.printf("ALDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO2)) { + Serial.printf("ALDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO3)) { + Serial.printf("ALDO3: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO4)) { + Serial.printf("ALDO4: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO1)) { + Serial.printf("BLDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO2)) { + Serial.printf("BLDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2)); + } + Serial.printf("=========================================\n"); + + + return true; +} + +#endif \ No newline at end of file diff --git a/lib/SensorsLib/examples/PCF8563_TimeSynchronization/PCF8563_TimeSynchronization.ino b/lib/SensorsLib/examples/PCF8563_TimeSynchronization/PCF8563_TimeSynchronization.ino new file mode 100644 index 0000000..f8418c3 --- /dev/null +++ b/lib/SensorsLib/examples/PCF8563_TimeSynchronization/PCF8563_TimeSynchronization.ino @@ -0,0 +1,153 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2022 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file PCF8563_TimeSynchronization.ino + * @author Lewis He (lewishe@outlook.com) + * @date 2022-12-12 + * + */ +#include +#include +#include +#include +#include +#include +#include "SensorPCF8563.tpp" + +// lilygo t-beam-s3-core pin +#define I2C_SDA 42 +#define I2C_SCL 41 +#define RTC_IRQ 14 + +const char *ssid = "YOUR_SSID"; +const char *password = "YOUR_PASS"; + +const char *ntpServer1 = "pool.ntp.org"; +const char *ntpServer2 = "time.nist.gov"; +const long gmtOffset_sec = 3600; +const int daylightOffset_sec = 3600; + +const char *time_zone = "CST-8"; // TimeZone rule for Europe/Rome including daylight adjustment rules (optional) + +SensorPCF8563 rtc; +uint32_t lastMillis; + + +// Callback function (get's called when time adjusts via NTP) +void timeavailable(struct timeval *t) +{ + Serial.println("Got time adjustment from NTP, Write the hardware clock"); + + // Write synchronization time to hardware + rtc.hwClockWrite(); +} + +void setup() +{ + Serial.begin(115200); + while (!Serial); + +#ifdef LILYGO_TBEAM_SUPREME_V3_0 + extern bool setupPower(); + setupPower(); +#endif + + pinMode(RTC_IRQ, INPUT_PULLUP); + + if (!rtc.begin(Wire, PCF8563_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) { + Serial.println("Failed to find PCF8563 - check your wiring!"); + while (1) { + delay(1000); + } + } + + // set notification call-back function + sntp_set_time_sync_notification_cb( timeavailable ); + + /** + * NTP server address could be aquired via DHCP, + * + * NOTE: This call should be made BEFORE esp32 aquires IP address via DHCP, + * otherwise SNTP option 42 would be rejected by default. + * NOTE: configTime() function call if made AFTER DHCP-client run + * will OVERRIDE aquired NTP server address + */ + sntp_servermode_dhcp(1); // (optional) + + /** + * This will set configured ntp servers and constant TimeZone/daylightOffset + * should be OK if your time zone does not need to adjust daylightOffset twice a year, + * in such a case time adjustment won't be handled automagicaly. + */ + // configTime(gmtOffset_sec, daylightOffset_sec, ntpServer1, ntpServer2); + + /** + * A more convenient approach to handle TimeZones with daylightOffset + * would be to specify a environmnet variable with TimeZone definition including daylight adjustmnet rules. + * A list of rules for your zone could be obtained from https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h + */ + configTzTime(time_zone, ntpServer1, ntpServer2); + + //connect to WiFi + Serial.printf("Connecting to %s ", ssid); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(" CONNECTED"); + +} + + + + +void loop() +{ + if (millis() - lastMillis > 1000) { + + lastMillis = millis(); + + // hardware clock + struct tm hwTimeinfo; + rtc.getDateTime(&hwTimeinfo); + Serial.print("Hardware clock :"); + Serial.println(&hwTimeinfo, "%A, %B %d %Y %H:%M:%S"); + + // system clock + struct tm timeinfo; + if (!getLocalTime(&timeinfo)) { + Serial.println("No time available (yet)"); + return; + } + + Serial.print("System clock :"); + Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); + Serial.println(); + + } +} + + + diff --git a/lib/SensorsLib/examples/PCF8563_TimeSynchronization/power.cpp b/lib/SensorsLib/examples/PCF8563_TimeSynchronization/power.cpp new file mode 100644 index 0000000..96d5804 --- /dev/null +++ b/lib/SensorsLib/examples/PCF8563_TimeSynchronization/power.cpp @@ -0,0 +1,167 @@ +/** + * @file power.cpp + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2022 + * @date 2022-10-25 + * + */ + + +#ifdef LILYGO_TBEAM_SUPREME_V3_0 +#include +#include "XPowersAXP2101.tpp" +#include "XPowersAXP192.tpp" + + + +#define I2C_SDA 42 +#define I2C_SCL 41 +#define PMU_IRQ 40 + +XPowersLibInterface *PMU = NULL; + +bool setupPower() +{ + Serial.println("setupPower"); + + if (!PMU) { + PMU = new XPowersAXP2101(Wire, I2C_SDA, I2C_SCL); + if (!PMU->init()) { + Serial.println("Warning: Failed to find AXP2101 power management"); + delete PMU; + PMU = NULL; + } else { + Serial.println("AXP2101 PMU init succeeded, using AXP2101 PMU"); + } + } + + if (!PMU) { + return false; + } + + if (PMU->getChipModel() == XPOWERS_AXP2101) { + +#if defined(LILYGO_TBEAM_V1_2) + + PMU->setProtectedChannel(XPOWERS_DCDC1); + + PMU->disablePowerOutput(XPOWERS_DCDC2); + PMU->disablePowerOutput(XPOWERS_DCDC3); + PMU->disablePowerOutput(XPOWERS_DCDC4); + PMU->disablePowerOutput(XPOWERS_DCDC5); + + // PMU->disablePowerOutput(XPOWERS_ALDO1); + // PMU->disablePowerOutput(XPOWERS_ALDO2); + // PMU->disablePowerOutput(XPOWERS_ALDO3); + PMU->disablePowerOutput(XPOWERS_ALDO4); + + PMU->disablePowerOutput(XPOWERS_BLDO1); + PMU->disablePowerOutput(XPOWERS_BLDO2); + + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + + PMU->enablePowerOutput(XPOWERS_VBACKUP); + PMU->enablePowerOutput(XPOWERS_ALDO1); + PMU->enablePowerOutput(XPOWERS_ALDO2); + PMU->enablePowerOutput(XPOWERS_ALDO3); + + PMU->setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V4); + +#elif defined(LILYGO_TBEAM_SUPREME_V3_0) + + //t-beam m.2 inface + //gps + PMU->setPowerChannelVoltage(XPOWERS_ALDO4, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO4); + + // lora + PMU->setPowerChannelVoltage(XPOWERS_ALDO3, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO3); + + // Sensor + PMU->setPowerChannelVoltage(XPOWERS_ALDO1, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO1); + + PMU->setPowerChannelVoltage(XPOWERS_ALDO2, 3300); + PMU->enablePowerOutput(XPOWERS_ALDO2); + + //Sdcard + PMU->setPowerChannelVoltage(XPOWERS_BLDO1, 3300); + PMU->enablePowerOutput(XPOWERS_BLDO1); + + //face m.2 + PMU->setPowerChannelVoltage(XPOWERS_DCDC3, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC3); + + PMU->setPowerChannelVoltage(XPOWERS_DCDC4, XPOWERS_AXP2101_DCDC4_VOL2_MAX); + PMU->enablePowerOutput(XPOWERS_DCDC4); + + PMU->setPowerChannelVoltage(XPOWERS_DCDC5, 3300); + PMU->enablePowerOutput(XPOWERS_DCDC5); + + + //not use channel + PMU->disablePowerOutput(XPOWERS_DCDC2); + // PMU->disablePowerOutput(XPOWERS_DCDC4); + // PMU->disablePowerOutput(XPOWERS_DCDC5); + PMU->disablePowerOutput(XPOWERS_DLDO1); + PMU->disablePowerOutput(XPOWERS_DLDO2); + PMU->disablePowerOutput(XPOWERS_VBACKUP); + +#endif + } + + PMU->enableSystemVoltageMeasure(); + PMU->enableVbusVoltageMeasure(); + PMU->enableBattVoltageMeasure(); + PMU->disableTSPinMeasure(); + + Serial.printf("=========================================\n"); + if (PMU->isChannelAvailable(XPOWERS_DCDC1)) { + Serial.printf("DC1 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC1)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC2)) { + Serial.printf("DC2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC2)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC3)) { + Serial.printf("DC3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC3)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC4)) { + Serial.printf("DC4 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC4)); + } + if (PMU->isChannelAvailable(XPOWERS_DCDC5)) { + Serial.printf("DC5 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_DCDC5) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_DCDC5)); + } + if (PMU->isChannelAvailable(XPOWERS_LDO2)) { + Serial.printf("LDO2 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO2)); + } + if (PMU->isChannelAvailable(XPOWERS_LDO3)) { + Serial.printf("LDO3 : %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_LDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_LDO3)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO1)) { + Serial.printf("ALDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO1)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO2)) { + Serial.printf("ALDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO2)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO3)) { + Serial.printf("ALDO3: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO3) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO3)); + } + if (PMU->isChannelAvailable(XPOWERS_ALDO4)) { + Serial.printf("ALDO4: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_ALDO4) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_ALDO4)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO1)) { + Serial.printf("BLDO1: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO1) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO1)); + } + if (PMU->isChannelAvailable(XPOWERS_BLDO2)) { + Serial.printf("BLDO2: %s Voltage: %04u mV \n", PMU->isPowerChannelEnable(XPOWERS_BLDO2) ? "+" : "-", PMU->getPowerChannelVoltage(XPOWERS_BLDO2)); + } + Serial.printf("=========================================\n"); + + + return true; +} + +#endif \ No newline at end of file diff --git a/lib/SensorsLib/src/REG/PCF8563Constants.h b/lib/SensorsLib/src/REG/PCF8563Constants.h new file mode 100644 index 0000000..2364d79 --- /dev/null +++ b/lib/SensorsLib/src/REG/PCF8563Constants.h @@ -0,0 +1,85 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2022 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file PCF8563Constants.h + * @author Lewis He (lewishe@outlook.com) + * @date 2022-12-09 + * + */ + +#pragma once + + +#define PCF8563_SLAVE_ADDRESS (0x51) + +#define PCF8563_STAT1_REG (0x00) +#define PCF8563_STAT2_REG (0x01) +#define PCF8563_SEC_REG (0x02) +#define PCF8563_MIN_REG (0x03) +#define PCF8563_HR_REG (0x04) +#define PCF8563_DAY_REG (0x05) +#define PCF8563_WEEKDAY_REG (0x06) +#define PCF8563_MONTH_REG (0x07) +#define PCF8563_YEAR_REG (0x08) +#define PCF8563_ALRM_MIN_REG (0x09) +#define PCF8563_SQW_REG (0x0D) +#define PCF8563_TIMER1_REG (0x0E) +#define PCF8563_TIMER2_REG (0x0F) + +#define PCF8563_VOL_LOW_MASK (0x80) +#define PCF8563_MINUTES_MASK (0x7F) +#define PCF8563_HOUR_MASK (0x3F) +#define PCF8563_WEEKDAY_MASK (0x07) +#define PCF8563_CENTURY_MASK (0x80) +#define PCF8563_DAY_MASK (0x3F) +#define PCF8563_MONTH_MASK (0x1F) +#define PCF8563_TIMER_CTL_MASK (0x03) + + +#define PCF8563_ALARM_AF (0x08) +#define PCF8563_TIMER_TF (0x04) +#define PCF8563_ALARM_AIE (0x02) +#define PCF8563_TIMER_TIE (0x01) +#define PCF8563_TIMER_TE (0x80) +#define PCF8563_TIMER_TD10 (0x03) + +#define PCF8563_NO_ALARM (0xFF) +#define PCF8563_ALARM_ENABLE (0x80) +#define PCF8563_CLK_ENABLE (0x80) + + +#define RTC_DAYS_IN_JANUARY (31u) +#define RTC_DAYS_IN_FEBRUARY (28u) +#define RTC_DAYS_IN_MARCH (31u) +#define RTC_DAYS_IN_APRIL (30u) +#define RTC_DAYS_IN_MAY (31u) +#define RTC_DAYS_IN_JUNE (30u) +#define RTC_DAYS_IN_JULY (31u) +#define RTC_DAYS_IN_AUGUST (31u) +#define RTC_DAYS_IN_SEPTEMBER (30u) +#define RTC_DAYS_IN_OCTOBER (31u) +#define RTC_DAYS_IN_NOVEMBER (30u) +#define RTC_DAYS_IN_DECEMBER (31u) + + diff --git a/lib/SensorsLib/src/SensorCommon.tpp b/lib/SensorsLib/src/SensorCommon.tpp index 0b8a3da..6370bd8 100644 --- a/lib/SensorsLib/src/SensorCommon.tpp +++ b/lib/SensorsLib/src/SensorCommon.tpp @@ -59,6 +59,24 @@ #define SENSORLIB_ATTR_NOT_IMPLEMENTED __attribute__((error("Not implemented"))) +#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA) +#define SPI_DATA_ORDER MSBFIRST +#define DEFAULT_SDA (0xFF) +#define DEFAULT_SCL (0xFF) +#define DEFAULT_SPISETTING SPISettings() +#else //esp32 +#define SPI_DATA_ORDER SPI_MSBFIRST +#define DEFAULT_SDA (SDA) +#define DEFAULT_SCL (SCL) +#define DEFAULT_SPISETTING SPISettings(__freq, __dataOrder, __dataMode); +#endif + +#ifndef ESP32 +#define log_e(...) +#define log_i(...) +#define log_d(...) +#endif + template class SensorCommon @@ -73,7 +91,7 @@ public: } } - void setSpiSetting(uint32_t freq, uint8_t dataOrder = SPI_MSBFIRST, uint8_t dataMode = SPI_MODE0) + void setSpiSetting(uint32_t freq, uint8_t dataOrder = SPI_DATA_ORDER, uint8_t dataMode = SPI_MODE0) { __freq = freq; __dataOrder = dataOrder; @@ -86,7 +104,11 @@ public: LOG("Using Wire interface.\n"); if (__has_init)return thisChip().initImpl(); __wire = &w; - __wire->begin(sda, scl); +#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA) + __wire->begin(); +#else + __wire->begin(__sda, __scl); +#endif __addr = addr; __spi = NULL; thisReadRegCallback = NULL; @@ -103,12 +125,16 @@ public: __cs = cs; pinMode(__cs, OUTPUT); digitalWrite(__cs, HIGH); - __spiSetting = new SPISettings(__freq, __dataOrder, __dataMode); + __spiSetting = new DEFAULT_SPISETTING; if (!__spiSetting) { return false; } if (mosi != -1 && miso != -1 && sck == -1) { +#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA) + __spi->begin(); +#else __spi->begin(sck, miso, mosi); +#endif } else { __spi->begin(); } @@ -332,7 +358,11 @@ protected: if (__wire) { log_i("SDA:%d SCL:%d", __sda, __scl); +#if defined(NRF52840_XXAA) || defined(NRF52832_XXAA) + __wire->begin(); +#else __wire->begin(__sda, __scl); +#endif } if (__spi) { // int cs, int mosi = -1, int miso = -1, int sck = -1, SPIClass &spi = SPI @@ -375,7 +405,7 @@ protected: SPISettings *__spiSetting = NULL; #endif uint32_t __freq = 1000000; - uint8_t __dataOrder = SPI_MSBFIRST; + uint8_t __dataOrder = SPI_DATA_ORDER; uint8_t __dataMode = SPI_MODE0; int __readMask = -1; int __sda = -1; diff --git a/lib/SensorsLib/src/SensorPCF8563.tpp b/lib/SensorsLib/src/SensorPCF8563.tpp new file mode 100644 index 0000000..fdb732f --- /dev/null +++ b/lib/SensorsLib/src/SensorPCF8563.tpp @@ -0,0 +1,560 @@ +/** + * + * @license MIT License + * + * Copyright (c) 2022 lewis he + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * @file SensorPCF8563.tpp + * @author Lewis He (lewishe@outlook.com) + * @date 2022-12-09 + * + */ + + +#include "REG/PCF8563Constants.h" +#include "SensorCommon.tpp" +#include + +class RTC_DateTime +{ +public: + RTC_DateTime() : year(0), month(0), day(0), hour(0), minute(0), second(0), week(0), available(false) {} + RTC_DateTime(const char *date, const char *time) + { + // sample input: date = "Dec 26 2009", time = "12:34:56" + year = 2000 + StringToUint8(date + 9); + // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec + switch (date[0]) { + case 'J': + if ( date[1] == 'a' ) + month = 1; + else if ( date[2] == 'n' ) + month = 6; + else + month = 7; + break; + case 'F': + month = 2; + break; + case 'A': + month = date[1] == 'p' ? 4 : 8; + break; + case 'M': + month = date[2] == 'r' ? 3 : 5; + break; + case 'S': + month = 9; + break; + case 'O': + month = 10; + break; + case 'N': + month = 11; + break; + case 'D': + month = 12; + break; + } + day = StringToUint8(date + 4); + hour = StringToUint8(time); + minute = StringToUint8(time + 3); + second = StringToUint8(time + 6); + } + RTC_DateTime(uint16_t year, + uint8_t month, + uint8_t day, + uint8_t hour, + uint8_t minute, + uint8_t second + ); + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t minute; + uint8_t second; + uint8_t week; + bool available; + bool operator==(RTC_DateTime d) + { + return ((d.year == year) && + (d.month == month) && + (d.day == day) && + (d.hour == hour) && + (d.minute == minute)); + } +private: + uint8_t StringToUint8(const char *pString) + { + uint8_t value = 0; + + // skip leading 0 and spaces + while ('0' == *pString || *pString == ' ') { + pString++; + } + + // calculate number until we hit non-numeral char + while ('0' <= *pString && *pString <= '9') { + value *= 10; + value += *pString - '0'; + pString++; + } + return value; + } +}; + +class RTC_Alarm +{ +public: + RTC_Alarm(void): minute(0), hour(0), day(0), week(0) {} + RTC_Alarm( + uint8_t minute, + uint8_t hour, + uint8_t day, + uint8_t week + ): minute(minute), hour(hour), day(day), week(week) + { + } + uint8_t minute; + uint8_t hour; + uint8_t day; + uint8_t week; +}; + + +class SensorPCF8563 : + public SensorCommon +{ + friend class SensorCommon; +public: + + enum { + CLK_32_768KHZ, + CLK_1024KHZ, + CLK_32HZ, + CLK_1HZ, + }; + + enum { + DATETIME_FORMAT_HM, + DATETIME_FORMAT_HMS, + DATETIME_FORMAT_YYYY_MM_DD, + DATETIME_FORMAT_MM_DD_YYYY, + DATETIME_FORMAT_DD_MM_YYYY, + DATETIME_FORMAT_YYYY_MM_DD_H_M_S, + DATETIME_FORMAT_YYYY_MM_DD_H_M_S_WEEK, + }; + +#if defined(ARDUINO) + SensorPCF8563(TwoWire &w, int sda = DEFAULT_SDA, int scl = DEFAULT_SCL, uint8_t addr = PCF8563_SLAVE_ADDRESS) + { + __wire = &w; + __sda = sda; + __scl = scl; + __addr = addr; + } +#endif + + SensorPCF8563() + { +#if defined(ARDUINO) + __wire = &Wire; + __sda = DEFAULT_SDA; + __scl = DEFAULT_SCL; +#endif + __addr = PCF8563_SLAVE_ADDRESS; + } + + ~SensorPCF8563() + { + deinit(); + } + + bool init() + { + return begin(); + } + + void deinit() + { + // end(); + } + + void setDateTime(uint16_t year, + uint8_t month, + uint8_t day, + uint8_t hour, + uint8_t minute, + uint8_t second) + { + uint8_t buffer[7]; + buffer[0] = DEC2BCD(second) & 0x7F; + buffer[1] = DEC2BCD(minute); + buffer[2] = DEC2BCD(hour); + buffer[3] = DEC2BCD(day); + buffer[4] = getDayOfWeek(day, month, year); + buffer[5] = DEC2BCD(month); + buffer[6] = DEC2BCD(year % 100); + + if ((2000 % year) == 2000) { + buffer[5] &= 0x7F; + } else { + buffer[5] |= 0x80; + } + writeRegister(PCF8563_SEC_REG, buffer, 7); + } + + + RTC_DateTime getDateTime() + { + RTC_DateTime datetime; + uint8_t buffer[7]; + readRegister(PCF8563_SEC_REG, buffer, 7); + datetime.available = ((buffer[0] & 0x80) == 0x80) ? false : true; + datetime.second = BCD2DEC(buffer[0] & 0x7F); + datetime.minute = BCD2DEC(buffer[1] & 0x7F); + datetime.hour = BCD2DEC(buffer[2] & 0x3F); + datetime.day = BCD2DEC(buffer[3] & 0x3F); + datetime.week = BCD2DEC(buffer[4] & 0x07); + datetime.month = BCD2DEC(buffer[5] & 0x1F); + datetime.year = BCD2DEC(buffer[6]); + //cetury : 0 = 1900 , 1 = 2000 + datetime.year += (buffer[5] & PCF8563_CENTURY_MASK) ? 1900 : 2000; + return datetime; + } + + void getDateTime(struct tm *timeinfo) + { + if (!timeinfo)return; + *timeinfo = conversionUnixTime(getDateTime()); + } + + RTC_Alarm getAlarm() + { + uint8_t buffer[4]; + readRegister(PCF8563_ALRM_MIN_REG, buffer, 4); + buffer[0] = BCD2DEC(buffer[0] & 0x80); + buffer[1] = BCD2DEC(buffer[1] & 0x40); + buffer[2] = BCD2DEC(buffer[2] & 0x40); + buffer[3] = BCD2DEC(buffer[3] & 0x08); + return RTC_Alarm(buffer[0], buffer[1], buffer[2], buffer[3]); + } + + void enableAlarm() + { + setRegisterBit(PCF8563_STAT2_REG, 1); + } + + void disableAlarm() + { + clrRegisterBit(PCF8563_STAT2_REG, 1); + } + + void resetAlarm() + { + clrRegisterBit(PCF8563_STAT2_REG, 3); + } + + bool isAlarmActive() + { + return getRegisterBit(PCF8563_STAT2_REG, 3); + } + + void setAlarm(RTC_Alarm alarm) + { + setAlarm(alarm.minute, alarm.hour, alarm.day, alarm.week); + } + + void setAlarm(uint8_t hour, uint8_t minute, uint8_t day, uint8_t week) + { + uint8_t buffer[4] = {0}; + if (minute != PCF8563_NO_ALARM) { + buffer[0] = DEC2BCD(constrain(minute, 0, 59)); + buffer[0] &= ~PCF8563_ALARM_ENABLE; + } else { + buffer[0] = PCF8563_ALARM_ENABLE; + } + + if (hour != PCF8563_NO_ALARM) { + buffer[1] = DEC2BCD(constrain(hour, 0, 23)); + buffer[1] &= ~PCF8563_ALARM_ENABLE; + } else { + buffer[1] = PCF8563_ALARM_ENABLE; + } + if (day != PCF8563_NO_ALARM) { + buffer[2] = DEC2BCD(constrain(day, 1, 31)); + buffer[2] &= ~PCF8563_ALARM_ENABLE; + } else { + buffer[2] = PCF8563_ALARM_ENABLE; + } + if (week != PCF8563_NO_ALARM) { + buffer[3] = DEC2BCD(constrain(week, 0, 6)); + buffer[3] &= ~PCF8563_ALARM_ENABLE; + } else { + buffer[3] = PCF8563_ALARM_ENABLE; + } + writeRegister(PCF8563_ALRM_MIN_REG, buffer, 4); + } + + void setAlarmByMinutes(uint8_t minute) + { + setAlarm(PCF8563_NO_ALARM, minute, PCF8563_NO_ALARM, PCF8563_NO_ALARM); + } + void setAlarmByDays(uint8_t day) + { + setAlarm(PCF8563_NO_ALARM, PCF8563_NO_ALARM, day, PCF8563_NO_ALARM); + } + void setAlarmByHours(uint8_t hour) + { + setAlarm(hour, PCF8563_NO_ALARM, PCF8563_NO_ALARM, PCF8563_NO_ALARM); + } + void setAlarmByWeekDay(uint8_t week) + { + setAlarm(PCF8563_NO_ALARM, PCF8563_NO_ALARM, PCF8563_NO_ALARM, week); + } + + bool isCountdownTimerEnable() + { + uint8_t buffer[2]; + buffer[0] = readRegister(PCF8563_STAT2_REG); + buffer[1] = readRegister(PCF8563_TIMER1_REG); + if (buffer[0] & PCF8563_TIMER_TIE) { + return buffer[1] & PCF8563_TIMER_TE ? true : false; + } + return false; + } + + bool isCountdownTimerActive() + { + return getRegisterBit(PCF8563_STAT2_REG, 2); + } + + void enableCountdownTimer() + { + setRegisterBit(PCF8563_STAT2_REG, 0); + } + + void disableCountdownTimer() + { + clrRegisterBit(PCF8563_STAT2_REG, 0); + } + + void setCountdownTimer(uint8_t val, uint8_t freq) + { + uint8_t buffer[3]; + buffer[1] = readRegister(PCF8563_TIMER1_REG); + buffer[1] |= (freq & PCF8563_TIMER_TD10); + buffer[2] = val; + writeRegister(PCF8563_TIMER1_REG, buffer[1]); + writeRegister(PCF8563_TIMER2_REG, buffer[2]); + } + + void clearCountdownTimer() + { + uint8_t val; + val = readRegister(PCF8563_STAT2_REG); + val &= ~(PCF8563_TIMER_TF | PCF8563_TIMER_TIE); + val |= PCF8563_ALARM_AF; + writeRegister(PCF8563_STAT2_REG, val); + writeRegister(PCF8563_TIMER1_REG, 0x00); + } + + void enableCLK(uint8_t freq) + { + if (freq > CLK_1HZ) return; + writeRegister(PCF8563_SQW_REG, freq | PCF8563_CLK_ENABLE); + } + + void disableCLK() + { + clrRegisterBit(PCF8563_SQW_REG, 7); + } + + const char *strftime(uint8_t sytle = DATETIME_FORMAT_YYYY_MM_DD_H_M_S_WEEK) + { + const char *weekString[] = {"Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"}; + static char format[64]; + RTC_DateTime t = getDateTime(); + switch (sytle) { + case DATETIME_FORMAT_HM: + snprintf(format, sizeof(format), "%02d:%02d", t.hour, t.minute); + break; + case DATETIME_FORMAT_HMS: + snprintf(format, sizeof(format), "%02d:%02d:%02d", t.hour, t.minute, t.second); + break; + case DATETIME_FORMAT_YYYY_MM_DD: + snprintf(format, sizeof(format), "%d-%02d-%02d", t.year, t.month, t.day); + break; + case DATETIME_FORMAT_MM_DD_YYYY: + snprintf(format, sizeof(format), "%02d-%02d-%d", t.month, t.day, t.year); + break; + case DATETIME_FORMAT_DD_MM_YYYY: + snprintf(format, sizeof(format), "%02d-%02d-%d", t.day, t.month, t.year); + break; + case DATETIME_FORMAT_YYYY_MM_DD_H_M_S: + snprintf(format, sizeof(format), "%d-%02d-%02d/%02d:%02d:%02d", t.year, t.month, t.day, t.hour, t.minute, t.second); + break; + case DATETIME_FORMAT_YYYY_MM_DD_H_M_S_WEEK: + snprintf(format, sizeof(format), "%d-%02d-%02d/%02d:%02d:%02d - %s", t.year, t.month, t.day, t.hour, t.minute, t.second, weekString[t.week > 6 ? 0 : t.week]); + break; + default: + snprintf(format, sizeof(format), "%02d:%02d", t.hour, t.minute); + break; + } + return format; + } + + struct tm conversionUnixTime(RTC_DateTime datetime) + { + struct tm t_tm; + t_tm.tm_hour = datetime.hour; + t_tm.tm_min = datetime.minute; + t_tm.tm_sec = datetime.second; + t_tm.tm_year = datetime.year - 1900; //Year, whose value starts from 1900 + t_tm.tm_mon = datetime.month - 1; //Month (starting from January, 0 for January) - Value range is [0,11] + t_tm.tm_mday = datetime.day; + t_tm.tm_wday = datetime.week; + return t_tm; + } + + time_t hwClockRead() + { + struct tm t_tm = conversionUnixTime(getDateTime()); + struct timeval val; + val.tv_sec = mktime(&t_tm); + val.tv_usec = 0; +#if __BSD_VISIBLE + settimeofday(&val, NULL); +#endif /*__BSD_VISIBLE*/ + return val.tv_sec; + } + + void hwClockWrite() + { + time_t now; + struct tm info; + time(&now); + localtime_r(&now, &info); + setDateTime(info.tm_year + 1900, + info.tm_mon + 1, + info.tm_mday, + info.tm_hour, + info.tm_min, + info.tm_sec); + } + + uint32_t getDayOfWeek(uint32_t day, uint32_t month, uint32_t year) + { + uint32_t val; + if (month < 3) { + month = 12u + month; + year--; + } + val = (day + (((month + 1u) * 26u) / 10u) + year + (year / 4u) + (6u * (year / 100u)) + (year / 400u)) % 7u; + if (0u == val) { + val = 7; + } + return (val - 1); + } + + uint8_t getNextMonth(uint8_t curMonth) + { + return ((curMonth < 12u) ? (curMonth + 1u) : 1u); + } + + uint16_t getNextYear(uint16_t curYear) + { + return (curYear + 1u); + } + + uint32_t getLeapYear(uint32_t year) + { + uint32_t val; + if (((0u == (year % 4Lu)) && (0u != (year % 100Lu))) || (0u == (year % 400Lu))) { + val = 1uL; + } else { + val = 0uL; + } + return val; + } + + uint8_t getDaysInMonth(uint8_t month, uint16_t year) + { + const uint8_t daysInMonthTable[12] = {RTC_DAYS_IN_JANUARY, + RTC_DAYS_IN_FEBRUARY, + RTC_DAYS_IN_MARCH, + RTC_DAYS_IN_APRIL, + RTC_DAYS_IN_MAY, + RTC_DAYS_IN_JUNE, + RTC_DAYS_IN_JULY, + RTC_DAYS_IN_AUGUST, + RTC_DAYS_IN_SEPTEMBER, + RTC_DAYS_IN_OCTOBER, + RTC_DAYS_IN_NOVEMBER, + RTC_DAYS_IN_DECEMBER + }; + + uint8_t val; + val = daysInMonthTable[month - 1u]; + if (2 == month) { + if (0u != getLeapYear(year)) { + val++; + } + } + return val; + } + +private: + + uint8_t BCD2DEC(uint8_t val) + { + return ((val / 16 * 10) + (val % 16)); + } + uint8_t DEC2BCD(uint8_t val) + { + return ((val / 10 * 16) + (val % 10)); + } + + bool initImpl() + { + // Check whether RTC time is valid? If it is invalid, it can be judged + // that there is a problem with the hardware, or the RTC power supply voltage is too low + int count = 0; + for (int i = 0; i < 3; ++i) { + if (!getRegisterBit(PCF8563_SEC_REG, 7)) { + count++; + } + } + return (count == 3); + } + + int getReadMaskImpl() + { + return -1; + } + +protected: + + +}; + + +