1use crate::util::open;
8use crate::{protocol, rcvbp, Ctx, Loader};
9use anyhow::Result;
10use panelspec::PanelSpec;
11use rawlink::Link;
12use rcvbp::image;
13use rcvbp::spec::Generated;
14use std::time::Duration;
15
16const VOID_LINE_HIGH_OFFSET: usize = 0x6800;
19const ANTI_VOID_HIGH_OFFSET: usize = 0x7000;
20
21struct Pack<'a> {
23 kind: u8,
24 sub: u8,
25 header: usize,
26 body: &'a [u8],
27}
28
29impl Pack<'_> {
30 fn send(&self, dev: &mut Link, gap: Duration) -> Result<()> {
33 let mut p = vec![0u8; self.header - 2 + self.body.len()];
34 p[1] = self.sub;
35 p[self.header - 2..].copy_from_slice(self.body);
36 dev.send(&protocol::frame([self.kind, 0x00], &p))?;
37 std::thread::sleep(gap);
38 Ok(())
39 }
40}
41
42pub fn send_params(
45 ctx: &Ctx,
46 spec_path: &str,
47 chip_only: bool,
48 gap_ms: u64,
49 load: Loader,
50) -> Result<()> {
51 let spec = PanelSpec::load(spec_path)?;
52 let g = rcvbp::spec::generate(&spec, &spec.chip_library(load)?)?;
53 send_generated(ctx, &spec, &g, chip_only, gap_ms)
54}
55
56#[rustfmt::skip] pub fn send_generated(ctx: &Ctx, spec: &PanelSpec, g: &Generated, chip_only: bool, gap_ms: u64) -> Result<()> {
59 let gap = Duration::from_millis(gap_ms);
60 let map = &ctx.model()?.memory.boot_image;
61 let mut dev = open(ctx)?;
62
63 if let Some(r) = g.rcvbp.find_by_id(0x84) {
67 Pack { kind: 0x05, sub: protocol::params::SUB_CHIP, header: 4, body: &r.payload }
68 .send(&mut dev, gap)?;
69 }
70 if chip_only {
71 return Ok(());
72 }
73
74 let img = image::Block7Builder::from_generated(map, spec, g)?.finish().image;
77
78 let mut packs: Vec<Pack> = vec![
79 Pack { kind: 0x05, sub: protocol::params::SUB_DATA_SWAP, header: 4,
80 body: &img[map.data_swap..map.data_swap + 0x100] },
81 Pack { kind: 0x05, sub: protocol::params::SUB_BASIC, header: 4, body: &g.basic_pack },
82 Pack { kind: 0x10, sub: 0, header: 4, body: &img[0x0100..0x0500] }, Pack { kind: 0x17, sub: 0, header: 5, body: &img[0x0600..0x0900] }, ];
85 for k in 0..16 {
87 let at = map.mapping + k * 0x300;
88 packs.push(Pack { kind: 0x03, sub: k as u8, header: 4, body: &img[at..at + 0x300] });
89 }
90 for k in 0..4usize {
93 let at = if k < 2 { map.void_line + k * 0x400 } else { VOID_LINE_HIGH_OFFSET + (k - 2) * 0x400 };
94 packs.push(Pack { kind: 0x1F, sub: k as u8, header: 8, body: &img[at..at + 0x400] });
95 }
96 for k in 0..8usize {
97 let at = if k < 4 { map.anti_void + k * 0x400 } else { ANTI_VOID_HIGH_OFFSET + (k - 4) * 0x400 };
98 packs.push(Pack { kind: 0x32, sub: k as u8, header: 8, body: &img[at..at + 0x400] });
99 }
100 packs.push(Pack { kind: 0x18, sub: 0, header: 4,
101 body: &img[map.scan_table..map.scan_table + 0x400] });
102
103 for pk in &packs {
104 pk.send(&mut dev, gap)?;
105 }
106 Ok(())
107}