Input side works but stutters
This commit is contained in:
commit
21a87f0e8b
|
@ -0,0 +1,19 @@
|
|||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||
# TODO(2) replace `$CHIP` with your chip's name (see `probe-run --list-chips` output)
|
||||
runner = "probe-run --chip STM32F103C8"
|
||||
rustflags = [
|
||||
"-C", "linker=flip-link",
|
||||
"-C", "link-arg=-Tlink.x",
|
||||
"-C", "link-arg=-Tdefmt.x",
|
||||
# This is needed if your flash or ram addresses are not aligned to 0x10000 in memory.x
|
||||
# See https://github.com/rust-embedded/cortex-m-quickstart/pull/95
|
||||
"-C", "link-arg=--nmagic",
|
||||
]
|
||||
|
||||
[build]
|
||||
target = "thumbv7m-none-eabi" # Cortex-M3
|
||||
|
||||
|
||||
[alias]
|
||||
rb = "run --bin"
|
||||
rrb = "run --release --bin"
|
|
@ -0,0 +1,14 @@
|
|||
**/*.rs.bk
|
||||
.#*
|
||||
.gdb_history
|
||||
Cargo.lock
|
||||
target/
|
||||
|
||||
# editor files
|
||||
.vscode/*
|
||||
!.vscode/*.md
|
||||
!.vscode/*.svd
|
||||
!.vscode/launch.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/settings.json
|
|
@ -0,0 +1,80 @@
|
|||
[package]
|
||||
authors = ["Sebastian <sebastian@sebastians-site.de>"]
|
||||
name = "stm32-usbd-audio"
|
||||
edition = "2018"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
cortex-m = { version = "0.7.6", features = ["critical-section-single-core"]}
|
||||
cortex-m-rt = "0.7.2"
|
||||
cortex-m-rtic = "1.1.3"
|
||||
defmt = "0.3.2"
|
||||
defmt-rtt = "0.4"
|
||||
panic-probe = { version = "0.3.0", features = ["print-defmt"] }
|
||||
stm32f1xx-hal = { version = "0.9.0", features = ["stm32f103", "rt"] }
|
||||
embedded-hal = {version = "0.2.3"}
|
||||
systick-monotonic = "1.0.0"
|
||||
usb-device = {version = "0.2.9", features = ["control-buffer-256"]}
|
||||
usbd-audio = "0.1.0"
|
||||
|
||||
|
||||
[features]
|
||||
# set logging levels here
|
||||
default = [
|
||||
"defmt-default",
|
||||
# "dependency-a/defmt-trace",
|
||||
]
|
||||
|
||||
# do NOT modify these features
|
||||
defmt-default = []
|
||||
defmt-trace = []
|
||||
defmt-debug = []
|
||||
defmt-info = []
|
||||
defmt-warn = []
|
||||
defmt-error = []
|
||||
|
||||
# cargo build/run
|
||||
[profile.dev]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = true # <-
|
||||
incremental = false
|
||||
opt-level = 'z' # <-
|
||||
overflow-checks = true # <-
|
||||
|
||||
# cargo test
|
||||
[profile.test]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = true # <-
|
||||
incremental = false
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = true # <-
|
||||
|
||||
# cargo build/run --release
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = false # <-
|
||||
incremental = false
|
||||
lto = 'fat'
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = false # <-
|
||||
|
||||
# cargo test --release
|
||||
[profile.bench]
|
||||
codegen-units = 1
|
||||
debug = 2
|
||||
debug-assertions = false # <-
|
||||
incremental = false
|
||||
lto = 'fat'
|
||||
opt-level = 3 # <-
|
||||
overflow-checks = false # <-
|
||||
|
||||
# uncomment this to switch from the crates.io version of defmt to its git version
|
||||
# check app-template's README for instructions
|
||||
# [patch.crates-io]
|
||||
# defmt = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
|
||||
# defmt-rtt = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
|
||||
# defmt-test = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
|
||||
# panic-probe = { git = "https://github.com/knurling-rs/defmt", rev = "use defmt version reported by `probe-run --version`" }
|
|
@ -0,0 +1,6 @@
|
|||
/* bluepill using STM32F103C8T6 */
|
||||
MEMORY
|
||||
{
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
#![no_main]
|
||||
#![no_std]
|
||||
use defmt_rtt as _; // global logger
|
||||
|
||||
use panic_probe as _;
|
||||
use stm32f1xx_hal as _;
|
||||
|
||||
// same panicking *behavior* as `panic-probe` but doesn't print a panic message
|
||||
// this prevents the panic message being printed *twice* when `defmt::panic` is invoked
|
||||
#[defmt::panic_handler]
|
||||
fn panic() -> ! {
|
||||
cortex_m::asm::udf()
|
||||
}
|
||||
|
||||
use rtic::app;
|
||||
|
||||
#[app(device = stm32f1xx_hal::pac, peripherals = true, dispatchers = [SPI2])]
|
||||
mod app {
|
||||
|
||||
use stm32f1xx_hal::{
|
||||
gpio::{gpioc, Output, PushPull},
|
||||
prelude::*,
|
||||
usb::{Peripheral, UsbBus},
|
||||
};
|
||||
|
||||
use usb_device::class_prelude::UsbBusAllocator;
|
||||
use usb_device::prelude::*;
|
||||
use usbd_audio::{AudioClass, AudioClassBuilder, Format, StreamConfig, TerminalType};
|
||||
|
||||
use systick_monotonic::Systick;
|
||||
|
||||
#[monotonic(binds = SysTick, default = true)]
|
||||
type MonoTimer = Systick<1_000>;
|
||||
|
||||
#[shared]
|
||||
struct Shared {
|
||||
usb_dev: UsbDevice<'static, UsbBus<Peripheral>>,
|
||||
usb_audio: AudioClass<'static, UsbBus<Peripheral>>,
|
||||
board_led: gpioc::PC13<Output<PushPull>>,
|
||||
}
|
||||
|
||||
#[local]
|
||||
struct Local {}
|
||||
|
||||
#[init(local = [usb_bus: Option<UsbBusAllocator<UsbBus<Peripheral>>> = None])]
|
||||
fn init(mut cx: init::Context) -> (Shared, Local, init::Monotonics) {
|
||||
let mut flash = cx.device.FLASH.constrain();
|
||||
let rcc = cx.device.RCC.constrain();
|
||||
|
||||
// Freeze the configuration of all the clocks in the system and store the frozen frequencies in
|
||||
// `clocks`
|
||||
let clocks = rcc
|
||||
.cfgr
|
||||
.use_hse(8.MHz())
|
||||
.sysclk(72.MHz())
|
||||
.pclk1(36.MHz())
|
||||
.freeze(&mut flash.acr);
|
||||
|
||||
defmt::info!("Clock Setup done");
|
||||
|
||||
// Acquire the GPIOC peripheral
|
||||
let mut gpioa = cx.device.GPIOA.split();
|
||||
//let mut gpiob = cx.device.GPIOB.split();
|
||||
let mut gpioc = cx.device.GPIOC.split();
|
||||
|
||||
let board_led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
|
||||
defmt::info!("ADC Setup done");
|
||||
|
||||
// BluePill board has a pull-up resistor on the D+ line.
|
||||
// Pull the D+ pin down to send a RESET condition to the USB bus.
|
||||
// This forced reset is needed only for development, without it host
|
||||
// will not reset your device when you upload new firmware.
|
||||
let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh);
|
||||
let mut delay = cortex_m::delay::Delay::new(cx.core.SYST, clocks.sysclk().to_Hz());
|
||||
usb_dp.set_low();
|
||||
delay.delay_ms(10);
|
||||
cx.core.SYST = delay.free();
|
||||
|
||||
let usb_dm = gpioa.pa11;
|
||||
let usb_dp = usb_dp.into_floating_input(&mut gpioa.crh);
|
||||
|
||||
let usb = Peripheral {
|
||||
usb: cx.device.USB,
|
||||
pin_dm: usb_dm,
|
||||
pin_dp: usb_dp,
|
||||
};
|
||||
|
||||
let usb_bus: &'static _ = cx.local.usb_bus.insert(UsbBus::new(usb));
|
||||
|
||||
let usb_audio = AudioClassBuilder::new()
|
||||
.input(
|
||||
StreamConfig::new_discrete(Format::S16le, 1, &[48000], TerminalType::InMicrophone)
|
||||
.unwrap(),
|
||||
)
|
||||
.output(
|
||||
StreamConfig::new_discrete(Format::S16le, 1, &[48000], TerminalType::OutSpeaker)
|
||||
.unwrap(),
|
||||
)
|
||||
.build(&usb_bus)
|
||||
.unwrap();
|
||||
|
||||
let usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
|
||||
.max_packet_size_0(64)
|
||||
.manufacturer("Kiffie Labs")
|
||||
.product("Audio port")
|
||||
.serial_number("42")
|
||||
.build();
|
||||
|
||||
let mono = Systick::new(cx.core.SYST, clocks.sysclk().to_Hz());
|
||||
|
||||
(
|
||||
Shared {
|
||||
usb_dev,
|
||||
usb_audio,
|
||||
board_led,
|
||||
},
|
||||
Local {},
|
||||
init::Monotonics(mono),
|
||||
)
|
||||
}
|
||||
|
||||
#[task(binds = USB_HP_CAN_TX, shared = [usb_dev, usb_audio])]
|
||||
fn usb_tx(cx: usb_tx::Context) {
|
||||
defmt::info!("usb_tx called");
|
||||
let mut usb_dev = cx.shared.usb_dev;
|
||||
let mut usb_audio = cx.shared.usb_audio;
|
||||
|
||||
(&mut usb_dev, &mut usb_audio).lock(|usb_dev, usb_audio| {
|
||||
if !usb_dev.poll(&mut [usb_audio]) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[task(binds = USB_LP_CAN_RX0, shared = [usb_dev, usb_audio])]
|
||||
fn usb_rx0(cx: usb_rx0::Context) {
|
||||
defmt::info!("usb_rx called");
|
||||
let mut usb_dev = cx.shared.usb_dev;
|
||||
let mut usb_audio = cx.shared.usb_audio;
|
||||
|
||||
(&mut usb_dev, &mut usb_audio).lock(|usb_dev, usb_audio| {
|
||||
if !usb_dev.poll(&mut [usb_audio]) {
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: Do something with usb_audio.read();
|
||||
});
|
||||
}
|
||||
|
||||
#[idle(shared = [usb_audio, board_led])]
|
||||
fn idle(mut cx: idle::Context) -> ! {
|
||||
defmt::info!("Idle Task");
|
||||
let sinetab = [
|
||||
0i16, 4276, 8480, 12539, 16383, 19947, 23169, 25995, 28377, 30272, 31650, 32486, 32767,
|
||||
32486, 31650, 30272, 28377, 25995, 23169, 19947, 16383, 12539, 8480, 4276, 0, -4276,
|
||||
-8480, -12539, -16383, -19947, -23169, -25995, -28377, -30272, -31650, -32486, -32767,
|
||||
-32486, -31650, -30272, -28377, -25995, -23169, -19947, -16383, -12539, -8480, -4276,
|
||||
];
|
||||
let sinetab_le = unsafe { &*(&sinetab as *const _ as *const [u8; 96]) };
|
||||
|
||||
loop {
|
||||
defmt::info!("Writing samples");
|
||||
cx.shared.usb_audio.lock(|usb_audio| {
|
||||
usb_audio.write(sinetab_le).ok();
|
||||
});
|
||||
rtic::export::wfi();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue