Skip to content

Commit 7c33fdf

Browse files
authored
Merge pull request #10 from Forairaaaaa/v1.1.0
V1.1.0
2 parents 595890d + 079c1b7 commit 7c33fdf

6 files changed

Lines changed: 229 additions & 149 deletions

File tree

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"M5Unified": "*",
1414
"M5GFX": "*"
1515
},
16-
"version": "1.0.0",
16+
"version": "1.1.0",
1717
"frameworks": "arduino",
1818
"platforms": "espressif32"
1919
}

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=M5StamPLC
2-
version=1.0.0
2+
version=1.1.0
33
author=M5Stack
44
maintainer=M5Stack
55
sentence=M5StamPLC is a library for M5StamPLC

src/M5StamPLC.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ void M5_STAMPLC::begin()
3838
}
3939
}
4040

41+
void M5_STAMPLC::update()
42+
{
43+
M5.update();
44+
}
45+
4146
/* -------------------------------------------------------------------------- */
4247
/* I2C */
4348
/* -------------------------------------------------------------------------- */
@@ -62,7 +67,7 @@ void M5_STAMPLC::io_expander_a_init()
6267
ioe.setDirection(5, true);
6368
ioe.setPullMode(5, false);
6469
ioe.setHighImpedance(5, true);
65-
70+
6671
ioe.setDirection(6, true);
6772
ioe.setPullMode(6, false);
6873
ioe.setHighImpedance(6, true);
@@ -73,7 +78,7 @@ void M5_STAMPLC::setBacklight(bool on)
7378
auto& ioe = M5.getIOExpander(0);
7479

7580
ioe.setHighImpedance(7, !on);
76-
ioe.digitalWrite(7, !on); // backlight is active low
81+
ioe.digitalWrite(7, !on); // backlight is active low
7782
}
7883

7984
void M5_STAMPLC::setStatusLight(const uint8_t& r, const uint8_t& g, const uint8_t& b)
@@ -200,12 +205,12 @@ void M5_STAMPLC::ina226_init()
200205
ESP_LOGE(TAG, "ina226 init failed");
201206
} else {
202207
INA226_Class::config_t cfg;
203-
cfg.sampling_rate = INA226_Class::Sampling::Rate16;
204-
cfg.bus_conversion_time = INA226_Class::ConversionTime::US_1100;
208+
cfg.sampling_rate = INA226_Class::Sampling::Rate16;
209+
cfg.bus_conversion_time = INA226_Class::ConversionTime::US_1100;
205210
cfg.shunt_conversion_time = INA226_Class::ConversionTime::US_1100;
206-
cfg.mode = INA226_Class::Mode::ShuntAndBus;
207-
cfg.shunt_res = 0.01f;
208-
cfg.max_expected_current = 2.0f;
211+
cfg.mode = INA226_Class::Mode::ShuntAndBus;
212+
cfg.shunt_res = 0.01f;
213+
cfg.max_expected_current = 2.0f;
209214
INA226.config(cfg);
210215
}
211216
}
@@ -481,6 +486,9 @@ void M5_STAMPLC::can_init()
481486
case 125000:
482487
t_config = TWAI_TIMING_CONFIG_125KBITS();
483488
break;
489+
case 250000:
490+
t_config = TWAI_TIMING_CONFIG_250KBITS();
491+
break;
484492
case 500000:
485493
t_config = TWAI_TIMING_CONFIG_500KBITS();
486494
break;

src/M5StamPLC.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,17 @@ class M5_STAMPLC {
4141
}
4242

4343
void begin();
44+
void update();
4445

4546
LGFX_Device& Display = M5.Display;
4647
LGFX_Device& Lcd = M5.Lcd;
4748

4849
LM75B_Class LM75B;
4950
INA226_Class INA226;
5051
RX8130_Class RX8130;
52+
Button_Class& BtnA = M5.BtnA;
53+
Button_Class& BtnB = M5.BtnB;
54+
Button_Class& BtnC = M5.BtnC;
5155

5256
/**
5357
* @brief Set Status Light
@@ -146,8 +150,8 @@ class M5_STAMPLC {
146150
*/
147151
void noTone();
148152

149-
private:
150-
AW9523_Class* _io_expander_b = nullptr; // Controls plc relays, plc inputs
153+
protected:
154+
AW9523_Class* _io_expander_b = nullptr; // Controls plc relays, plc inputs
151155
Config_t _config;
152156

153157
void i2c_init();

src/utils/rx8130/rx8130.cpp

Lines changed: 181 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,181 @@
1-
/*
2-
* SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3-
*
4-
* SPDX-License-Identifier: MIT
5-
*/
6-
#include "rx8130.h"
7-
8-
// RX-8130 Register definitions
9-
#define RX8130_REG_SEC 0x10
10-
#define RX8130_REG_MIN 0x11
11-
#define RX8130_REG_HOUR 0x12
12-
#define RX8130_REG_WDAY 0x13
13-
#define RX8130_REG_MDAY 0x14
14-
#define RX8130_REG_MONTH 0x15
15-
#define RX8130_REG_YEAR 0x16
16-
17-
#define RX8130_REG_ALMIN 0x17
18-
#define RX8130_REG_ALHOUR 0x18
19-
#define RX8130_REG_ALWDAY 0x19
20-
#define RX8130_REG_TCOUNT0 0x1A
21-
#define RX8130_REG_TCOUNT1 0x1B
22-
#define RX8130_REG_EXT 0x1C
23-
#define RX8130_REG_FLAG 0x1D
24-
#define RX8130_REG_CTRL0 0x1E
25-
#define RX8130_REG_CTRL1 0x1F
26-
27-
#define RX8130_REG_END 0x23
28-
29-
// Extension Register (1Ch) bit positions
30-
#define RX8130_BIT_EXT_TSEL (7 << 0)
31-
#define RX8130_BIT_EXT_WADA (1 << 3)
32-
#define RX8130_BIT_EXT_TE (1 << 4)
33-
#define RX8130_BIT_EXT_USEL (1 << 5)
34-
#define RX8130_BIT_EXT_FSEL (3 << 6)
35-
36-
// Flag Register (1Dh) bit positions
37-
#define RX8130_BIT_FLAG_VLF (1 << 1)
38-
#define RX8130_BIT_FLAG_AF (1 << 3)
39-
#define RX8130_BIT_FLAG_TF (1 << 4)
40-
#define RX8130_BIT_FLAG_UF (1 << 5)
41-
42-
// Control 0 Register (1Еh) bit positions
43-
#define RX8130_BIT_CTRL_TSTP (1 << 2)
44-
#define RX8130_BIT_CTRL_AIE (1 << 3)
45-
#define RX8130_BIT_CTRL_TIE (1 << 4)
46-
#define RX8130_BIT_CTRL_UIE (1 << 5)
47-
#define RX8130_BIT_CTRL_STOP (1 << 6)
48-
#define RX8130_BIT_CTRL_TEST (1 << 7)
49-
50-
static uint8_t bcd2dec(uint8_t val)
51-
{
52-
return (val >> 4) * 10 + (val & 0x0f);
53-
}
54-
55-
static uint8_t dec2bcd(uint8_t val)
56-
{
57-
return ((val / 10) << 4) + (val % 10);
58-
}
59-
60-
bool RX8130_Class::begin()
61-
{
62-
bool result = _i2c->start(_addr, false, _freq) && _i2c->stop();
63-
return result;
64-
}
65-
66-
void RX8130_Class::setTime(struct tm *time)
67-
{
68-
uint8_t rbuf = 0;
69-
70-
time->tm_year -= 100;
71-
72-
// set STOP bit before changing clock/calendar
73-
rbuf = readRegister8(RX8130_REG_CTRL0);
74-
rbuf = rbuf | RX8130_BIT_CTRL_STOP;
75-
writeRegister8(RX8130_REG_CTRL0, rbuf);
76-
77-
uint8_t date[7] = {dec2bcd(time->tm_sec), dec2bcd(time->tm_min), dec2bcd(time->tm_hour),
78-
dec2bcd(time->tm_wday), dec2bcd(time->tm_mday), dec2bcd(time->tm_mon),
79-
dec2bcd(time->tm_year % 100)};
80-
81-
writeRegister(RX8130_REG_SEC, date, 7);
82-
83-
// clear STOP bit after changing clock/calendar
84-
rbuf = readRegister8(RX8130_REG_CTRL0);
85-
rbuf = rbuf & ~RX8130_BIT_CTRL_STOP;
86-
writeRegister8(RX8130_REG_CTRL0, rbuf);
87-
}
88-
89-
void RX8130_Class::getTime(struct tm *time)
90-
{
91-
uint8_t date[7];
92-
readRegister(RX8130_REG_SEC, date, 7);
93-
94-
time->tm_sec = bcd2dec(date[RX8130_REG_SEC - 0x10] & 0x7f);
95-
time->tm_min = bcd2dec(date[RX8130_REG_MIN - 0x10] & 0x7f);
96-
time->tm_hour = bcd2dec(date[RX8130_REG_HOUR - 0x10] & 0x3f); // only 24-hour clock
97-
time->tm_mday = bcd2dec(date[RX8130_REG_MDAY - 0x10] & 0x3f);
98-
time->tm_mon = bcd2dec(date[RX8130_REG_MONTH - 0x10] & 0x1f);
99-
time->tm_year = bcd2dec(date[RX8130_REG_YEAR - 0x10]);
100-
time->tm_wday = bcd2dec(date[RX8130_REG_WDAY - 0x10] & 0x7f);
101-
102-
time->tm_year += 100;
103-
}
104-
105-
void RX8130_Class::clearIrqFlags()
106-
{
107-
writeRegister8(RX8130_REG_FLAG, 0);
108-
}
109-
110-
void RX8130_Class::disableIrq()
111-
{
112-
writeRegister8(RX8130_REG_CTRL0, 0);
113-
}
1+
/*
2+
* SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
#include "rx8130.h"
7+
8+
// RX-8130 Register definitions
9+
#define RX8130_REG_SEC 0x10
10+
#define RX8130_REG_MIN 0x11
11+
#define RX8130_REG_HOUR 0x12
12+
#define RX8130_REG_WDAY 0x13
13+
#define RX8130_REG_MDAY 0x14
14+
#define RX8130_REG_MONTH 0x15
15+
#define RX8130_REG_YEAR 0x16
16+
17+
#define RX8130_REG_ALMIN 0x17
18+
#define RX8130_REG_ALHOUR 0x18
19+
#define RX8130_REG_ALWDAY 0x19
20+
#define RX8130_REG_TCOUNT0 0x1A
21+
#define RX8130_REG_TCOUNT1 0x1B
22+
#define RX8130_REG_EXT 0x1C
23+
#define RX8130_REG_FLAG 0x1D
24+
#define RX8130_REG_CTRL0 0x1E
25+
#define RX8130_REG_CTRL1 0x1F
26+
27+
#define RX8130_REG_END 0x23
28+
29+
// Extension Register (1Ch) bit positions
30+
#define RX8130_BIT_EXT_TSEL (7 << 0)
31+
#define RX8130_BIT_EXT_WADA (1 << 3)
32+
#define RX8130_BIT_EXT_TE (1 << 4)
33+
#define RX8130_BIT_EXT_USEL (1 << 5)
34+
#define RX8130_BIT_EXT_FSEL (3 << 6)
35+
36+
// Flag Register (1Dh) bit positions
37+
#define RX8130_BIT_FLAG_VLF (1 << 1)
38+
#define RX8130_BIT_FLAG_AF (1 << 3)
39+
#define RX8130_BIT_FLAG_TF (1 << 4)
40+
#define RX8130_BIT_FLAG_UF (1 << 5)
41+
42+
// Control 0 Register (1Еh) bit positions
43+
#define RX8130_BIT_CTRL_TSTP (1 << 2)
44+
#define RX8130_BIT_CTRL_AIE (1 << 3)
45+
#define RX8130_BIT_CTRL_TIE (1 << 4)
46+
#define RX8130_BIT_CTRL_UIE (1 << 5)
47+
#define RX8130_BIT_CTRL_STOP (1 << 6)
48+
#define RX8130_BIT_CTRL_TEST (1 << 7)
49+
50+
static uint8_t bcd2dec(uint8_t val)
51+
{
52+
return (val >> 4) * 10 + (val & 0x0f);
53+
}
54+
55+
static uint8_t dec2bcd(uint8_t val)
56+
{
57+
return ((val / 10) << 4) + (val % 10);
58+
}
59+
60+
// Helper function to check if a year is a leap year
61+
static bool isLeapYear(int year)
62+
{
63+
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
64+
}
65+
66+
// Helper function to get the number of days in a given month
67+
// Note: month is 1-12 for this function
68+
static int getDaysInMonth(int month, int year)
69+
{
70+
static const int daysInMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
71+
72+
if (month == 2 && isLeapYear(year)) {
73+
return 29;
74+
}
75+
return daysInMonth[month - 1];
76+
}
77+
78+
bool RX8130_Class::begin()
79+
{
80+
bool result = _i2c->start(_addr, false, _freq) && _i2c->stop();
81+
return result;
82+
}
83+
84+
void RX8130_Class::setTime(struct tm *time)
85+
{
86+
uint8_t rbuf = 0;
87+
88+
time->tm_year -= 100;
89+
90+
// set STOP bit before changing clock/calendar
91+
rbuf = readRegister8(RX8130_REG_CTRL0);
92+
rbuf = rbuf | RX8130_BIT_CTRL_STOP;
93+
writeRegister8(RX8130_REG_CTRL0, rbuf);
94+
95+
uint8_t date[7] = {dec2bcd(time->tm_sec), dec2bcd(time->tm_min), dec2bcd(time->tm_hour),
96+
dec2bcd(time->tm_wday), dec2bcd(time->tm_mday), dec2bcd(time->tm_mon + 1),
97+
dec2bcd(time->tm_year % 100)};
98+
99+
writeRegister(RX8130_REG_SEC, date, 7);
100+
101+
// clear STOP bit after changing clock/calendar
102+
rbuf = readRegister8(RX8130_REG_CTRL0);
103+
rbuf = rbuf & ~RX8130_BIT_CTRL_STOP;
104+
writeRegister8(RX8130_REG_CTRL0, rbuf);
105+
}
106+
107+
void RX8130_Class::getTime(struct tm *time)
108+
{
109+
uint8_t date[7];
110+
readRegister(RX8130_REG_SEC, date, 7);
111+
112+
time->tm_sec = bcd2dec(date[RX8130_REG_SEC - 0x10] & 0x7f);
113+
time->tm_min = bcd2dec(date[RX8130_REG_MIN - 0x10] & 0x7f);
114+
time->tm_hour = bcd2dec(date[RX8130_REG_HOUR - 0x10] & 0x3f); // only 24-hour clock
115+
time->tm_mday = bcd2dec(date[RX8130_REG_MDAY - 0x10] & 0x3f);
116+
time->tm_year = bcd2dec(date[RX8130_REG_YEAR - 0x10]);
117+
time->tm_wday = bcd2dec(date[RX8130_REG_WDAY - 0x10] & 0x7f);
118+
119+
// Read month from RTC (1-12) and convert to tm_mon (0-11)
120+
int rtc_month = bcd2dec(date[RX8130_REG_MONTH - 0x10] & 0x1f);
121+
time->tm_mon = rtc_month - 1;
122+
time->tm_year += 100;
123+
124+
// Fix date overflow issues - RX8130 doesn't handle month/day overflow automatically
125+
// Only correct when we detect actual invalid dates
126+
bool dateChanged = false;
127+
128+
// Check for invalid day (day > maximum days in current month)
129+
int maxDaysInMonth = getDaysInMonth(rtc_month, time->tm_year + 1900);
130+
if (time->tm_mday > maxDaysInMonth) {
131+
time->tm_mday = 1;
132+
rtc_month++;
133+
if (rtc_month > 12) {
134+
rtc_month = 1;
135+
time->tm_year++;
136+
}
137+
time->tm_mon = rtc_month - 1;
138+
dateChanged = true;
139+
}
140+
141+
// Check for invalid month (month > 12 or month < 1)
142+
else if (rtc_month > 12) {
143+
rtc_month = 1;
144+
time->tm_year++;
145+
time->tm_mon = rtc_month - 1;
146+
dateChanged = true;
147+
} else if (rtc_month < 1) {
148+
rtc_month = 12;
149+
time->tm_year--;
150+
time->tm_mon = rtc_month - 1;
151+
dateChanged = true;
152+
}
153+
154+
// If we corrected the date, update the RTC to prevent future issues
155+
if (dateChanged) {
156+
// Set STOP bit before changing clock/calendar
157+
uint8_t rbuf = readRegister8(RX8130_REG_CTRL0);
158+
rbuf = rbuf | RX8130_BIT_CTRL_STOP;
159+
writeRegister8(RX8130_REG_CTRL0, rbuf);
160+
161+
// Only update date registers, preserve time
162+
uint8_t dateRegs[4] = {dec2bcd(time->tm_wday), dec2bcd(time->tm_mday), dec2bcd(rtc_month),
163+
dec2bcd((time->tm_year - 100) % 100)};
164+
writeRegister(RX8130_REG_WDAY, dateRegs, 4);
165+
166+
// Clear STOP bit after changing clock/calendar
167+
rbuf = readRegister8(RX8130_REG_CTRL0);
168+
rbuf = rbuf & ~RX8130_BIT_CTRL_STOP;
169+
writeRegister8(RX8130_REG_CTRL0, rbuf);
170+
}
171+
}
172+
173+
void RX8130_Class::clearIrqFlags()
174+
{
175+
writeRegister8(RX8130_REG_FLAG, 0);
176+
}
177+
178+
void RX8130_Class::disableIrq()
179+
{
180+
writeRegister8(RX8130_REG_CTRL0, 0);
181+
}

0 commit comments

Comments
 (0)