-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Expand the capabilities of various macros (#55)
* Hah Hah! I'm doing macros! * Macros overwhelming! * Remove now-incorrect message pre-check * Implement schema querying * Add minimal reference example * Implement logging, fill out docs, format
- Loading branch information
1 parent
0544018
commit a2808a3
Showing
27 changed files
with
2,971 additions
and
314 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
#![no_std] | ||
#![no_main] | ||
|
||
use defmt::info; | ||
use embassy_executor::Spawner; | ||
use embassy_rp::{peripherals::USB, usb}; | ||
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | ||
use embassy_time::{Duration, Ticker}; | ||
use embassy_usb::{Config, UsbDevice}; | ||
use postcard_rpc::{ | ||
define_dispatch, sender_fmt, | ||
server::{ | ||
impls::embassy_usb_v0_3::{ | ||
dispatch_impl::{WireRxBuf, WireRxImpl, WireSpawnImpl, WireStorage, WireTxImpl}, | ||
PacketBuffers, | ||
}, | ||
Dispatch, Sender, Server, | ||
}, | ||
}; | ||
use static_cell::ConstStaticCell; | ||
use workbook_fw::Irqs; | ||
use workbook_icd::{ENDPOINT_LIST, TOPICS_IN_LIST, TOPICS_OUT_LIST}; | ||
use {defmt_rtt as _, panic_probe as _}; | ||
|
||
pub struct Context {} | ||
|
||
type AppDriver = usb::Driver<'static, USB>; | ||
type AppStorage = WireStorage<ThreadModeRawMutex, AppDriver, 256, 256, 64, 256>; | ||
type BufStorage = PacketBuffers<1024, 1024>; | ||
type AppTx = WireTxImpl<ThreadModeRawMutex, AppDriver>; | ||
type AppRx = WireRxImpl<AppDriver>; | ||
type AppServer = Server<AppTx, AppRx, WireRxBuf, MyApp>; | ||
|
||
static PBUFS: ConstStaticCell<BufStorage> = ConstStaticCell::new(BufStorage::new()); | ||
static STORAGE: AppStorage = AppStorage::new(); | ||
|
||
fn usb_config() -> Config<'static> { | ||
let mut config = Config::new(0x16c0, 0x27DD); | ||
config.manufacturer = Some("OneVariable"); | ||
config.product = Some("ov-twin"); | ||
config.serial_number = Some("12345678"); | ||
|
||
// Required for windows compatibility. | ||
// https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help | ||
config.device_class = 0xEF; | ||
config.device_sub_class = 0x02; | ||
config.device_protocol = 0x01; | ||
config.composite_with_iads = true; | ||
|
||
config | ||
} | ||
|
||
define_dispatch! { | ||
app: MyApp; | ||
spawn_fn: spawn_fn; | ||
tx_impl: AppTx; | ||
spawn_impl: WireSpawnImpl; | ||
context: Context; | ||
|
||
endpoints: { | ||
list: ENDPOINT_LIST; | ||
|
||
| EndpointTy | kind | handler | | ||
| ---------- | ---- | ------- | | ||
}; | ||
topics_in: { | ||
list: TOPICS_IN_LIST; | ||
|
||
| TopicTy | kind | handler | | ||
| ---------- | ---- | ------- | | ||
}; | ||
topics_out: { | ||
list: TOPICS_OUT_LIST; | ||
}; | ||
} | ||
|
||
#[embassy_executor::main] | ||
async fn main(spawner: Spawner) { | ||
// SYSTEM INIT | ||
info!("Start"); | ||
let p = embassy_rp::init(Default::default()); | ||
|
||
// USB/RPC INIT | ||
let driver = usb::Driver::new(p.USB, Irqs); | ||
let pbufs = PBUFS.take(); | ||
let config = usb_config(); | ||
|
||
let context = Context {}; | ||
|
||
let (device, tx_impl, rx_impl) = STORAGE.init(driver, config, pbufs.tx_buf.as_mut_slice()); | ||
let dispatcher = MyApp::new(context, spawner.into()); | ||
let vkk = dispatcher.min_key_len(); | ||
let server: AppServer = Server::new( | ||
&tx_impl, | ||
rx_impl, | ||
pbufs.rx_buf.as_mut_slice(), | ||
dispatcher, | ||
vkk, | ||
); | ||
let sender = server.sender(); | ||
spawner.must_spawn(usb_task(device)); | ||
spawner.must_spawn(server_task(server)); | ||
spawner.must_spawn(logging_task(sender)); | ||
} | ||
|
||
#[embassy_executor::task] | ||
pub async fn logging_task(sender: Sender<AppTx>) { | ||
let mut ticker = Ticker::every(Duration::from_millis(1000)); | ||
let mut ctr = 0u16; | ||
loop { | ||
ticker.next().await; | ||
defmt::info!("logging"); | ||
if ctr & 0b1 != 0 { | ||
let _ = sender.log_str("Hello world!").await; | ||
} else { | ||
let _ = sender_fmt!(sender, "formatted: {ctr}").await; | ||
} | ||
ctr = ctr.wrapping_add(1); | ||
} | ||
} | ||
|
||
#[embassy_executor::task] | ||
pub async fn server_task(mut server: AppServer) { | ||
loop { | ||
// If the host disconnects, we'll return an error here. | ||
// If this happens, just wait until the host reconnects | ||
let _ = server.run().await; | ||
} | ||
} | ||
|
||
/// This handles the low level USB management | ||
#[embassy_executor::task] | ||
pub async fn usb_task(mut usb: UsbDevice<'static, AppDriver>) { | ||
usb.run().await; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#![no_std] | ||
#![no_main] | ||
|
||
use defmt::info; | ||
use embassy_executor::Spawner; | ||
use embassy_rp::{peripherals::USB, usb}; | ||
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; | ||
use embassy_usb::{Config, UsbDevice}; | ||
use postcard_rpc::{ | ||
define_dispatch, | ||
server::{ | ||
impls::embassy_usb_v0_3::{ | ||
dispatch_impl::{WireRxBuf, WireRxImpl, WireSpawnImpl, WireStorage, WireTxImpl}, | ||
PacketBuffers, | ||
}, | ||
Dispatch, Server, | ||
}, | ||
}; | ||
use static_cell::ConstStaticCell; | ||
use workbook_fw::Irqs; | ||
use workbook_icd::{ENDPOINT_LIST, TOPICS_IN_LIST, TOPICS_OUT_LIST}; | ||
use {defmt_rtt as _, panic_probe as _}; | ||
|
||
pub struct Context {} | ||
|
||
type AppDriver = usb::Driver<'static, USB>; | ||
type AppStorage = WireStorage<ThreadModeRawMutex, AppDriver, 256, 256, 64, 256>; | ||
type BufStorage = PacketBuffers<1024, 1024>; | ||
type AppTx = WireTxImpl<ThreadModeRawMutex, AppDriver>; | ||
type AppRx = WireRxImpl<AppDriver>; | ||
type AppServer = Server<AppTx, AppRx, WireRxBuf, MyApp>; | ||
|
||
static PBUFS: ConstStaticCell<BufStorage> = ConstStaticCell::new(BufStorage::new()); | ||
static STORAGE: AppStorage = AppStorage::new(); | ||
|
||
fn usb_config() -> Config<'static> { | ||
let mut config = Config::new(0x16c0, 0x27DD); | ||
config.manufacturer = Some("OneVariable"); | ||
config.product = Some("ov-twin"); | ||
config.serial_number = Some("12345678"); | ||
|
||
// Required for windows compatibility. | ||
// https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help | ||
config.device_class = 0xEF; | ||
config.device_sub_class = 0x02; | ||
config.device_protocol = 0x01; | ||
config.composite_with_iads = true; | ||
|
||
config | ||
} | ||
|
||
define_dispatch! { | ||
app: MyApp; | ||
spawn_fn: spawn_fn; | ||
tx_impl: AppTx; | ||
spawn_impl: WireSpawnImpl; | ||
context: Context; | ||
|
||
endpoints: { | ||
list: ENDPOINT_LIST; | ||
|
||
| EndpointTy | kind | handler | | ||
| ---------- | ---- | ------- | | ||
}; | ||
topics_in: { | ||
list: TOPICS_IN_LIST; | ||
|
||
| TopicTy | kind | handler | | ||
| ---------- | ---- | ------- | | ||
}; | ||
topics_out: { | ||
list: TOPICS_OUT_LIST; | ||
}; | ||
} | ||
|
||
#[embassy_executor::main] | ||
async fn main(spawner: Spawner) { | ||
// SYSTEM INIT | ||
info!("Start"); | ||
let p = embassy_rp::init(Default::default()); | ||
|
||
// USB/RPC INIT | ||
let driver = usb::Driver::new(p.USB, Irqs); | ||
let pbufs = PBUFS.take(); | ||
let config = usb_config(); | ||
|
||
let context = Context {}; | ||
|
||
let (device, tx_impl, rx_impl) = STORAGE.init(driver, config, pbufs.tx_buf.as_mut_slice()); | ||
let dispatcher = MyApp::new(context, spawner.into()); | ||
let vkk = dispatcher.min_key_len(); | ||
let server: AppServer = Server::new( | ||
&tx_impl, | ||
rx_impl, | ||
pbufs.rx_buf.as_mut_slice(), | ||
dispatcher, | ||
vkk, | ||
); | ||
spawner.must_spawn(usb_task(device)); | ||
spawner.must_spawn(server_task(server)); | ||
} | ||
|
||
#[embassy_executor::task] | ||
pub async fn server_task(mut server: AppServer) { | ||
loop { | ||
// If the host disconnects, we'll return an error here. | ||
// If this happens, just wait until the host reconnects | ||
let _ = server.run().await; | ||
} | ||
} | ||
|
||
/// This handles the low level USB management | ||
#[embassy_executor::task] | ||
pub async fn usb_task(mut usb: UsbDevice<'static, AppDriver>) { | ||
usb.run().await; | ||
} |
Oops, something went wrong.