Merge pull request #60 from pdh11/pdh-macraw-interrupts

Allow interrupt-driven MACRAW operation
This commit is contained in:
Ryan Summers 2024-04-15 13:16:20 +02:00 committed by GitHub
commit 74ef83910d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 49 additions and 3 deletions

View file

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed an issue where internal function names were conflicting with trait names by [@ryan-summers](https://github.com/ryan-summers) ([#36](https://github.com/kellerkindt/w5500/issues/36))
- Add `RetryTime` and `RetryCount` common register methods to `Device` and `UninitializedDevice` by [@elpiel](https://github.com/elpiel) ([#54][PR54])
- Add `Udp::get_port` and `Udp::set_port` by [@elpiel](https://github.com/elpiel) ([#57](https://github.com/kellerkindt/w5500/pull/57))
- Add `RawDevice::enable_interrupts` (and `clear_interrupts`, `disable_interrupts`) for interrupt-driven MACRAW mode by [@pdh11](https://github.com/pdh11) ([#60](https://github.com/kellerkindt/w5000/pull/60))
### Fixed

View file

@ -39,6 +39,48 @@ impl<SpiBus: Bus> RawDevice<SpiBus> {
Ok(Self { bus, raw_socket })
}
/// Enable one or more interrupts
///
/// # Args
/// * `which` - The interrupts to enable; see `register::socketn::Interrupt`
/// For instance, pass `Interrupt::Receive` to get interrupts
/// on packet reception only.
///
pub fn enable_interrupts(&mut self, which: u8) -> Result<(), SpiBus::Error> {
self.raw_socket.set_interrupt_mask(&mut self.bus, which)?;
self.bus.write_frame(
register::COMMON,
register::common::SOCKET_INTERRUPT_MASK,
&[1],
)?;
Ok(())
}
/// Clear pending interrupts
///
/// If using RTIC or similar, this should be called from the
/// interrupt handler. If not (i.e., if there's concern that this
/// use of the SPI bus will clobber someone else's use), then you
/// can mask the interrupt *at microcontroller level* in the
/// interrupt handler, then call this from thread mode before
/// unmasking again.
pub fn clear_interrupts(&mut self) -> Result<(), SpiBus::Error> {
self.raw_socket
.reset_interrupt(&mut self.bus, register::socketn::Interrupt::All)
}
/// Disable all interrupts
///
pub fn disable_interrupts(&mut self) -> Result<(), SpiBus::Error> {
self.bus.write_frame(
register::COMMON,
register::common::SOCKET_INTERRUPT_MASK,
&[0],
)?;
self.raw_socket.set_interrupt_mask(&mut self.bus, 0xFF)?;
Ok(())
}
/// Read an ethernet frame from the device.
///
/// # Args

View file

@ -22,6 +22,9 @@ pub mod common {
/// Register: INTLEVEL (Interrupt Low Level Timer Register) [R/W] [0x0013 0x0014] [0x0000]
pub const INTERRUPT_TIMER: u16 = 0x13;
/// Register: SIMR (Socket Interrupt Mask Register) [R/W] [0x0018] [0x00]
pub const SOCKET_INTERRUPT_MASK: u16 = 0x18;
/// Register: RTR (Retry Time-value Register) [R/W] [0x0019 0x001A] [0x07D0]
pub const RETRY_TIME: u16 = 0x19;

View file

@ -223,7 +223,7 @@ impl<SpiBus: Bus, HostImpl: Host> TcpClientStack for DeviceRefMut<'_, SpiBus, Ho
remote: SocketAddr,
) -> nb::Result<(), Self::Error> {
let SocketAddr::V4(remote) = remote else {
return Err(nb::Error::Other(Self::Error::UnsupportedAddress))
return Err(nb::Error::Other(Self::Error::UnsupportedAddress));
};
// TODO dynamically select a random port
socket.open(&mut self.bus, 49849 + u16::from(socket.socket.index))?; // chosen by fair dice roll.

View file

@ -534,7 +534,7 @@ where
remote: SocketAddr,
) -> Result<(), Self::Error> {
let SocketAddr::V4(remote) = remote else {
return Err(Self::Error::UnsupportedAddress)
return Err(Self::Error::UnsupportedAddress);
};
socket.open(&mut self.bus)?;
socket.set_destination(&mut self.bus, remote)?;
@ -602,7 +602,7 @@ where
buffer: &[u8],
) -> nb::Result<(), Self::Error> {
let SocketAddr::V4(remote) = remote else {
return Err(nb::Error::Other(Self::Error::UnsupportedAddress))
return Err(nb::Error::Other(Self::Error::UnsupportedAddress));
};
socket.socket_send_to(&mut self.bus, remote, buffer)?;