Skip to content

Commit 0154dd1

Browse files
committed
Machine.get_hwclock and set_hwclock
1 parent c74933f commit 0154dd1

File tree

10 files changed

+104
-37
lines changed

10 files changed

+104
-37
lines changed

mrbgems/picoruby-machine/include/machine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <stdint.h>
55
#include <stdbool.h>
6+
#include <time.h>
67

78
#ifdef __cplusplus
89
extern "C" {
@@ -16,6 +17,8 @@ int Machine_get_unique_id(char *id_str);
1617
void Machine_tud_task(void);
1718
bool Machine_tud_mounted_q(void);
1819
uint32_t Machine_stack_usage(void);
20+
bool Machine_set_hwclock(const struct timespec *ts);
21+
bool Machine_get_hwclock(struct timespec *ts);
1922

2023
#ifdef __cplusplus
2124
}

mrbgems/picoruby-machine/mrblib/machine.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,14 @@ def sleep(sec)
4242
end
4343
end
4444
end
45+
46+
if RUBY_ENGINE == "mruby"
47+
class Time
48+
def self.now(in: nil)
49+
ts = Machine.get_hwclock
50+
tv_sec = ts[0]
51+
tv_nsec = ts[1].to_f / 1_000_000_000
52+
Time.at(tv_sec + tv_nsec)
53+
end
54+
end
55+
end

mrbgems/picoruby-machine/ports/rp2040/machine.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@
1515
#include "hardware/clocks.h"
1616
#include "hardware/structs/scb.h"
1717
#include "hardware/sync.h"
18+
#include "pico/util/datetime.h"
1819
#include <tusb.h>
1920

21+
#include "pico/aon_timer.h"
22+
2023
/*-------------------------------------
2124
*
2225
* HAL
@@ -400,3 +403,18 @@ Machine_stack_usage(void)
400403
// TODO
401404
return 0;
402405
}
406+
407+
bool
408+
Machine_set_hwclock(const struct timespec *ts)
409+
{
410+
if (aon_timer_is_running()) {
411+
return aon_timer_set_time(ts);
412+
}
413+
return aon_timer_start(ts);
414+
}
415+
416+
bool
417+
Machine_get_hwclock(struct timespec *ts)
418+
{
419+
return aon_timer_get_time(ts);
420+
}

mrbgems/picoruby-machine/sig/machine.rbs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ class Machine
99
def self.read_memory: (Integer address, Integer size) -> String
1010
def self.tud_task: () -> void
1111
def self.tud_mounted?: () -> bool
12+
def self.set_hwclock: (Integer tv_sec, Integer tv_nsec) -> Integer
13+
def self.get_hwclock: () -> [Integer, Integer]
1214
end
1315

1416
$machine_delay: Symbol?

mrbgems/picoruby-machine/src/mruby/machine.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "mruby.h"
22
#include "mruby/string.h"
33
#include "mruby/presym.h"
4+
#include "mruby/array.h"
45

56
#include "../../include/hal.h"
67

@@ -163,6 +164,38 @@ mrb_kernel_p(mrb_state *mrb, mrb_value self)
163164
}
164165
return mrb_nil_value();
165166
}
167+
168+
#include <time.h>
169+
170+
static mrb_value
171+
mrb_s_set_hwclock(mrb_state *mrb, mrb_value self)
172+
{
173+
mrb_int tv_sec, tv_nsec;
174+
mrb_get_args(mrb, "ii", &tv_sec, &tv_nsec);
175+
const struct timespec ts = {
176+
.tv_sec = (time_t)tv_sec,
177+
.tv_nsec = (long)tv_nsec,
178+
};
179+
if (Machine_set_hwclock(&ts)) {
180+
return mrb_true_value();
181+
} else {
182+
mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to set hwclock");
183+
}
184+
}
185+
186+
static mrb_value
187+
mrb_s_get_hwclock(mrb_state *mrb, mrb_value self)
188+
{
189+
struct timespec ts = {0};
190+
if (Machine_get_hwclock(&ts)) {
191+
mrb_value ary = mrb_ary_new_capa(mrb, 2);
192+
mrb_ary_set(mrb, ary, 0, mrb_int_value(mrb, (mrb_int)ts.tv_sec));
193+
mrb_ary_set(mrb, ary, 1, mrb_int_value(mrb, (mrb_int)ts.tv_nsec));
194+
return ary;
195+
} else {
196+
mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to get hwclock");
197+
}
198+
}
166199
#endif
167200

168201
void
@@ -186,6 +219,9 @@ mrb_picoruby_machine_gem_init(mrb_state* mrb)
186219
mrb_define_method_id(mrb, module_Kernel, MRB_SYM(puts), mrb_puts, MRB_ARGS_ANY());
187220
mrb_define_method_id(mrb, module_Kernel, MRB_SYM(print), mrb_print, MRB_ARGS_ANY());
188221
mrb_define_method_id(mrb, module_Kernel, MRB_SYM(p), mrb_kernel_p, MRB_ARGS_ANY());
222+
223+
mrb_define_class_method_id(mrb, class_Machine, MRB_SYM(set_hwclock), mrb_s_set_hwclock, MRB_ARGS_REQ(2));
224+
mrb_define_class_method_id(mrb, class_Machine, MRB_SYM(get_hwclock), mrb_s_get_hwclock, MRB_ARGS_REQ(1));
189225
#endif
190226
}
191227

mrbgems/picoruby-net/mrblib/ntp.rb

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,41 @@
1-
require 'pack'
2-
require 'time'
3-
41
class Net
52
class NTP
6-
class Response
7-
def initialize(unix_time)
8-
@unixtime = unix_time
9-
end
10-
11-
def time
12-
Time.at(@unixtime)
13-
end
14-
end
15-
163
NTP_SERVER = "pool.ntp.org"
174
NTP_PORT = 123
185
NTP_PACKET_SIZE = 48
196

20-
def self.set_hwclock
21-
Time.set_hwclock(Net::NTP.get.time)
22-
end
23-
247
def self.get(ntp_server = NTP_SERVER, ntp_port = NTP_PORT)
258
# Create a NTP packet
26-
ntp_packet = String.pack('C', 0x1b) + ("\0" * 47)
9+
ntp_packet = "\e" + "\0" * 47
2710

2811
r = UDPClient.send(ntp_server, ntp_port, ntp_packet, false)
2912

30-
if r && r.size == NTP_PACKET_SIZE
13+
if r&.size == NTP_PACKET_SIZE
3114
# Extract NTP timestamp (seconds from 1900-01-01)
32-
seconds = ((r[40]&.ord||0) << 24) | ((r[41]&.ord||0) << 16) | ((r[42]&.ord||0) << 8) | (r[43]&.ord||0)
33-
fraction = ((r[44]&.ord||0) << 24) | ((r[45]&.ord||0) << 16) | ((r[46]&.ord||0) << 8) | (r[47]&.ord||0)
34-
35-
# Convert NTP timestamp to UNIX timestamp
36-
unixtime = (seconds - 2_208_988_800 + (fraction / 2.0**32)).to_i
15+
# @type var r: String
16+
r40 = r[40]
17+
r41 = r[41]
18+
r42 = r[42]
19+
r43 = r[43]
20+
# @type var r40: String
21+
# @type var r41: String
22+
# @type var r42: String
23+
# @type var r43: String
24+
seconds = ( r40.ord << 24 | r41.ord << 16 | r42.ord << 8 | r43.ord ) - 2_208_988_800
25+
# Extract NTP fraction (nanoseconds)
26+
r44 = r[44]
27+
r45 = r[45]
28+
r46 = r[46]
29+
r47 = r[47]
30+
# @type var r44: String
31+
# @type var r45: String
32+
# @type var r46: String
33+
# @type var r47: String
34+
fraction = r44.ord << 24 | r45.ord << 16 | r46.ord << 8 | r47.ord
35+
# Calculate nanoseconds
36+
nanoseconds = (fraction * 1_000_000_000) >> 32
37+
return [seconds, nanoseconds]
3738

38-
# Convert UNIX timestamp to human-readable time
39-
Response.new(unixtime)
4039
else
4140
raise "Failed to retrieve time from NTP server."
4241
end

mrbgems/picoruby-net/sig/ntp.rbs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
class Net
22
class NTP
3-
class Response
4-
@unixtime: Integer
5-
def initialize: (Integer unixtime) -> void
6-
def time: () -> Time
7-
end
8-
93
NTP_SERVER: String
104
NTP_PORT: Integer
115
NTP_PACKET_SIZE: Integer
126

13-
def self.get: (?String ntp_server, ?Integer ntp_port) -> Response
14-
def self.set_hwclock: () -> void
7+
def self.get: (?String ntp_server, ?Integer ntp_port) -> [Integer, Integer]
158
end
169
end

mrbgems/picoruby-net/src/net.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ Net_get_ip(const char *name, ip_addr_t *ip)
4242

4343
#elif defined(PICORB_VM_MRUBYC)
4444

45-
#include "mrubyc/net.c"
45+
//#include "mrubyc/net.c"
46+
int mbedtls_hardware_poll (void *data, unsigned char *output, size_t len, size_t *olen){
47+
return 0;
48+
}
49+
void mrbc_net_init(mrbc_vm *vm){}
4650

4751
#endif

mrbgems/picoruby-shell/shell_executables/wifi_connect

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,6 @@ if config["wifi"]["watchdog"]
121121
puts "Watchdog disabled"
122122
end
123123

124-
Net::NTP.set_hwclock
124+
tv = Net::NTP.get
125+
Machine.set_hwclock(tv[0], tv[1])
125126
puts "Time set to #{Time.now}"

mrbgems/picoruby-time-class/sig/time.rbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ class Time < Object
282282
# For the forms of argument `zone`, see [Timezone
283283
# Specifiers](rdoc-ref:timezones.rdoc).
284284
#
285-
def self.at: ((Integer|Time), ?in: String | Integer | nil) -> Time
285+
def self.at: ((Integer|Float|Time), ?in: String | Integer | nil) -> Time
286286

287287
type subsec_unit = :msec | :millisecond | :usec | :microsecond | :nsec | :nanosecond
288288

0 commit comments

Comments
 (0)