acid/firmware/acid-firmware/src/peripherals/st7701s/spi.rs
Jakub Hlusička c3f58178fc Code cleanup
2026-02-28 03:15:04 +01:00

103 lines
2.2 KiB
Rust

use core::iter::once;
use embassy_time::{Duration, Timer};
use esp_hal::gpio::{Flex, Level, Output};
async fn spi_delay() {
Timer::after(Duration::from_micros(1)).await;
}
async fn spi_dummy_bit(sck: &mut Output<'_>) {
sck.set_low();
spi_delay().await;
sck.set_high();
spi_delay().await;
}
async fn spi_write_bit(bit: bool, mosi: &mut Flex<'_>, sck: &mut Output<'_>) {
mosi.set_level(if bit { Level::High } else { Level::Low });
sck.set_low();
spi_delay().await;
sck.set_high();
spi_delay().await;
}
async fn spi_read_bit(mosi: &mut Flex<'_>, sck: &mut Output<'_>) -> bool {
sck.set_low();
spi_delay().await;
sck.set_high();
spi_delay().await;
mosi.is_high()
}
async fn spi_write_bits(
bits: impl Iterator<Item = bool>,
mosi: &mut Flex<'_>,
sck: &mut Output<'_>,
) {
for bit in bits {
spi_write_bit(bit, mosi, sck).await;
}
}
async fn spi_write_word(is_param: bool, data: u8, mosi: &mut Flex<'_>, sck: &mut Output<'_>) {
assert!(sck.is_set_high());
spi_write_bits(
once(is_param).chain((0..8).map(|i| (data >> i) & 1 != 0).rev()),
mosi,
sck,
)
.await;
}
pub async fn spi_write(
command: u8,
args: impl IntoIterator<Item = u8>,
mosi: &mut Flex<'_>,
sck: &mut Output<'_>,
cs: &mut Output<'_>,
) {
cs.set_low();
spi_write_word(false, command, mosi, sck).await;
for arg in args {
spi_write_word(true, arg, mosi, sck).await;
}
cs.set_high();
}
#[expect(unused)]
pub async fn spi_read(
command: u8,
dummy_cycle: bool,
mosi: &mut Flex<'_>,
sck: &mut Output<'_>,
cs: &mut Output<'_>,
output_buffer: &mut [u8],
) {
output_buffer.fill(0);
cs.set_low();
spi_write_word(false, command, mosi, sck).await;
mosi.set_output_enable(false);
mosi.set_input_enable(true);
if dummy_cycle {
spi_dummy_bit(sck).await;
}
for output_byte in output_buffer {
for i in (0..8).rev() {
if spi_read_bit(mosi, sck).await {
*output_byte |= 1 << i;
}
}
}
mosi.set_input_enable(false);
mosi.set_output_enable(true);
cs.set_high();
}