1
+ use chrono:: { DateTime , Datelike , Local , LocalResult , TimeZone , Timelike } ;
1
2
use embedded_sdmmc:: { TimeSource , Timestamp } ;
2
3
use esp_idf_hal:: {
3
4
gpio:: PinDriver ,
4
5
peripherals,
5
6
prelude:: * ,
6
7
spi:: { config, SpiDeviceDriver , SpiDriver , SpiDriverConfig , SPI2 } ,
7
8
} ;
8
- use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
9
+ use esp_idf_svc:: eventloop:: EspSystemEventLoop ;
10
+ use simple_ntp:: sntp;
11
+ mod wifi;
12
+ use wifi:: wifi;
9
13
10
- struct Clock ;
11
- impl TimeSource for Clock {
12
- fn get_timestamp ( & self ) -> Timestamp { }
14
+ struct NtpClient < ' a > {
15
+ url : & ' a str ,
16
+ port : i8 ,
13
17
}
14
18
19
+ impl < ' a > NtpClient < ' a > {
20
+ fn get_timestamp ( & self ) -> LocalResult < DateTime < Local > > {
21
+ // Fetch current time using ntp.
22
+ let duration =
23
+ sntp:: unix_timestamp ( format ! ( "{}:{}" , & self . url, & self . port) . as_str ( ) ) . unwrap ( ) ;
24
+ println ! ( "Timestamps in local time:" ) ;
25
+ println ! ( "{:?}" , duration. as_secs( ) ) ;
26
+ let seconds = duration. as_secs ( ) ;
27
+ chrono:: Local . timestamp_opt ( seconds as i64 , 0 )
28
+ }
29
+ }
30
+
31
+ struct Clock < ' a > {
32
+ ntp_client : NtpClient < ' a > ,
33
+ }
34
+
35
+ impl TimeSource for Clock < ' _ > {
36
+ fn get_timestamp ( & self ) -> Timestamp {
37
+ let now = & self . ntp_client . get_timestamp ( ) . unwrap ( ) ;
38
+ Timestamp {
39
+ year_since_1970 : ( now. year ( ) - 1970 ) as u8 ,
40
+ zero_indexed_month : now. month0 ( ) as u8 ,
41
+ zero_indexed_day : now. day0 ( ) as u8 ,
42
+ hours : now. hour ( ) as u8 ,
43
+ minutes : now. minute ( ) as u8 ,
44
+ seconds : now. second ( ) as u8 ,
45
+ }
46
+ }
47
+ }
48
+
49
+ // Please SSID and WIFI_PASSWORD to use wifi.
50
+ const SSID : & str = "" ;
51
+ const WIFI_PASSWORD : & str = "" ;
52
+
15
53
fn main ( ) {
16
54
// It is necessary to call this function once. Otherwise some patches to the runtime
17
55
// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
@@ -23,6 +61,14 @@ fn main() {
23
61
let gpios = peripherals. pins ;
24
62
let pin_cs = PinDriver :: output ( gpios. gpio4 ) . unwrap ( ) ;
25
63
64
+ // Initialize wifi.
65
+ let _wifi = wifi (
66
+ SSID ,
67
+ WIFI_PASSWORD ,
68
+ peripherals. modem ,
69
+ EspSystemEventLoop :: take ( ) . unwrap ( ) ,
70
+ ) ;
71
+
26
72
// Initialize SPI interface
27
73
let spi = peripherals. spi2 ;
28
74
let driver = SpiDriver :: new :: < SPI2 > (
@@ -37,34 +83,56 @@ fn main() {
37
83
let spi_device_config = config:: Config :: new ( ) . baudrate ( 10 . MHz ( ) . into ( ) ) ;
38
84
let spi_device = SpiDeviceDriver :: new ( driver, Some ( gpios. gpio14 ) , & spi_device_config) . unwrap ( ) ;
39
85
86
+ // Following is based on https://github.com/rust-embedded-community/embedded-sdmmc-rs/tree/v0.5.0#using-the-crate
87
+
40
88
// Build an SD Card interface out of an SPI device, a chip-select pin and a delay object
41
89
let sdcard = embedded_sdmmc:: SdCard :: new ( spi_device, pin_cs, esp_idf_hal:: delay:: FreeRtos ) ;
42
90
// Get the card size (this also triggers card initialisation because it's not been done yet)
43
91
println ! ( "Card size is {} bytes" , sdcard. num_bytes( ) . unwrap( ) ) ;
44
92
// Now let's look for volumes (also known as partitions) on our block device.
45
93
// To do this we need a Volume Manager. It will take ownership of the block device.
46
- let mut volume_mgr = embedded_sdmmc:: VolumeManager :: new ( sdcard, time_source) ;
94
+ let mut volume_mgr = embedded_sdmmc:: VolumeManager :: new (
95
+ sdcard,
96
+ Clock {
97
+ ntp_client : NtpClient {
98
+ url : "time.google.com" ,
99
+ port : 123 ,
100
+ } ,
101
+ } ,
102
+ ) ;
103
+
47
104
// Try and access Volume 0 (i.e. the first partition).
48
105
// The volume object holds information about the filesystem on that volume.
49
106
// It doesn't hold a reference to the Volume Manager and so must be passed back
50
107
// to every Volume Manager API call. This makes it easier to handle multiple
51
108
// volumes in parallel.
52
- let volume0 = volume_mgr. get_volume ( embedded_sdmmc:: VolumeIdx ( 0 ) ) ? ;
109
+ let mut volume0 = volume_mgr. get_volume ( embedded_sdmmc:: VolumeIdx ( 0 ) ) . unwrap ( ) ;
53
110
println ! ( "Volume 0: {:?}" , volume0) ;
54
111
// Open the root directory (passing in the volume we're using).
55
- let root_dir = volume_mgr. open_root_dir ( & volume0) ? ;
112
+ let root_dir = volume_mgr. open_root_dir ( & volume0) . unwrap ( ) ;
56
113
// Open a file called "MY_FILE.TXT" in the root directory
57
- let my_file = volume_mgr
58
- . open_file_in_dir ( root_dir, "MY_FILE.TXT" , embedded_sdmmc:: Mode :: ReadOnly )
59
- . unwrap ( ) ;
60
- // Print the contents of the file
61
- while !volume_mgr. file_eof ( my_file) . unwrap ( ) {
62
- let mut buffer = [ 0u8 ; 32 ] ;
63
- let num_read = volume_mgr. read ( & volume0, & mut my_file, & mut buffer) ?;
64
- for b in & buffer[ 0 ..num_read] {
65
- print ! ( "{}" , * b as char ) ;
114
+ let my_file = volume_mgr. open_file_in_dir (
115
+ & mut volume0,
116
+ & root_dir,
117
+ "MY_FILE.TXT" ,
118
+ embedded_sdmmc:: Mode :: ReadOnly ,
119
+ ) ;
120
+
121
+ match my_file {
122
+ Ok ( mut f) => {
123
+ // Print the contents of the file
124
+ while !f. eof ( ) {
125
+ let mut buffer = [ 0u8 ; 32 ] ;
126
+ let num_read = volume_mgr. read ( & volume0, & mut f, & mut buffer) . unwrap ( ) ;
127
+ for b in & buffer[ 0 ..num_read] {
128
+ print ! ( "{}" , * b as char ) ;
129
+ }
130
+ }
131
+ let _ = volume_mgr. close_file ( & volume0, f) ;
132
+ volume_mgr. close_dir ( & volume0, root_dir) ;
133
+ }
134
+ Err ( error) => {
135
+ println ! ( "Error happen while opening file {:?}" , error) ;
66
136
}
67
137
}
68
- volume_mgr. close_file ( & volume0, my_file) ;
69
- volume_mgr. close_dir ( & volume0, root_dir) ;
70
138
}
0 commit comments