diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-06-05 22:16:44 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-06-05 22:16:44 +0000 |
| commit | 79b982c941576597bd09d585a9bdaa7fce47688a (patch) | |
| tree | 10b980663e8326f4a9a15e64a0c1f6df3c3cae17 | |
| parent | d690a1717fd03a1f3fdad509d6a638567f8a645a (diff) | |
| parent | 593fc78dd892338386a2a81400e0621372264053 (diff) | |
Merge pull request #1536 from embassy-rs/rp-flash-fix
Rp flash fix
| -rw-r--r-- | embassy-rp/Cargo.toml | 5 | ||||
| -rw-r--r-- | embassy-rp/src/dma.rs | 5 | ||||
| -rw-r--r-- | embassy-rp/src/flash.rs | 82 | ||||
| -rw-r--r-- | tests/rp/Cargo.toml | 2 |
4 files changed, 53 insertions, 41 deletions
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 5f08c7f33..ddada655b 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml | |||
| @@ -41,6 +41,11 @@ boot2-ram-memcpy = [] | |||
| 41 | boot2-w25q080 = [] | 41 | boot2-w25q080 = [] |
| 42 | boot2-w25x10cl = [] | 42 | boot2-w25x10cl = [] |
| 43 | 43 | ||
| 44 | # Indicate code is running from RAM. | ||
| 45 | # Set this if all code is in RAM, and the cores never access memory-mapped flash memory through XIP. | ||
| 46 | # This allows the flash driver to not force pausing execution on both cores when doing flash operations. | ||
| 47 | run-from-ram = [] | ||
| 48 | |||
| 44 | # Enable nightly-only features | 49 | # Enable nightly-only features |
| 45 | nightly = ["embassy-executor/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"] | 50 | nightly = ["embassy-executor/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"] |
| 46 | 51 | ||
diff --git a/embassy-rp/src/dma.rs b/embassy-rp/src/dma.rs index 74f4e6998..1cbb4651a 100644 --- a/embassy-rp/src/dma.rs +++ b/embassy-rp/src/dma.rs | |||
| @@ -75,16 +75,17 @@ pub unsafe fn write<'a, C: Channel, W: Word>( | |||
| 75 | ) | 75 | ) |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static DUMMY: u32 = 0; | ||
| 79 | |||
| 78 | pub unsafe fn write_repeated<'a, C: Channel, W: Word>( | 80 | pub unsafe fn write_repeated<'a, C: Channel, W: Word>( |
| 79 | ch: impl Peripheral<P = C> + 'a, | 81 | ch: impl Peripheral<P = C> + 'a, |
| 80 | to: *mut W, | 82 | to: *mut W, |
| 81 | len: usize, | 83 | len: usize, |
| 82 | dreq: u8, | 84 | dreq: u8, |
| 83 | ) -> Transfer<'a, C> { | 85 | ) -> Transfer<'a, C> { |
| 84 | let dummy: u32 = 0; | ||
| 85 | copy_inner( | 86 | copy_inner( |
| 86 | ch, | 87 | ch, |
| 87 | &dummy as *const u32, | 88 | &DUMMY as *const u32, |
| 88 | to as *mut u32, | 89 | to as *mut u32, |
| 89 | len, | 90 | len, |
| 90 | W::size(), | 91 | W::size(), |
diff --git a/embassy-rp/src/flash.rs b/embassy-rp/src/flash.rs index 0410429e0..5d928abad 100644 --- a/embassy-rp/src/flash.rs +++ b/embassy-rp/src/flash.rs | |||
| @@ -9,7 +9,11 @@ use embedded_storage::nor_flash::{ | |||
| 9 | use crate::pac; | 9 | use crate::pac; |
| 10 | use crate::peripherals::FLASH; | 10 | use crate::peripherals::FLASH; |
| 11 | 11 | ||
| 12 | pub const FLASH_BASE: usize = 0x10000000; | 12 | pub const FLASH_BASE: *const u32 = 0x10000000 as _; |
| 13 | |||
| 14 | // If running from RAM, we might have no boot2. Use bootrom `flash_enter_cmd_xip` instead. | ||
| 15 | // TODO: when run-from-ram is set, completely skip the "pause cores and jumpp to RAM" dance. | ||
| 16 | pub const USE_BOOT2: bool = !cfg!(feature = "run-from-ram"); | ||
| 13 | 17 | ||
| 14 | // **NOTE**: | 18 | // **NOTE**: |
| 15 | // | 19 | // |
| @@ -63,8 +67,8 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | |||
| 63 | pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { | 67 | pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { |
| 64 | trace!( | 68 | trace!( |
| 65 | "Reading from 0x{:x} to 0x{:x}", | 69 | "Reading from 0x{:x} to 0x{:x}", |
| 66 | FLASH_BASE + offset as usize, | 70 | FLASH_BASE as u32 + offset, |
| 67 | FLASH_BASE + offset as usize + bytes.len() | 71 | FLASH_BASE as u32 + offset + bytes.len() as u32 |
| 68 | ); | 72 | ); |
| 69 | check_read(self, offset, bytes.len())?; | 73 | check_read(self, offset, bytes.len())?; |
| 70 | 74 | ||
| @@ -89,7 +93,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | |||
| 89 | 93 | ||
| 90 | let len = to - from; | 94 | let len = to - from; |
| 91 | 95 | ||
| 92 | unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len, true))? }; | 96 | unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len))? }; |
| 93 | 97 | ||
| 94 | Ok(()) | 98 | Ok(()) |
| 95 | } | 99 | } |
| @@ -114,7 +118,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | |||
| 114 | 118 | ||
| 115 | let unaligned_offset = offset as usize - start; | 119 | let unaligned_offset = offset as usize - start; |
| 116 | 120 | ||
| 117 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf, true))? } | 121 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } |
| 118 | } | 122 | } |
| 119 | 123 | ||
| 120 | let remaining_len = bytes.len() - start_padding; | 124 | let remaining_len = bytes.len() - start_padding; |
| @@ -132,12 +136,12 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | |||
| 132 | if bytes.as_ptr() as usize >= 0x2000_0000 { | 136 | if bytes.as_ptr() as usize >= 0x2000_0000 { |
| 133 | let aligned_data = &bytes[start_padding..end_padding]; | 137 | let aligned_data = &bytes[start_padding..end_padding]; |
| 134 | 138 | ||
| 135 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data, true))? } | 139 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? } |
| 136 | } else { | 140 | } else { |
| 137 | for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) { | 141 | for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) { |
| 138 | let mut ram_buf = [0xFF_u8; PAGE_SIZE]; | 142 | let mut ram_buf = [0xFF_u8; PAGE_SIZE]; |
| 139 | ram_buf.copy_from_slice(chunk); | 143 | ram_buf.copy_from_slice(chunk); |
| 140 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf, true))? } | 144 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? } |
| 141 | aligned_offset += PAGE_SIZE; | 145 | aligned_offset += PAGE_SIZE; |
| 142 | } | 146 | } |
| 143 | } | 147 | } |
| @@ -152,7 +156,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | |||
| 152 | 156 | ||
| 153 | let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset); | 157 | let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset); |
| 154 | 158 | ||
| 155 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf, true))? } | 159 | unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? } |
| 156 | } | 160 | } |
| 157 | 161 | ||
| 158 | Ok(()) | 162 | Ok(()) |
| @@ -190,7 +194,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | |||
| 190 | 194 | ||
| 191 | /// Read SPI flash unique ID | 195 | /// Read SPI flash unique ID |
| 192 | pub fn unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> { | 196 | pub fn unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> { |
| 193 | unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid, true))? }; | 197 | unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid))? }; |
| 194 | Ok(()) | 198 | Ok(()) |
| 195 | } | 199 | } |
| 196 | 200 | ||
| @@ -199,7 +203,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> { | |||
| 199 | let mut jedec = None; | 203 | let mut jedec = None; |
| 200 | unsafe { | 204 | unsafe { |
| 201 | self.in_ram(|| { | 205 | self.in_ram(|| { |
| 202 | jedec.replace(ram_helpers::flash_jedec_id(true)); | 206 | jedec.replace(ram_helpers::flash_jedec_id()); |
| 203 | })?; | 207 | })?; |
| 204 | }; | 208 | }; |
| 205 | Ok(jedec.unwrap()) | 209 | Ok(jedec.unwrap()) |
| @@ -242,6 +246,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S | |||
| 242 | mod ram_helpers { | 246 | mod ram_helpers { |
| 243 | use core::marker::PhantomData; | 247 | use core::marker::PhantomData; |
| 244 | 248 | ||
| 249 | use super::*; | ||
| 245 | use crate::rom_data; | 250 | use crate::rom_data; |
| 246 | 251 | ||
| 247 | #[repr(C)] | 252 | #[repr(C)] |
| @@ -306,7 +311,7 @@ mod ram_helpers { | |||
| 306 | /// | 311 | /// |
| 307 | /// `addr` and `len` must be multiples of 4096 | 312 | /// `addr` and `len` must be multiples of 4096 |
| 308 | /// | 313 | /// |
| 309 | /// If `use_boot2` is `true`, a copy of the 2nd stage boot loader | 314 | /// If `USE_BOOT2` is `true`, a copy of the 2nd stage boot loader |
| 310 | /// is used to re-initialize the XIP engine after flashing. | 315 | /// is used to re-initialize the XIP engine after flashing. |
| 311 | /// | 316 | /// |
| 312 | /// # Safety | 317 | /// # Safety |
| @@ -318,10 +323,10 @@ mod ram_helpers { | |||
| 318 | /// - DMA must not access flash memory | 323 | /// - DMA must not access flash memory |
| 319 | /// | 324 | /// |
| 320 | /// `addr` and `len` parameters must be valid and are not checked. | 325 | /// `addr` and `len` parameters must be valid and are not checked. |
| 321 | pub unsafe fn flash_range_erase(addr: u32, len: u32, use_boot2: bool) { | 326 | pub unsafe fn flash_range_erase(addr: u32, len: u32) { |
| 322 | let mut boot2 = [0u32; 256 / 4]; | 327 | let mut boot2 = [0u32; 256 / 4]; |
| 323 | let ptrs = if use_boot2 { | 328 | let ptrs = if USE_BOOT2 { |
| 324 | rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256); | 329 | rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); |
| 325 | flash_function_pointers_with_boot2(true, false, &boot2) | 330 | flash_function_pointers_with_boot2(true, false, &boot2) |
| 326 | } else { | 331 | } else { |
| 327 | flash_function_pointers(true, false) | 332 | flash_function_pointers(true, false) |
| @@ -336,7 +341,7 @@ mod ram_helpers { | |||
| 336 | /// | 341 | /// |
| 337 | /// `addr` and `data.len()` must be multiples of 4096 | 342 | /// `addr` and `data.len()` must be multiples of 4096 |
| 338 | /// | 343 | /// |
| 339 | /// If `use_boot2` is `true`, a copy of the 2nd stage boot loader | 344 | /// If `USE_BOOT2` is `true`, a copy of the 2nd stage boot loader |
| 340 | /// is used to re-initialize the XIP engine after flashing. | 345 | /// is used to re-initialize the XIP engine after flashing. |
| 341 | /// | 346 | /// |
| 342 | /// # Safety | 347 | /// # Safety |
| @@ -348,10 +353,10 @@ mod ram_helpers { | |||
| 348 | /// - DMA must not access flash memory | 353 | /// - DMA must not access flash memory |
| 349 | /// | 354 | /// |
| 350 | /// `addr` and `len` parameters must be valid and are not checked. | 355 | /// `addr` and `len` parameters must be valid and are not checked. |
| 351 | pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8], use_boot2: bool) { | 356 | pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8]) { |
| 352 | let mut boot2 = [0u32; 256 / 4]; | 357 | let mut boot2 = [0u32; 256 / 4]; |
| 353 | let ptrs = if use_boot2 { | 358 | let ptrs = if USE_BOOT2 { |
| 354 | rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256); | 359 | rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); |
| 355 | flash_function_pointers_with_boot2(true, true, &boot2) | 360 | flash_function_pointers_with_boot2(true, true, &boot2) |
| 356 | } else { | 361 | } else { |
| 357 | flash_function_pointers(true, true) | 362 | flash_function_pointers(true, true) |
| @@ -371,7 +376,7 @@ mod ram_helpers { | |||
| 371 | /// | 376 | /// |
| 372 | /// `addr` and `data.len()` must be multiples of 256 | 377 | /// `addr` and `data.len()` must be multiples of 256 |
| 373 | /// | 378 | /// |
| 374 | /// If `use_boot2` is `true`, a copy of the 2nd stage boot loader | 379 | /// If `USE_BOOT2` is `true`, a copy of the 2nd stage boot loader |
| 375 | /// is used to re-initialize the XIP engine after flashing. | 380 | /// is used to re-initialize the XIP engine after flashing. |
| 376 | /// | 381 | /// |
| 377 | /// # Safety | 382 | /// # Safety |
| @@ -383,10 +388,10 @@ mod ram_helpers { | |||
| 383 | /// - DMA must not access flash memory | 388 | /// - DMA must not access flash memory |
| 384 | /// | 389 | /// |
| 385 | /// `addr` and `len` parameters must be valid and are not checked. | 390 | /// `addr` and `len` parameters must be valid and are not checked. |
| 386 | pub unsafe fn flash_range_program(addr: u32, data: &[u8], use_boot2: bool) { | 391 | pub unsafe fn flash_range_program(addr: u32, data: &[u8]) { |
| 387 | let mut boot2 = [0u32; 256 / 4]; | 392 | let mut boot2 = [0u32; 256 / 4]; |
| 388 | let ptrs = if use_boot2 { | 393 | let ptrs = if USE_BOOT2 { |
| 389 | rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256); | 394 | rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); |
| 390 | flash_function_pointers_with_boot2(false, true, &boot2) | 395 | flash_function_pointers_with_boot2(false, true, &boot2) |
| 391 | } else { | 396 | } else { |
| 392 | flash_function_pointers(false, true) | 397 | flash_function_pointers(false, true) |
| @@ -508,10 +513,10 @@ mod ram_helpers { | |||
| 508 | /// - DMA must not access flash memory | 513 | /// - DMA must not access flash memory |
| 509 | /// | 514 | /// |
| 510 | /// Credit: taken from `rp2040-flash` (also licensed Apache+MIT) | 515 | /// Credit: taken from `rp2040-flash` (also licensed Apache+MIT) |
| 511 | pub unsafe fn flash_unique_id(out: &mut [u8], use_boot2: bool) { | 516 | pub unsafe fn flash_unique_id(out: &mut [u8]) { |
| 512 | let mut boot2 = [0u32; 256 / 4]; | 517 | let mut boot2 = [0u32; 256 / 4]; |
| 513 | let ptrs = if use_boot2 { | 518 | let ptrs = if USE_BOOT2 { |
| 514 | rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256); | 519 | rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); |
| 515 | flash_function_pointers_with_boot2(false, false, &boot2) | 520 | flash_function_pointers_with_boot2(false, false, &boot2) |
| 516 | } else { | 521 | } else { |
| 517 | flash_function_pointers(false, false) | 522 | flash_function_pointers(false, false) |
| @@ -536,10 +541,10 @@ mod ram_helpers { | |||
| 536 | /// - DMA must not access flash memory | 541 | /// - DMA must not access flash memory |
| 537 | /// | 542 | /// |
| 538 | /// Credit: taken from `rp2040-flash` (also licensed Apache+MIT) | 543 | /// Credit: taken from `rp2040-flash` (also licensed Apache+MIT) |
| 539 | pub unsafe fn flash_jedec_id(use_boot2: bool) -> u32 { | 544 | pub unsafe fn flash_jedec_id() -> u32 { |
| 540 | let mut boot2 = [0u32; 256 / 4]; | 545 | let mut boot2 = [0u32; 256 / 4]; |
| 541 | let ptrs = if use_boot2 { | 546 | let ptrs = if USE_BOOT2 { |
| 542 | rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256); | 547 | rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256); |
| 543 | flash_function_pointers_with_boot2(false, false, &boot2) | 548 | flash_function_pointers_with_boot2(false, false, &boot2) |
| 544 | } else { | 549 | } else { |
| 545 | flash_function_pointers(false, false) | 550 | flash_function_pointers(false, false) |
| @@ -586,7 +591,6 @@ mod ram_helpers { | |||
| 586 | "ldr r4, [r5, #4]", | 591 | "ldr r4, [r5, #4]", |
| 587 | "blx r4", // flash_exit_xip() | 592 | "blx r4", // flash_exit_xip() |
| 588 | 593 | ||
| 589 | "mov r7, r10", // cmd | ||
| 590 | 594 | ||
| 591 | "movs r4, #0x18", | 595 | "movs r4, #0x18", |
| 592 | "lsls r4, r4, #24", // 0x18000000, SSI, RP2040 datasheet 4.10.13 | 596 | "lsls r4, r4, #24", // 0x18000000, SSI, RP2040 datasheet 4.10.13 |
| @@ -603,8 +607,9 @@ mod ram_helpers { | |||
| 603 | "str r1, [r4, #0]", | 607 | "str r1, [r4, #0]", |
| 604 | 608 | ||
| 605 | // Write ctrlr1 with len-1 | 609 | // Write ctrlr1 with len-1 |
| 606 | "ldr r0, [r7, #8]", // dummy_len | 610 | "mov r3, r10", // cmd |
| 607 | "ldr r1, [r7, #16]", // data_len | 611 | "ldr r0, [r3, #8]", // dummy_len |
| 612 | "ldr r1, [r3, #16]", // data_len | ||
| 608 | "add r0, r1", | 613 | "add r0, r1", |
| 609 | "subs r0, #1", | 614 | "subs r0, #1", |
| 610 | "str r0, [r4, #0x04]", // CTRLR1 | 615 | "str r0, [r4, #0x04]", // CTRLR1 |
| @@ -616,8 +621,8 @@ mod ram_helpers { | |||
| 616 | // Write cmd/addr phase to DR | 621 | // Write cmd/addr phase to DR |
| 617 | "mov r2, r4", | 622 | "mov r2, r4", |
| 618 | "adds r2, 0x60", // &DR | 623 | "adds r2, 0x60", // &DR |
| 619 | "ldr r0, [r7, #0]", // cmd_addr | 624 | "ldr r0, [r3, #0]", // cmd_addr |
| 620 | "ldr r1, [r7, #4]", // cmd_addr_len | 625 | "ldr r1, [r3, #4]", // cmd_addr_len |
| 621 | "10:", | 626 | "10:", |
| 622 | "ldrb r3, [r0]", | 627 | "ldrb r3, [r0]", |
| 623 | "strb r3, [r2]", // DR | 628 | "strb r3, [r2]", // DR |
| @@ -626,7 +631,8 @@ mod ram_helpers { | |||
| 626 | "bne 10b", | 631 | "bne 10b", |
| 627 | 632 | ||
| 628 | // Skip any dummy cycles | 633 | // Skip any dummy cycles |
| 629 | "ldr r1, [r7, #8]", // dummy_len | 634 | "mov r3, r10", // cmd |
| 635 | "ldr r1, [r3, #8]", // dummy_len | ||
| 630 | "cmp r1, #0", | 636 | "cmp r1, #0", |
| 631 | "beq 9f", | 637 | "beq 9f", |
| 632 | "4:", | 638 | "4:", |
| @@ -643,8 +649,9 @@ mod ram_helpers { | |||
| 643 | 649 | ||
| 644 | // Read RX fifo | 650 | // Read RX fifo |
| 645 | "9:", | 651 | "9:", |
| 646 | "ldr r0, [r7, #12]", // data | 652 | "mov r2, r10", // cmd |
| 647 | "ldr r1, [r7, #16]", // data_len | 653 | "ldr r0, [r2, #12]", // data |
| 654 | "ldr r1, [r2, #16]", // data_len | ||
| 648 | 655 | ||
| 649 | "2:", | 656 | "2:", |
| 650 | "ldr r3, [r4, #0x28]", // SR | 657 | "ldr r3, [r4, #0x28]", // SR |
| @@ -678,13 +685,12 @@ mod ram_helpers { | |||
| 678 | out("r2") _, | 685 | out("r2") _, |
| 679 | out("r3") _, | 686 | out("r3") _, |
| 680 | out("r4") _, | 687 | out("r4") _, |
| 688 | out("r5") _, | ||
| 681 | // Registers r8-r10 are used to store values | 689 | // Registers r8-r10 are used to store values |
| 682 | // from r0-r2 in registers not clobbered by | 690 | // from r0-r2 in registers not clobbered by |
| 683 | // function calls. | 691 | // function calls. |
| 684 | // The values can't be passed in using r8-r10 directly | 692 | // The values can't be passed in using r8-r10 directly |
| 685 | // due to https://github.com/rust-lang/rust/issues/99071 | 693 | // due to https://github.com/rust-lang/rust/issues/99071 |
| 686 | out("r8") _, | ||
| 687 | out("r9") _, | ||
| 688 | out("r10") _, | 694 | out("r10") _, |
| 689 | clobber_abi("C"), | 695 | clobber_abi("C"), |
| 690 | ); | 696 | ); |
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 1786baee3..6bcac373c 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -10,7 +10,7 @@ teleprobe-meta = "1" | |||
| 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] } | 12 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] } |
| 13 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics"] } | 13 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } |
| 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 14 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 15 | 15 | ||
| 16 | defmt = "0.3.0" | 16 | defmt = "0.3.0" |
