Compare commits

...

7 Commits

Author SHA1 Message Date
doryan c5788c5b2e code improvement
change variable names + using if let conditions instead match for
Result/Options values
2025-02-14 00:16:04 +04:00
doryan e27c5e7803 feat: reduce code 2025-02-14 00:12:57 +04:00
doryan 5b3cce5ea5 feat(cleaner): use interrupt cleaner 2025-02-14 00:12:27 +04:00
doryan 685ed323f7 feat(imports): add imports for cleaner 2025-02-14 00:11:02 +04:00
doryan 7c3fcdabcc fix(const): use mask as constant value instead magic number 2025-02-14 00:10:41 +04:00
doryan b1dd7eea9d feat(conditions): use if let ... conditions instead match 2025-02-14 00:09:48 +04:00
doryan 18a3368565 feat(interrupt): add interrupt cleaner 2025-02-14 00:08:45 +04:00
2 changed files with 87 additions and 55 deletions

View File

@ -133,24 +133,24 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
fn force_reset(&self) -> UsbResult<()> {
free(|cs| {
let usbcon = &self.usb.borrow(cs).usbcon;
usbcon.modify(|_, w| w.usbe().set_bit());
self.usb.borrow(cs).usbcon.modify(|_, w| w.usbe().set_bit());
});
delay_cycles(ONE_MS_16_MGHZ);
free(|cs| {
let usbcon = &self.usb.borrow(cs).usbcon;
usbcon.modify(|_, w| w.usbe().set_bit());
self.usb.borrow(cs).usbcon.modify(|_, w| w.usbe().set_bit());
});
Ok(())
}
fn is_stalled(&self, ep_addr: EndpointAddress) -> bool {
free(|cs| match self.select_endpoint(cs, ep_addr.index()) {
Ok(_) => self.usb.borrow(cs).ueconx.read().stallrq().bit_is_set(),
Err(_) => false,
free(|cs| {
if self.select_endpoint(cs, ep_addr.index()).is_ok() {
return self.usb.borrow(cs).ueconx.read().stallrq().bit_is_set();
}
false
})
}
@ -162,7 +162,7 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
if usbint.vbusti().bit_is_set() {
usb.usbint
.write(|w| unsafe { w.bits(0x01) }.vbusti().clear_bit());
.write(|w| w.clear_interrupts().vbusti().clear_bit());
if usb.usbsta.read().vbus().bit_is_set() {
return PollResult::Resume;
} else {
@ -183,8 +183,7 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
}
if udint.sofi().bit_is_set() {
usb.udint
.write(|w| unsafe { w.bits(0x7d) }.sofi().clear_bit());
usb.udint.write(|w| w.clear_interrupts().sofi().clear_bit());
}
if usb.usbcon.read().frzclk().bit_is_clear() {
@ -226,8 +225,8 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
free(|cs| {
let usb = self.usb.borrow(cs);
if let Err(error) = self.select_endpoint(cs, ep_addr.index()) {
Err(error)
if let Err(usb_error) = self.select_endpoint(cs, ep_addr.index()) {
Err(usb_error)
} else {
let ep = &self.ep_table[ep_addr.index()];
@ -248,7 +247,7 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
}
usb.ueintx.write(|w| {
unsafe { w.bits(0xdf) }
w.clear_interrupts()
.rxouti()
.clear_bit()
.rxstpi()
@ -261,14 +260,14 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
return Err(UsbError::WouldBlock);
}
usb.ueintx
.write(|w| unsafe { w.bits(0xdf) }.rxouti().clear_bit());
.write(|w| w.clear_interrupts().rxouti().clear_bit());
let mut bytes_read = 0;
for slot in buf {
for data in buf {
if usb.ueintx.read().rwal().bit_is_clear() {
break;
}
*slot = usb.uedatx.read().bits();
*data = usb.uedatx.read().bits();
bytes_read += 1;
}
@ -277,7 +276,7 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
}
usb.ueintx
.write(|w| unsafe { w.bits(0xdf) }.fifocon().clear_bit());
.write(|w| w.clear_interrupts().fifocon().clear_bit());
Ok(bytes_read)
}
}
@ -297,7 +296,7 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
// Clear resume informations. //
usb.udint.write(|w| {
unsafe { w.bits(0x7d) }
w.clear_interrupts()
.wakeupi()
.clear_bit()
.suspi()
@ -325,7 +324,7 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
usb.usbcon.modify(|_, w| w.frzclk().clear_bit());
usb.udint.write(|w| {
unsafe { w.bits(0x7d) }
w.clear_interrupts()
.wakeupi()
.clear_bit()
.suspi()
@ -369,7 +368,7 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
let (usb, pll) = (self.usb.borrow(cs), self.pll.borrow(cs));
usb.udint.write(|w| {
unsafe { w.bits(0x7d) }
w.clear_interrupts()
.wakeupi()
.clear_bit()
.suspi()
@ -416,13 +415,13 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
}
usb.ueintx
.write(|w| unsafe { w.bits(0xdf) }.txini().clear_bit());
.write(|w| w.clear_interrupts().txini().clear_bit());
} else {
if usb.ueintx.read().txini().bit_is_clear() {
return Err(UsbError::WouldBlock);
}
usb.ueintx.write(|w| {
unsafe { w.bits(0xdf) }
w.clear_interrupts()
.txini()
.clear_bit()
.rxouti()
@ -438,7 +437,7 @@ impl<const L: usize> UsbBus for UsbDevice<L> {
}
usb.ueintx.write(|w| {
unsafe { w.bits(0xdf) }
w.clear_interrupts()
.rxouti()
.clear_bit()
.fifocon()

View File

@ -1,6 +1,9 @@
use core::cell::Cell;
use avr_device::{
atmega32u4::usb_device::{
udint::W as UDINTWriter, ueintx::W as UEINTXWriter, usbint::W as USBINTWriter,
},
atmega32u4::{PLL, USB_DEVICE},
interrupt::{CriticalSection, Mutex},
};
@ -81,6 +84,36 @@ pub(crate) const DPRAM_SIZE: u16 = 832;
pub(crate) const ENDPOINTS_ALLOC_LAYOUT: [u16; MAX_ENDPOINTS] = [64, 256, 64, 64, 64, 64, 64];
pub(crate) const ONE_MS_16_MGHZ: u32 = 16000;
const UDINT_BYTE: u8 = 0x7d;
const USBINT_BYTE: u8 = 0x01;
const UEINTX_BYTE: u8 = 0xdf;
const UENUM_MASK: u8 = 0b111;
pub(crate) trait InterruptCleaner {
fn clear_interrupts(&mut self) -> &mut Self;
}
impl InterruptCleaner for UDINTWriter {
#[inline]
fn clear_interrupts(&mut self) -> &mut Self {
unsafe { self.bits(UDINT_BYTE) }
}
}
impl InterruptCleaner for USBINTWriter {
#[inline]
fn clear_interrupts(&mut self) -> &mut Self {
unsafe { self.bits(USBINT_BYTE) }
}
}
impl InterruptCleaner for UEINTXWriter {
#[inline]
fn clear_interrupts(&mut self) -> &mut Self {
unsafe { self.bits(UEINTX_BYTE) }
}
}
impl<const L: usize> UsbDevice<L> {
#[inline]
pub(crate) fn get_size(&self, cs: CriticalSection<'_>) -> usize {
@ -114,9 +147,8 @@ impl<const L: usize> UsbDevice<L> {
endpoint_index: usize,
) -> Result<(), UsbError> {
let usb = self.usb.borrow(cs);
let endpoint_index = endpoint_index as u8;
if endpoint_index >= 7 {
if endpoint_index >= MAX_ENDPOINTS {
return Err(UsbError::InvalidEndpoint);
}
@ -124,9 +156,9 @@ impl<const L: usize> UsbDevice<L> {
return Err(UsbError::InvalidState);
}
usb.uenum.write(|w| w.bits(endpoint_index));
usb.uenum.write(|w| w.bits(endpoint_index as u8));
if usb.uenum.read().bits() & 7 /* 0b111 */ != endpoint_index {
if usb.uenum.read().bits() & UENUM_MASK != endpoint_index as u8 {
return Err(UsbError::InvalidEndpoint);
}
@ -141,41 +173,42 @@ impl<const L: usize> UsbDevice<L> {
let usb = self.usb.borrow(cs);
let current_endpoint = self.ep_table[endpoint_index];
match self.select_endpoint(cs, endpoint_index) {
Ok(_) => {
// Enable endpoint. //
let select_endpoint_result = self.select_endpoint(cs, endpoint_index);
usb.ueconx.modify(|_, w| w.epen().set_bit());
usb.uecfg1x.modify(|_, w| w.alloc().clear_bit());
if select_endpoint_result.is_err() {
select_endpoint_result
} else {
// Enable endpoint. //
// Set markered endpoint parameters to uecfg0x/1x register. //
usb.ueconx.modify(|_, w| w.epen().set_bit());
usb.uecfg1x.modify(|_, w| w.alloc().clear_bit());
usb.uecfg0x.modify(|_, w| {
w.epdir()
.bit(current_endpoint.ep_dir)
.eptype()
.bits(current_endpoint.ep_type)
});
// Set markered endpoint parameters to uecfg0x/1x register. //
usb.uecfg1x.modify(|_, w| {
w.epbk()
.bits(0)
.epsize()
.bits(current_endpoint.size)
.alloc()
.set_bit()
});
usb.uecfg0x.modify(|_, w| {
w.epdir()
.bit(current_endpoint.ep_dir)
.eptype()
.bits(current_endpoint.ep_type)
});
if usb.uesta0x.read().cfgok().bit_is_clear() {
Err(UsbError::EndpointMemoryOverflow)
} else {
usb.ueienx
.modify(|_, w| w.rxoute().set_bit().rxstpe().set_bit());
usb.uecfg1x.modify(|_, w| {
w.epbk()
.bits(0)
.epsize()
.bits(current_endpoint.size)
.alloc()
.set_bit()
});
Ok(())
}
if usb.uesta0x.read().cfgok().bit_is_clear() {
Err(UsbError::EndpointMemoryOverflow)
} else {
usb.ueienx
.modify(|_, w| w.rxoute().set_bit().rxstpe().set_bit());
select_endpoint_result
}
Err(exception) => Err(exception),
}
}
}