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

Configure Feed

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

eepy: initial (broken) impl of userspace USB

+927 -52
+2
eepy-launcher/Cargo.toml
··· 7 7 eepy-sys = { path = "../eepy-sys" } 8 8 eepy-gui = { path = "../eepy-gui" } 9 9 embedded-graphics.workspace = true 10 + usb-device.workspace = true 11 + usbd-serial.workspace = true 10 12 panic-halt = "1.0"
+67
eepy-launcher/src/main.rs
··· 8 8 use embedded_graphics::pixelcolor::BinaryColor; 9 9 use embedded_graphics::prelude::*; 10 10 use embedded_graphics::primitives::{Circle, Line, PrimitiveStyle, Rectangle}; 11 + use usb_device::bus::UsbBusAllocator; 11 12 use eepy_gui::draw_target::EpdDrawTarget; 12 13 use eepy_gui::element::button::Button; 13 14 use eepy_gui::element::Gui; ··· 16 17 use eepy_sys::image::RefreshBlockMode; 17 18 use eepy_sys::input::{has_event, next_event, set_touch_enabled, Event, TouchEventType}; 18 19 use eepy_sys::header::{ProgramSlotHeader, Programs}; 20 + use eepy_sys::misc::{get_serial, info}; 21 + use eepy_sys::usb; 22 + use eepy_sys::usb::UsbBus; 23 + use usb_device::prelude::*; 24 + use usbd_serial::SerialPort; 19 25 20 26 #[link_section = ".header"] 21 27 #[used] ··· 91 97 let response = button.tick(draw_target, ev); 92 98 93 99 if response.clicked { 100 + cleanup_usb(); 94 101 exec(*s); 95 102 } 96 103 ··· 279 286 } 280 287 } 281 288 289 + static mut USB: Option<UsbBusAllocator<UsbBus>> = None; 290 + static mut USB_DEVICE: Option<UsbDevice<UsbBus>> = None; 291 + static mut USB_SERIAL: Option<SerialPort<UsbBus>> = None; 292 + 293 + #[allow(static_mut_refs)] 294 + pub extern "C" fn testing_usb_handler() { 295 + let dev: &mut UsbDevice<UsbBus> = unsafe { USB_DEVICE.as_mut().unwrap() }; 296 + let serial: &mut SerialPort<UsbBus> = unsafe { USB_SERIAL.as_mut().unwrap() }; 297 + 298 + info("hello from USB handler"); 299 + 300 + if dev.poll(&mut [serial]) { 301 + let mut buf = [0u8; 64]; 302 + match serial.read(&mut buf) { 303 + Err(_) => {}, 304 + Ok(0) => {}, 305 + Ok(_) => { 306 + let s = core::str::from_utf8(&buf); 307 + if let Ok(s) = s { 308 + info(s); 309 + } 310 + } 311 + } 312 + } 313 + } 314 + 315 + fn cleanup_usb() { 316 + #[allow(static_mut_refs)] 317 + unsafe { 318 + let _ = USB.take(); 319 + let _ = USB_DEVICE.take(); 320 + let _ = USB_SERIAL.take(); 321 + } 322 + } 282 323 283 324 #[no_mangle] 284 325 pub extern "C" fn entry() { 326 + #[allow(static_mut_refs)] 327 + unsafe { 328 + let bus = UsbBusAllocator::new(UsbBus::init()); 329 + USB = Some(bus); 330 + let bus_ref = USB.as_ref().unwrap(); 331 + 332 + let serial = SerialPort::new(bus_ref); 333 + USB_SERIAL = Some(serial); 334 + 335 + let usb_dev = UsbDeviceBuilder::new( 336 + bus_ref, 337 + UsbVidPid(0x2e8a, 0x000a), 338 + ) 339 + .strings(&[StringDescriptors::default() 340 + .manufacturer("arthomnix") 341 + .product("Touchscreen E-Paper Input Module for Framework 16 [eepyOS Launcher]") 342 + .serial_number(get_serial()) 343 + ]) 344 + .unwrap() 345 + .device_class(usbd_serial::USB_CLASS_CDC) 346 + .build(); 347 + USB_DEVICE = Some(usb_dev); 348 + } 349 + 350 + usb::set_handler(testing_usb_handler); 351 + 285 352 let mut draw_target = EpdDrawTarget::new(); 286 353 set_touch_enabled(true); 287 354 let mut gui = MainGui::new();
+5 -1
eepy-sys/Cargo.toml
··· 8 8 defmt = { workspace = true, optional = true } 9 9 embedded-graphics = { workspace = true, optional = true } 10 10 serde.workspace = true 11 - crc32fast.workspace = true 11 + crc32fast.workspace = true 12 + usb-device.workspace = true 13 + 14 + [features] 15 + defmt = ["dep:defmt", "usb-device/defmt"]
+26
eepy-sys/src/lib.rs
··· 37 37 SafeOption::Some(v) => Some(v), 38 38 } 39 39 } 40 + } 41 + 42 + #[repr(C)] 43 + #[derive(Copy, Clone, Debug, Eq, PartialEq)] 44 + #[cfg_attr(feature = "defmt", derive(defmt::Format))] 45 + pub enum SafeResult<T, E> { 46 + Ok(T), 47 + Err(E), 48 + } 49 + 50 + impl<T, E> From<SafeResult<T, E>> for Result<T, E> { 51 + fn from(value: SafeResult<T, E>) -> Self { 52 + match value { 53 + SafeResult::Ok(v) => Ok(v), 54 + SafeResult::Err(e) => Err(e), 55 + } 56 + } 57 + } 58 + 59 + impl<T, E> From<Result<T, E>> for SafeResult<T, E> { 60 + fn from(value: Result<T, E>) -> Self { 61 + match value { 62 + Ok(v) => SafeResult::Ok(v), 63 + Err(e) => SafeResult::Err(e), 64 + } 65 + } 40 66 }
+63
eepy-sys/src/misc.rs
··· 6 6 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 7 7 pub enum MiscSyscall { 8 8 GetSerial = 0, 9 + LogMessage = 1, 9 10 } 10 11 11 12 impl TryFrom<usize> for MiscSyscall { ··· 14 15 fn try_from(value: usize) -> Result<Self, Self::Error> { 15 16 match value { 16 17 x if x == MiscSyscall::GetSerial as usize => Ok(MiscSyscall::GetSerial), 18 + x if x == MiscSyscall::LogMessage as usize => Ok(MiscSyscall::LogMessage), 19 + _ => Err(()), 20 + } 21 + } 22 + } 23 + 24 + #[repr(usize)] 25 + #[derive(Copy, Clone, Debug, Eq, PartialEq)] 26 + #[cfg_attr(feature = "defmt", derive(defmt::Format))] 27 + pub enum LogLevel { 28 + Trace = 0, 29 + Debug = 1, 30 + Info = 2, 31 + Warn = 3, 32 + Error = 4, 33 + } 34 + 35 + impl TryFrom<usize> for LogLevel { 36 + type Error = (); 37 + 38 + fn try_from(value: usize) -> Result<Self, ()> { 39 + match value { 40 + x if x == LogLevel::Trace as usize => Ok(LogLevel::Trace), 41 + x if x == LogLevel::Info as usize => Ok(LogLevel::Info), 42 + x if x == LogLevel::Debug as usize => Ok(LogLevel::Debug), 43 + x if x == LogLevel::Warn as usize => Ok(LogLevel::Warn), 44 + x if x == LogLevel::Error as usize => Ok(LogLevel::Error), 17 45 _ => Err(()), 18 46 } 19 47 } ··· 28 56 ); 29 57 core::str::from_utf8_unchecked(&*ptr) 30 58 } 59 + } 60 + 61 + pub fn log(message: &str, level: LogLevel) { 62 + let len = message.len(); 63 + let ptr = message.as_ptr(); 64 + 65 + unsafe { 66 + syscall!( 67 + SyscallNumber::Misc, 68 + in MiscSyscall::LogMessage, 69 + in level, 70 + in len, 71 + in ptr, 72 + ); 73 + } 74 + } 75 + 76 + pub fn trace(message: &str) { 77 + log(message, LogLevel::Trace); 78 + } 79 + 80 + pub fn debug(message: &str) { 81 + log(message, LogLevel::Debug); 82 + } 83 + 84 + pub fn info(message: &str) { 85 + log(message, LogLevel::Info); 86 + } 87 + 88 + pub fn warn(message: &str) { 89 + log(message, LogLevel::Warn); 90 + } 91 + 92 + pub fn error(message: &str) { 93 + log(message, LogLevel::Error); 31 94 }
+459
eepy-sys/src/usb.rs
··· 1 + use core::mem::MaybeUninit; 2 + use usb_device::bus::PollResult; 3 + use usb_device::class_prelude::{EndpointAddress, EndpointType}; 4 + use usb_device::{UsbDirection, UsbError}; 5 + use usb_device::endpoint::{IsochronousSynchronizationType, IsochronousUsageType}; 6 + use crate::{syscall, SafeOption, SafeResult}; 7 + use crate::syscall::SyscallNumber; 8 + 1 9 #[repr(usize)] 2 10 #[derive(Copy, Clone, Debug, Eq, PartialEq)] 3 11 #[cfg_attr(feature = "defmt", derive(defmt::Format))] 4 12 pub enum UsbSyscall { 5 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, 6 27 } 7 28 8 29 impl TryFrom<usize> for UsbSyscall { ··· 11 32 fn try_from(value: usize) -> Result<Self, Self::Error> { 12 33 match value { 13 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 + 14 49 _ => Err(()), 50 + } 51 + } 52 + } 53 + 54 + pub 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 + 64 + pub 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))] 76 + pub 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 + 88 + impl 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 + 100 + impl 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))] 115 + pub enum SafeUsbError { 116 + WouldBlock, 117 + ParseError, 118 + BufferOverflow, 119 + EndpointOverflow, 120 + EndpointMemoryOverflow, 121 + InvalidEndpoint, 122 + Unsupported, 123 + InvalidState, 124 + } 125 + 126 + impl 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 + 141 + impl 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))] 159 + pub enum SafeIsochronousSynchronizationType { 160 + NoSynchronization, 161 + Asynchronous, 162 + Adaptive, 163 + Synchronous, 164 + } 165 + 166 + impl 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 + 177 + impl 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))] 191 + pub enum SafeIsochronousUsageType { 192 + Data, 193 + Feedback, 194 + ImplicitFeedbackData, 195 + } 196 + 197 + impl 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 + 207 + impl 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))] 220 + pub enum SafeEndpointType { 221 + Control, 222 + Isochronous { 223 + synchronization: SafeIsochronousSynchronizationType, 224 + usage: SafeIsochronousUsageType, 225 + }, 226 + Bulk, 227 + Interrupt, 228 + } 229 + 230 + impl 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 + 243 + impl 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))] 259 + pub 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))] 270 + pub 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))] 280 + pub 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 + 287 + pub struct UsbBus { 288 + _dummy: (), 289 + } 290 + 291 + impl 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 + 304 + impl Drop for UsbBus { 305 + fn drop(&mut self) { 306 + unsafe { 307 + syscall!( 308 + SyscallNumber::Usb, 309 + in UsbSyscall::Uninit, 310 + ) 311 + } 312 + } 313 + } 314 + 315 + impl 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() 15 474 } 16 475 } 17 476 }
+2 -7
eepy/Cargo.toml
··· 6 6 [dependencies] 7 7 fw16-epd-bsp = { path = "../fw16-epd-bsp" } 8 8 eepy-sys = { path = "../eepy-sys", features = ["defmt"] } 9 - eepy-gui = { path = "../eepy-gui", features = ["defmt-derive"] } 10 9 eepy-serial = { path = "../eepy-serial" } 11 10 tp370pgh01 = { path = "../tp370pgh01", features = ["rp2040", "defmt"] } 12 11 cortex-m.workspace = true ··· 18 17 panic-probe.workspace = true 19 18 critical-section.workspace = true 20 19 portable-atomic.workspace = true 21 - mcp9808.workspace = true 22 20 usb-device.workspace = true 23 - usbd-serial.workspace = true 24 - crc32fast.workspace = true 25 - embedded-graphics = { workspace = true, features = ["defmt"] } 26 - heapless.workspace = true 27 - once_cell.workspace = true 21 + once_cell.workspace = true 22 + mcp9808.workspace = true
+1
eepy/src/exception.rs
··· 1 1 use defmt::Formatter; 2 2 3 + #[repr(C)] 3 4 #[derive(Copy, Clone, Debug, Eq, PartialEq)] 4 5 pub(crate) struct StackFrame { 5 6 pub r0: usize,
+10 -14
eepy/src/main.rs
··· 1 1 #![no_main] 2 2 #![no_std] 3 3 4 - mod serial; 4 + //mod serial; 5 5 mod ringbuffer; 6 6 mod syscall; 7 7 mod launcher; ··· 25 25 use once_cell::sync::OnceCell; 26 26 use portable_atomic::{AtomicBool, AtomicU8}; 27 27 use portable_atomic::Ordering; 28 - use usb_device::bus::UsbBusAllocator; 29 - use usb_device::prelude::*; 30 - use usbd_serial::SerialPort; 31 28 use eepy_sys::exec::exec; 32 29 use fw16_epd_bsp::{entry, hal, pac, EpdBusy, EpdCs, EpdDc, EpdPowerSwitch, EpdReset, EpdSck, EpdSdaWrite, EpdTouchInt, EpdTouchReset, I2CScl, I2CSda, LaptopSleep, Pins}; 33 30 use fw16_epd_bsp::hal::{Sio, Timer, I2C}; ··· 39 36 use fw16_epd_bsp::pac::I2C0; 40 37 use fw16_epd_bsp::pac::interrupt; 41 38 use eepy_sys::input::{Event, TouchEvent, TouchEventType}; 42 - use eepy_sys::misc::get_serial; 43 39 use tp370pgh01::rp2040::{Rp2040PervasiveSpiDelays, IoPin}; 44 40 use tp370pgh01::{Tp370pgh01, IMAGE_BYTES}; 45 41 use crate::ringbuffer::RingBuffer; ··· 62 58 static REFRESHING: AtomicBool = AtomicBool::new(false); 63 59 static EPD_NEEDS_HARD_RESET: AtomicBool = AtomicBool::new(true); 64 60 static TEMP: AtomicU8 = AtomicU8::new(20); 65 - 66 - static mut GLOBAL_USB_DEVICE: Option<UsbDevice<hal::usb::UsbBus>> = None; 67 - static mut GLOBAL_USB_BUS: Option<UsbBusAllocator<hal::usb::UsbBus>> = None; 68 - static mut GLOBAL_USB_SERIAL: Option<SerialPort<hal::usb::UsbBus>> = None; 69 - 70 61 static SERIAL_NUMBER: OnceCell<[u8; 16]> = OnceCell::new(); 71 62 72 63 static EVENT_QUEUE: Mutex<RefCell<RingBuffer<Event>>> = Mutex::new(RefCell::new(RingBuffer::new())); ··· 247 238 } 248 239 pac::NVIC::pend(interrupt::TIMER_IRQ_0); 249 240 241 + usb::init_usb(pac.USBCTRL_REGS, pac.USBCTRL_DPRAM, clocks.usb_clock); 242 + 243 + /* 250 244 let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new( 251 245 pac.USBCTRL_REGS, 252 246 pac.USBCTRL_DPRAM, ··· 287 281 // FIXME testing 288 282 core.NVIC.set_priority(interrupt::SW5_IRQ, 0b11000000); 289 283 pac::NVIC::unmask(interrupt::SW5_IRQ); 284 + } 285 + */ 286 + 287 + unsafe { 288 + core.NVIC.set_priority(interrupt::SW5_IRQ, 0b11000000); 290 289 } 291 290 292 291 let mut mc = Multicore::new(&mut pac.PSM, &mut pac.PPB, &mut sio.fifo); ··· 382 381 TEMP.store(clamped, Ordering::Relaxed); 383 382 384 383 alarm.clear_interrupt(); 385 - alarm.schedule(1.secs()).unwrap(); 384 + alarm.schedule(1.minutes()).unwrap(); 386 385 } else { 387 386 // I2C bus was in use, so try again in a short time 388 387 alarm.clear_interrupt(); ··· 391 390 } 392 391 393 392 critical_section::with(|cs| GLOBAL_I2C.borrow(cs).replace(i2c)); 394 - 395 - // FIXME testing 396 - pac::NVIC::pend(interrupt::SW5_IRQ); 397 393 } 398 394 399 395 #[interrupt]
+3 -3
eepy/src/serial.rs
··· 8 8 use eepy_serial::{Response, SerialCommand}; 9 9 use eepy_sys::image::{refresh, write_image, RefreshBlockMode}; 10 10 use tp370pgh01::IMAGE_BYTES; 11 - use crate::{GLOBAL_USB_DEVICE, GLOBAL_USB_SERIAL}; 12 - 13 11 #[derive(Copy, Clone, Debug, defmt::Format)] 14 12 enum SerialState { 15 13 ReadyForCommand, ··· 67 65 debug!("End write slot {} page {}", slot, page); 68 66 } 69 67 68 + /* 70 69 #[interrupt] 71 70 fn USBCTRL_IRQ() { 72 71 static mut STATE: SerialState = SerialState::ReadyForCommand; ··· 179 178 } 180 179 } 181 180 } 182 - } 181 + } 182 + */
+28 -5
eepy/src/syscall.rs
··· 1 1 use core::arch::{asm, global_asm}; 2 - use defmt::{debug, trace, Formatter}; 2 + use defmt::trace; 3 3 use eepy_sys::exec::exec; 4 4 use eepy_sys::header::slot; 5 5 use eepy_sys::syscall::SyscallNumber; ··· 37 37 } 38 38 39 39 fn handle_exec(stack_values: &mut StackFrame, using_psp: bool) { 40 + // cleanup previous program's USB 41 + crate::usb::handle_uninit(); 42 + crate::usb::handle_clear_handler(); 43 + 40 44 // disable privileged mode 41 45 unsafe { 42 46 asm!( ··· 84 88 } 85 89 86 90 mod misc { 87 - use eepy_sys::misc::MiscSyscall; 91 + use defmt::{debug, error, info, trace, warn}; 92 + use eepy_sys::header::{SLOT_SIZE, XIP_BASE}; 93 + use eepy_sys::misc::{LogLevel, MiscSyscall}; 88 94 use crate::SERIAL_NUMBER; 89 95 use super::StackFrame; 90 96 91 97 pub(super) fn handle_misc(stack_values: &mut StackFrame) { 92 98 match MiscSyscall::try_from(stack_values.r0) { 93 99 Ok(MiscSyscall::GetSerial) => handle_get_serial(stack_values), 94 - _ => panic!("illegal syscall"), 100 + Ok(MiscSyscall::LogMessage) => handle_log_message(stack_values), 101 + Err(_) => panic!("illegal syscall"), 95 102 } 96 103 } 97 104 98 105 fn handle_get_serial(stack_values: &mut StackFrame) { 99 106 stack_values.r0 = (&raw const *SERIAL_NUMBER.get().unwrap()) as usize; 100 107 } 108 + 109 + fn handle_log_message(stack_values: &mut StackFrame) { 110 + let log_level: LogLevel = stack_values.r1.try_into().expect("invalid log level"); 111 + let len = stack_values.r2; 112 + let ptr = stack_values.r3 as *const u8; 113 + let s = unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(ptr, len)) }; 114 + let slot_n = (stack_values.pc as usize - XIP_BASE as usize) / SLOT_SIZE; 115 + 116 + match log_level { 117 + LogLevel::Trace => trace!("[PROGRAM:{}] {}", slot_n, s), 118 + LogLevel::Debug => debug!("[PROGRAM:{}] {}", slot_n, s), 119 + LogLevel::Info => info!("[PROGRAM:{}] {}", slot_n, s), 120 + LogLevel::Warn => warn!("[PROGRAM:{}] {}", slot_n, s), 121 + LogLevel::Error => error!("[PROGRAM:{}] {}", slot_n, s), 122 + } 123 + } 101 124 } 102 125 103 126 mod image { ··· 111 134 match ImageSyscall::try_from(stack_values.r0) { 112 135 Ok(ImageSyscall::WriteImage) => handle_write_image(stack_values), 113 136 Ok(ImageSyscall::Refresh) => handle_refresh(stack_values), 114 - _ => panic!("illegal syscall"), 137 + Err(_) => panic!("illegal syscall"), 115 138 } 116 139 } 117 140 ··· 150 173 Ok(InputSyscall::NextEvent) => handle_next_event(stack_values), 151 174 Ok(InputSyscall::SetTouchEnabled) => handle_set_touch_enabled(stack_values), 152 175 Ok(InputSyscall::HasEvent) => handle_has_event(stack_values), 153 - _ => panic!("illegal syscall"), 176 + Err(_) => panic!("illegal syscall"), 154 177 } 155 178 } 156 179
+252 -13
eepy/src/usb.rs
··· 1 1 use core::arch::{asm, global_asm}; 2 - use defmt::trace; 3 - use eepy_sys::misc::get_serial; 4 - use eepy_sys::usb::UsbSyscall; 2 + use core::cell::RefCell; 3 + use core::fmt::{Debug, Formatter}; 4 + use core::sync::atomic::Ordering; 5 + use critical_section::Mutex; 6 + use defmt::{debug, trace, warn}; 7 + use portable_atomic::AtomicPtr; 8 + use eepy_sys::usb::{SafePollResult, SafeUsbError, UsbEpAllocArgs, UsbReadArgs, UsbSyscall, UsbWriteArgs}; 9 + use fw16_epd_bsp::hal::clocks::UsbClock; 10 + use fw16_epd_bsp::hal::usb::UsbBus; 5 11 use fw16_epd_bsp::pac; 6 - use fw16_epd_bsp::pac::interrupt; 12 + use fw16_epd_bsp::pac::{interrupt, USBCTRL_DPRAM, USBCTRL_REGS}; 13 + use usb_device::class_prelude::{*, UsbBus as _}; 14 + use eepy_sys::SafeResult; 7 15 use crate::exception::StackFrame; 8 16 9 17 global_asm!(include_str!("usb.s")); 10 18 11 - extern "C" { 12 - fn usb_ret(); 19 + struct Usb { 20 + bus: Option<UsbBus>, 21 + freed: Option<(USBCTRL_REGS, USBCTRL_DPRAM, UsbClock)>, 22 + } 23 + 24 + impl Usb { 25 + fn init_bus(&mut self) { 26 + if let Some((regs, dpram, clock)) = self.freed.take() { 27 + self.bus.replace(UsbBus::new( 28 + regs, 29 + dpram, 30 + clock, 31 + false, 32 + &mut unsafe { pac::RESETS::steal() }, 33 + )); 34 + } 35 + } 36 + 37 + fn free_bus(&mut self) { 38 + if let Some(bus) = self.bus.take() { 39 + let (regs, dpram, clock) = bus.free( 40 + &mut unsafe { pac::RESETS::steal() } 41 + ); 42 + self.freed.replace((regs, dpram, clock)); 43 + } 44 + } 45 + 46 + fn get_bus(&mut self) -> &mut UsbBus { 47 + self.bus.as_mut().expect("USB bus not initialised") 48 + } 49 + } 50 + 51 + impl Debug for Usb { 52 + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { 53 + if self.bus.is_some() { 54 + f.write_str("Active USB") 55 + } else if self.freed.is_some() { 56 + f.write_str("Freed USB") 57 + } else { 58 + f.write_str("Uninitialised USB") 59 + } 60 + } 61 + } 62 + 63 + static USB: Mutex<RefCell<Option<Usb>>> = Mutex::new(RefCell::new(None)); 64 + 65 + fn with_usb<R>(mut f: impl FnMut(&mut Usb) -> R) -> R { 66 + critical_section::with(|cs| { 67 + f( 68 + USB 69 + .borrow_ref_mut(cs) 70 + .as_mut() 71 + .expect("USB bus not initialised") 72 + ) 73 + }) 74 + } 75 + 76 + fn with_usb_bus<R>(mut f: impl FnMut(&mut UsbBus) -> R) -> R { 77 + critical_section::with(|cs| { 78 + f( 79 + USB 80 + .borrow_ref_mut(cs) 81 + .as_mut() 82 + .expect("USB bus not initialised") 83 + .get_bus() 84 + ) 85 + }) 13 86 } 14 87 15 - extern "C" fn example_usb_handler() { 16 - // Do a syscall so it shows up in the kernel logs 17 - // (we should be in unprivileged thread mode here so we can't use defmt) 18 - core::hint::black_box(get_serial()); 88 + pub(crate) fn init_usb(regs: USBCTRL_REGS, dpram: USBCTRL_DPRAM, clock: UsbClock) { 89 + critical_section::with(|cs| USB.borrow_ref_mut(cs).replace( 90 + Usb { 91 + bus: None, 92 + freed: Some((regs, dpram, clock)), 93 + } 94 + )); 95 + } 96 + 97 + static USB_HANDLER: AtomicPtr<u8> = AtomicPtr::new(core::ptr::null_mut()); 98 + 99 + extern "C" { 100 + fn usb_ret(); 19 101 } 20 102 21 103 #[no_mangle] 22 104 extern "C" fn handle_usb_irq(sp: *mut StackFrame, using_psp: bool) { 23 - trace!("fake USBCTRL_IRQ"); 105 + trace!("USBCTRL_IRQ"); 24 106 25 107 if !using_psp { 26 108 return; 27 109 } 28 110 111 + let handler = USB_HANDLER.load(Ordering::Relaxed); 112 + if handler.is_null() { 113 + warn!("USB handler is null but interrupt was not masked"); 114 + return; 115 + } 116 + 117 + // make sure the interrupt doesn't fire again whilst the unprivileged handler 118 + // is running (we unmask again after the handler is done as part of the UsbRet 119 + // syscall 120 + trace!("masking USBCTRL_IRQ"); 121 + pac::NVIC::mask(interrupt::USBCTRL_IRQ); 122 + 29 123 unsafe { 30 124 let new_sp = sp.sub(1); 31 125 new_sp.write(StackFrame { ··· 35 129 r3: 0, 36 130 r12: 0, 37 131 lr: usb_ret as *const u8, 38 - pc: example_usb_handler as *const u8, 132 + pc: handler, 39 133 xpsr: 0x1000000, 40 134 }); 41 135 ··· 49 143 pub(crate) fn handle_usb(stack_values: &mut StackFrame) { 50 144 match UsbSyscall::try_from(stack_values.r0) { 51 145 Ok(UsbSyscall::UsbRet) => handle_usb_ret(stack_values), 52 - Err(_) => {}, 146 + Ok(UsbSyscall::SetHandler) => handle_set_handler(stack_values), 147 + Ok(UsbSyscall::ClearHandler) => handle_clear_handler(), 148 + Ok(UsbSyscall::Init) => handle_init(), 149 + Ok(UsbSyscall::Uninit) => handle_uninit(), 150 + Ok(UsbSyscall::AllocEp) => handle_alloc_ep(stack_values), 151 + Ok(UsbSyscall::Enable) => handle_enable(), 152 + Ok(UsbSyscall::Reset) => handle_reset(), 153 + Ok(UsbSyscall::SetDeviceAddr) => handle_set_device_addr(stack_values), 154 + Ok(UsbSyscall::Write) => handle_write(stack_values), 155 + Ok(UsbSyscall::Read) => handle_read(stack_values), 156 + Ok(UsbSyscall::SetStalled) => handle_set_stalled(stack_values), 157 + Ok(UsbSyscall::IsStalled) => handle_is_stalled(stack_values), 158 + Ok(UsbSyscall::Poll) => handle_poll(stack_values), 159 + Err(_) => panic!("illegal syscall"), 160 + } 161 + } 162 + 163 + pub(crate) fn handle_clear_handler() { 164 + USB_HANDLER.store(core::ptr::null_mut(), Ordering::Relaxed); 165 + trace!("masking USBCTRL_IRQ"); 166 + pac::NVIC::mask(interrupt::USBCTRL_IRQ); 167 + } 168 + 169 + fn handle_set_handler(stack_values: &mut StackFrame) { 170 + let handler = stack_values.r1 as *mut u8; 171 + USB_HANDLER.store(handler, Ordering::Relaxed); 172 + unsafe { 173 + trace!("unmasking USBCTRL_IRQ"); 174 + pac::NVIC::unmask(interrupt::USBCTRL_IRQ); 53 175 } 54 176 } 55 177 56 178 fn handle_usb_ret(stack_values: &mut StackFrame) { 57 179 trace!("usb_ret"); 58 180 unsafe { 181 + trace!("unmasking USBCTRL_IRQ"); 182 + pac::NVIC::unmask(interrupt::USBCTRL_IRQ); 183 + 59 184 let new_sp = (&raw mut *stack_values).add(1); 60 185 asm!( 61 186 "msr psp, {new_psp}", 62 187 new_psp = in(reg) new_sp, 63 188 ); 189 + } 190 + } 191 + 192 + fn handle_init() { 193 + trace!("USB init"); 194 + with_usb(|usb| usb.init_bus()); 195 + } 196 + 197 + pub(crate) fn handle_uninit() { 198 + trace!("USB uninit"); 199 + with_usb(|usb| usb.free_bus()); 200 + } 201 + 202 + fn handle_alloc_ep(stack_values: &mut StackFrame) { 203 + trace!("USB alloc endpoint"); 204 + let alloc_info = stack_values.r1 as *const UsbEpAllocArgs; 205 + trace!("{}", unsafe { *alloc_info }); 206 + 207 + let ep_dir = unsafe { (*alloc_info).ep_dir }; 208 + let ep_addr: Option<EndpointAddress> = unsafe { 209 + let addr: Option<u8> = (*alloc_info).ep_addr.into(); 210 + addr.map(|v| v.into()) 211 + }; 212 + let ep_type: EndpointType = unsafe { (*alloc_info).ep_type.into() }; 213 + let max_packet_size = unsafe { (*alloc_info).max_packet_size }; 214 + let interval = unsafe { (*alloc_info).interval }; 215 + 216 + let res_ptr = stack_values.r2 as *mut SafeResult<u8, SafeUsbError>; 217 + 218 + let res = with_usb_bus(|bus| { 219 + bus.alloc_ep( 220 + ep_dir, 221 + ep_addr, 222 + ep_type, 223 + max_packet_size, 224 + interval, 225 + ) 226 + }); 227 + 228 + let res: Result<u8, SafeUsbError> = res.map(|v| v.into()).map_err(|e| e.into()); 229 + unsafe { 230 + res_ptr.write(res.into()); 231 + } 232 + } 233 + 234 + fn handle_enable() { 235 + trace!("USB enable"); 236 + with_usb_bus(|bus| bus.enable()); 237 + } 238 + 239 + fn handle_reset() { 240 + trace!("USB reset"); 241 + with_usb_bus(|bus| bus.reset()); 242 + } 243 + 244 + fn handle_set_device_addr(stack_values: &mut StackFrame) { 245 + trace!("USB set device address"); 246 + with_usb_bus(|bus| bus.set_device_address(stack_values.r1 as u8)); 247 + } 248 + 249 + fn handle_write(stack_values: &mut StackFrame) { 250 + trace!("USB write"); 251 + let args = stack_values.r1 as *const UsbWriteArgs; 252 + 253 + let ep_addr = unsafe { (*args).ep_addr }.into(); 254 + let buf = unsafe { core::slice::from_raw_parts((*args).buf, (*args).len) }; 255 + 256 + let res = with_usb_bus(|bus| { 257 + bus.write(ep_addr, buf) 258 + }); 259 + 260 + let res: Result<usize, SafeUsbError> = res.map_err(|e| e.into()); 261 + unsafe { 262 + (*args).ptr.write(res.into()); 263 + } 264 + } 265 + 266 + fn handle_read(stack_values: &mut StackFrame) { 267 + trace!("USB read"); 268 + let args = stack_values.r1 as *const UsbReadArgs; 269 + 270 + let ep_addr = unsafe { (*args).ep_addr }.into(); 271 + let buf = unsafe { core::slice::from_raw_parts_mut((*args).buf, (*args).len) }; 272 + 273 + let res = with_usb_bus(|bus| { 274 + bus.read(ep_addr, buf) 275 + }); 276 + 277 + let res: Result<usize, SafeUsbError> = res.map_err(|e| e.into()); 278 + unsafe { 279 + (*args).ptr.write(res.into()); 280 + } 281 + } 282 + 283 + fn handle_set_stalled(stack_values: &mut StackFrame) { 284 + trace!("USB set stalled"); 285 + let ep_addr: EndpointAddress = (stack_values.r1 as u8).into(); 286 + let stalled = stack_values.r2 != 0; 287 + with_usb_bus(|bus| bus.set_stalled(ep_addr, stalled)); 288 + } 289 + 290 + fn handle_is_stalled(stack_values: &mut StackFrame) { 291 + trace!("USB query stalled"); 292 + let ep_addr: EndpointAddress = (stack_values.r1 as u8).into(); 293 + let stalled = with_usb_bus(|bus| bus.is_stalled(ep_addr)); 294 + stack_values.r0 = stalled as usize; 295 + } 296 + 297 + fn handle_poll(stack_values: &mut StackFrame) { 298 + trace!("USB poll"); 299 + let res_ptr = stack_values.r1 as *mut SafePollResult; 300 + let result = with_usb_bus(|bus| bus.poll()); 301 + unsafe { 302 + res_ptr.write(result.into()); 64 303 } 65 304 }
+4 -4
eepy/src/usb.s
··· 1 - //.global USBCTRL_IRQ 2 - .global SW5_IRQ 1 + .global USBCTRL_IRQ 2 + //.global SW5_IRQ 3 3 4 4 .thumb_func 5 - //USBCTRL_IRQ: 6 - SW5_IRQ: 5 + USBCTRL_IRQ: 6 + //SW5_IRQ: 7 7 ldr r2, =handle_usb_irq 8 8 movs r0, #4 9 9 mov r1, lr
+5 -5
elf2epb/src/main.rs
··· 31 31 let mut current_addr: Option<u32> = None; 32 32 33 33 for phdr in elf.segments().expect("Failed to parse ELF file") { 34 - if phdr.p_type == PT_LOAD { 34 + if phdr.p_type == PT_LOAD && phdr.p_filesz > 0 { 35 35 if current_addr.is_none() { 36 - current_addr.replace(phdr.p_vaddr as u32); 36 + current_addr.replace(phdr.p_paddr as u32); 37 37 } 38 38 39 39 let current_addr = current_addr.as_mut().unwrap(); 40 40 41 - if *current_addr < phdr.p_vaddr as u32 { 42 - let diff = phdr.p_vaddr as u32 - *current_addr; 41 + if *current_addr < phdr.p_paddr as u32 { 42 + let diff = phdr.p_paddr as u32 - *current_addr; 43 43 for _ in 0..diff { 44 44 bin.push(0); 45 45 } ··· 71 71 let len = bin.len() as u32; 72 72 73 73 // Add missing EPB header entries 74 - bin[8..12].copy_from_slice(&len.to_le_bytes()); // len 74 + bin[8..12].copy_from_slice(&len.to_le_bytes()); // len 75 75 bin[12..16].copy_from_slice(&data_len.to_le_bytes()); // data_len 76 76 bin[16..20].copy_from_slice(&data_paddr.to_le_bytes()); // data_lma 77 77 bin[20..24].copy_from_slice(&data_vaddr.to_le_bytes()); // data_vma