diff --git a/Cargo.toml b/Cargo.toml index 2c3a04f..50f251f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,6 @@ name = "usb_avr" version = "0.1.0" edition = "2021" - [dependencies] panic-halt = "0.2.0" ufmt = "0.2.0" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d0c456a..7426853 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2024-03-22" +channel = "nightly-2024-06-13" components = [ "rust-src" ] profile = "complete" diff --git a/src/lib.rs b/src/lib.rs index 16814df..0e47101 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,6 @@ #![no_std] -use core::{cmp::max, u8}; +use core::cmp::max; use avr_device::{asm::delay_cycles, interrupt::free}; use usb_device::{ @@ -10,7 +10,7 @@ use usb_device::{ }; mod types; -pub use types::UsbDevice; +pub use types::*; use types::{DPRAM_SIZE, ENDPOINTS_ALLOC_LAYOUT, ONE_MS_16_MGHZ}; @@ -24,57 +24,60 @@ impl UsbBus for UsbDevice { _interval: u8, ) -> UsbResult { // Handle first endpoint. // - if ep_addr == Some(EndpointAddress::from_parts(0, UsbDirection::In)) { - Ok(ep_addr.unwrap()) - } else { - let address = match ep_addr { - // If current endpoint doesn't allocated, assign ep_addr to variable. // - Some(addr) if !self.ep_table[addr.index()].is_allocated => addr, - - // If ep_aadr not provided, or current endpoint is allocated, try to find next free endpoint, otherwise return UsbError. // - _ => { - let index = self - .ep_table - .iter() - .enumerate() - .skip(1) - .find(|(index, ep)| { - !ep.is_allocated && max_packet_size <= ENDPOINTS_ALLOC_LAYOUT[*index] - }) - .ok_or(UsbError::EndpointOverflow)? - .0; - - EndpointAddress::from_parts(index, ep_dir) - } - }; - - // Select endpoint info by address index. // - - let target_endpoint = &mut self.ep_table[address.index()]; - - // Get power of two number of endpoint size. // - - let ep_size = max(8, max_packet_size.next_power_of_two()); - - // Endpoint allocation marker. // - - if DPRAM_SIZE - self.dpram_already_used < ep_size { - Err(UsbError::EndpointMemoryOverflow) + free(|_cs| { + if ep_addr == Some(EndpointAddress::from_parts(0, UsbDirection::In)) { + Ok(ep_addr.unwrap()) } else { - // Set endpoint parameters. // + let address = match ep_addr { + // If current endpoint doesn't allocated, assign ep_addr to variable. // + Some(addr) if !self.ep_table[addr.index()].is_allocated => addr, - target_endpoint.set_dir(ep_dir); - target_endpoint.set_type(ep_type); - target_endpoint.set_size(ep_size)?; + // If ep_aadr not provided, or current endpoint is allocated, try to find next free endpoint, otherwise return UsbError. // + _ => { + let index = self + .ep_table + .iter() + .enumerate() + .skip(1) + .find(|(index, ep)| { + !ep.is_allocated + && max_packet_size <= ENDPOINTS_ALLOC_LAYOUT[*index] + }) + .ok_or(UsbError::EndpointOverflow)? + .0; - // Add used dpram memory. // + EndpointAddress::from_parts(index, ep_dir) + } + }; - target_endpoint.is_allocated = true; - self.dpram_already_used += ep_size; + // Select endpoint info by address index. // - Ok(address) + let target_endpoint = &mut self.ep_table[address.index()]; + + // Get power of two number of endpoint size. // + + let ep_size = max(8, max_packet_size.next_power_of_two()); + + // Endpoint allocation marker. // + + if DPRAM_SIZE - self.dpram_already_used < ep_size { + Err(UsbError::EndpointMemoryOverflow) + } else { + // Set endpoint parameters. // + + target_endpoint.set_dir(ep_dir); + target_endpoint.set_type(ep_type); + target_endpoint.set_size(ep_size)?; + + // Add used dpram memory. // + + target_endpoint.is_allocated = true; + self.dpram_already_used += ep_size; + + Ok(address) + } } - } + }) } fn enable(&mut self) { @@ -118,7 +121,8 @@ impl UsbBus for UsbDevice { // Set high speed and attach the USB. // - usb.udcon.modify(|_, w| w.detach().clear_bit()); + usb.udcon + .modify(|_, w| w.detach().clear_bit().lsm().clear_bit()); // Interrupts. // @@ -157,7 +161,9 @@ impl UsbBus for UsbDevice { let (udint, udien, usbint) = (usb.udint.read(), usb.udien.read(), usb.usbint.read()); if usbint.vbusti().bit_is_set() { - usb.usbint.write(|w| w.vbusti().clear_bit()); + usb.usbint.write(|w| + // unsafe { w.bits(0x01) } + w.vbusti().clear_bit()); if usb.usbsta.read().vbus().bit_is_set() { return PollResult::Resume; } else { @@ -178,7 +184,9 @@ impl UsbBus for UsbDevice { } if udint.sofi().bit_is_set() { - usb.udint.write(|w| w.sofi().clear_bit()); + usb.udint.write(|w| + // unsafe { w.bits(0x7d) } + w.sofi().clear_bit()); } if usb.usbcon.read().frzclk().bit_is_clear() { @@ -241,15 +249,19 @@ impl UsbBus for UsbDevice { *byte = usb.uedatx.read().bits(); } - usb.ueintx - .write(|w| w.rxouti().clear_bit().rxstpi().clear_bit()); + usb.ueintx.write(|w| { + /* unsafe { w.bits(0xdf) } */ + w.rxouti().clear_bit().rxstpi().clear_bit() + }); Ok(buf_size) } else { if usb.ueintx.read().rxouti().bit_is_clear() { return Err(UsbError::WouldBlock); } - usb.ueintx.write(|w| w.rxouti().clear_bit()); + usb.ueintx.write(|w| + // unsafe { w.bits(0xdf) } + w.rxouti().clear_bit()); let mut bytes_read = 0; for slot in buf { @@ -264,7 +276,9 @@ impl UsbBus for UsbDevice { return Err(UsbError::BufferOverflow); } - usb.ueintx.write(|w| w.fifocon().clear_bit()); + usb.ueintx.write(|w| + // unsafe { w.bits(0xdf) } + w.fifocon().clear_bit()); Ok(bytes_read) } } @@ -283,8 +297,10 @@ impl UsbBus for UsbDevice { // Clear resume informations. // - usb.udint - .write(|w| w.wakeupi().clear_bit().suspi().clear_bit()); + usb.udint.write(|w| { + // unsafe { w.bits(0x7d) } + w.wakeupi().clear_bit().suspi().clear_bit() + }); usb.udien .modify(|_, w| w.wakeupe().clear_bit().suspe().set_bit()); @@ -306,8 +322,10 @@ impl UsbBus for UsbDevice { usb.usbcon.modify(|_, w| w.frzclk().clear_bit()); - usb.udint - .write(|w| w.wakeupi().clear_bit().suspi().clear_bit()); + usb.udint.write(|w| { + // unsafe { w.bits(0x7d) } + w.wakeupi().clear_bit().suspi().clear_bit() + }); usb.udien .modify(|_, w| w.wakeupe().clear_bit().suspe().set_bit()); @@ -345,8 +363,10 @@ impl UsbBus for UsbDevice { free(|cs| { let (usb, pll) = (self.usb.borrow(cs), self.pll.borrow(cs)); - usb.udint - .write(|w| w.wakeupi().clear_bit().suspi().clear_bit()); + usb.udint.write(|w| { + // unsafe { w.bits(0x7d) } + w.wakeupi().clear_bit().suspi().clear_bit() + }); // Suspend. // @@ -387,13 +407,17 @@ impl UsbBus for UsbDevice { usb.uedatx.write(|w| w.bits(byte)); } - usb.ueintx.write(|w| w.txini().clear_bit()); + usb.ueintx.write(|w| + // unsafe { w.bits(0xdf) } + w.txini().clear_bit()); } else { if usb.ueintx.read().txini().bit_is_clear() { return Err(UsbError::WouldBlock); } - usb.ueintx - .write(|w| w.txini().clear_bit().rxouti().clear_bit()); + usb.ueintx.write(|w| { + // unsafe { w.bits(0xdf) } + w.txini().clear_bit().rxouti().clear_bit() + }); for &byte in buf { if usb.ueintx.read().rwal().bit_is_set() { @@ -403,8 +427,10 @@ impl UsbBus for UsbDevice { } } - usb.ueintx - .write(|w| w.txini().clear_bit().fifocon().clear_bit()); + usb.ueintx.write(|w| { + // unsafe { w.bits(0xdf) } + w.rxouti().clear_bit().fifocon().clear_bit() + }); } let pending_ins = self.pending_ins.borrow(cs);