Update with master changes
This commit is contained in:
parent
dd9ec05cf9
commit
e960bca5fd
@ -9,9 +9,10 @@ use self::cbw::CommandBlockWrapper;
|
|||||||
use self::csw::{CommandStatus, CommandStatusWrapper};
|
use self::csw::{CommandStatus, CommandStatusWrapper};
|
||||||
use super::{CommandError, CommandSetHandler, DataPipeError, DataPipeIn, DataPipeOut};
|
use super::{CommandError, CommandSetHandler, DataPipeError, DataPipeIn, DataPipeOut};
|
||||||
use crate::class::msc::{MscProtocol, USB_CLASS_MSC};
|
use crate::class::msc::{MscProtocol, USB_CLASS_MSC};
|
||||||
use crate::control::{ControlHandler, InResponse, Request, RequestType};
|
use crate::control::{InResponse, Request, RequestType};
|
||||||
use crate::driver::Driver;
|
use crate::driver::Driver;
|
||||||
use crate::Builder;
|
use crate::types::InterfaceNumber;
|
||||||
|
use crate::{Builder, Handler};
|
||||||
|
|
||||||
const REQ_GET_MAX_LUN: u8 = 0xFE;
|
const REQ_GET_MAX_LUN: u8 = 0xFE;
|
||||||
const REQ_BULK_ONLY_RESET: u8 = 0xFF;
|
const REQ_BULK_ONLY_RESET: u8 = 0xFF;
|
||||||
@ -30,21 +31,26 @@ impl Default for State {
|
|||||||
|
|
||||||
pub struct Control {
|
pub struct Control {
|
||||||
max_lun: u8,
|
max_lun: u8,
|
||||||
|
if_num: InterfaceNumber,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Handler for Control {
|
||||||
|
fn control_in<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> Option<InResponse<'a>> {
|
||||||
|
if req.index != self.if_num.0 as u16 {
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ControlHandler for Control {
|
|
||||||
fn control_in<'a>(&'a mut self, req: Request, buf: &'a mut [u8]) -> InResponse<'a> {
|
|
||||||
match (req.request_type, req.request) {
|
match (req.request_type, req.request) {
|
||||||
(RequestType::Class, REQ_GET_MAX_LUN) => {
|
(RequestType::Class, REQ_GET_MAX_LUN) => {
|
||||||
debug!("REQ_GET_MAX_LUN");
|
debug!("REQ_GET_MAX_LUN");
|
||||||
buf[0] = self.max_lun;
|
buf[0] = self.max_lun;
|
||||||
InResponse::Accepted(&buf[..1])
|
Some(InResponse::Accepted(&buf[..1]))
|
||||||
}
|
}
|
||||||
(RequestType::Class, REQ_BULK_ONLY_RESET) => {
|
(RequestType::Class, REQ_BULK_ONLY_RESET) => {
|
||||||
debug!("REQ_BULK_ONLY_RESET");
|
debug!("REQ_BULK_ONLY_RESET");
|
||||||
InResponse::Accepted(&[])
|
Some(InResponse::Accepted(&[]))
|
||||||
}
|
}
|
||||||
_ => InResponse::Rejected,
|
_ => Some(InResponse::Rejected),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -60,20 +66,25 @@ impl<'d, D: Driver<'d>, C: CommandSetHandler> BulkOnlyTransport<'d, D, C> {
|
|||||||
pub fn new(builder: &mut Builder<'d, D>, state: &'d mut State, max_packet_size: u16, handler: C) -> Self {
|
pub fn new(builder: &mut Builder<'d, D>, state: &'d mut State, max_packet_size: u16, handler: C) -> Self {
|
||||||
assert!(C::MAX_LUN < 16, "BulkOnlyTransport supports maximum 16 LUNs");
|
assert!(C::MAX_LUN < 16, "BulkOnlyTransport supports maximum 16 LUNs");
|
||||||
|
|
||||||
let control = state.control.write(Control { max_lun: C::MAX_LUN });
|
|
||||||
|
|
||||||
let subclass = C::MSC_SUBCLASS as u8;
|
let subclass = C::MSC_SUBCLASS as u8;
|
||||||
let mut func = builder.function(USB_CLASS_MSC, subclass, MscProtocol::BulkOnlyTransport as _);
|
let mut func = builder.function(USB_CLASS_MSC, subclass, MscProtocol::BulkOnlyTransport as _);
|
||||||
|
|
||||||
// Control interface
|
// Control interface
|
||||||
let mut iface = func.interface();
|
let mut iface = func.interface();
|
||||||
iface.handler(control);
|
|
||||||
|
|
||||||
let mut alt = iface.alt_setting(USB_CLASS_MSC, subclass, MscProtocol::BulkOnlyTransport as _);
|
let mut alt = iface.alt_setting(USB_CLASS_MSC, subclass, MscProtocol::BulkOnlyTransport as _, None);
|
||||||
|
|
||||||
let read_ep = alt.endpoint_bulk_out(max_packet_size);
|
let read_ep = alt.endpoint_bulk_out(max_packet_size);
|
||||||
let write_ep = alt.endpoint_bulk_in(max_packet_size);
|
let write_ep = alt.endpoint_bulk_in(max_packet_size);
|
||||||
|
|
||||||
|
let control = state.control.write(Control {
|
||||||
|
max_lun: C::MAX_LUN,
|
||||||
|
if_num: iface.interface_number(),
|
||||||
|
});
|
||||||
|
|
||||||
|
drop(func);
|
||||||
|
builder.handler(control);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
read_ep,
|
read_ep,
|
||||||
write_ep,
|
write_ep,
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use defmt::*;
|
use defmt::{panic, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_stm32::peripherals::{DMA2_CH6, SDIO};
|
use embassy_stm32::peripherals::{DMA2_CH6, SDIO};
|
||||||
use embassy_stm32::sdmmc::{self, Sdmmc};
|
use embassy_stm32::sdmmc::Sdmmc;
|
||||||
use embassy_stm32::time::{mhz, Hertz};
|
use embassy_stm32::time::{mhz, Hertz};
|
||||||
use embassy_stm32::usb_otg::Driver;
|
use embassy_stm32::usb_otg::Driver;
|
||||||
use embassy_stm32::{interrupt, Config};
|
use embassy_stm32::{interrupt, Config};
|
||||||
@ -44,6 +44,13 @@ impl<'d> BlockDevice for SdmmcBlockDevice<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn read_block(&self, lba: u32, block: &mut [u8]) -> Result<(), BlockDeviceError> {
|
async fn read_block(&self, lba: u32, block: &mut [u8]) -> Result<(), BlockDeviceError> {
|
||||||
|
if block.as_ptr() as usize % 4 != 0 {
|
||||||
|
panic!("Invalid block alignment for SDMMC");
|
||||||
|
}
|
||||||
|
|
||||||
|
let block: &mut [u8; BLOCK_SIZE] = block.try_into().unwrap();
|
||||||
|
let block = unsafe { core::mem::transmute(block) };
|
||||||
|
|
||||||
self.sdmmc.borrow_mut().read_block(lba, block).await.map_err(|e| {
|
self.sdmmc.borrow_mut().read_block(lba, block).await.map_err(|e| {
|
||||||
error!("SDMMC read error: {:?}", e);
|
error!("SDMMC read error: {:?}", e);
|
||||||
BlockDeviceError::ReadError
|
BlockDeviceError::ReadError
|
||||||
@ -51,6 +58,13 @@ impl<'d> BlockDevice for SdmmcBlockDevice<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn write_block(&mut self, lba: u32, block: &[u8]) -> Result<(), BlockDeviceError> {
|
async fn write_block(&mut self, lba: u32, block: &[u8]) -> Result<(), BlockDeviceError> {
|
||||||
|
if block.as_ptr() as usize % 4 != 0 {
|
||||||
|
panic!("Invalid block alignment for SDMMC");
|
||||||
|
}
|
||||||
|
|
||||||
|
let block: &[u8; BLOCK_SIZE] = block.try_into().unwrap();
|
||||||
|
let block = unsafe { core::mem::transmute(block) };
|
||||||
|
|
||||||
self.sdmmc.borrow_mut().write_block(lba, block).await.map_err(|e| {
|
self.sdmmc.borrow_mut().write_block(lba, block).await.map_err(|e| {
|
||||||
error!("SDMMC write error: {:?}", e);
|
error!("SDMMC write error: {:?}", e);
|
||||||
BlockDeviceError::WriteError
|
BlockDeviceError::WriteError
|
||||||
@ -71,8 +85,6 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
let p = embassy_stm32::init(config);
|
let p = embassy_stm32::init(config);
|
||||||
|
|
||||||
let mut config = sdmmc::Config::default();
|
|
||||||
// config.data_transfer_timeout = 20_000_000;
|
|
||||||
let mut sdmmc = Sdmmc::new_4bit(
|
let mut sdmmc = Sdmmc::new_4bit(
|
||||||
p.SDIO,
|
p.SDIO,
|
||||||
interrupt::take!(SDIO),
|
interrupt::take!(SDIO),
|
||||||
@ -83,7 +95,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
p.PC9,
|
p.PC9,
|
||||||
p.PC10,
|
p.PC10,
|
||||||
p.PC11,
|
p.PC11,
|
||||||
config,
|
Default::default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
sdmmc.init_card(SDIO_FREQ).await.expect("SD card init failed");
|
sdmmc.init_card(SDIO_FREQ).await.expect("SD card init failed");
|
||||||
@ -123,7 +135,6 @@ async fn main(_spawner: Spawner) {
|
|||||||
&mut config_descriptor,
|
&mut config_descriptor,
|
||||||
&mut bos_descriptor,
|
&mut bos_descriptor,
|
||||||
&mut control_buf,
|
&mut control_buf,
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create SCSI target for our block device
|
// Create SCSI target for our block device
|
||||||
|
Loading…
Reference in New Issue
Block a user