Skip to content

Commit

Permalink
Fix for incorrect poll rate on isochronous endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
sourcebox committed Apr 8, 2024
1 parent c098430 commit eac85f7
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 17 deletions.
26 changes: 26 additions & 0 deletions src/bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,22 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
}
}

if status == 0x02 {
if let Some(ep) = &self.allocator.endpoints_out[epnum as usize] {
if let EndpointType::Isochronous {
synchronization: _,
usage: _,
} = ep.ep_type()
{
let ep = regs.endpoint_out(epnum as usize);
let odd = read_reg!(endpoint_out, ep, DOEPCTL, EONUM_DPID);
modify_reg!(endpoint_out, ep, DOEPCTL,
SD0PID_SEVNFRM: odd as u32,
SODDFRM: !odd as u32);
}
}
}

if status == 0x02 || status == 0x06 {
if let Some(ep) = &self.allocator.endpoints_out[epnum as usize] {
let mut buffer = ep.buffer.borrow_ref_mut(cs);
Expand Down Expand Up @@ -751,6 +767,16 @@ impl<USB: UsbPeripheral> usb_device::bus::UsbBus for UsbBus<USB> {
if let Some(ep) = ep {
let ep_regs = regs.endpoint_in(ep.address().index());
if read_reg!(endpoint_in, ep_regs, DIEPINT, XFRC) != 0 {
if let EndpointType::Isochronous {
synchronization: _,
usage: _,
} = ep.ep_type()
{
let odd = read_reg!(endpoint_in, ep_regs, DIEPCTL, EONUM_DPID);
modify_reg!(endpoint_in, ep_regs, DIEPCTL,
SD0PID_SEVNFRM: odd as u32,
SODDFRM_SD1PID: !odd as u32);
}
write_reg!(endpoint_in, ep_regs, DIEPINT, XFRC: 1);
ep_in_complete |= 1 << ep.address().index();
}
Expand Down
73 changes: 56 additions & 17 deletions src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::UsbPeripheral;
use core::cell::RefCell;
use core::ops::{Deref, DerefMut};
use critical_section::{CriticalSection, Mutex};
use usb_device::endpoint::EndpointAddress;
use usb_device::endpoint::{EndpointAddress, EndpointType};
use usb_device::{Result, UsbDirection, UsbError};

pub fn set_stalled(usb: UsbRegisters, address: EndpointAddress, stalled: bool) {
Expand Down Expand Up @@ -58,6 +58,10 @@ impl Endpoint {
fn index(&self) -> u8 {
self.descriptor.address.index() as u8
}

pub fn ep_type(&self) -> EndpointType {
self.descriptor.ep_type
}
}

pub struct EndpointIn {
Expand Down Expand Up @@ -86,14 +90,30 @@ impl EndpointIn {
write_reg!(endpoint_in, regs, DIEPTSIZ, PKTCNT: 0, XFRSIZ: self.descriptor.max_packet_size as u32);
} else {
let regs = self.usb.endpoint_in(self.index() as usize);
write_reg!(endpoint_in, regs, DIEPCTL,
SNAK: 1,
USBAEP: 1,
EPTYP: self.descriptor.ep_type.to_bm_attributes() as u32,
SD0PID_SEVNFRM: 1,
TXFNUM: self.index() as u32,
MPSIZ: self.descriptor.max_packet_size as u32
);
if let EndpointType::Isochronous {
synchronization: _,
usage: _,
} = self.descriptor.ep_type
{
write_reg!(endpoint_in, regs, DIEPCTL,
SNAK: 1,
USBAEP: 1,
EPTYP: self.descriptor.ep_type.to_bm_attributes() as u32,
SD0PID_SEVNFRM: 1,
TXFNUM: self.index() as u32,
MPSIZ: self.descriptor.max_packet_size as u32,
EONUM_DPID: 0
);
} else {
write_reg!(endpoint_in, regs, DIEPCTL,
SNAK: 1,
USBAEP: 1,
EPTYP: self.descriptor.ep_type.to_bm_attributes() as u32,
SD0PID_SEVNFRM: 1,
TXFNUM: self.index() as u32,
MPSIZ: self.descriptor.max_packet_size as u32
);
}
}
}

Expand Down Expand Up @@ -178,14 +198,33 @@ impl EndpointOut {
modify_reg!(endpoint0_out, regs, DOEPCTL0, MPSIZ: mpsiz as u32, EPENA: 1, CNAK: 1);
} else {
let regs = self.usb.endpoint_out(self.index() as usize);
write_reg!(endpoint_out, regs, DOEPCTL,
SD0PID_SEVNFRM: 1,
CNAK: 1,
EPENA: 1,
USBAEP: 1,
EPTYP: self.descriptor.ep_type.to_bm_attributes() as u32,
MPSIZ: self.descriptor.max_packet_size as u32
);
if let EndpointType::Isochronous {
synchronization: _,
usage: _,
} = self.descriptor.ep_type
{
write_reg!(endpoint_out, regs, DOEPTSIZ, PKTCNT: 1, XFRSIZ: 0);
// let odd = read_reg!(otg_device, self.usb.device(), DSTS, FNSOF) & 0x01 == 1;
write_reg!(endpoint_out, regs, DOEPCTL,
//SODDFRM: 1,
SD0PID_SEVNFRM: 1,
CNAK: 1,
EPENA: 1,
USBAEP: 1,
EPTYP: self.descriptor.ep_type.to_bm_attributes() as u32,
MPSIZ: self.descriptor.max_packet_size as u32,
EONUM_DPID: 0
);
} else {
write_reg!(endpoint_out, regs, DOEPCTL,
SD0PID_SEVNFRM: 1,
CNAK: 1,
EPENA: 1,
USBAEP: 1,
EPTYP: self.descriptor.ep_type.to_bm_attributes() as u32,
MPSIZ: self.descriptor.max_packet_size as u32
);
}
}
}

Expand Down

0 comments on commit eac85f7

Please sign in to comment.