1#![no_std]
20
21pub mod audio;
22pub mod buttons;
23pub mod clock;
24pub mod cpu;
25pub mod display;
26pub mod knobs;
27pub mod leds;
28pub mod sdram;
29pub mod touch;
30
31use embassy_stm32::adc::AdcChannel;
32use embassy_stm32::fmc::Fmc;
33use embassy_stm32::gpio::{Level, Output, Speed};
34use embassy_stm32::i2c::{self, I2c, Master};
35use embassy_stm32::mode::Blocking;
36use embassy_stm32::time::Hertz;
37use embassy_stm32::{bind_interrupts, peripherals};
38
39bind_interrupts!(pub struct Irqs {
40 LTDC => embassy_stm32::ltdc::InterruptHandler<peripherals::LTDC>;
41});
42
43pub struct Board {
45 pub display: display::Display,
46 pub leds: leds::Leds,
47 pub buttons: buttons::Buttons,
48 pub knobs: knobs::Knobs,
49 pub touch: touch::Touch,
50 pub i2c: I2c<'static, Blocking, Master>,
52 pub codec_ok: bool,
54}
55
56pub async fn init() -> Board {
58 let p = embassy_stm32::init(clock::config());
59 defmt::info!("blackbox: STM32H743XI, sysclk 399.36 MHz");
60
61 cpu::init();
62 cpu::dual_pad_fix();
63
64 let mut sdram = Fmc::sdram_a13bits_d32bits_4banks_bank1(
66 p.FMC, p.PF0, p.PF1, p.PF2, p.PF3, p.PF4, p.PF5, p.PF12, p.PF13, p.PF14, p.PF15, p.PG0, p.PG1,
68 p.PG2, p.PG4, p.PG5, p.PD14, p.PD15, p.PD0, p.PD1, p.PE7, p.PE8, p.PE9, p.PE10, p.PE11, p.PE12, p.PE13, p.PE14,
71 p.PE15, p.PD8, p.PD9, p.PD10, p.PH8, p.PH9, p.PH10, p.PH11, p.PH12, p.PH13, p.PH14, p.PH15,
72 p.PI0, p.PI1, p.PI2, p.PI3, p.PI6, p.PI7, p.PI9, p.PI10, p.PE0, p.PE1, p.PI4, p.PI5, p.PH2, p.PG8, p.PG15, p.PH3, p.PF11, p.PH5, sdram::Is42s16160j,
76 );
77 let mut delay = sdram::BusyDelay(800);
78 let base = sdram.init(&mut delay) as usize;
79 sdram::smoke_test(base);
80
81 let leds = leds::Leds::new([
82 p.PG9.into(),
83 p.PJ8.into(),
84 p.PB10.into(),
85 p.PB8.into(),
86 p.PB9.into(),
87 p.PK2.into(),
88 p.PA5.into(),
89 p.PJ5.into(),
90 p.PJ4.into(),
91 p.PB11.into(),
92 p.PA4.into(),
93 ]);
94
95 let buttons = buttons::Buttons::new([
96 p.PI8.into(),
97 p.PD4.into(),
98 p.PD7.into(),
99 p.PI12.into(),
100 p.PI14.into(),
101 p.PG3.into(),
102 p.PH7.into(),
103 p.PC13.into(),
104 p.PB13.into(),
105 p.PJ1.into(),
106 p.PH4.into(),
107 p.PC2.into(),
108 p.PC3.into(),
109 ]);
110
111 let knobs = knobs::Knobs::new(
112 p.ADC1,
113 [
114 p.PA0.degrade_adc(), p.PA1.degrade_adc(), p.PA6.degrade_adc(), p.PC4.degrade_adc(), p.PB1.degrade_adc(), p.PA7.degrade_adc(), p.PC5.degrade_adc(), p.PB0.degrade_adc(), ],
123 );
124
125 let display = display::Display::new(p.LTDC, p.PK7, p.TIM8, p.PJ6, base).await;
127
128 let mut i2c_config = i2c::Config::default();
130 i2c_config.frequency = Hertz(400_000);
131 let mut i2c = I2c::new_blocking(p.I2C1, p.PB6, p.PB7, i2c_config);
132
133 let mut codec_rst = Output::new(p.PG13, Level::High, Speed::Low);
134 let codec_ok = audio::init_codec(&mut i2c, &mut codec_rst).await;
135
136 let touch_int = touch::bias_int_low(p.PG12.into());
139 let touch = touch::Touch::new(&mut i2c, touch_int).await;
140
141 audio::play_sine(440);
142 defmt::info!("blackbox: board up — controls + display + audio live");
143
144 Board {
145 display,
146 leds,
147 buttons,
148 knobs,
149 touch,
150 i2c,
151 codec_ok,
152 }
153}