mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-24 14:46:53 +01:00
[SC64][FW][SW] Added option to set and read century when updating RTC datetime
This commit is contained in:
parent
6bbfee44e7
commit
e4af127e55
@ -328,18 +328,18 @@ Use this command to set value of persistent setting option. Available persistent
|
|||||||
_This command does not require arguments or data._
|
_This command does not require arguments or data._
|
||||||
|
|
||||||
#### `response` (time)
|
#### `response` (time)
|
||||||
| offset | type | description |
|
| offset | type | description |
|
||||||
| ------ | ------- | ------------------------------------ |
|
| ------ | ------- | ----------------------------------------- |
|
||||||
| `0` | uint8_t | Weekday (1 - 7), 1 represents Monday |
|
| `0` | uint8_t | Weekday (1 - 7), 1 represents Monday |
|
||||||
| `1` | uint8_t | Hours (0 - 23) |
|
| `1` | uint8_t | Hours (0 - 23) |
|
||||||
| `2` | uint8_t | Minutes (0 - 59) |
|
| `2` | uint8_t | Minutes (0 - 59) |
|
||||||
| `3` | uint8_t | Seconds (0 - 59) |
|
| `3` | uint8_t | Seconds (0 - 59) |
|
||||||
| `4` | uint8_t | _Unused_ (returns zero) |
|
| `4` | uint8_t | Century (0 - 255), 0 represents year 1900 |
|
||||||
| `5` | uint8_t | Year (0 - 99) |
|
| `5` | uint8_t | Year (0 - 99) |
|
||||||
| `6` | uint8_t | Month (1 - 12) |
|
| `6` | uint8_t | Month (1 - 12) |
|
||||||
| `7` | uint8_t | Day (1 - 31) |
|
| `7` | uint8_t | Day (1 - 31) |
|
||||||
|
|
||||||
Date/time values use the [BCD](https://en.wikipedia.org/wiki/Binary-coded_decimal) format.
|
Date/time values use the [BCD](https://en.wikipedia.org/wiki/Binary-coded_decimal) format, except for the century field.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -356,16 +356,16 @@ Date/time values use the [BCD](https://en.wikipedia.org/wiki/Binary-coded_decima
|
|||||||
| `[7:0]` | Seconds (0 - 59) |
|
| `[7:0]` | Seconds (0 - 59) |
|
||||||
|
|
||||||
#### `arg1` (time_1)
|
#### `arg1` (time_1)
|
||||||
| bits | description |
|
| bits | description |
|
||||||
| --------- | -------------- |
|
| --------- | ----------------------------------------- |
|
||||||
| `[31:24]` | _Unused_ |
|
| `[31:24]` | Century (0 - 255), 0 represents year 1900 |
|
||||||
| `[23:16]` | Year (0 - 99) |
|
| `[23:16]` | Year (0 - 99) |
|
||||||
| `[15:8]` | Month (1 - 12) |
|
| `[15:8]` | Month (1 - 12) |
|
||||||
| `[7:0]` | Day (1 - 31) |
|
| `[7:0]` | Day (1 - 31) |
|
||||||
|
|
||||||
_This command does not send response data._
|
_This command does not send response data._
|
||||||
|
|
||||||
Date/time values use the [BCD](https://en.wikipedia.org/wiki/Binary-coded_decimal) format.
|
Date/time values use the [BCD](https://en.wikipedia.org/wiki/Binary-coded_decimal) format, except for the century field.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -506,7 +506,7 @@ module mcu_top (
|
|||||||
|
|
||||||
REG_RTC_TIME_1: begin
|
REG_RTC_TIME_1: begin
|
||||||
reg_rdata <= {
|
reg_rdata <= {
|
||||||
8'd0,
|
7'd0, n64_scb.rtc_rdata[42],
|
||||||
n64_scb.rtc_rdata[41:34],
|
n64_scb.rtc_rdata[41:34],
|
||||||
3'd0, n64_scb.rtc_rdata[33:29],
|
3'd0, n64_scb.rtc_rdata[33:29],
|
||||||
2'd0, n64_scb.rtc_rdata[25:20]
|
2'd0, n64_scb.rtc_rdata[25:20]
|
||||||
@ -849,6 +849,7 @@ module mcu_top (
|
|||||||
|
|
||||||
REG_RTC_TIME_1: begin
|
REG_RTC_TIME_1: begin
|
||||||
n64_scb.rtc_wdata_valid <= 1'b1;
|
n64_scb.rtc_wdata_valid <= 1'b1;
|
||||||
|
n64_scb.rtc_wdata[42] <= reg_wdata[24];
|
||||||
n64_scb.rtc_wdata[41:34] <= reg_wdata[23:16];
|
n64_scb.rtc_wdata[41:34] <= reg_wdata[23:16];
|
||||||
n64_scb.rtc_wdata[33:29] <= reg_wdata[12:8];
|
n64_scb.rtc_wdata[33:29] <= reg_wdata[12:8];
|
||||||
n64_scb.rtc_wdata[25:20] <= reg_wdata[5:0];
|
n64_scb.rtc_wdata[25:20] <= reg_wdata[5:0];
|
||||||
|
@ -40,8 +40,8 @@ interface n64_scb ();
|
|||||||
logic rtc_pending;
|
logic rtc_pending;
|
||||||
logic rtc_done;
|
logic rtc_done;
|
||||||
logic rtc_wdata_valid;
|
logic rtc_wdata_valid;
|
||||||
logic [41:0] rtc_rdata;
|
logic [42:0] rtc_rdata;
|
||||||
logic [41:0] rtc_wdata;
|
logic [42:0] rtc_wdata;
|
||||||
|
|
||||||
logic cfg_unlock;
|
logic cfg_unlock;
|
||||||
logic cfg_pending;
|
logic cfg_pending;
|
||||||
|
@ -362,6 +362,7 @@ module n64_si (
|
|||||||
logic [2:0] rtc_time_weekday;
|
logic [2:0] rtc_time_weekday;
|
||||||
logic [4:0] rtc_time_month;
|
logic [4:0] rtc_time_month;
|
||||||
logic [7:0] rtc_time_year;
|
logic [7:0] rtc_time_year;
|
||||||
|
logic rtc_time_century;
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
@ -377,6 +378,7 @@ module n64_si (
|
|||||||
|
|
||||||
if (!(|rtc_stopped) && !n64_scb.rtc_pending && n64_scb.rtc_wdata_valid && (tx_state != TX_STATE_DATA)) begin
|
if (!(|rtc_stopped) && !n64_scb.rtc_pending && n64_scb.rtc_wdata_valid && (tx_state != TX_STATE_DATA)) begin
|
||||||
{
|
{
|
||||||
|
rtc_time_century,
|
||||||
rtc_time_year,
|
rtc_time_year,
|
||||||
rtc_time_month,
|
rtc_time_month,
|
||||||
rtc_time_weekday,
|
rtc_time_weekday,
|
||||||
@ -408,6 +410,7 @@ module n64_si (
|
|||||||
4'd5: rtc_time_weekday <= rx_byte_data[2:0];
|
4'd5: rtc_time_weekday <= rx_byte_data[2:0];
|
||||||
4'd6: rtc_time_month <= rx_byte_data[4:0];
|
4'd6: rtc_time_month <= rx_byte_data[4:0];
|
||||||
4'd7: rtc_time_year <= rx_byte_data;
|
4'd7: rtc_time_year <= rx_byte_data;
|
||||||
|
4'd8: rtc_time_century <= rx_byte_data[0];
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -415,6 +418,7 @@ module n64_si (
|
|||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
n64_scb.rtc_rdata = {
|
n64_scb.rtc_rdata = {
|
||||||
|
rtc_time_century,
|
||||||
rtc_time_year,
|
rtc_time_year,
|
||||||
rtc_time_month,
|
rtc_time_month,
|
||||||
rtc_time_weekday,
|
rtc_time_weekday,
|
||||||
@ -469,7 +473,7 @@ module n64_si (
|
|||||||
4'd4: tx_byte_data = {5'd0, rtc_time_weekday};
|
4'd4: tx_byte_data = {5'd0, rtc_time_weekday};
|
||||||
4'd5: tx_byte_data = {3'd0, rtc_time_month};
|
4'd5: tx_byte_data = {3'd0, rtc_time_month};
|
||||||
4'd6: tx_byte_data = rtc_time_year;
|
4'd6: tx_byte_data = rtc_time_year;
|
||||||
4'd7: tx_byte_data = 8'h01;
|
4'd7: tx_byte_data = {7'd0, rtc_time_century};
|
||||||
4'd8: tx_byte_data = {(|rtc_stopped), 7'd0};
|
4'd8: tx_byte_data = {(|rtc_stopped), 7'd0};
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
@ -263,10 +263,11 @@ sc64_error_t sc64_get_time (sc64_rtc_time_t *t) {
|
|||||||
.id = CMD_ID_TIME_GET
|
.id = CMD_ID_TIME_GET
|
||||||
};
|
};
|
||||||
sc64_error_t error = sc64_execute_cmd(&cmd);
|
sc64_error_t error = sc64_execute_cmd(&cmd);
|
||||||
|
t->weekday = ((cmd.rsp[0] >> 24) & 0xFF);
|
||||||
t->hour = ((cmd.rsp[0] >> 16) & 0xFF);
|
t->hour = ((cmd.rsp[0] >> 16) & 0xFF);
|
||||||
t->minute = ((cmd.rsp[0] >> 8) & 0xFF);
|
t->minute = ((cmd.rsp[0] >> 8) & 0xFF);
|
||||||
t->second = (cmd.rsp[0] & 0xFF);
|
t->second = (cmd.rsp[0] & 0xFF);
|
||||||
t->weekday = ((cmd.rsp[1] >> 24) & 0xFF);
|
t->century = ((cmd.rsp[1] >> 24) & 0xFF);
|
||||||
t->year = ((cmd.rsp[1] >> 16) & 0xFF);
|
t->year = ((cmd.rsp[1] >> 16) & 0xFF);
|
||||||
t->month = ((cmd.rsp[1] >> 8) & 0xFF);
|
t->month = ((cmd.rsp[1] >> 8) & 0xFF);
|
||||||
t->day = (cmd.rsp[1] & 0xFF);
|
t->day = (cmd.rsp[1] & 0xFF);
|
||||||
@ -275,11 +276,12 @@ sc64_error_t sc64_get_time (sc64_rtc_time_t *t) {
|
|||||||
|
|
||||||
sc64_error_t sc64_set_time (sc64_rtc_time_t *t) {
|
sc64_error_t sc64_set_time (sc64_rtc_time_t *t) {
|
||||||
uint32_t time[2] = {(
|
uint32_t time[2] = {(
|
||||||
|
((t->weekday << 24) & 0xFF) |
|
||||||
((t->hour << 16) & 0xFF) |
|
((t->hour << 16) & 0xFF) |
|
||||||
((t->minute << 8) & 0xFF) |
|
((t->minute << 8) & 0xFF) |
|
||||||
(t->second & 0xFF)
|
(t->second & 0xFF)
|
||||||
), (
|
), (
|
||||||
((t->weekday << 24) & 0xFF) |
|
((t->century << 24) & 0xFF) |
|
||||||
((t->year << 16) & 0xFF) |
|
((t->year << 16) & 0xFF) |
|
||||||
((t->month << 8) & 0xFF) |
|
((t->month << 8) & 0xFF) |
|
||||||
(t->day & 0xFF)
|
(t->day & 0xFF)
|
||||||
|
@ -149,6 +149,7 @@ typedef struct {
|
|||||||
uint8_t day;
|
uint8_t day;
|
||||||
uint8_t month;
|
uint8_t month;
|
||||||
uint8_t year;
|
uint8_t year;
|
||||||
|
uint8_t century;
|
||||||
} sc64_rtc_time_t;
|
} sc64_rtc_time_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -110,7 +110,7 @@ static void test_sc64_cfg (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
display_printf("RTC current time:\n ");
|
display_printf("RTC current time:\n ");
|
||||||
display_printf("%04d-%02d-%02d", 2000 + FROM_BCD(t.year), FROM_BCD(t.month), FROM_BCD(t.day));
|
display_printf("%04d-%02d-%02d", 1900 + (t.century * 100) + FROM_BCD(t.year), FROM_BCD(t.month), FROM_BCD(t.day));
|
||||||
display_printf("T");
|
display_printf("T");
|
||||||
display_printf("%02d:%02d:%02d", FROM_BCD(t.hour), FROM_BCD(t.minute), FROM_BCD(t.second));
|
display_printf("%02d:%02d:%02d", FROM_BCD(t.hour), FROM_BCD(t.minute), FROM_BCD(t.second));
|
||||||
display_printf(" (%s)", weekdays[FROM_BCD(t.weekday)]);
|
display_printf(" (%s)", weekdays[FROM_BCD(t.weekday)]);
|
||||||
|
@ -437,8 +437,8 @@ save_type_t cfg_get_save_type (void) {
|
|||||||
void cfg_get_time (uint32_t *args) {
|
void cfg_get_time (uint32_t *args) {
|
||||||
rtc_time_t t;
|
rtc_time_t t;
|
||||||
rtc_get_time(&t);
|
rtc_get_time(&t);
|
||||||
args[0] = ((t.hour << 16) | (t.minute << 8) | t.second);
|
args[0] = ((t.weekday << 24) | (t.hour << 16) | (t.minute << 8) | t.second);
|
||||||
args[1] = ((t.weekday << 24) | (t.year << 16) | (t.month << 8) | t.day);
|
args[1] = ((t.century << 24) | (t.year << 16) | (t.month << 8) | t.day);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfg_set_time (uint32_t *args) {
|
void cfg_set_time (uint32_t *args) {
|
||||||
@ -450,6 +450,7 @@ void cfg_set_time (uint32_t *args) {
|
|||||||
t.day = (args[1] & 0xFF);
|
t.day = (args[1] & 0xFF);
|
||||||
t.month = ((args[1] >> 8) & 0xFF);
|
t.month = ((args[1] >> 8) & 0xFF);
|
||||||
t.year = ((args[1] >> 16) & 0xFF);
|
t.year = ((args[1] >> 16) & 0xFF);
|
||||||
|
t.century = ((args[1] >> 24) & 0xFF);
|
||||||
rtc_set_time(&t);
|
rtc_set_time(&t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +365,7 @@ void dd_process (void) {
|
|||||||
case DD_CMD_SET_RTC_MINUTE_SECOND:
|
case DD_CMD_SET_RTC_MINUTE_SECOND:
|
||||||
p.time.minute = ((data >> 8) & 0xFF);
|
p.time.minute = ((data >> 8) & 0xFF);
|
||||||
p.time.second = (data & 0xFF);
|
p.time.second = (data & 0xFF);
|
||||||
|
p.time.century = (p.time.year >= 0x96) ? 0 : 1;
|
||||||
rtc_set_time(&p.time);
|
rtc_set_time(&p.time);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#define RTC_ADDRESS_SRAM_REGION (0x24)
|
#define RTC_ADDRESS_SRAM_REGION (0x24)
|
||||||
#define RTC_ADDRESS_SRAM_VERSION (0x28)
|
#define RTC_ADDRESS_SRAM_VERSION (0x28)
|
||||||
#define RTC_ADDRESS_SRAM_SETTINGS (0x2C)
|
#define RTC_ADDRESS_SRAM_SETTINGS (0x2C)
|
||||||
|
#define RTC_ADDRESS_SRAM_CENTURY (0x40)
|
||||||
|
#define RTC_ADDRESS_SRAM_LAST_YEAR (0x41)
|
||||||
|
|
||||||
#define RTC_RTCSEC_ST (1 << 7)
|
#define RTC_RTCSEC_ST (1 << 7)
|
||||||
|
|
||||||
@ -37,8 +39,9 @@ static rtc_time_t rtc_time = {
|
|||||||
.hour = 0x12,
|
.hour = 0x12,
|
||||||
.weekday = 0x01,
|
.weekday = 0x01,
|
||||||
.day = 0x01,
|
.day = 0x01,
|
||||||
.month = 0x01,
|
.month = 0x06,
|
||||||
.year = 0x24
|
.year = 0x24,
|
||||||
|
.century = 0x01,
|
||||||
};
|
};
|
||||||
static bool rtc_time_pending = false;
|
static bool rtc_time_pending = false;
|
||||||
|
|
||||||
@ -102,10 +105,17 @@ static void rtc_osc_stop (void) {
|
|||||||
|
|
||||||
static void rtc_read_time (void) {
|
static void rtc_read_time (void) {
|
||||||
uint8_t regs[7];
|
uint8_t regs[7];
|
||||||
|
uint8_t last_year;
|
||||||
|
|
||||||
if (rtc_read(RTC_ADDRESS_RTCSEC, regs, 7)) {
|
if (rtc_read(RTC_ADDRESS_RTCSEC, regs, 7)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (rtc_read(RTC_ADDRESS_SRAM_CENTURY, &rtc_time.century, 1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (rtc_read(RTC_ADDRESS_SRAM_LAST_YEAR, &last_year, 1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rtc_sanitize_time(regs);
|
rtc_sanitize_time(regs);
|
||||||
|
|
||||||
@ -116,6 +126,15 @@ static void rtc_read_time (void) {
|
|||||||
rtc_time.day = regs[4];
|
rtc_time.day = regs[4];
|
||||||
rtc_time.month = regs[5];
|
rtc_time.month = regs[5];
|
||||||
rtc_time.year = regs[6];
|
rtc_time.year = regs[6];
|
||||||
|
|
||||||
|
if (rtc_time.year < last_year) {
|
||||||
|
rtc_time.century += 1;
|
||||||
|
rtc_write(RTC_ADDRESS_SRAM_CENTURY, &rtc_time.century, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtc_time.year != last_year) {
|
||||||
|
rtc_write(RTC_ADDRESS_SRAM_LAST_YEAR, &rtc_time.year, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_write_time (void) {
|
static void rtc_write_time (void) {
|
||||||
@ -136,8 +155,12 @@ static void rtc_write_time (void) {
|
|||||||
regs[0] |= RTC_RTCSEC_ST;
|
regs[0] |= RTC_RTCSEC_ST;
|
||||||
regs[3] |= RTC_RTCWKDAY_VBATEN;
|
regs[3] |= RTC_RTCWKDAY_VBATEN;
|
||||||
|
|
||||||
|
rtc_write(RTC_ADDRESS_SRAM_CENTURY, &rtc_time.century, 1);
|
||||||
|
rtc_write(RTC_ADDRESS_SRAM_LAST_YEAR, &rtc_time.year, 1);
|
||||||
rtc_write(RTC_ADDRESS_RTCMIN, ®s[1], 6);
|
rtc_write(RTC_ADDRESS_RTCMIN, ®s[1], 6);
|
||||||
rtc_write(RTC_ADDRESS_RTCSEC, ®s[0], 1);
|
rtc_write(RTC_ADDRESS_RTCSEC, ®s[0], 1);
|
||||||
|
|
||||||
|
rtc_read_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_read_region (void) {
|
static void rtc_read_region (void) {
|
||||||
@ -165,6 +188,7 @@ void rtc_get_time (rtc_time_t *time) {
|
|||||||
time->day = rtc_time.day;
|
time->day = rtc_time.day;
|
||||||
time->month = rtc_time.month;
|
time->month = rtc_time.month;
|
||||||
time->year = rtc_time.year;
|
time->year = rtc_time.year;
|
||||||
|
time->century = rtc_time.century;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_set_time (rtc_time_t *time) {
|
void rtc_set_time (rtc_time_t *time) {
|
||||||
@ -175,6 +199,7 @@ void rtc_set_time (rtc_time_t *time) {
|
|||||||
rtc_time.day = time->day;
|
rtc_time.day = time->day;
|
||||||
rtc_time.month = time->month;
|
rtc_time.month = time->month;
|
||||||
rtc_time.year = time->year;
|
rtc_time.year = time->year;
|
||||||
|
rtc_time.century = time->century;
|
||||||
rtc_time_pending = true;
|
rtc_time_pending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,6 +279,7 @@ void rtc_process (void) {
|
|||||||
rtc_time.hour = ((data[0] >> 16) & 0xFF);
|
rtc_time.hour = ((data[0] >> 16) & 0xFF);
|
||||||
rtc_time.minute = ((data[0] >> 8) & 0xFF);
|
rtc_time.minute = ((data[0] >> 8) & 0xFF);
|
||||||
rtc_time.second = ((data[0] >> 0) & 0xFF);
|
rtc_time.second = ((data[0] >> 0) & 0xFF);
|
||||||
|
rtc_time.century = ((data[1] >> 24) & 0xFF);
|
||||||
rtc_time.year = ((data[1] >> 16) & 0xFF);
|
rtc_time.year = ((data[1] >> 16) & 0xFF);
|
||||||
rtc_time.month = ((data[1] >> 8) & 0xFF);
|
rtc_time.month = ((data[1] >> 8) & 0xFF);
|
||||||
rtc_time.day = ((data[1] >> 0) & 0xFF);
|
rtc_time.day = ((data[1] >> 0) & 0xFF);
|
||||||
@ -293,6 +319,7 @@ void rtc_process (void) {
|
|||||||
(rtc_time.second << 0)
|
(rtc_time.second << 0)
|
||||||
);
|
);
|
||||||
data[1] = (
|
data[1] = (
|
||||||
|
(rtc_time.century << 24) |
|
||||||
(rtc_time.year << 16) |
|
(rtc_time.year << 16) |
|
||||||
(rtc_time.month << 8) |
|
(rtc_time.month << 8) |
|
||||||
(rtc_time.day << 0)
|
(rtc_time.day << 0)
|
||||||
|
@ -14,6 +14,7 @@ typedef struct {
|
|||||||
uint8_t day;
|
uint8_t day;
|
||||||
uint8_t month;
|
uint8_t month;
|
||||||
uint8_t year;
|
uint8_t year;
|
||||||
|
uint8_t century;
|
||||||
} rtc_time_t;
|
} rtc_time_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -781,7 +781,7 @@ fn handle_set_command(connection: Connection, command: &SetCommands) -> Result<(
|
|||||||
|
|
||||||
match command {
|
match command {
|
||||||
SetCommands::Rtc => {
|
SetCommands::Rtc => {
|
||||||
let datetime = Local::now();
|
let datetime = Local::now().naive_local();
|
||||||
sc64.set_datetime(datetime)?;
|
sc64.set_datetime(datetime)?;
|
||||||
println!(
|
println!(
|
||||||
"SC64 RTC datetime synchronized to: {}",
|
"SC64 RTC datetime synchronized to: {}",
|
||||||
|
@ -25,7 +25,7 @@ use self::{
|
|||||||
get_config, get_setting, Config, ConfigId, FirmwareStatus, Setting, SettingId, UpdateStatus,
|
get_config, get_setting, Config, ConfigId, FirmwareStatus, Setting, SettingId, UpdateStatus,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use chrono::{DateTime, Local};
|
use chrono::NaiveDateTime;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::{
|
use std::{
|
||||||
cmp::min,
|
cmp::min,
|
||||||
@ -55,7 +55,7 @@ pub struct DeviceState {
|
|||||||
pub button_mode: ButtonMode,
|
pub button_mode: ButtonMode,
|
||||||
pub rom_extended_enable: Switch,
|
pub rom_extended_enable: Switch,
|
||||||
pub led_enable: Switch,
|
pub led_enable: Switch,
|
||||||
pub datetime: DateTime<Local>,
|
pub datetime: NaiveDateTime,
|
||||||
pub fpga_debug_data: FpgaDebugData,
|
pub fpga_debug_data: FpgaDebugData,
|
||||||
pub diagnostic_data: DiagnosticData,
|
pub diagnostic_data: DiagnosticData,
|
||||||
}
|
}
|
||||||
@ -210,7 +210,7 @@ impl SC64 {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_time_get(&mut self) -> Result<DateTime<Local>, Error> {
|
fn command_time_get(&mut self) -> Result<NaiveDateTime, Error> {
|
||||||
let data = self.link.execute_command(&Command {
|
let data = self.link.execute_command(&Command {
|
||||||
id: b't',
|
id: b't',
|
||||||
args: [0, 0],
|
args: [0, 0],
|
||||||
@ -224,7 +224,7 @@ impl SC64 {
|
|||||||
Ok(convert_to_datetime(&data[0..8].try_into().unwrap())?)
|
Ok(convert_to_datetime(&data[0..8].try_into().unwrap())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn command_time_set(&mut self, datetime: DateTime<Local>) -> Result<(), Error> {
|
fn command_time_set(&mut self, datetime: NaiveDateTime) -> Result<(), Error> {
|
||||||
self.link.execute_command(&Command {
|
self.link.execute_command(&Command {
|
||||||
id: b'T',
|
id: b'T',
|
||||||
args: convert_from_datetime(datetime),
|
args: convert_from_datetime(datetime),
|
||||||
@ -529,11 +529,11 @@ impl SC64 {
|
|||||||
self.command_config_set(Config::TvType(tv_type))
|
self.command_config_set(Config::TvType(tv_type))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_datetime(&mut self) -> Result<DateTime<Local>, Error> {
|
pub fn get_datetime(&mut self) -> Result<NaiveDateTime, Error> {
|
||||||
self.command_time_get()
|
self.command_time_get()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_datetime(&mut self, datetime: DateTime<Local>) -> Result<(), Error> {
|
pub fn set_datetime(&mut self, datetime: NaiveDateTime) -> Result<(), Error> {
|
||||||
self.command_time_set(datetime)
|
self.command_time_set(datetime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::Error;
|
use super::Error;
|
||||||
use chrono::{DateTime, Datelike, Local, NaiveDateTime, TimeZone, Timelike};
|
use chrono::{Datelike, NaiveDateTime, Timelike};
|
||||||
|
|
||||||
pub fn u8_from_bcd(value: u8) -> u8 {
|
pub fn u8_from_bcd(value: u8) -> u8 {
|
||||||
(((value & 0xF0) >> 4) * 10) + (value & 0x0F)
|
(((value & 0xF0) >> 4) * 10) + (value & 0x0F)
|
||||||
@ -9,31 +9,31 @@ pub fn bcd_from_u8(value: u8) -> u8 {
|
|||||||
(((value / 10) & 0x0F) << 4) | ((value % 10) & 0x0F)
|
(((value / 10) & 0x0F) << 4) | ((value % 10) & 0x0F)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn convert_to_datetime(data: &[u8; 8]) -> Result<DateTime<Local>, Error> {
|
pub fn convert_to_datetime(data: &[u8; 8]) -> Result<NaiveDateTime, Error> {
|
||||||
let hour = u8_from_bcd(data[1]);
|
|
||||||
let minute = u8_from_bcd(data[2]);
|
|
||||||
let second = u8_from_bcd(data[3]);
|
let second = u8_from_bcd(data[3]);
|
||||||
let year = u8_from_bcd(data[5]) as u32 + 2000;
|
let minute = u8_from_bcd(data[2]);
|
||||||
let month = u8_from_bcd(data[6]);
|
let hour = u8_from_bcd(data[1]);
|
||||||
let day = u8_from_bcd(data[7]);
|
let day = u8_from_bcd(data[7]);
|
||||||
let native = &NaiveDateTime::parse_from_str(
|
let month = u8_from_bcd(data[6]);
|
||||||
&format!("{year:02}-{month:02}-{day:02}T{hour:02}:{minute:02}:{second:02}"),
|
let year = 1900u32 + (data[4] as u32 * 100) + u8_from_bcd(data[5]) as u32;
|
||||||
|
NaiveDateTime::parse_from_str(
|
||||||
|
&format!("{year:4}-{month:02}-{day:02}T{hour:02}:{minute:02}:{second:02}"),
|
||||||
"%Y-%m-%dT%H:%M:%S",
|
"%Y-%m-%dT%H:%M:%S",
|
||||||
)
|
)
|
||||||
.map_err(|_| Error::new("Couldn't convert from bytes to DateTime<Local>"))?;
|
.map_err(|_| Error::new("Couldn't convert from bytes to NaiveDateTime"))
|
||||||
Ok(Local.from_local_datetime(native).unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn convert_from_datetime(datetime: DateTime<Local>) -> [u32; 2] {
|
pub fn convert_from_datetime(datetime: NaiveDateTime) -> [u32; 2] {
|
||||||
let weekday = bcd_from_u8((datetime.weekday() as u8) + 1);
|
|
||||||
let hour = bcd_from_u8(datetime.hour() as u8);
|
|
||||||
let minute = bcd_from_u8(datetime.minute() as u8);
|
|
||||||
let second = bcd_from_u8(datetime.second() as u8);
|
let second = bcd_from_u8(datetime.second() as u8);
|
||||||
let year = bcd_from_u8((datetime.year() - 2000) as u8);
|
let minute = bcd_from_u8(datetime.minute() as u8);
|
||||||
let month = bcd_from_u8(datetime.month() as u8);
|
let hour = bcd_from_u8(datetime.hour() as u8);
|
||||||
|
let weekday = bcd_from_u8((datetime.weekday() as u8) + 1);
|
||||||
let day = bcd_from_u8(datetime.day() as u8);
|
let day = bcd_from_u8(datetime.day() as u8);
|
||||||
|
let month = bcd_from_u8(datetime.month() as u8);
|
||||||
|
let year = bcd_from_u8((datetime.year() % 100) as u8);
|
||||||
|
let century = ((datetime.year() - 1900) / 100) as u8;
|
||||||
[
|
[
|
||||||
u32::from_be_bytes([weekday, hour, minute, second]),
|
u32::from_be_bytes([weekday, hour, minute, second]),
|
||||||
u32::from_be_bytes([0, year, month, day]),
|
u32::from_be_bytes([century, year, month, day]),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user