preparation for angle values
This commit is contained in:
parent
4dd80e53fd
commit
9a1c09bbf1
4 changed files with 262 additions and 280 deletions
75
pico/src/input.rs
Normal file
75
pico/src/input.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
use as5600::As5600;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_rp::{
|
||||
Peri,
|
||||
gpio::{AnyPin, Input},
|
||||
i2c::{Config, I2c},
|
||||
peripherals::{I2C0, PIN_4, PIN_5},
|
||||
};
|
||||
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel, mutex::Mutex};
|
||||
use embassy_time::{Duration, Timer};
|
||||
|
||||
use crate::{Irqs, unwrap};
|
||||
|
||||
/// Button input notification channel
|
||||
pub static INPUT: Channel<CriticalSectionRawMutex, u8, 64> = Channel::new();
|
||||
|
||||
#[embassy_executor::task]
|
||||
/// Polls a single pin for falling edge (assumes buttons are pulled up and shorted when pressed)
|
||||
/// Sends [INPUT] with given id
|
||||
pub async fn button_poll_task(mut button: Input<'static>, id: u8) {
|
||||
loop {
|
||||
button.wait_for_falling_edge().await;
|
||||
INPUT.send(id).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub static ANGLE: Mutex<CriticalSectionRawMutex, u16> = Mutex::new(0);
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn rotation_read_task(
|
||||
i2c: Peri<'static, I2C0>,
|
||||
scl: Peri<'static, PIN_5>,
|
||||
sda: Peri<'static, PIN_4>,
|
||||
) {
|
||||
let i2c = I2c::new_async(i2c, scl, sda, Irqs, Config::default());
|
||||
let mut as5600 = As5600::new(i2c);
|
||||
|
||||
loop {
|
||||
let angle = as5600.angle().unwrap_or(0);
|
||||
let mut locked = ANGLE.lock().await;
|
||||
let old = *locked as i32;
|
||||
*locked = angle;
|
||||
let left_diff = old - angle as i32;
|
||||
let right_diff = angle as i32 - old;
|
||||
let diff = if left_diff.abs() < right_diff.abs() {
|
||||
left_diff
|
||||
} else {
|
||||
right_diff
|
||||
};
|
||||
Timer::after(Duration::from_millis(50)).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct InputConfig {
|
||||
pub i2c0: Peri<'static, I2C0>,
|
||||
pub scl: Peri<'static, PIN_5>,
|
||||
pub sda: Peri<'static, PIN_4>,
|
||||
|
||||
pub button_pins: [(Peri<'static, AnyPin>, u8); 4],
|
||||
}
|
||||
|
||||
pub fn setup(spawner: Spawner, config: InputConfig) {
|
||||
spawner.spawn(unwrap!(rotation_read_task(
|
||||
config.i2c0,
|
||||
config.scl,
|
||||
config.sda,
|
||||
)));
|
||||
|
||||
for (pin, id) in config.button_pins {
|
||||
spawner.spawn(unwrap!(button_poll_task(
|
||||
Input::new(pin, embassy_rp::gpio::Pull::Up),
|
||||
id,
|
||||
)));
|
||||
}
|
||||
}
|
||||
289
pico/src/main.rs
289
pico/src/main.rs
|
|
@ -1,40 +1,36 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::net::SocketAddrV4;
|
||||
use core::str::FromStr;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_net::tcp::{TcpReader, TcpSocket, TcpWriter};
|
||||
use embassy_net::tcp::{TcpReader, TcpWriter};
|
||||
use embassy_rp::multicore::{Stack, spawn_core1};
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::channel::Channel;
|
||||
use embassy_sync::mutex::Mutex;
|
||||
use embassy_sync::signal::Signal;
|
||||
use embedded_io::Write;
|
||||
use owned_str::OwnedStr;
|
||||
|
||||
use crate::buffer::{WriteBuffer, wait_for_config};
|
||||
use crate::screen::{SCREEN_BUFFER, lcd_display_task};
|
||||
use crate::buffer::WriteBuffer;
|
||||
use crate::input::{ANGLE, INPUT, InputConfig};
|
||||
use crate::net::network_setup_task;
|
||||
use crate::screen::lcd_display_task;
|
||||
use ag_lcd::{Blink, Cursor, Display, LcdDisplay};
|
||||
use as5600::As5600;
|
||||
use cyw43::{JoinOptions, aligned_bytes};
|
||||
use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi};
|
||||
use defmt::*;
|
||||
use embassy_executor::{Executor, Spawner};
|
||||
use embassy_net::StackResources;
|
||||
use embassy_rp::clocks::RoscRng;
|
||||
use embassy_rp::gpio::{Input, Level, Output};
|
||||
use embassy_rp::i2c::{self, Config, I2c};
|
||||
use embassy_rp::peripherals::{DMA_CH0, I2C0, PIN_4, PIN_5, PIN_23, PIN_24, PIN_25, PIN_29, PIO0};
|
||||
use embassy_rp::pio::{InterruptHandler, Pio};
|
||||
use embassy_rp::{Peri, bind_interrupts, dma};
|
||||
use embassy_executor::Executor;
|
||||
use embassy_rp::gpio::{Level, Output};
|
||||
use embassy_rp::i2c::{self};
|
||||
use embassy_rp::peripherals::{DMA_CH0, I2C0, PIO0};
|
||||
use embassy_rp::pio::InterruptHandler;
|
||||
use embassy_rp::{bind_interrupts, dma};
|
||||
use embassy_rp::{peripherals::USB, usb};
|
||||
use embassy_time::{Delay, Duration, Timer};
|
||||
use embassy_time::Delay;
|
||||
use static_cell::StaticCell;
|
||||
use ufmt::uwrite;
|
||||
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
mod buffer;
|
||||
mod input;
|
||||
mod net;
|
||||
mod screen;
|
||||
|
||||
const WIFI_NETWORK: &str = "flamme";
|
||||
|
|
@ -49,161 +45,12 @@ bind_interrupts!(struct Irqs {
|
|||
I2C0_IRQ => i2c::InterruptHandler<I2C0>;
|
||||
});
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn cyw43_task(
|
||||
runner: cyw43::Runner<'static, cyw43::SpiBus<Output<'static>, PioSpi<'static, PIO0, 0>>>,
|
||||
) -> ! {
|
||||
runner.run().await
|
||||
}
|
||||
#[embassy_executor::task]
|
||||
async fn logger_task(usb: embassy_rp::Peri<'static, embassy_rp::peripherals::USB>) {
|
||||
let driver = embassy_rp::usb::Driver::new(usb, Irqs);
|
||||
|
||||
embassy_usb_logger::run!(1024, log::LevelFilter::Info, driver);
|
||||
}
|
||||
#[embassy_executor::task]
|
||||
async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! {
|
||||
runner.run().await
|
||||
}
|
||||
|
||||
/// Button input notification channel
|
||||
static INPUT: Channel<CriticalSectionRawMutex, u8, 64> = Channel::new();
|
||||
|
||||
#[embassy_executor::task]
|
||||
/// Polls a single pin for falling edge (assumes buttons are pulled up and shorted when pressed)
|
||||
/// Sends [INPUT] with given id
|
||||
async fn button_poll_task(mut button: Input<'static>, id: u8) {
|
||||
loop {
|
||||
button.wait_for_falling_edge().await;
|
||||
INPUT.send(id).await;
|
||||
}
|
||||
}
|
||||
|
||||
static ANGLE: Mutex<CriticalSectionRawMutex, u16> = Mutex::new(0);
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn rotation_read_task(
|
||||
i2c: Peri<'static, I2C0>,
|
||||
scl: Peri<'static, PIN_5>,
|
||||
sda: Peri<'static, PIN_4>,
|
||||
) {
|
||||
let i2c = I2c::new_async(i2c, scl, sda, Irqs, Config::default());
|
||||
let mut as5600 = As5600::new(i2c);
|
||||
|
||||
loop {
|
||||
let angle = as5600.angle().unwrap_or(0);
|
||||
*ANGLE.lock().await = angle;
|
||||
Timer::after(Duration::from_millis(50)).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn network_setup_task(
|
||||
pin23: Peri<'static, PIN_23>,
|
||||
pin25: Peri<'static, PIN_25>,
|
||||
pio: Peri<'static, PIO0>,
|
||||
pin24: Peri<'static, PIN_24>,
|
||||
pin29: Peri<'static, PIN_29>,
|
||||
dma: Peri<'static, DMA_CH0>,
|
||||
spawner: Spawner,
|
||||
) {
|
||||
let fw = aligned_bytes!("../firmware/43439A0.bin");
|
||||
let clm = aligned_bytes!("../firmware/43439A0_clm.bin");
|
||||
let nvram = aligned_bytes!("../firmware/nvram_rp2040.bin");
|
||||
let mut rng = RoscRng;
|
||||
|
||||
// To make flashing faster for development, you may want to flash the firmwares independently
|
||||
// at hardcoded addresses, instead of baking them into the program with `include_bytes!`:
|
||||
// probe-rs download ../../cyw43-firmware/43439A0.bin --binary-format bin --chip RP2040 --base-address 0x10100000
|
||||
// probe-rs download ../../cyw43-firmware/43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x10140000
|
||||
//let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) };
|
||||
//let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) };
|
||||
|
||||
let pwr = Output::new(pin23, Level::Low);
|
||||
let cs = Output::new(pin25, Level::High);
|
||||
let mut pio = Pio::new(pio, Irqs);
|
||||
let spi = PioSpi::new(
|
||||
&mut pio.common,
|
||||
pio.sm0,
|
||||
DEFAULT_CLOCK_DIVIDER,
|
||||
pio.irq0,
|
||||
cs,
|
||||
pin24,
|
||||
pin29,
|
||||
dma::Channel::new(dma, Irqs),
|
||||
);
|
||||
|
||||
static STATE: StaticCell<cyw43::State> = StaticCell::new();
|
||||
let state = STATE.init(cyw43::State::new());
|
||||
let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw, nvram).await;
|
||||
spawner.spawn(unwrap!(cyw43_task(runner)));
|
||||
|
||||
control.init(clm).await;
|
||||
control
|
||||
.set_power_management(cyw43::PowerManagementMode::PowerSave)
|
||||
.await;
|
||||
|
||||
static RESOURCES: StaticCell<StackResources<5>> = StaticCell::new();
|
||||
let (stack, runner) = embassy_net::new(
|
||||
net_device,
|
||||
embassy_net::Config::dhcpv4(Default::default()),
|
||||
RESOURCES.init(StackResources::new()),
|
||||
rng.next_u64(),
|
||||
);
|
||||
spawner.spawn(unwrap!(net_task(runner)));
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "con");
|
||||
|
||||
while let Err(err) = control
|
||||
.join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))
|
||||
.await
|
||||
{
|
||||
let num = match err {
|
||||
cyw43::JoinError::AuthenticationFailure => 200,
|
||||
cyw43::JoinError::JoinFailure(e) => e,
|
||||
cyw43::JoinError::NetworkNotFound => 201,
|
||||
};
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "join {}", num);
|
||||
}
|
||||
|
||||
// uwrite!(lcd, "link.");
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "link.");
|
||||
stack.wait_link_up().await;
|
||||
|
||||
// lcd.clear();
|
||||
// // lcd.home();
|
||||
// uwrite!(lcd, "dhcp.");
|
||||
let mut buf = SCREEN_BUFFER.lock().await;
|
||||
buf.clear();
|
||||
uwrite!(buf.line1(), "dhcp.");
|
||||
drop(buf);
|
||||
stack.wait_config_up().await;
|
||||
let cfg = wait_for_config(stack).await;
|
||||
let local_addr = cfg.address.address();
|
||||
info!("IP address: {:?}", local_addr);
|
||||
|
||||
let host_addr = embassy_net::Ipv4Address::from_str(TARGET_IP).unwrap();
|
||||
// let target = UdpMetadata::from(SocketAddrV4::new(host_addr, 7070));
|
||||
let mut rx_buffer = [0; 4096];
|
||||
// let mut rx_meta = [PacketMetadata::EMPTY; 16];
|
||||
let mut tx_buffer = [0; 4096];
|
||||
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
||||
socket.set_timeout(Some(Duration::from_secs(10)));
|
||||
if let Err(e) = socket
|
||||
.connect(SocketAddrV4::new(host_addr, TARGET_PORT))
|
||||
.await
|
||||
{
|
||||
// uwrite!(lcd, "tcperr");
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "tcperr");
|
||||
error!("tcp connect error: {}", e);
|
||||
} else {
|
||||
// uwrite!(lcd, "tcpok");
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "tcpok");
|
||||
}
|
||||
|
||||
let (read, write) = socket.split();
|
||||
|
||||
join(tcp_read_loop(read), tcp_write_loop(write)).await;
|
||||
}
|
||||
|
||||
enum QuestionType {
|
||||
Choice,
|
||||
|
|
@ -216,7 +63,11 @@ struct QuestionData {
|
|||
points: i32,
|
||||
}
|
||||
|
||||
async fn tcp_read_loop(mut read: TcpReader<'_>) {
|
||||
static QUESTION: Mutex<CriticalSectionRawMutex, Option<QuestionData>> = Mutex::new(None);
|
||||
static QUESTION_UPDATE: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
||||
static WHEEL_VALUE: Mutex<CriticalSectionRawMutex, i32> = Mutex::new(0);
|
||||
|
||||
pub async fn tcp_read_loop(mut read: TcpReader<'_>) {
|
||||
let mut buf = [0u8; 1024];
|
||||
|
||||
while let Ok(len) = read.read(&mut buf).await {
|
||||
|
|
@ -228,6 +79,7 @@ async fn tcp_read_loop(mut read: TcpReader<'_>) {
|
|||
};
|
||||
let mut counter = 0;
|
||||
let mut question_data = None;
|
||||
let mut future_wheel = 0;
|
||||
for line in str.lines() {
|
||||
if line == "$$" {
|
||||
counter = 1;
|
||||
|
|
@ -266,6 +118,14 @@ async fn tcp_read_loop(mut read: TcpReader<'_>) {
|
|||
}
|
||||
}
|
||||
|
||||
match q_type {
|
||||
QuestionType::Numeric { min, max } => {
|
||||
let diff = max - min;
|
||||
future_wheel = min + diff / 2;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
question_data = Some(QuestionData {
|
||||
text: OwnedStr::new(),
|
||||
q_type,
|
||||
|
|
@ -279,16 +139,22 @@ async fn tcp_read_loop(mut read: TcpReader<'_>) {
|
|||
counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(question_data) = question_data {
|
||||
*QUESTION.lock().await = Some(question_data);
|
||||
*WHEEL_VALUE.lock().await = future_wheel;
|
||||
QUESTION_UPDATE.signal(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn tcp_write_loop(mut write: TcpWriter<'_>) {
|
||||
pub async fn tcp_write_loop(mut write: TcpWriter<'_>) {
|
||||
let mut buffer = WriteBuffer::<256>::new();
|
||||
loop {
|
||||
let data = INPUT.receive().await;
|
||||
let angle = *ANGLE.lock().await;
|
||||
core::writeln!(buffer, "button={} angle={}", data, angle).ok();
|
||||
write.write(&*buffer).await.ok();
|
||||
write.write(&buffer).await.ok();
|
||||
buffer.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -301,13 +167,6 @@ static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
|
|||
fn main() -> ! {
|
||||
let p = embassy_rp::init(Default::default());
|
||||
|
||||
let pin23 = p.PIN_23;
|
||||
let pin24 = p.PIN_24;
|
||||
let pin25 = p.PIN_25;
|
||||
let pin29 = p.PIN_29;
|
||||
let pio = p.PIO0;
|
||||
let dma = p.DMA_CH0;
|
||||
|
||||
let lcd: LcdDisplay<_, _> = LcdDisplay::new(
|
||||
Output::new(p.PIN_15, Level::Low),
|
||||
Output::new(p.PIN_14, Level::Low),
|
||||
|
|
@ -343,65 +202,21 @@ fn main() -> ! {
|
|||
executor0.run(|spawner| {
|
||||
spawner.spawn(unwrap!(logger_task(p.USB)));
|
||||
spawner.spawn(unwrap!(network_setup_task(
|
||||
pin23, pin25, pio, pin24, pin29, dma, spawner
|
||||
)));
|
||||
spawner.spawn(unwrap!(rotation_read_task(p.I2C0, p.PIN_5, p.PIN_4,)));
|
||||
|
||||
spawner.spawn(unwrap!(button_poll_task(
|
||||
Input::new(p.PIN_18, embassy_rp::gpio::Pull::Up),
|
||||
1,
|
||||
)));
|
||||
spawner.spawn(unwrap!(button_poll_task(
|
||||
Input::new(p.PIN_19, embassy_rp::gpio::Pull::Up),
|
||||
2,
|
||||
)));
|
||||
spawner.spawn(unwrap!(button_poll_task(
|
||||
Input::new(p.PIN_20, embassy_rp::gpio::Pull::Up),
|
||||
3,
|
||||
)));
|
||||
spawner.spawn(unwrap!(button_poll_task(
|
||||
Input::new(p.PIN_21, embassy_rp::gpio::Pull::Up),
|
||||
4,
|
||||
p.PIN_23, p.PIN_25, p.PIO0, p.PIN_24, p.PIN_29, p.DMA_CH0, spawner
|
||||
)));
|
||||
crate::input::setup(
|
||||
spawner,
|
||||
InputConfig {
|
||||
i2c0: p.I2C0,
|
||||
scl: p.PIN_5,
|
||||
sda: p.PIN_4,
|
||||
button_pins: [
|
||||
(p.PIN_18.into(), 1),
|
||||
(p.PIN_19.into(), 2),
|
||||
(p.PIN_20.into(), 3),
|
||||
(p.PIN_21.into(), 4),
|
||||
],
|
||||
},
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
// async fn mainz(spawner: Spawner) {
|
||||
// let delay = Duration::from_millis(100);
|
||||
// loop {
|
||||
// // let angle = as5600.angle().unwrap_or(0);
|
||||
// // {
|
||||
// // use embedded_io::Write;
|
||||
// // let _ = core::writeln!(
|
||||
// // &mut buffer,
|
||||
// // "in1={} in2={} in3={} in4={} angle={}",
|
||||
// // in1,
|
||||
// // in2,
|
||||
// // in3,
|
||||
// // in4,
|
||||
// // angle
|
||||
// // );
|
||||
// // }
|
||||
// // {
|
||||
// // let _ = write.write(&*buffer).await;
|
||||
// // buffer.clear();
|
||||
// // }
|
||||
// if read.read_ready().unwrap() {
|
||||
// let mut rx_buffer = [0; 4096];
|
||||
// let n = read.read(&mut rx_buffer).await.unwrap();
|
||||
// if n > 0 {
|
||||
// lcd.clear();
|
||||
// lcd.home();
|
||||
// let s = core::str::from_utf8(&rx_buffer[..n]).unwrap_or("");
|
||||
// let npos = s.find('\n').unwrap_or(n);
|
||||
// let display_text = &s[..npos];
|
||||
// lcd.write_str(display_text).ok();
|
||||
|
||||
// Timer::after(Duration::from_micros(100)).await;
|
||||
// lcd.set_position(0, 1);
|
||||
// lcd.write_str(&s[npos..]);
|
||||
// }
|
||||
// }
|
||||
// Timer::after(delay).await;
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
135
pico/src/net.rs
Normal file
135
pico/src/net.rs
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
use core::net::SocketAddrV4;
|
||||
use core::str::FromStr;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_net::tcp::TcpSocket;
|
||||
|
||||
use crate::buffer::wait_for_config;
|
||||
use crate::screen::SCREEN_BUFFER;
|
||||
use crate::{
|
||||
Irqs, TARGET_IP, TARGET_PORT, WIFI_NETWORK, WIFI_PASSWORD, tcp_read_loop, tcp_write_loop,
|
||||
};
|
||||
use cyw43::{JoinOptions, aligned_bytes};
|
||||
use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi};
|
||||
use defmt::*;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_net::StackResources;
|
||||
use embassy_rp::clocks::RoscRng;
|
||||
use embassy_rp::gpio::{Level, Output};
|
||||
use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_24, PIN_25, PIN_29, PIO0};
|
||||
use embassy_rp::pio::Pio;
|
||||
use embassy_rp::{Peri, dma};
|
||||
use embassy_time::Duration;
|
||||
use static_cell::StaticCell;
|
||||
use ufmt::uwrite;
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn cyw43_task(
|
||||
runner: cyw43::Runner<'static, cyw43::SpiBus<Output<'static>, PioSpi<'static, PIO0, 0>>>,
|
||||
) -> ! {
|
||||
runner.run().await
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! {
|
||||
runner.run().await
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
pub async fn network_setup_task(
|
||||
pin23: Peri<'static, PIN_23>,
|
||||
pin25: Peri<'static, PIN_25>,
|
||||
pio: Peri<'static, PIO0>,
|
||||
pin24: Peri<'static, PIN_24>,
|
||||
pin29: Peri<'static, PIN_29>,
|
||||
dma: Peri<'static, DMA_CH0>,
|
||||
spawner: Spawner,
|
||||
) {
|
||||
let fw = aligned_bytes!("../firmware/43439A0.bin");
|
||||
let clm = aligned_bytes!("../firmware/43439A0_clm.bin");
|
||||
let nvram = aligned_bytes!("../firmware/nvram_rp2040.bin");
|
||||
let mut rng = RoscRng;
|
||||
|
||||
// To make flashing faster for development, you may want to flash the firmwares independently
|
||||
// at hardcoded addresses, instead of baking them into the program with `include_bytes!`:
|
||||
// probe-rs download ../../cyw43-firmware/43439A0.bin --binary-format bin --chip RP2040 --base-address 0x10100000
|
||||
// probe-rs download ../../cyw43-firmware/43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x10140000
|
||||
//let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) };
|
||||
//let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) };
|
||||
|
||||
let pwr = Output::new(pin23, Level::Low);
|
||||
let cs = Output::new(pin25, Level::High);
|
||||
let mut pio = Pio::new(pio, Irqs);
|
||||
let spi = PioSpi::new(
|
||||
&mut pio.common,
|
||||
pio.sm0,
|
||||
DEFAULT_CLOCK_DIVIDER,
|
||||
pio.irq0,
|
||||
cs,
|
||||
pin24,
|
||||
pin29,
|
||||
dma::Channel::new(dma, Irqs),
|
||||
);
|
||||
|
||||
static STATE: StaticCell<cyw43::State> = StaticCell::new();
|
||||
let state = STATE.init(cyw43::State::new());
|
||||
let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw, nvram).await;
|
||||
spawner.spawn(unwrap!(cyw43_task(runner)));
|
||||
|
||||
control.init(clm).await;
|
||||
control
|
||||
.set_power_management(cyw43::PowerManagementMode::PowerSave)
|
||||
.await;
|
||||
|
||||
static RESOURCES: StaticCell<StackResources<5>> = StaticCell::new();
|
||||
let (stack, runner) = embassy_net::new(
|
||||
net_device,
|
||||
embassy_net::Config::dhcpv4(Default::default()),
|
||||
RESOURCES.init(StackResources::new()),
|
||||
rng.next_u64(),
|
||||
);
|
||||
spawner.spawn(unwrap!(net_task(runner)));
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "con");
|
||||
|
||||
while let Err(err) = control
|
||||
.join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))
|
||||
.await
|
||||
{
|
||||
let num = match err {
|
||||
cyw43::JoinError::AuthenticationFailure => 200,
|
||||
cyw43::JoinError::JoinFailure(e) => e,
|
||||
cyw43::JoinError::NetworkNotFound => 201,
|
||||
};
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "join {}", num);
|
||||
}
|
||||
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "link.");
|
||||
stack.wait_link_up().await;
|
||||
|
||||
let mut buf = SCREEN_BUFFER.lock().await;
|
||||
buf.clear();
|
||||
uwrite!(buf.line1(), "dhcp.");
|
||||
drop(buf);
|
||||
stack.wait_config_up().await;
|
||||
let cfg = wait_for_config(stack).await;
|
||||
let local_addr = cfg.address.address();
|
||||
info!("IP address: {:?}", local_addr);
|
||||
|
||||
let host_addr = embassy_net::Ipv4Address::from_str(TARGET_IP).unwrap();
|
||||
let mut rx_buffer = [0; 4096];
|
||||
let mut tx_buffer = [0; 4096];
|
||||
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
||||
socket.set_timeout(Some(Duration::from_secs(10)));
|
||||
if let Err(e) = socket
|
||||
.connect(SocketAddrV4::new(host_addr, TARGET_PORT))
|
||||
.await
|
||||
{
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "tcperr");
|
||||
error!("tcp connect error: {}", e);
|
||||
} else {
|
||||
uwrite!(SCREEN_BUFFER.lock().await.line1(), "tcpok");
|
||||
}
|
||||
|
||||
let (read, write) = socket.split();
|
||||
|
||||
join(tcp_read_loop(read), tcp_write_loop(write)).await;
|
||||
}
|
||||
|
|
@ -73,49 +73,6 @@ pub static SCREEN_BUFFER: Mutex<CriticalSectionRawMutex, ScreenBuffer> = Mutex::
|
|||
line2_ptr: 0,
|
||||
});
|
||||
|
||||
struct LcdWriter<const LINE: u8>;
|
||||
pub type LcdLine1 = LcdWriter<0>;
|
||||
pub type LcdLine2 = LcdWriter<1>;
|
||||
|
||||
impl<const LINE: u8> uWrite for LcdWriter<LINE> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn write_char(&mut self, c: char) -> Result<(), Self::Error> {
|
||||
block_on(async {
|
||||
let mut buffer = SCREEN_BUFFER.lock().await;
|
||||
if LINE == 0 {
|
||||
let ptr = buffer.line1_ptr as usize;
|
||||
buffer.line1[ptr] = c as u8;
|
||||
buffer.line1_ptr = (buffer.line1_ptr + 1) % 16;
|
||||
} else {
|
||||
let ptr = buffer.line2_ptr as usize;
|
||||
buffer.line2[ptr] = c as u8;
|
||||
buffer.line2_ptr = (buffer.line2_ptr + 1) % 16;
|
||||
}
|
||||
LCD_UPDATE.signal(());
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
fn write_str(&mut self, s: &str) -> Result<(), Self::Error> {
|
||||
block_on(async {
|
||||
let mut buffer = SCREEN_BUFFER.lock().await;
|
||||
for c in s.chars() {
|
||||
if LINE == 0 {
|
||||
let ptr = buffer.line1_ptr as usize;
|
||||
buffer.line1[ptr] = c as u8;
|
||||
buffer.line1_ptr = (buffer.line1_ptr + 1) % 16;
|
||||
} else {
|
||||
let ptr = buffer.line2_ptr as usize;
|
||||
buffer.line2[ptr] = c as u8;
|
||||
buffer.line2_ptr = (buffer.line2_ptr + 1) % 16;
|
||||
}
|
||||
}
|
||||
LCD_UPDATE.signal(());
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
static LCD_UPDATE: Signal<CriticalSectionRawMutex, ()> = Signal::new();
|
||||
|
||||
#[embassy_executor::task]
|
||||
|
|
|
|||
Loading…
Reference in a new issue