Implement int to str conversion for serial

This commit is contained in:
hodasemi 2022-11-01 09:51:00 +01:00
parent 38e294b619
commit a9110c9197
3 changed files with 92 additions and 22 deletions

View file

@ -19,6 +19,8 @@ usbd-serial = "0.1"
# We're using a Pico by default on this template # We're using a Pico by default on this template
rp-pico = "0.5" rp-pico = "0.5"
numtoa = "*"
# but you can use any BSP. Uncomment this to use the pro_micro_rp2040 BSP instead # but you can use any BSP. Uncomment this to use the pro_micro_rp2040 BSP instead
# sparkfun-pro-micro-rp2040 = "0.3" # sparkfun-pro-micro-rp2040 = "0.3"

View file

@ -4,9 +4,8 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
extern crate alloc; mod serial;
use alloc::string::ToString;
use bsp::entry; use bsp::entry;
use defmt::*; use defmt::*;
use defmt_rtt as _; use defmt_rtt as _;
@ -30,7 +29,8 @@ use bsp::hal::{
use embedded_hal::adc::OneShot; use embedded_hal::adc::OneShot;
use usb_device::{class_prelude::*, prelude::*}; use usb_device::{class_prelude::*, prelude::*};
use usbd_serial::SerialPort;
use crate::serial::Serial;
#[entry] #[entry]
fn main() -> ! { fn main() -> ! {
@ -67,7 +67,7 @@ fn main() -> ! {
let mut led_pin = pins.led.into_push_pull_output(); let mut led_pin = pins.led.into_push_pull_output();
led_pin.set_low(); led_pin.set_low().unwrap();
// Set up the USB driver // Set up the USB driver
let usb_bus = UsbBusAllocator::new(UsbBus::new( let usb_bus = UsbBusAllocator::new(UsbBus::new(
@ -78,8 +78,7 @@ fn main() -> ! {
&mut pac.RESETS, &mut pac.RESETS,
)); ));
// Set up the USB Communications Class Device driver let mut serial = Serial::new(&usb_bus);
let mut serial = SerialPort::new(&usb_bus);
// Create a USB device with a fake VID and PID // Create a USB device with a fake VID and PID
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
@ -114,7 +113,7 @@ fn main() -> ! {
// let adc_1_value: u16 = adc.read(&mut adc_pin_1).unwrap(); // let adc_1_value: u16 = adc.read(&mut adc_pin_1).unwrap();
// let adc_2_value: u16 = adc.read(&mut adc_pin_2).unwrap(); // let adc_2_value: u16 = adc.read(&mut adc_pin_2).unwrap();
serial_send(&mut serial, &adc_0_value.to_string()); serial.send(adc_0_value);
} }
delay.delay_ms(8); delay.delay_ms(8);
@ -154,19 +153,4 @@ fn main() -> ! {
} }
} }
fn serial_send(serial: &mut SerialPort<UsbBus>, msg: &str) {
// Send back to the host
let mut wr_ptr = msg.as_bytes();
while !wr_ptr.is_empty() {
match serial.write(wr_ptr) {
Ok(len) => wr_ptr = &wr_ptr[len..],
// On error, just drop unwritten data.
// One possible error is Err(WouldBlock), meaning the USB
// write buffer is full.
Err(_) => break,
};
}
}
// End of file // End of file

84
rust/pico/src/serial.rs Normal file
View file

@ -0,0 +1,84 @@
use rp_pico as bsp;
use bsp::hal::usb::UsbBus;
use usb_device::class_prelude::*;
use usbd_serial::SerialPort;
use numtoa::NumToA;
pub struct Serial<'a> {
serial: SerialPort<'a, UsbBus>,
buf: [u8; 20],
}
impl<'a> Serial<'a> {
pub fn new(usb_bus: &'a UsbBusAllocator<UsbBus>) -> Self {
Self {
serial: SerialPort::new(&usb_bus),
buf: [0u8; 20],
}
}
pub fn send(&mut self, i: impl NumToA<u16>) {
let s = i.numtoa_str(10, &mut self.buf);
// Send back to the host
let mut wr_ptr = s.as_bytes();
while !wr_ptr.is_empty() {
match self.serial.write(wr_ptr) {
Ok(len) => wr_ptr = &wr_ptr[len..],
// On error, just drop unwritten data.
// One possible error is Err(WouldBlock), meaning the USB
// write buffer is full.
Err(_) => break,
};
}
}
}
impl<'a> usb_device::class::UsbClass<rp_pico::hal::usb::UsbBus> for Serial<'a> {
fn get_configuration_descriptors(
&self,
writer: &mut DescriptorWriter,
) -> usb_device::Result<()> {
self.serial.get_configuration_descriptors(writer)
}
fn get_bos_descriptors(&self, writer: &mut BosWriter) -> usb_device::Result<()> {
self.serial.get_bos_descriptors(writer)
}
fn get_string(&self, index: StringIndex, lang_id: u16) -> Option<&str> {
self.serial.get_string(index, lang_id)
}
fn reset(&mut self) {
self.serial.reset()
}
fn poll(&mut self) {
self.serial.poll()
}
fn control_out(&mut self, xfer: ControlOut<rp_pico::hal::usb::UsbBus>) {
self.serial.control_out(xfer)
}
fn control_in(&mut self, xfer: ControlIn<rp_pico::hal::usb::UsbBus>) {
self.serial.control_in(xfer)
}
fn endpoint_setup(&mut self, addr: EndpointAddress) {
self.serial.endpoint_setup(addr)
}
fn endpoint_out(&mut self, addr: EndpointAddress) {
self.serial.endpoint_out(addr)
}
fn endpoint_in_complete(&mut self, addr: EndpointAddress) {
self.serial.endpoint_in_complete(addr)
}
}