firmware for my Touchscreen E-Paper Input Module for Framework Laptop 16
0

Configure Feed

Select the types of activity you want to include in your feed.

1use core::mem::MaybeUninit; 2use usb_device::bus::PollResult; 3use usb_device::class_prelude::{EndpointAddress, EndpointType}; 4use usb_device::{UsbDirection, UsbError}; 5use usb_device::endpoint::{IsochronousSynchronizationType, IsochronousUsageType}; 6use crate::{syscall, SafeOption, SafeResult}; 7use crate::syscall::SyscallNumber; 8 9#[repr(usize)] 10#[derive(Copy, Clone, Debug, Eq, PartialEq)] 11#[cfg_attr(feature = "defmt", derive(defmt::Format))] 12pub enum UsbSyscall { 13 UsbRet = 0, 14 SetHandler = 1, 15 ClearHandler = 2, 16 Init = 3, 17 Uninit = 4, 18 AllocEp = 5, 19 Enable = 6, 20 Reset = 7, 21 SetDeviceAddr = 8, 22 Write = 9, 23 Read = 10, 24 SetStalled = 11, 25 IsStalled = 12, 26 Poll = 13, 27} 28 29impl TryFrom<usize> for UsbSyscall { 30 type Error = (); 31 32 fn try_from(value: usize) -> Result<Self, Self::Error> { 33 match value { 34 x if x == UsbSyscall::UsbRet as usize => Ok(UsbSyscall::UsbRet), 35 x if x == UsbSyscall::SetHandler as usize => Ok(UsbSyscall::SetHandler), 36 x if x == UsbSyscall::ClearHandler as usize => Ok(UsbSyscall::ClearHandler), 37 x if x == UsbSyscall::Init as usize => Ok(UsbSyscall::Init), 38 x if x == UsbSyscall::Uninit as usize => Ok(UsbSyscall::Uninit), 39 x if x == UsbSyscall::AllocEp as usize => Ok(UsbSyscall::AllocEp), 40 x if x == UsbSyscall::Enable as usize => Ok(UsbSyscall::Enable), 41 x if x == UsbSyscall::Reset as usize => Ok(UsbSyscall::Reset), 42 x if x == UsbSyscall::SetDeviceAddr as usize => Ok(UsbSyscall::SetDeviceAddr), 43 x if x == UsbSyscall::Write as usize => Ok(UsbSyscall::Write), 44 x if x == UsbSyscall::Read as usize => Ok(UsbSyscall::Read), 45 x if x == UsbSyscall::SetStalled as usize => Ok(UsbSyscall::SetStalled), 46 x if x == UsbSyscall::IsStalled as usize => Ok(UsbSyscall::IsStalled), 47 x if x == UsbSyscall::Poll as usize => Ok(UsbSyscall::Poll), 48 49 _ => Err(()), 50 } 51 } 52} 53 54pub fn set_handler(f: extern "C" fn()) { 55 unsafe { 56 syscall!( 57 SyscallNumber::Usb, 58 in UsbSyscall::SetHandler, 59 in f, 60 ); 61 } 62} 63 64pub fn clear_handler() { 65 unsafe { 66 syscall!( 67 SyscallNumber::Usb, 68 in UsbSyscall::ClearHandler, 69 ) 70 } 71} 72 73#[repr(C)] 74#[derive(Copy, Clone, Debug, Eq, PartialEq)] 75#[cfg_attr(feature = "defmt", derive(defmt::Format))] 76pub enum SafePollResult { 77 None, 78 Reset, 79 Data { 80 ep_out: u16, 81 ep_in_complete: u16, 82 ep_setup: u16, 83 }, 84 Suspend, 85 Resume, 86} 87 88impl From<SafePollResult> for PollResult { 89 fn from(value: SafePollResult) -> Self { 90 match value { 91 SafePollResult::None => PollResult::None, 92 SafePollResult::Reset => PollResult::Reset, 93 SafePollResult::Data { ep_out, ep_in_complete, ep_setup } => PollResult::Data { ep_out, ep_in_complete, ep_setup }, 94 SafePollResult::Suspend => PollResult::Suspend, 95 SafePollResult::Resume => PollResult::Resume 96 } 97 } 98} 99 100impl From<PollResult> for SafePollResult { 101 fn from(value: PollResult) -> Self { 102 match value { 103 PollResult::None => SafePollResult::None, 104 PollResult::Reset => SafePollResult::Reset, 105 PollResult::Data { ep_out, ep_in_complete, ep_setup } => SafePollResult::Data { ep_out, ep_in_complete, ep_setup }, 106 PollResult::Suspend => SafePollResult::Suspend, 107 PollResult::Resume => SafePollResult::Resume, 108 } 109 } 110} 111 112#[repr(C)] 113#[derive(Copy, Clone, Debug, Eq, PartialEq)] 114#[cfg_attr(feature = "defmt", derive(defmt::Format))] 115pub enum SafeUsbError { 116 WouldBlock, 117 ParseError, 118 BufferOverflow, 119 EndpointOverflow, 120 EndpointMemoryOverflow, 121 InvalidEndpoint, 122 Unsupported, 123 InvalidState, 124} 125 126impl From<SafeUsbError> for UsbError { 127 fn from(value: SafeUsbError) -> Self { 128 match value { 129 SafeUsbError::WouldBlock => UsbError::WouldBlock, 130 SafeUsbError::ParseError => UsbError::ParseError, 131 SafeUsbError::BufferOverflow => UsbError::BufferOverflow, 132 SafeUsbError::EndpointOverflow => UsbError::EndpointOverflow, 133 SafeUsbError::EndpointMemoryOverflow => UsbError::EndpointMemoryOverflow, 134 SafeUsbError::InvalidEndpoint => UsbError::InvalidEndpoint, 135 SafeUsbError::Unsupported => UsbError::Unsupported, 136 SafeUsbError::InvalidState => UsbError::InvalidState, 137 } 138 } 139} 140 141impl From<UsbError> for SafeUsbError { 142 fn from(value: UsbError) -> Self { 143 match value { 144 UsbError::WouldBlock => SafeUsbError::WouldBlock, 145 UsbError::ParseError => SafeUsbError::ParseError, 146 UsbError::BufferOverflow => SafeUsbError::BufferOverflow, 147 UsbError::EndpointOverflow => SafeUsbError::EndpointOverflow, 148 UsbError::EndpointMemoryOverflow => SafeUsbError::EndpointMemoryOverflow, 149 UsbError::InvalidEndpoint => SafeUsbError::InvalidEndpoint, 150 UsbError::Unsupported => SafeUsbError::Unsupported, 151 UsbError::InvalidState => SafeUsbError::InvalidState, 152 } 153 } 154} 155 156#[repr(C)] 157#[derive(Copy, Clone, Debug, Eq, PartialEq)] 158#[cfg_attr(feature = "defmt", derive(defmt::Format))] 159pub enum SafeIsochronousSynchronizationType { 160 NoSynchronization, 161 Asynchronous, 162 Adaptive, 163 Synchronous, 164} 165 166impl From<IsochronousSynchronizationType> for SafeIsochronousSynchronizationType { 167 fn from(value: IsochronousSynchronizationType) -> Self { 168 match value { 169 IsochronousSynchronizationType::NoSynchronization => SafeIsochronousSynchronizationType::NoSynchronization, 170 IsochronousSynchronizationType::Asynchronous => SafeIsochronousSynchronizationType::Asynchronous, 171 IsochronousSynchronizationType::Adaptive => SafeIsochronousSynchronizationType::Adaptive, 172 IsochronousSynchronizationType::Synchronous => SafeIsochronousSynchronizationType::Synchronous, 173 } 174 } 175} 176 177impl From<SafeIsochronousSynchronizationType> for IsochronousSynchronizationType { 178 fn from(value: SafeIsochronousSynchronizationType) -> Self { 179 match value { 180 SafeIsochronousSynchronizationType::NoSynchronization => IsochronousSynchronizationType::NoSynchronization, 181 SafeIsochronousSynchronizationType::Asynchronous => IsochronousSynchronizationType::Asynchronous, 182 SafeIsochronousSynchronizationType::Adaptive => IsochronousSynchronizationType::Adaptive, 183 SafeIsochronousSynchronizationType::Synchronous => IsochronousSynchronizationType::Synchronous, 184 } 185 } 186} 187 188#[repr(C)] 189#[derive(Copy, Clone, Debug, Eq, PartialEq)] 190#[cfg_attr(feature = "defmt", derive(defmt::Format))] 191pub enum SafeIsochronousUsageType { 192 Data, 193 Feedback, 194 ImplicitFeedbackData, 195} 196 197impl From<IsochronousUsageType> for SafeIsochronousUsageType { 198 fn from(value: IsochronousUsageType) -> Self { 199 match value { 200 IsochronousUsageType::Data => SafeIsochronousUsageType::Data, 201 IsochronousUsageType::Feedback => SafeIsochronousUsageType::Feedback, 202 IsochronousUsageType::ImplicitFeedbackData => SafeIsochronousUsageType::ImplicitFeedbackData, 203 } 204 } 205} 206 207impl From<SafeIsochronousUsageType> for IsochronousUsageType { 208 fn from(value: SafeIsochronousUsageType) -> Self { 209 match value { 210 SafeIsochronousUsageType::Data => IsochronousUsageType::Data, 211 SafeIsochronousUsageType::Feedback => IsochronousUsageType::Feedback, 212 SafeIsochronousUsageType::ImplicitFeedbackData => IsochronousUsageType::ImplicitFeedbackData, 213 } 214 } 215} 216 217#[repr(C)] 218#[derive(Copy, Clone, Debug, Eq, PartialEq)] 219#[cfg_attr(feature = "defmt", derive(defmt::Format))] 220pub enum SafeEndpointType { 221 Control, 222 Isochronous { 223 synchronization: SafeIsochronousSynchronizationType, 224 usage: SafeIsochronousUsageType, 225 }, 226 Bulk, 227 Interrupt, 228} 229 230impl From<EndpointType> for SafeEndpointType { 231 fn from(value: EndpointType) -> Self { 232 match value { 233 EndpointType::Control => SafeEndpointType::Control, 234 EndpointType::Isochronous { synchronization, usage } => { 235 SafeEndpointType::Isochronous { synchronization: synchronization.into(), usage: usage.into() } 236 }, 237 EndpointType::Bulk => SafeEndpointType::Bulk, 238 EndpointType::Interrupt => SafeEndpointType::Interrupt, 239 } 240 } 241} 242 243impl From<SafeEndpointType> for EndpointType { 244 fn from(value: SafeEndpointType) -> Self { 245 match value { 246 SafeEndpointType::Control => EndpointType::Control, 247 SafeEndpointType::Isochronous { synchronization, usage } => { 248 EndpointType::Isochronous { synchronization: synchronization.into(), usage: usage.into() } 249 }, 250 SafeEndpointType::Bulk => EndpointType::Bulk, 251 SafeEndpointType::Interrupt => EndpointType::Interrupt, 252 } 253 } 254} 255 256#[repr(C)] 257#[derive(Copy, Clone, Debug, Eq, PartialEq)] 258#[cfg_attr(feature = "defmt", derive(defmt::Format))] 259pub struct UsbEpAllocArgs { 260 pub ep_dir: UsbDirection, 261 pub ep_addr: SafeOption<u8>, 262 pub ep_type: SafeEndpointType, 263 pub max_packet_size: u16, 264 pub interval: u8, 265} 266 267#[repr(C)] 268#[derive(Copy, Clone, Debug, Eq, PartialEq)] 269#[cfg_attr(feature = "defmt", derive(defmt::Format))] 270pub struct UsbWriteArgs { 271 pub ep_addr: u8, 272 pub len: usize, 273 pub buf: *const u8, 274 pub ptr: *mut SafeResult<usize, SafeUsbError>, 275} 276 277#[repr(C)] 278#[derive(Copy, Clone, Debug, Eq, PartialEq)] 279#[cfg_attr(feature = "defmt", derive(defmt::Format))] 280pub struct UsbReadArgs { 281 pub ep_addr: u8, 282 pub len: usize, 283 pub buf: *mut u8, 284 pub ptr: *mut SafeResult<usize, SafeUsbError>, 285} 286 287pub struct UsbBus { 288 _dummy: (), 289} 290 291impl UsbBus { 292 pub fn init() -> Self { 293 unsafe { 294 syscall!( 295 SyscallNumber::Usb, 296 in UsbSyscall::Init, 297 ); 298 } 299 300 Self { _dummy: () } 301 } 302} 303 304impl Drop for UsbBus { 305 fn drop(&mut self) { 306 unsafe { 307 syscall!( 308 SyscallNumber::Usb, 309 in UsbSyscall::Uninit, 310 ) 311 } 312 } 313} 314 315impl usb_device::bus::UsbBus for UsbBus { 316 fn alloc_ep( 317 &mut self, 318 ep_dir: UsbDirection, 319 ep_addr: Option<EndpointAddress>, 320 ep_type: EndpointType, 321 max_packet_size: u16, 322 interval: u8 323 ) -> usb_device::Result<EndpointAddress> { 324 let mut res: MaybeUninit<SafeResult<u8, SafeUsbError>> = MaybeUninit::uninit(); 325 let res_ptr = res.as_mut_ptr(); 326 327 let alloc_info = UsbEpAllocArgs { 328 ep_dir, 329 ep_addr: ep_addr.map(|v| v.into()).into(), 330 ep_type: ep_type.into(), 331 max_packet_size, 332 interval 333 }; 334 335 unsafe { 336 syscall!( 337 SyscallNumber::Usb, 338 in UsbSyscall::AllocEp, 339 in &raw const alloc_info, 340 in res_ptr, 341 ); 342 343 let res: Result<u8, SafeUsbError> = res.assume_init().into(); 344 res.map(|v| v.into()).map_err(|e| e.into()) 345 } 346 } 347 348 fn enable(&mut self) { 349 unsafe { 350 syscall!( 351 SyscallNumber::Usb, 352 in UsbSyscall::Enable, 353 ); 354 } 355 } 356 357 fn reset(&self) { 358 unsafe { 359 syscall!( 360 SyscallNumber::Usb, 361 in UsbSyscall::Reset, 362 ); 363 } 364 } 365 366 fn set_device_address(&self, addr: u8) { 367 unsafe { 368 syscall!( 369 SyscallNumber::Usb, 370 in UsbSyscall::SetDeviceAddr, 371 in addr, 372 ); 373 } 374 } 375 376 fn write(&self, ep_addr: EndpointAddress, buf: &[u8]) -> usb_device::Result<usize> { 377 let ep_addr: u8 = ep_addr.into(); 378 let mut res: MaybeUninit<SafeResult<usize, SafeUsbError>> = MaybeUninit::uninit(); 379 let ptr = res.as_mut_ptr(); 380 let len = buf.len(); 381 let buf = buf.as_ptr(); 382 383 let args = UsbWriteArgs { 384 ep_addr, 385 len, 386 buf, 387 ptr, 388 }; 389 390 unsafe { 391 syscall!( 392 SyscallNumber::Usb, 393 in UsbSyscall::Write, 394 in &raw const args, 395 ); 396 397 let stdres: Result<usize, SafeUsbError> = res.assume_init().into(); 398 stdres.map_err(|e| e.into()) 399 } 400 } 401 402 fn read(&self, ep_addr: EndpointAddress, buf: &mut [u8]) -> usb_device::Result<usize> { 403 let ep_addr: u8 = ep_addr.into(); 404 let mut res: MaybeUninit<SafeResult<usize, SafeUsbError>> = MaybeUninit::uninit(); 405 let ptr = res.as_mut_ptr(); 406 let len = buf.len(); 407 let buf = buf.as_mut_ptr(); 408 409 let args = UsbReadArgs { 410 ep_addr, 411 len, 412 buf, 413 ptr, 414 }; 415 416 unsafe { 417 syscall!( 418 SyscallNumber::Usb, 419 in UsbSyscall::Read, 420 in &raw const args, 421 ); 422 423 let stdres: Result<usize, SafeUsbError> = res.assume_init().into(); 424 stdres.map_err(|e| e.into()) 425 } 426 } 427 428 fn set_stalled(&self, ep_addr: EndpointAddress, stalled: bool) { 429 let ep_addr: u8 = ep_addr.into(); 430 unsafe { 431 syscall!( 432 SyscallNumber::Usb, 433 in UsbSyscall::SetStalled, 434 in ep_addr, 435 in stalled, 436 ) 437 } 438 } 439 440 fn is_stalled(&self, ep_addr: EndpointAddress) -> bool { 441 let ep_addr: u8 = ep_addr.into(); 442 443 let mut stalled: usize; 444 unsafe { 445 syscall!( 446 SyscallNumber::Usb, 447 out stalled in UsbSyscall::IsStalled, 448 in ep_addr, 449 ); 450 } 451 452 stalled != 0 453 } 454 455 fn suspend(&self) { 456 // not implemented in rp2040 usb-device implementation 457 } 458 459 fn resume(&self) { 460 // not implemented in rp2040 usb-device implementation 461 } 462 463 fn poll(&self) -> PollResult { 464 let mut spr: MaybeUninit<SafePollResult> = MaybeUninit::uninit(); 465 let ptr = spr.as_mut_ptr(); 466 unsafe { 467 syscall!( 468 SyscallNumber::Usb, 469 in UsbSyscall::Poll, 470 in ptr, 471 ); 472 473 spr.assume_init().into() 474 } 475 } 476}