aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-07-11 03:07:39 +0200
committerDario Nieuwenhuis <[email protected]>2022-07-11 03:07:39 +0200
commit7ddcacac7bbfaed303dcda7d14ab29cad94fd570 (patch)
tree56d3ad19c6abd231853a93c872da3d3a44b19a8d /src/lib.rs
parent069a57fcf85c725d000e03163716edb4ae3922ca (diff)
clm download, country config.
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs98
1 files changed, 79 insertions, 19 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 3609ecaeb..698c52f49 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,9 +1,12 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3#![feature(type_alias_impl_trait, concat_bytes, const_slice_from_raw_parts)] 3#![feature(type_alias_impl_trait, concat_bytes, const_slice_from_raw_parts)]
4#![deny(unused_must_use)]
5
4// This mod MUST go first, so that the others see its macros. 6// This mod MUST go first, so that the others see its macros.
5pub(crate) mod fmt; 7pub(crate) mod fmt;
6 8
9mod countries;
7mod structs; 10mod structs;
8 11
9use core::cell::Cell; 12use core::cell::Cell;
@@ -206,14 +209,67 @@ pub struct Control<'a> {
206 209
207impl<'a> Control<'a> { 210impl<'a> Control<'a> {
208 pub async fn init(&mut self) { 211 pub async fn init(&mut self) {
212 const CHUNK_SIZE: usize = 1024;
213
209 let clm = unsafe { slice::from_raw_parts(0x10140000 as *const u8, 4752) }; 214 let clm = unsafe { slice::from_raw_parts(0x10140000 as *const u8, 4752) };
210 215
211 let mut buf = [0; 8 + 12 + 1024]; 216 info!("Downloading CLM...");
212 buf[0..8].copy_from_slice(b"clmload\x00"); 217
213 buf[8..20].copy_from_slice(b"\x02\x10\x02\x00\x00\x04\x00\x00\x00\x00\x00\x00"); 218 let mut offs = 0;
214 buf[20..].copy_from_slice(&clm[..1024]); 219 for chunk in clm.chunks(CHUNK_SIZE) {
215 self.ioctl(2, 263, 0, &buf).await; 220 let mut flag = DOWNLOAD_FLAG_HANDLER_VER;
216 info!("IOCTL done"); 221 if offs == 0 {
222 flag |= DOWNLOAD_FLAG_BEGIN;
223 }
224 offs += chunk.len();
225 if offs == clm.len() {
226 flag |= DOWNLOAD_FLAG_END;
227 }
228
229 let header = DownloadHeader {
230 flag,
231 dload_type: DOWNLOAD_TYPE_CLM,
232 len: chunk.len() as _,
233 crc: 0,
234 };
235 let mut buf = [0; 8 + 12 + CHUNK_SIZE];
236 buf[0..8].copy_from_slice(b"clmload\x00");
237 buf[8..20].copy_from_slice(&header.to_bytes());
238 buf[20..][..chunk.len()].copy_from_slice(&chunk);
239 self.ioctl(2, 263, 0, &buf[..8 + 12 + chunk.len()]).await;
240 }
241
242 info!("Configuring misc stuff...");
243
244 self.set_iovar_u32("bus:txglom", 0).await;
245 self.set_iovar_u32("apsta", 1).await;
246 self.set_iovar("cur_etheraddr", &[02, 03, 04, 05, 06, 07]).await;
247
248 let country = countries::WORLD_WIDE_XX;
249 let country_info = CountryInfo {
250 country_abbrev: [country.code[0], country.code[1], 0, 0],
251 country_code: [country.code[0], country.code[1], 0, 0],
252 rev: if country.rev == 0 { -1 } else { country.rev as _ },
253 };
254 self.set_iovar("country", &country_info.to_bytes()).await;
255
256 info!("INIT DONE");
257 }
258
259 async fn set_iovar_u32(&mut self, name: &str, val: u32) {
260 self.set_iovar(name, &val.to_le_bytes()).await
261 }
262
263 async fn set_iovar(&mut self, name: &str, val: &[u8]) {
264 info!("set {} = {:02x}", name, val);
265
266 let mut buf = [0; 64];
267 buf[..name.len()].copy_from_slice(name.as_bytes());
268 buf[name.len()] = 0;
269 buf[name.len() + 1..][..val.len()].copy_from_slice(val);
270
271 let total_len = name.len() + 1 + val.len();
272 self.ioctl(2, 263, 0, &buf[..total_len]).await;
217 } 273 }
218 274
219 async fn ioctl(&mut self, kind: u32, cmd: u32, iface: u32, buf: &[u8]) { 275 async fn ioctl(&mut self, kind: u32, cmd: u32, iface: u32, buf: &[u8]) {
@@ -255,6 +311,7 @@ pub struct Runner<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> {
255 /// - strap to set to gSPI mode on boot. 311 /// - strap to set to gSPI mode on boot.
256 dio: Flex<'a, DIO>, 312 dio: Flex<'a, DIO>,
257 313
314 ioctl_seq: u8,
258 backplane_window: u32, 315 backplane_window: u32,
259} 316}
260 317
@@ -271,6 +328,8 @@ pub async fn new<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin>(
271 cs, 328 cs,
272 clk, 329 clk,
273 dio, 330 dio,
331
332 ioctl_seq: 0,
274 backplane_window: 0xAAAA_AAAA, 333 backplane_window: 0xAAAA_AAAA,
275 }; 334 };
276 335
@@ -397,7 +456,6 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
397 } 456 }
398 457
399 pub async fn run(mut self) -> ! { 458 pub async fn run(mut self) -> ! {
400 let mut old_irq = 0;
401 let mut buf = [0; 2048]; 459 let mut buf = [0; 2048];
402 loop { 460 loop {
403 // Send stuff 461 // Send stuff
@@ -408,10 +466,6 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
408 466
409 // Receive stuff 467 // Receive stuff
410 let irq = self.read16(FUNC_BUS, REG_BUS_INTERRUPT); 468 let irq = self.read16(FUNC_BUS, REG_BUS_INTERRUPT);
411 if irq != old_irq {
412 info!("irq: {:04x}", irq);
413 }
414 old_irq = irq;
415 469
416 if irq & IRQ_F2_PACKET_AVAILABLE != 0 { 470 if irq & IRQ_F2_PACKET_AVAILABLE != 0 {
417 let mut status = 0xFFFF_FFFF; 471 let mut status = 0xFFFF_FFFF;
@@ -421,7 +475,6 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
421 475
422 if status & STATUS_F2_PKT_AVAILABLE != 0 { 476 if status & STATUS_F2_PKT_AVAILABLE != 0 {
423 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT; 477 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT;
424 info!("got len {}", len);
425 478
426 let cmd = cmd_word(false, true, FUNC_WLAN, 0, len); 479 let cmd = cmd_word(false, true, FUNC_WLAN, 0, len);
427 480
@@ -435,7 +488,7 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
435 } 488 }
436 self.cs.set_high(); 489 self.cs.set_high();
437 490
438 info!("rxd packet {:02x}", &buf[..len as usize]); 491 info!("rx {:02x}", &buf[..(len as usize).min(48)]);
439 492
440 self.rx(&buf[..len as usize]); 493 self.rx(&buf[..len as usize]);
441 } 494 }
@@ -466,15 +519,17 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
466 519
467 let channel = sdpcm_header.channel_and_flags & 0x0f; 520 let channel = sdpcm_header.channel_and_flags & 0x0f;
468 521
522 let payload = &packet[sdpcm_header.header_length as _..];
523
469 match channel { 524 match channel {
470 0 => { 525 0 => {
471 if packet.len() < SdpcmHeader::SIZE + CdcHeader::SIZE { 526 if payload.len() < CdcHeader::SIZE {
472 warn!("control packet too short, len={}", packet.len()); 527 warn!("payload too short, len={}", payload.len());
473 return; 528 return;
474 } 529 }
475 530
476 let cdc_header = 531 let cdc_header =
477 CdcHeader::from_bytes(packet[SdpcmHeader::SIZE..][..CdcHeader::SIZE].try_into().unwrap()); 532 CdcHeader::from_bytes(payload[..CdcHeader::SIZE].try_into().unwrap());
478 533
479 if cdc_header.id == self.state.ioctl_id.get() { 534 if cdc_header.id == self.state.ioctl_id.get() {
480 assert_eq!(cdc_header.status, 0); // todo propagate error 535 assert_eq!(cdc_header.status, 0); // todo propagate error
@@ -490,10 +545,13 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
490 545
491 let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len(); 546 let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len();
492 547
548 let seq = self.ioctl_seq;
549 self.ioctl_seq = self.ioctl_seq.wrapping_add(1);
550
493 let sdpcm_header = SdpcmHeader { 551 let sdpcm_header = SdpcmHeader {
494 len: total_len as u16, 552 len: total_len as u16, // TODO does this len need to be rounded up to u32?
495 len_inv: !total_len as u16, 553 len_inv: !total_len as u16,
496 sequence: 0x02, // todo 554 sequence: seq,
497 channel_and_flags: 0, // control channel 555 channel_and_flags: 0, // control channel
498 next_length: 0, 556 next_length: 0,
499 header_length: SdpcmHeader::SIZE as _, 557 header_length: SdpcmHeader::SIZE as _,
@@ -515,7 +573,9 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
515 buf[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes()); 573 buf[SdpcmHeader::SIZE..][..CdcHeader::SIZE].copy_from_slice(&cdc_header.to_bytes());
516 buf[SdpcmHeader::SIZE + CdcHeader::SIZE..][..data.len()].copy_from_slice(data); 574 buf[SdpcmHeader::SIZE + CdcHeader::SIZE..][..data.len()].copy_from_slice(data);
517 575
518 info!("txing {:02x}", &buf[..total_len]); 576 let total_len = (total_len + 3) & !3; // round up to 4byte
577
578 info!("tx {:02x}", &buf[..total_len.min(48)]);
519 579
520 let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _); 580 let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _);
521 self.cs.set_low(); 581 self.cs.set_low();