-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.rs
291 lines (244 loc) · 8.83 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#![no_std]
#![no_main]
extern crate alloc;
use core::mem::MaybeUninit;
use hal::{psram, prelude::*, peripherals::Peripherals, spi, timer::TimerGroup, clock::{ClockControl, CpuClock}, Delay, Rtc, Rng, IO};
use embedded_io::blocking::*;
use embedded_svc::ipv4::Interface;
use embedded_svc::wifi::{AccessPointInfo, ClientConfiguration, Configuration, Wifi};
use esp_backtrace as _;
use esp_println::{print, println};
use esp_println::println as esp_println;
use esp_wifi::wifi::utils::create_network_interface;
use esp_wifi::wifi::{WifiError, WifiMode};
use esp_wifi::wifi_interface::WifiStack;
use esp_wifi::{current_millis, initialize, EspWifiInitFor};
use smoltcp::iface::SocketStorage;
use smoltcp::wire::IpAddress;
use smoltcp::wire::Ipv4Address;
use embedded_graphics::{
fonts::{Font24x32, Text},
prelude::*,
style::PrimitiveStyle,
text_style,
};
use ssd1680::prelude::*;
use ssd1680::color::{Black, White};
const SSID: &str = env!("SSID");
const PASSWORD: &str = env!("PASSWORD");
#[global_allocator]
static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();
fn init_heap() {
const HEAP_SIZE: usize = 32 * 1024;
static mut HEAP: MaybeUninit<[u8; HEAP_SIZE]> = MaybeUninit::uninit();
unsafe {
ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, HEAP_SIZE);
}
}
fn draw_text(display: &mut Display2in13, text: &str, x: i32, y: i32) {
let _ = Text::new(text, Point::new(x, y))
.into_styled(text_style!(
font = Font24x32,
text_color = Black,
background_color = White
))
.draw(display);
}
#[entry]
fn main() -> ! {
// panic!("End of scan");
// Initialize heap and other system resources
init_heap();
let peripherals = Peripherals::take();
let mut system = peripherals.DPORT.split();
let clocks = ClockControl::max(system.clock_control).freeze();
let timer = hal::timer::TimerGroup::new(
peripherals.TIMG1,
&clocks,
&mut system.peripheral_clock_control,
)
.timer0;
let init = initialize(
EspWifiInitFor::Wifi,
timer,
Rng::new(peripherals.RNG),
system.radio_clock_control,
&clocks,
)
.unwrap();
use embedded_hal::blocking::delay::DelayMs;
// Create an SPI interface and pins
let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let mut delay = Delay::new(&clocks);
let busy = io.pins.gpio4.into_floating_input();
let rst = io.pins.gpio16.into_push_pull_output();
let mosi = io.pins.gpio23.into_push_pull_output();
// let miso = io.pins.gpio19.into_floating_input();
let sclk = io.pins.gpio18.into_push_pull_output();
let dc = io.pins.gpio17.into_push_pull_output();
let cs = io.pins.gpio5.into_push_pull_output();
delay.delay_ms(10u32);
let mut spi = spi::Spi::new_no_cs_no_miso(
peripherals.SPI3,
sclk,
mosi,
40u32.MHz(),
spi::SpiMode::Mode0,
&mut system.peripheral_clock_control,
&clocks,
);
let mut ssd1680 = Ssd1680::new(&mut spi, cs, busy, dc, rst, &mut delay).unwrap();
// Initialize ePaper display
ssd1680.clear_bw_frame(&mut spi).unwrap();
// Define the size of the buffer
const BUF_SIZE: usize = 4000;
use alloc::alloc::{alloc, dealloc, Layout};
// Create a layout
let layout = Layout::from_size_align(BUF_SIZE, 1).unwrap();
// Allocate a buffer
let buf_ptr = unsafe { alloc(layout) };
let buf_array: &mut [u8; 4000] = unsafe {
&mut *(buf_ptr as *mut [u8; 4000])
};
// let buf_array = alloc::vec![0u8; 4000];
let mut display_bw = Display2in13::bw_with_buffer(*buf_array);
draw_text(&mut display_bw, "...", 0, 10); // Assuming draw_text function is defined
ssd1680.update_bw_frame(&mut spi, display_bw.buffer()).unwrap();
ssd1680.display_frame(&mut spi, &mut delay).unwrap();
esp_println!("Initializing");
// Initialize WiFi
let (wifi, ..) = peripherals.RADIO.split();
esp_println!("Allocating sockets");
let mut socket_set_entries: [SocketStorage; 5] = Default::default();
esp_println!("Acquiring WiFi interface");
let (iface, device, mut controller, sockets) =
match create_network_interface(&init, wifi, WifiMode::Sta, &mut socket_set_entries)
{
Ok(val) => val,
Err(_) => {
let err_msg = "Network init failed";
draw_text(&mut display_bw, err_msg, 0, 0); // Assuming draw_text function is defined
ssd1680.update_bw_frame(&mut spi, display_bw.buffer()).unwrap();
ssd1680.display_frame(&mut spi, &mut delay).unwrap();
// Log the error message to serial console or another debugging interface
print!("{}", err_msg);
loop {}
}
};
esp_println!("Creating WifiStack");
let wifi_stack = WifiStack::new(iface, device, sockets, current_millis);
esp_println!("Creating ClientConfiguration");
let client_config = Configuration::Client(ClientConfiguration {
ssid: SSID.into(),
password: PASSWORD.into(),
..Default::default()
});
esp_println!("Setting configuration");
controller.set_configuration(&client_config).unwrap();
esp_println!("Starting WiFi controller");
controller.start().unwrap();
println!("is wifi started: {:?}", controller.is_started());
println!("Start Wifi Scan");
let res: Result<(heapless::Vec<AccessPointInfo, 10>, usize), WifiError> = controller.scan_n();
if let Ok((res, _count)) = res {
for ap in res {
println!("{:?}", ap);
}
}
println!("{:?}", controller.get_capabilities());
println!("wifi_connect {:?}", controller.connect());
// wait to get connected
println!("Wait to get connected");
loop {
let res = controller.is_connected();
match res {
Ok(connected) => {
if connected {
break;
}
}
Err(err) => {
println!("WiFi Error - {:?} - delay 1000 ms", err);
delay.delay_ms(1000u32);
controller.connect().unwrap();
}
}
}
println!("Is connected: {:?}", controller.is_connected());
// wait for getting an ip address
println!("Wait to get an ip address");
loop {
wifi_stack.work();
if wifi_stack.is_iface_up() {
println!("got ip {:?}", wifi_stack.get_ip_info());
delay.delay_ms(500u32);
break;
}
}
println!("Start busy loop on main");
let mut rx_buffer = [0u8; 1536];
let mut tx_buffer = [0u8; 1536];
let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer);
loop {
println!("Making HTTP request");
socket.work();
println!("Opening socket");
match socket.open(IpAddress::Ipv4(Ipv4Address::new(93, 99, 115, 9)), 80) {
Ok(_) => {
// Successfully opened the socket
// Continue with the next steps
},
Err(e) => {
println!("error{:?}", e);
loop{};
}
}
println!("Sendig GET request");
socket
.write(b"GET /info.txt HTTP/1.0\r\nHost: iot.georgik.rocks\r\n\r\n")
.unwrap();
socket.flush().unwrap();
let wait_end = current_millis() + 20 * 1000;
// A fixed-size buffer to hold the HTTP response.
let mut full_response = [0u8; 2048];
let mut full_len = 0;
println!("Reading response");
// Read the HTTP response into the buffer.
loop {
let mut buffer = [0u8; 512];
if let Ok(len) = socket.read(&mut buffer) {
// Copy the newly read bytes into `full_response`.
full_response[full_len..full_len + len].copy_from_slice(&buffer[0..len]);
full_len += len;
println!("Read {} bytes", len);
} else {
println!("Read error");
break;
}
if current_millis() > wait_end {
println!("Timeout");
break;
}
}
// Search for the double CRLF sequence to find the start of the HTTP body.
let mut body_start = 0;
for i in 0..(full_len - 3) {
if &full_response[i..i + 4] == b"\r\n\r\n" {
body_start = i + 4;
break;
}
}
if body_start != 0 {
let body = &full_response[body_start..full_len];
let to_print = unsafe { core::str::from_utf8_unchecked(body) };
draw_text(&mut display_bw, &to_print, 0, 10); // Assuming draw_text function is defined
print!("{}", to_print);
}
println!();
socket.disconnect();
ssd1680.update_bw_frame(&mut spi, display_bw.buffer()).unwrap();
ssd1680.display_frame(&mut spi, &mut delay).unwrap();
// Delay before repeating
delay.delay_ms(500000u32);
}
}