diff options
| author | Frostie314159 <[email protected]> | 2024-03-21 14:17:03 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-03-21 14:17:03 +0100 |
| commit | 7efe8e0005ca75c3753081848e8b176f8ac3a9ba (patch) | |
| tree | 3690b3b873b4643a07e29b60bf92596a819d30f0 /tests | |
| parent | 8707462ec23807782796fbac4295bc5bce9ff136 (diff) | |
| parent | 29d388042cdbd76d46f66ebe58cc580edb4515f8 (diff) | |
Merge branch 'embassy-rs:main' into reset-at-after
Diffstat (limited to 'tests')
50 files changed, 1282 insertions, 796 deletions
diff --git a/tests/stm32/link_ram.x b/tests/link_ram_cortex_m.x index 26da86baa..39a31b52a 100644 --- a/tests/stm32/link_ram.x +++ b/tests/link_ram_cortex_m.x | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* ##### EMBASSY NOTE | 1 | /* ##### EMBASSY NOTE |
| 2 | Originally from https://github.com/rust-embedded/cortex-m-rt/blob/master/link.x.in | 2 | Originally from https://github.com/rust-embedded/cortex-m/blob/master/cortex-m-rt/link.x.in |
| 3 | Adjusted to put everything in RAM | 3 | Adjusted to put everything in RAM |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| @@ -65,22 +65,30 @@ PROVIDE(__pre_init = DefaultPreInit); | |||
| 65 | /* # Sections */ | 65 | /* # Sections */ |
| 66 | SECTIONS | 66 | SECTIONS |
| 67 | { | 67 | { |
| 68 | PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM)); | 68 | PROVIDE(_ram_start = ORIGIN(RAM)); |
| 69 | PROVIDE(_ram_end = ORIGIN(RAM) + LENGTH(RAM)); | ||
| 70 | PROVIDE(_stack_start = _ram_end); | ||
| 69 | 71 | ||
| 70 | /* ## Sections in RAM */ | 72 | /* ## Sections in RAM */ |
| 71 | /* ### Vector table */ | 73 | /* ### Vector table */ |
| 72 | .vector_table ORIGIN(RAM) : | 74 | .vector_table ORIGIN(RAM) : |
| 73 | { | 75 | { |
| 74 | /* Initial Stack Pointer (SP) value */ | 76 | __vector_table = .; |
| 75 | LONG(_stack_start); | 77 | |
| 78 | /* Initial Stack Pointer (SP) value. | ||
| 79 | * We mask the bottom three bits to force 8-byte alignment. | ||
| 80 | * Despite having an assert for this later, it's possible that a separate | ||
| 81 | * linker script could override _stack_start after the assert is checked. | ||
| 82 | */ | ||
| 83 | LONG(_stack_start & 0xFFFFFFF8); | ||
| 76 | 84 | ||
| 77 | /* Reset vector */ | 85 | /* Reset vector */ |
| 78 | KEEP(*(.vector_table.reset_vector)); /* this is the `__RESET_VECTOR` symbol */ | 86 | KEEP(*(.vector_table.reset_vector)); /* this is the `__RESET_VECTOR` symbol */ |
| 79 | __reset_vector = .; | ||
| 80 | 87 | ||
| 81 | /* Exceptions */ | 88 | /* Exceptions */ |
| 89 | __exceptions = .; /* start of exceptions */ | ||
| 82 | KEEP(*(.vector_table.exceptions)); /* this is the `__EXCEPTIONS` symbol */ | 90 | KEEP(*(.vector_table.exceptions)); /* this is the `__EXCEPTIONS` symbol */ |
| 83 | __eexceptions = .; | 91 | __eexceptions = .; /* end of exceptions */ |
| 84 | 92 | ||
| 85 | /* Device specific interrupts */ | 93 | /* Device specific interrupts */ |
| 86 | KEEP(*(.vector_table.interrupts)); /* this is the `__INTERRUPTS` symbol */ | 94 | KEEP(*(.vector_table.interrupts)); /* this is the `__INTERRUPTS` symbol */ |
| @@ -125,14 +133,18 @@ SECTIONS | |||
| 125 | { | 133 | { |
| 126 | . = ALIGN(4); | 134 | . = ALIGN(4); |
| 127 | __sdata = .; | 135 | __sdata = .; |
| 128 | __edata = .; | 136 | __edata = .; /* RAM: By setting __sdata=__edata cortex-m-rt has to copy 0 bytes as .data is already in RAM */ |
| 137 | |||
| 129 | *(.data .data.*); | 138 | *(.data .data.*); |
| 130 | . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ | 139 | . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ |
| 131 | } > RAM | 140 | } > RAM |
| 132 | /* Allow sections from user `memory.x` injected using `INSERT AFTER .data` to | 141 | /* Allow sections from user `memory.x` injected using `INSERT AFTER .data` to |
| 133 | * use the .data loading mechanism by pushing __edata. Note: do not change | 142 | * use the .data loading mechanism by pushing __edata. Note: do not change |
| 134 | * output region or load region in those user sections! */ | 143 | * output region or load region in those user sections! */ |
| 144 | /* Link from RAM: Disabled, now __sdata == __edata | ||
| 135 | . = ALIGN(4); | 145 | . = ALIGN(4); |
| 146 | __edata = .; | ||
| 147 | */ | ||
| 136 | 148 | ||
| 137 | /* LMA of .data */ | 149 | /* LMA of .data */ |
| 138 | __sidata = LOADADDR(.data); | 150 | __sidata = LOADADDR(.data); |
| @@ -147,8 +159,12 @@ SECTIONS | |||
| 147 | __veneer_base = .; | 159 | __veneer_base = .; |
| 148 | *(.gnu.sgstubs*) | 160 | *(.gnu.sgstubs*) |
| 149 | . = ALIGN(32); | 161 | . = ALIGN(32); |
| 150 | __veneer_limit = .; | ||
| 151 | } > RAM | 162 | } > RAM |
| 163 | /* Place `__veneer_limit` outside the `.gnu.sgstubs` section because veneers are | ||
| 164 | * always inserted last in the section, which would otherwise be _after_ the `__veneer_limit` symbol. | ||
| 165 | */ | ||
| 166 | . = ALIGN(32); | ||
| 167 | __veneer_limit = .; | ||
| 152 | 168 | ||
| 153 | /* ### .bss */ | 169 | /* ### .bss */ |
| 154 | .bss (NOLOAD) : ALIGN(4) | 170 | .bss (NOLOAD) : ALIGN(4) |
| @@ -213,10 +229,21 @@ BUG(cortex-m-rt): .bss is not 4-byte aligned"); | |||
| 213 | ASSERT(__sheap % 4 == 0, " | 229 | ASSERT(__sheap % 4 == 0, " |
| 214 | BUG(cortex-m-rt): start of .heap is not 4-byte aligned"); | 230 | BUG(cortex-m-rt): start of .heap is not 4-byte aligned"); |
| 215 | 231 | ||
| 232 | ASSERT(_stack_start % 8 == 0, " | ||
| 233 | ERROR(cortex-m-rt): stack start address is not 8-byte aligned. | ||
| 234 | If you have set _stack_start, check it's set to an address which is a multiple of 8 bytes. | ||
| 235 | If you haven't, stack starts at the end of RAM by default. Check that both RAM | ||
| 236 | origin and length are set to multiples of 8 in the `memory.x` file."); | ||
| 237 | |||
| 216 | /* # Position checks */ | 238 | /* # Position checks */ |
| 217 | 239 | ||
| 218 | /* ## .vector_table */ | 240 | /* ## .vector_table |
| 219 | ASSERT(__reset_vector == ADDR(.vector_table) + 0x8, " | 241 | * |
| 242 | * If the *start* of exception vectors is not 8 bytes past the start of the | ||
| 243 | * vector table, then we somehow did not place the reset vector, which should | ||
| 244 | * live 4 bytes past the start of the vector table. | ||
| 245 | */ | ||
| 246 | ASSERT(__exceptions == ADDR(.vector_table) + 0x8, " | ||
| 220 | BUG(cortex-m-rt): the reset vector is missing"); | 247 | BUG(cortex-m-rt): the reset vector is missing"); |
| 221 | 248 | ||
| 222 | ASSERT(__eexceptions == ADDR(.vector_table) + 0x40, " | 249 | ASSERT(__eexceptions == ADDR(.vector_table) + 0x40, " |
| @@ -248,7 +275,6 @@ the 'cc' crate then modify your build script to compile the C code _without_ | |||
| 248 | the -fPIC flag. See the documentation of the `cc::Build.pic` method for details."); | 275 | the -fPIC flag. See the documentation of the `cc::Build.pic` method for details."); |
| 249 | /* Do not exceed this mark in the error messages above | */ | 276 | /* Do not exceed this mark in the error messages above | */ |
| 250 | 277 | ||
| 251 | |||
| 252 | /* Provides weak aliases (cf. PROVIDED) for device specific interrupt handlers */ | 278 | /* Provides weak aliases (cf. PROVIDED) for device specific interrupt handlers */ |
| 253 | /* This will usually be provided by a device crate generated using svd2rust (see `device.x`) */ | 279 | /* This will usually be provided by a device crate generated using svd2rust (see `device.x`) */ |
| 254 | INCLUDE device.x \ No newline at end of file | 280 | INCLUDE device.x |
diff --git a/tests/nrf/link_ram.x b/tests/nrf/link_ram.x deleted file mode 100644 index 26da86baa..000000000 --- a/tests/nrf/link_ram.x +++ /dev/null | |||
| @@ -1,254 +0,0 @@ | |||
| 1 | /* ##### EMBASSY NOTE | ||
| 2 | Originally from https://github.com/rust-embedded/cortex-m-rt/blob/master/link.x.in | ||
| 3 | Adjusted to put everything in RAM | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* # Developer notes | ||
| 7 | |||
| 8 | - Symbols that start with a double underscore (__) are considered "private" | ||
| 9 | |||
| 10 | - Symbols that start with a single underscore (_) are considered "semi-public"; they can be | ||
| 11 | overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" { | ||
| 12 | static mut __sbss }`). | ||
| 13 | |||
| 14 | - `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a | ||
| 15 | symbol if not dropped if it appears in or near the front of the linker arguments and "it's not | ||
| 16 | needed" by any of the preceding objects (linker arguments) | ||
| 17 | |||
| 18 | - `PROVIDE` is used to provide default values that can be overridden by a user linker script | ||
| 19 | |||
| 20 | - On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and* | ||
| 21 | the LMA of .data are all 4-byte aligned. These alignments are assumed by the RAM initialization | ||
| 22 | routine. There's also a second benefit: 4-byte aligned boundaries means that you won't see | ||
| 23 | "Address (..) is out of bounds" in the disassembly produced by `objdump`. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* Provides information about the memory layout of the device */ | ||
| 27 | /* This will be provided by the user (see `memory.x`) or by a Board Support Crate */ | ||
| 28 | INCLUDE memory.x | ||
| 29 | |||
| 30 | /* # Entry point = reset vector */ | ||
| 31 | EXTERN(__RESET_VECTOR); | ||
| 32 | EXTERN(Reset); | ||
| 33 | ENTRY(Reset); | ||
| 34 | |||
| 35 | /* # Exception vectors */ | ||
| 36 | /* This is effectively weak aliasing at the linker level */ | ||
| 37 | /* The user can override any of these aliases by defining the corresponding symbol themselves (cf. | ||
| 38 | the `exception!` macro) */ | ||
| 39 | EXTERN(__EXCEPTIONS); /* depends on all the these PROVIDED symbols */ | ||
| 40 | |||
| 41 | EXTERN(DefaultHandler); | ||
| 42 | |||
| 43 | PROVIDE(NonMaskableInt = DefaultHandler); | ||
| 44 | EXTERN(HardFaultTrampoline); | ||
| 45 | PROVIDE(MemoryManagement = DefaultHandler); | ||
| 46 | PROVIDE(BusFault = DefaultHandler); | ||
| 47 | PROVIDE(UsageFault = DefaultHandler); | ||
| 48 | PROVIDE(SecureFault = DefaultHandler); | ||
| 49 | PROVIDE(SVCall = DefaultHandler); | ||
| 50 | PROVIDE(DebugMonitor = DefaultHandler); | ||
| 51 | PROVIDE(PendSV = DefaultHandler); | ||
| 52 | PROVIDE(SysTick = DefaultHandler); | ||
| 53 | |||
| 54 | PROVIDE(DefaultHandler = DefaultHandler_); | ||
| 55 | PROVIDE(HardFault = HardFault_); | ||
| 56 | |||
| 57 | /* # Interrupt vectors */ | ||
| 58 | EXTERN(__INTERRUPTS); /* `static` variable similar to `__EXCEPTIONS` */ | ||
| 59 | |||
| 60 | /* # Pre-initialization function */ | ||
| 61 | /* If the user overrides this using the `pre_init!` macro or by creating a `__pre_init` function, | ||
| 62 | then the function this points to will be called before the RAM is initialized. */ | ||
| 63 | PROVIDE(__pre_init = DefaultPreInit); | ||
| 64 | |||
| 65 | /* # Sections */ | ||
| 66 | SECTIONS | ||
| 67 | { | ||
| 68 | PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM)); | ||
| 69 | |||
| 70 | /* ## Sections in RAM */ | ||
| 71 | /* ### Vector table */ | ||
| 72 | .vector_table ORIGIN(RAM) : | ||
| 73 | { | ||
| 74 | /* Initial Stack Pointer (SP) value */ | ||
| 75 | LONG(_stack_start); | ||
| 76 | |||
| 77 | /* Reset vector */ | ||
| 78 | KEEP(*(.vector_table.reset_vector)); /* this is the `__RESET_VECTOR` symbol */ | ||
| 79 | __reset_vector = .; | ||
| 80 | |||
| 81 | /* Exceptions */ | ||
| 82 | KEEP(*(.vector_table.exceptions)); /* this is the `__EXCEPTIONS` symbol */ | ||
| 83 | __eexceptions = .; | ||
| 84 | |||
| 85 | /* Device specific interrupts */ | ||
| 86 | KEEP(*(.vector_table.interrupts)); /* this is the `__INTERRUPTS` symbol */ | ||
| 87 | } > RAM | ||
| 88 | |||
| 89 | PROVIDE(_stext = ADDR(.vector_table) + SIZEOF(.vector_table)); | ||
| 90 | |||
| 91 | /* ### .text */ | ||
| 92 | .text _stext : | ||
| 93 | { | ||
| 94 | __stext = .; | ||
| 95 | *(.Reset); | ||
| 96 | |||
| 97 | *(.text .text.*); | ||
| 98 | |||
| 99 | /* The HardFaultTrampoline uses the `b` instruction to enter `HardFault`, | ||
| 100 | so must be placed close to it. */ | ||
| 101 | *(.HardFaultTrampoline); | ||
| 102 | *(.HardFault.*); | ||
| 103 | |||
| 104 | . = ALIGN(4); /* Pad .text to the alignment to workaround overlapping load section bug in old lld */ | ||
| 105 | __etext = .; | ||
| 106 | } > RAM | ||
| 107 | |||
| 108 | /* ### .rodata */ | ||
| 109 | .rodata : ALIGN(4) | ||
| 110 | { | ||
| 111 | . = ALIGN(4); | ||
| 112 | __srodata = .; | ||
| 113 | *(.rodata .rodata.*); | ||
| 114 | |||
| 115 | /* 4-byte align the end (VMA) of this section. | ||
| 116 | This is required by LLD to ensure the LMA of the following .data | ||
| 117 | section will have the correct alignment. */ | ||
| 118 | . = ALIGN(4); | ||
| 119 | __erodata = .; | ||
| 120 | } > RAM | ||
| 121 | |||
| 122 | /* ## Sections in RAM */ | ||
| 123 | /* ### .data */ | ||
| 124 | .data : ALIGN(4) | ||
| 125 | { | ||
| 126 | . = ALIGN(4); | ||
| 127 | __sdata = .; | ||
| 128 | __edata = .; | ||
| 129 | *(.data .data.*); | ||
| 130 | . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ | ||
| 131 | } > RAM | ||
| 132 | /* Allow sections from user `memory.x` injected using `INSERT AFTER .data` to | ||
| 133 | * use the .data loading mechanism by pushing __edata. Note: do not change | ||
| 134 | * output region or load region in those user sections! */ | ||
| 135 | . = ALIGN(4); | ||
| 136 | |||
| 137 | /* LMA of .data */ | ||
| 138 | __sidata = LOADADDR(.data); | ||
| 139 | |||
| 140 | /* ### .gnu.sgstubs | ||
| 141 | This section contains the TrustZone-M veneers put there by the Arm GNU linker. */ | ||
| 142 | /* Security Attribution Unit blocks must be 32 bytes aligned. */ | ||
| 143 | /* Note that this pads the RAM usage to 32 byte alignment. */ | ||
| 144 | .gnu.sgstubs : ALIGN(32) | ||
| 145 | { | ||
| 146 | . = ALIGN(32); | ||
| 147 | __veneer_base = .; | ||
| 148 | *(.gnu.sgstubs*) | ||
| 149 | . = ALIGN(32); | ||
| 150 | __veneer_limit = .; | ||
| 151 | } > RAM | ||
| 152 | |||
| 153 | /* ### .bss */ | ||
| 154 | .bss (NOLOAD) : ALIGN(4) | ||
| 155 | { | ||
| 156 | . = ALIGN(4); | ||
| 157 | __sbss = .; | ||
| 158 | *(.bss .bss.*); | ||
| 159 | *(COMMON); /* Uninitialized C statics */ | ||
| 160 | . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ | ||
| 161 | } > RAM | ||
| 162 | /* Allow sections from user `memory.x` injected using `INSERT AFTER .bss` to | ||
| 163 | * use the .bss zeroing mechanism by pushing __ebss. Note: do not change | ||
| 164 | * output region or load region in those user sections! */ | ||
| 165 | . = ALIGN(4); | ||
| 166 | __ebss = .; | ||
| 167 | |||
| 168 | /* ### .uninit */ | ||
| 169 | .uninit (NOLOAD) : ALIGN(4) | ||
| 170 | { | ||
| 171 | . = ALIGN(4); | ||
| 172 | __suninit = .; | ||
| 173 | *(.uninit .uninit.*); | ||
| 174 | . = ALIGN(4); | ||
| 175 | __euninit = .; | ||
| 176 | } > RAM | ||
| 177 | |||
| 178 | /* Place the heap right after `.uninit` in RAM */ | ||
| 179 | PROVIDE(__sheap = __euninit); | ||
| 180 | |||
| 181 | /* ## .got */ | ||
| 182 | /* Dynamic relocations are unsupported. This section is only used to detect relocatable code in | ||
| 183 | the input files and raise an error if relocatable code is found */ | ||
| 184 | .got (NOLOAD) : | ||
| 185 | { | ||
| 186 | KEEP(*(.got .got.*)); | ||
| 187 | } | ||
| 188 | |||
| 189 | /* ## Discarded sections */ | ||
| 190 | /DISCARD/ : | ||
| 191 | { | ||
| 192 | /* Unused exception related info that only wastes space */ | ||
| 193 | *(.ARM.exidx); | ||
| 194 | *(.ARM.exidx.*); | ||
| 195 | *(.ARM.extab.*); | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | /* Do not exceed this mark in the error messages below | */ | ||
| 200 | /* # Alignment checks */ | ||
| 201 | ASSERT(ORIGIN(RAM) % 4 == 0, " | ||
| 202 | ERROR(cortex-m-rt): the start of the RAM region must be 4-byte aligned"); | ||
| 203 | |||
| 204 | ASSERT(__sdata % 4 == 0 && __edata % 4 == 0, " | ||
| 205 | BUG(cortex-m-rt): .data is not 4-byte aligned"); | ||
| 206 | |||
| 207 | ASSERT(__sidata % 4 == 0, " | ||
| 208 | BUG(cortex-m-rt): the LMA of .data is not 4-byte aligned"); | ||
| 209 | |||
| 210 | ASSERT(__sbss % 4 == 0 && __ebss % 4 == 0, " | ||
| 211 | BUG(cortex-m-rt): .bss is not 4-byte aligned"); | ||
| 212 | |||
| 213 | ASSERT(__sheap % 4 == 0, " | ||
| 214 | BUG(cortex-m-rt): start of .heap is not 4-byte aligned"); | ||
| 215 | |||
| 216 | /* # Position checks */ | ||
| 217 | |||
| 218 | /* ## .vector_table */ | ||
| 219 | ASSERT(__reset_vector == ADDR(.vector_table) + 0x8, " | ||
| 220 | BUG(cortex-m-rt): the reset vector is missing"); | ||
| 221 | |||
| 222 | ASSERT(__eexceptions == ADDR(.vector_table) + 0x40, " | ||
| 223 | BUG(cortex-m-rt): the exception vectors are missing"); | ||
| 224 | |||
| 225 | ASSERT(SIZEOF(.vector_table) > 0x40, " | ||
| 226 | ERROR(cortex-m-rt): The interrupt vectors are missing. | ||
| 227 | Possible solutions, from most likely to less likely: | ||
| 228 | - Link to a svd2rust generated device crate | ||
| 229 | - Check that you actually use the device/hal/bsp crate in your code | ||
| 230 | - Disable the 'device' feature of cortex-m-rt to build a generic application (a dependency | ||
| 231 | may be enabling it) | ||
| 232 | - Supply the interrupt handlers yourself. Check the documentation for details."); | ||
| 233 | |||
| 234 | /* ## .text */ | ||
| 235 | ASSERT(ADDR(.vector_table) + SIZEOF(.vector_table) <= _stext, " | ||
| 236 | ERROR(cortex-m-rt): The .text section can't be placed inside the .vector_table section | ||
| 237 | Set _stext to an address greater than the end of .vector_table (See output of `nm`)"); | ||
| 238 | |||
| 239 | ASSERT(_stext + SIZEOF(.text) < ORIGIN(RAM) + LENGTH(RAM), " | ||
| 240 | ERROR(cortex-m-rt): The .text section must be placed inside the RAM memory. | ||
| 241 | Set _stext to an address smaller than 'ORIGIN(RAM) + LENGTH(RAM)'"); | ||
| 242 | |||
| 243 | /* # Other checks */ | ||
| 244 | ASSERT(SIZEOF(.got) == 0, " | ||
| 245 | ERROR(cortex-m-rt): .got section detected in the input object files | ||
| 246 | Dynamic relocations are not supported. If you are linking to C code compiled using | ||
| 247 | the 'cc' crate then modify your build script to compile the C code _without_ | ||
| 248 | the -fPIC flag. See the documentation of the `cc::Build.pic` method for details."); | ||
| 249 | /* Do not exceed this mark in the error messages above | */ | ||
| 250 | |||
| 251 | |||
| 252 | /* Provides weak aliases (cf. PROVIDED) for device specific interrupt handlers */ | ||
| 253 | /* This will usually be provided by a device crate generated using svd2rust (see `device.x`) */ | ||
| 254 | INCLUDE device.x \ No newline at end of file | ||
diff --git a/tests/nrf/src/bin/buffered_uart.rs b/tests/nrf/src/bin/buffered_uart.rs deleted file mode 100644 index 354d787b4..000000000 --- a/tests/nrf/src/bin/buffered_uart.rs +++ /dev/null | |||
| @@ -1,78 +0,0 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | ||
| 4 | |||
| 5 | use defmt::{assert_eq, *}; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_futures::join::join; | ||
| 8 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | ||
| 9 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let p = embassy_nrf::init(Default::default()); | ||
| 19 | let mut config = uarte::Config::default(); | ||
| 20 | config.parity = uarte::Parity::EXCLUDED; | ||
| 21 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 22 | |||
| 23 | let mut tx_buffer = [0u8; 1024]; | ||
| 24 | let mut rx_buffer = [0u8; 1024]; | ||
| 25 | |||
| 26 | let mut u = BufferedUarte::new( | ||
| 27 | p.UARTE0, | ||
| 28 | p.TIMER0, | ||
| 29 | p.PPI_CH0, | ||
| 30 | p.PPI_CH1, | ||
| 31 | p.PPI_GROUP0, | ||
| 32 | Irqs, | ||
| 33 | p.P1_03, | ||
| 34 | p.P1_02, | ||
| 35 | config.clone(), | ||
| 36 | &mut rx_buffer, | ||
| 37 | &mut tx_buffer, | ||
| 38 | ); | ||
| 39 | |||
| 40 | info!("uarte initialized!"); | ||
| 41 | |||
| 42 | let (mut rx, mut tx) = u.split(); | ||
| 43 | |||
| 44 | const COUNT: usize = 40_000; | ||
| 45 | |||
| 46 | let tx_fut = async { | ||
| 47 | let mut tx_buf = [0; 215]; | ||
| 48 | let mut i = 0; | ||
| 49 | while i < COUNT { | ||
| 50 | let n = tx_buf.len().min(COUNT - i); | ||
| 51 | let tx_buf = &mut tx_buf[..n]; | ||
| 52 | for (j, b) in tx_buf.iter_mut().enumerate() { | ||
| 53 | *b = (i + j) as u8; | ||
| 54 | } | ||
| 55 | let n = unwrap!(tx.write(tx_buf).await); | ||
| 56 | i += n; | ||
| 57 | } | ||
| 58 | }; | ||
| 59 | let rx_fut = async { | ||
| 60 | let mut i = 0; | ||
| 61 | while i < COUNT { | ||
| 62 | let buf = unwrap!(rx.fill_buf().await); | ||
| 63 | |||
| 64 | for &b in buf { | ||
| 65 | assert_eq!(b, i as u8); | ||
| 66 | i = i + 1; | ||
| 67 | } | ||
| 68 | |||
| 69 | let n = buf.len(); | ||
| 70 | rx.consume(n); | ||
| 71 | } | ||
| 72 | }; | ||
| 73 | |||
| 74 | join(rx_fut, tx_fut).await; | ||
| 75 | |||
| 76 | info!("Test OK"); | ||
| 77 | cortex_m::asm::bkpt(); | ||
| 78 | } | ||
diff --git a/tests/nrf51422/.cargo/config.toml b/tests/nrf51422/.cargo/config.toml new file mode 100644 index 000000000..634805633 --- /dev/null +++ b/tests/nrf51422/.cargo/config.toml | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | ||
| 2 | #runner = "teleprobe local run --chip nRF51422_xxAA --elf" | ||
| 3 | runner = "teleprobe client run" | ||
| 4 | |||
| 5 | [build] | ||
| 6 | target = "thumbv6m-none-eabi" | ||
| 7 | |||
| 8 | [env] | ||
| 9 | DEFMT_LOG = "trace,embassy_hal_internal=debug" | ||
diff --git a/tests/nrf51422/Cargo.toml b/tests/nrf51422/Cargo.toml new file mode 100644 index 000000000..07236987b --- /dev/null +++ b/tests/nrf51422/Cargo.toml | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | [package] | ||
| 2 | edition = "2021" | ||
| 3 | name = "embassy-nrf51-tests" | ||
| 4 | version = "0.1.0" | ||
| 5 | license = "MIT OR Apache-2.0" | ||
| 6 | |||
| 7 | [dependencies] | ||
| 8 | teleprobe-meta = "1" | ||
| 9 | |||
| 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||
| 11 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt", ] } | ||
| 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-128", "integrated-timers"] } | ||
| 13 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||
| 14 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf51", "time-driver-rtc1", "unstable-pac", "time", "gpiote"] } | ||
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | ||
| 16 | embedded-hal-async = { version = "1.0" } | ||
| 17 | |||
| 18 | defmt = "0.3" | ||
| 19 | defmt-rtt = "0.4" | ||
| 20 | |||
| 21 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | ||
| 22 | cortex-m-rt = "0.7.0" | ||
| 23 | panic-probe = { version = "0.3", features = ["print-defmt"] } | ||
diff --git a/tests/nrf51422/build.rs b/tests/nrf51422/build.rs new file mode 100644 index 000000000..13ebbe4ee --- /dev/null +++ b/tests/nrf51422/build.rs | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | use std::error::Error; | ||
| 2 | use std::path::PathBuf; | ||
| 3 | use std::{env, fs}; | ||
| 4 | |||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | ||
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | ||
| 7 | fs::write(out.join("memory.x"), include_bytes!("memory.x")).unwrap(); | ||
| 8 | println!("cargo:rustc-link-search={}", out.display()); | ||
| 9 | println!("cargo:rerun-if-changed=memory.x"); | ||
| 10 | |||
| 11 | println!("cargo:rustc-link-arg-bins=--nmagic"); | ||
| 12 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | ||
| 13 | println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); | ||
| 14 | println!("cargo:rustc-link-arg-bins=-Tteleprobe.x"); | ||
| 15 | |||
| 16 | Ok(()) | ||
| 17 | } | ||
diff --git a/tests/nrf51422/memory.x b/tests/nrf51422/memory.x new file mode 100644 index 000000000..a5881e66f --- /dev/null +++ b/tests/nrf51422/memory.x | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | MEMORY | ||
| 2 | { | ||
| 3 | FLASH : ORIGIN = 0x00000000, LENGTH = 128K | ||
| 4 | RAM : ORIGIN = 0x20000000, LENGTH = 16K | ||
| 5 | } | ||
diff --git a/tests/nrf51422/src/bin/gpio.rs b/tests/nrf51422/src/bin/gpio.rs new file mode 100644 index 000000000..6d5a87d0a --- /dev/null +++ b/tests/nrf51422/src/bin/gpio.rs | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | teleprobe_meta::target!(b"nrf51-dk"); | ||
| 4 | |||
| 5 | use defmt::{assert, info}; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | ||
| 8 | use embassy_time::Timer; | ||
| 9 | use {defmt_rtt as _, panic_probe as _}; | ||
| 10 | |||
| 11 | #[embassy_executor::main] | ||
| 12 | async fn main(_spawner: Spawner) { | ||
| 13 | let p = embassy_nrf::init(Default::default()); | ||
| 14 | |||
| 15 | let input = Input::new(p.P0_13, Pull::Up); | ||
| 16 | let mut output = Output::new(p.P0_14, Level::Low, OutputDrive::Standard); | ||
| 17 | |||
| 18 | output.set_low(); | ||
| 19 | Timer::after_millis(10).await; | ||
| 20 | assert!(input.is_low()); | ||
| 21 | |||
| 22 | output.set_high(); | ||
| 23 | Timer::after_millis(10).await; | ||
| 24 | assert!(input.is_high()); | ||
| 25 | |||
| 26 | info!("Test OK"); | ||
| 27 | cortex_m::asm::bkpt(); | ||
| 28 | } | ||
diff --git a/tests/nrf51422/src/bin/gpiote.rs b/tests/nrf51422/src/bin/gpiote.rs new file mode 100644 index 000000000..330fe993e --- /dev/null +++ b/tests/nrf51422/src/bin/gpiote.rs | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | teleprobe_meta::target!(b"nrf51-dk"); | ||
| 4 | |||
| 5 | use defmt::{assert, info}; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_futures::join::join; | ||
| 8 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; | ||
| 9 | use embassy_time::{Duration, Instant, Timer}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | #[embassy_executor::main] | ||
| 13 | async fn main(_spawner: Spawner) { | ||
| 14 | let p = embassy_nrf::init(Default::default()); | ||
| 15 | |||
| 16 | let mut input = Input::new(p.P0_13, Pull::Up); | ||
| 17 | let mut output = Output::new(p.P0_14, Level::Low, OutputDrive::Standard); | ||
| 18 | |||
| 19 | let fut1 = async { | ||
| 20 | Timer::after_millis(100).await; | ||
| 21 | output.set_high(); | ||
| 22 | }; | ||
| 23 | let fut2 = async { | ||
| 24 | let start = Instant::now(); | ||
| 25 | input.wait_for_high().await; | ||
| 26 | let dur = Instant::now() - start; | ||
| 27 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); | ||
| 28 | }; | ||
| 29 | |||
| 30 | join(fut1, fut2).await; | ||
| 31 | |||
| 32 | let fut1 = async { | ||
| 33 | Timer::after_millis(100).await; | ||
| 34 | output.set_low(); | ||
| 35 | }; | ||
| 36 | let fut2 = async { | ||
| 37 | let start = Instant::now(); | ||
| 38 | input.wait_for_low().await; | ||
| 39 | let dur = Instant::now() - start; | ||
| 40 | assert!((Duration::from_millis(90)..Duration::from_millis(110)).contains(&dur)); | ||
| 41 | }; | ||
| 42 | |||
| 43 | join(fut1, fut2).await; | ||
| 44 | |||
| 45 | info!("Test OK"); | ||
| 46 | cortex_m::asm::bkpt(); | ||
| 47 | } | ||
diff --git a/tests/nrf51422/src/bin/timer.rs b/tests/nrf51422/src/bin/timer.rs new file mode 100644 index 000000000..cf9ea41a8 --- /dev/null +++ b/tests/nrf51422/src/bin/timer.rs | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | teleprobe_meta::target!(b"nrf51-dk"); | ||
| 4 | |||
| 5 | use defmt::{assert, info}; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_time::{Instant, Timer}; | ||
| 8 | use {defmt_rtt as _, panic_probe as _}; | ||
| 9 | |||
| 10 | #[embassy_executor::main] | ||
| 11 | async fn main(_spawner: Spawner) { | ||
| 12 | let _p = embassy_nrf::init(Default::default()); | ||
| 13 | info!("Hello World!"); | ||
| 14 | |||
| 15 | let start = Instant::now(); | ||
| 16 | Timer::after_millis(100).await; | ||
| 17 | let end = Instant::now(); | ||
| 18 | let ms = (end - start).as_millis(); | ||
| 19 | info!("slept for {} ms", ms); | ||
| 20 | assert!(ms >= 99); | ||
| 21 | |||
| 22 | info!("Test OK"); | ||
| 23 | cortex_m::asm::bkpt(); | ||
| 24 | } | ||
diff --git a/tests/nrf/.cargo/config.toml b/tests/nrf52840/.cargo/config.toml index 9d6b0313a..9d6b0313a 100644 --- a/tests/nrf/.cargo/config.toml +++ b/tests/nrf52840/.cargo/config.toml | |||
diff --git a/tests/nrf/Cargo.toml b/tests/nrf52840/Cargo.toml index 7b0d59ee2..84ca99f1f 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf52840/Cargo.toml | |||
| @@ -9,16 +9,16 @@ teleprobe-meta = "1" | |||
| 9 | 9 | ||
| 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 10 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 11 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt", ] } | 11 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt", ] } |
| 12 | embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-16384", "integrated-timers"] } | 12 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "task-arena-size-16384", "integrated-timers"] } |
| 13 | embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 13 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 14 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } | 14 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } |
| 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } | 15 | embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } |
| 16 | embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } | 16 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", ] } |
| 17 | embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } | 17 | embassy-net-esp-hosted = { version = "0.1.0", path = "../../embassy-net-esp-hosted", features = ["defmt"] } |
| 18 | embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } | 18 | embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60", features = ["defmt"] } |
| 19 | embedded-hal-async = { version = "1.0.0-rc.2" } | 19 | embedded-hal-async = { version = "1.0" } |
| 20 | embedded-hal-bus = { version = "0.1.0-rc.2", features = ["async"] } | 20 | embedded-hal-bus = { version = "0.1", features = ["async"] } |
| 21 | static_cell = { version = "2", features = [ "nightly" ] } | 21 | static_cell = "2" |
| 22 | perf-client = { path = "../perf-client" } | 22 | perf-client = { path = "../perf-client" } |
| 23 | 23 | ||
| 24 | defmt = "0.3" | 24 | defmt = "0.3" |
diff --git a/tests/nrf/build.rs b/tests/nrf52840/build.rs index 93e2a28cf..71c82a70f 100644 --- a/tests/nrf/build.rs +++ b/tests/nrf52840/build.rs | |||
| @@ -4,7 +4,7 @@ use std::{env, fs}; | |||
| 4 | 4 | ||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | 5 | fn main() -> Result<(), Box<dyn Error>> { |
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| 7 | fs::write(out.join("link_ram.x"), include_bytes!("link_ram.x")).unwrap(); | 7 | fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap(); |
| 8 | println!("cargo:rustc-link-search={}", out.display()); | 8 | println!("cargo:rustc-link-search={}", out.display()); |
| 9 | println!("cargo:rerun-if-changed=link_ram.x"); | 9 | println!("cargo:rerun-if-changed=link_ram.x"); |
| 10 | 10 | ||
diff --git a/tests/nrf/memory.x b/tests/nrf52840/memory.x index 58900a7bd..58900a7bd 100644 --- a/tests/nrf/memory.x +++ b/tests/nrf52840/memory.x | |||
diff --git a/tests/nrf52840/src/bin/buffered_uart.rs b/tests/nrf52840/src/bin/buffered_uart.rs new file mode 100644 index 000000000..a01d66d85 --- /dev/null +++ b/tests/nrf52840/src/bin/buffered_uart.rs | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | ||
| 4 | |||
| 5 | use defmt::{assert_eq, *}; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_futures::join::join; | ||
| 8 | use embassy_nrf::buffered_uarte::{self, BufferedUarte}; | ||
| 9 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 14 | }); | ||
| 15 | |||
| 16 | #[embassy_executor::main] | ||
| 17 | async fn main(_spawner: Spawner) { | ||
| 18 | let mut p = embassy_nrf::init(Default::default()); | ||
| 19 | let mut config = uarte::Config::default(); | ||
| 20 | config.parity = uarte::Parity::EXCLUDED; | ||
| 21 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 22 | |||
| 23 | let mut tx_buffer = [0u8; 1024]; | ||
| 24 | let mut rx_buffer = [0u8; 1024]; | ||
| 25 | |||
| 26 | // test teardown + recreate of the buffereduarte works fine. | ||
| 27 | for _ in 0..2 { | ||
| 28 | let u = BufferedUarte::new( | ||
| 29 | &mut p.UARTE0, | ||
| 30 | &mut p.TIMER0, | ||
| 31 | &mut p.PPI_CH0, | ||
| 32 | &mut p.PPI_CH1, | ||
| 33 | &mut p.PPI_GROUP0, | ||
| 34 | Irqs, | ||
| 35 | &mut p.P1_03, | ||
| 36 | &mut p.P1_02, | ||
| 37 | config.clone(), | ||
| 38 | &mut rx_buffer, | ||
| 39 | &mut tx_buffer, | ||
| 40 | ); | ||
| 41 | |||
| 42 | info!("uarte initialized!"); | ||
| 43 | |||
| 44 | let (mut rx, mut tx) = u.split(); | ||
| 45 | |||
| 46 | const COUNT: usize = 40_000; | ||
| 47 | |||
| 48 | let tx_fut = async { | ||
| 49 | let mut tx_buf = [0; 215]; | ||
| 50 | let mut i = 0; | ||
| 51 | while i < COUNT { | ||
| 52 | let n = tx_buf.len().min(COUNT - i); | ||
| 53 | let tx_buf = &mut tx_buf[..n]; | ||
| 54 | for (j, b) in tx_buf.iter_mut().enumerate() { | ||
| 55 | *b = (i + j) as u8; | ||
| 56 | } | ||
| 57 | let n = unwrap!(tx.write(tx_buf).await); | ||
| 58 | i += n; | ||
| 59 | } | ||
| 60 | }; | ||
| 61 | let rx_fut = async { | ||
| 62 | let mut i = 0; | ||
| 63 | while i < COUNT { | ||
| 64 | let buf = unwrap!(rx.fill_buf().await); | ||
| 65 | |||
| 66 | for &b in buf { | ||
| 67 | assert_eq!(b, i as u8); | ||
| 68 | i = i + 1; | ||
| 69 | } | ||
| 70 | |||
| 71 | let n = buf.len(); | ||
| 72 | rx.consume(n); | ||
| 73 | } | ||
| 74 | }; | ||
| 75 | |||
| 76 | join(rx_fut, tx_fut).await; | ||
| 77 | } | ||
| 78 | |||
| 79 | info!("Test OK"); | ||
| 80 | cortex_m::asm::bkpt(); | ||
| 81 | } | ||
diff --git a/tests/nrf/src/bin/buffered_uart_full.rs b/tests/nrf52840/src/bin/buffered_uart_full.rs index e59c75ba9..62edaed25 100644 --- a/tests/nrf/src/bin/buffered_uart_full.rs +++ b/tests/nrf52840/src/bin/buffered_uart_full.rs | |||
| @@ -23,7 +23,7 @@ async fn main(_spawner: Spawner) { | |||
| 23 | let mut tx_buffer = [0u8; 1024]; | 23 | let mut tx_buffer = [0u8; 1024]; |
| 24 | let mut rx_buffer = [0u8; 1024]; | 24 | let mut rx_buffer = [0u8; 1024]; |
| 25 | 25 | ||
| 26 | let mut u = BufferedUarte::new( | 26 | let u = BufferedUarte::new( |
| 27 | p.UARTE0, | 27 | p.UARTE0, |
| 28 | p.TIMER0, | 28 | p.TIMER0, |
| 29 | p.PPI_CH0, | 29 | p.PPI_CH0, |
diff --git a/tests/nrf52840/src/bin/buffered_uart_halves.rs b/tests/nrf52840/src/bin/buffered_uart_halves.rs new file mode 100644 index 000000000..54a9fef5b --- /dev/null +++ b/tests/nrf52840/src/bin/buffered_uart_halves.rs | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | teleprobe_meta::target!(b"nrf52840-dk"); | ||
| 4 | |||
| 5 | use defmt::{assert_eq, *}; | ||
| 6 | use embassy_executor::Spawner; | ||
| 7 | use embassy_futures::join::join; | ||
| 8 | use embassy_nrf::buffered_uarte::{self, BufferedUarteRx, BufferedUarteTx}; | ||
| 9 | use embassy_nrf::{bind_interrupts, peripherals, uarte}; | ||
| 10 | use {defmt_rtt as _, panic_probe as _}; | ||
| 11 | |||
| 12 | bind_interrupts!(struct Irqs { | ||
| 13 | UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>; | ||
| 14 | UARTE1 => buffered_uarte::InterruptHandler<peripherals::UARTE1>; | ||
| 15 | }); | ||
| 16 | |||
| 17 | #[embassy_executor::main] | ||
| 18 | async fn main(_spawner: Spawner) { | ||
| 19 | let mut p = embassy_nrf::init(Default::default()); | ||
| 20 | let mut config = uarte::Config::default(); | ||
| 21 | config.parity = uarte::Parity::EXCLUDED; | ||
| 22 | config.baudrate = uarte::Baudrate::BAUD1M; | ||
| 23 | |||
| 24 | let mut tx_buffer = [0u8; 1024]; | ||
| 25 | let mut rx_buffer = [0u8; 1024]; | ||
| 26 | |||
| 27 | // test teardown + recreate of the buffereduarte works fine. | ||
| 28 | for _ in 0..2 { | ||
| 29 | const COUNT: usize = 40_000; | ||
| 30 | |||
| 31 | let mut tx = BufferedUarteTx::new(&mut p.UARTE1, Irqs, &mut p.P1_02, config.clone(), &mut tx_buffer); | ||
| 32 | |||
| 33 | let mut rx = BufferedUarteRx::new( | ||
| 34 | &mut p.UARTE0, | ||
| 35 | &mut p.TIMER0, | ||
| 36 | &mut p.PPI_CH0, | ||
| 37 | &mut p.PPI_CH1, | ||
| 38 | &mut p.PPI_GROUP0, | ||
| 39 | Irqs, | ||
| 40 | &mut p.P1_03, | ||
| 41 | config.clone(), | ||
| 42 | &mut rx_buffer, | ||
| 43 | ); | ||
| 44 | |||
| 45 | let tx_fut = async { | ||
| 46 | info!("tx initialized!"); | ||
| 47 | |||
| 48 | let mut tx_buf = [0; 215]; | ||
| 49 | let mut i = 0; | ||
| 50 | while i < COUNT { | ||
| 51 | let n = tx_buf.len().min(COUNT - i); | ||
| 52 | let tx_buf = &mut tx_buf[..n]; | ||
| 53 | for (j, b) in tx_buf.iter_mut().enumerate() { | ||
| 54 | *b = (i + j) as u8; | ||
| 55 | } | ||
| 56 | let n = unwrap!(tx.write(tx_buf).await); | ||
| 57 | i += n; | ||
| 58 | } | ||
| 59 | }; | ||
| 60 | let rx_fut = async { | ||
| 61 | info!("rx initialized!"); | ||
| 62 | |||
| 63 | let mut i = 0; | ||
| 64 | while i < COUNT { | ||
| 65 | let buf = unwrap!(rx.fill_buf().await); | ||
| 66 | |||
| 67 | for &b in buf { | ||
| 68 | assert_eq!(b, i as u8); | ||
| 69 | i = i + 1; | ||
| 70 | } | ||
| 71 | |||
| 72 | let n = buf.len(); | ||
| 73 | rx.consume(n); | ||
| 74 | } | ||
| 75 | }; | ||
| 76 | |||
| 77 | join(rx_fut, tx_fut).await; | ||
| 78 | } | ||
| 79 | |||
| 80 | info!("Test OK"); | ||
| 81 | cortex_m::asm::bkpt(); | ||
| 82 | } | ||
diff --git a/tests/nrf/src/bin/buffered_uart_spam.rs b/tests/nrf52840/src/bin/buffered_uart_spam.rs index 400c0df99..400c0df99 100644 --- a/tests/nrf/src/bin/buffered_uart_spam.rs +++ b/tests/nrf52840/src/bin/buffered_uart_spam.rs | |||
diff --git a/tests/nrf/src/bin/ethernet_enc28j60_perf.rs b/tests/nrf52840/src/bin/ethernet_enc28j60_perf.rs index 60d30a2ff..33c2f4235 100644 --- a/tests/nrf/src/bin/ethernet_enc28j60_perf.rs +++ b/tests/nrf52840/src/bin/ethernet_enc28j60_perf.rs | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | teleprobe_meta::target!(b"ak-gwe-r7"); | 3 | teleprobe_meta::target!(b"ak-gwe-r7"); |
| 5 | teleprobe_meta::timeout!(120); | 4 | teleprobe_meta::timeout!(120); |
| 6 | 5 | ||
| @@ -14,7 +13,7 @@ use embassy_nrf::spim::{self, Spim}; | |||
| 14 | use embassy_nrf::{bind_interrupts, peripherals}; | 13 | use embassy_nrf::{bind_interrupts, peripherals}; |
| 15 | use embassy_time::Delay; | 14 | use embassy_time::Delay; |
| 16 | use embedded_hal_bus::spi::ExclusiveDevice; | 15 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 17 | use static_cell::make_static; | 16 | use static_cell::StaticCell; |
| 18 | use {defmt_rtt as _, panic_probe as _}; | 17 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | 18 | ||
| 20 | bind_interrupts!(struct Irqs { | 19 | bind_interrupts!(struct Irqs { |
| @@ -22,10 +21,7 @@ bind_interrupts!(struct Irqs { | |||
| 22 | RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>; | 21 | RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>; |
| 23 | }); | 22 | }); |
| 24 | 23 | ||
| 25 | type MyDriver = Enc28j60< | 24 | type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>; |
| 26 | ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_15>, Delay>, | ||
| 27 | Output<'static, peripherals::P0_13>, | ||
| 28 | >; | ||
| 29 | 25 | ||
| 30 | #[embassy_executor::task] | 26 | #[embassy_executor::task] |
| 31 | async fn net_task(stack: &'static Stack<MyDriver>) -> ! { | 27 | async fn net_task(stack: &'static Stack<MyDriver>) -> ! { |
| @@ -68,11 +64,13 @@ async fn main(spawner: Spawner) { | |||
| 68 | let seed = u64::from_le_bytes(seed); | 64 | let seed = u64::from_le_bytes(seed); |
| 69 | 65 | ||
| 70 | // Init network stack | 66 | // Init network stack |
| 71 | let stack = &*make_static!(Stack::new( | 67 | static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new(); |
| 68 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 69 | let stack = &*STACK.init(Stack::new( | ||
| 72 | device, | 70 | device, |
| 73 | config, | 71 | config, |
| 74 | make_static!(StackResources::<2>::new()), | 72 | RESOURCES.init(StackResources::<2>::new()), |
| 75 | seed | 73 | seed, |
| 76 | )); | 74 | )); |
| 77 | 75 | ||
| 78 | unwrap!(spawner.spawn(net_task(stack))); | 76 | unwrap!(spawner.spawn(net_task(stack))); |
diff --git a/tests/nrf/src/bin/timer.rs b/tests/nrf52840/src/bin/timer.rs index 2a147e7ba..117947a94 100644 --- a/tests/nrf/src/bin/timer.rs +++ b/tests/nrf52840/src/bin/timer.rs | |||
| @@ -18,7 +18,6 @@ async fn main(_spawner: Spawner) { | |||
| 18 | let ms = (end - start).as_millis(); | 18 | let ms = (end - start).as_millis(); |
| 19 | info!("slept for {} ms", ms); | 19 | info!("slept for {} ms", ms); |
| 20 | assert!(ms >= 99); | 20 | assert!(ms >= 99); |
| 21 | assert!(ms < 110); | ||
| 22 | 21 | ||
| 23 | info!("Test OK"); | 22 | info!("Test OK"); |
| 24 | cortex_m::asm::bkpt(); | 23 | cortex_m::asm::bkpt(); |
diff --git a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs b/tests/nrf52840/src/bin/wifi_esp_hosted_perf.rs index 9eee39ccf..b83edddc4 100644 --- a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs +++ b/tests/nrf52840/src/bin/wifi_esp_hosted_perf.rs | |||
| @@ -1,19 +1,18 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | teleprobe_meta::target!(b"nrf52840-dk"); | 3 | teleprobe_meta::target!(b"nrf52840-dk"); |
| 5 | teleprobe_meta::timeout!(120); | 4 | teleprobe_meta::timeout!(120); |
| 6 | 5 | ||
| 7 | use defmt::{info, unwrap}; | 6 | use defmt::{info, unwrap}; |
| 8 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 9 | use embassy_net::{Config, Stack, StackResources}; | 8 | use embassy_net::{Config, Stack, StackResources}; |
| 10 | use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull}; | 9 | use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; |
| 11 | use embassy_nrf::rng::Rng; | 10 | use embassy_nrf::rng::Rng; |
| 12 | use embassy_nrf::spim::{self, Spim}; | 11 | use embassy_nrf::spim::{self, Spim}; |
| 13 | use embassy_nrf::{bind_interrupts, peripherals}; | 12 | use embassy_nrf::{bind_interrupts, peripherals}; |
| 14 | use embassy_time::Delay; | 13 | use embassy_time::Delay; |
| 15 | use embedded_hal_bus::spi::ExclusiveDevice; | 14 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 16 | use static_cell::make_static; | 15 | use static_cell::StaticCell; |
| 17 | use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _}; | 16 | use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _}; |
| 18 | 17 | ||
| 19 | bind_interrupts!(struct Irqs { | 18 | bind_interrupts!(struct Irqs { |
| @@ -29,9 +28,9 @@ const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; | |||
| 29 | async fn wifi_task( | 28 | async fn wifi_task( |
| 30 | runner: hosted::Runner< | 29 | runner: hosted::Runner< |
| 31 | 'static, | 30 | 'static, |
| 32 | ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static, peripherals::P0_31>, Delay>, | 31 | ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, |
| 33 | Input<'static, AnyPin>, | 32 | Input<'static>, |
| 34 | Output<'static, peripherals::P1_05>, | 33 | Output<'static>, |
| 35 | >, | 34 | >, |
| 36 | ) -> ! { | 35 | ) -> ! { |
| 37 | runner.run().await | 36 | runner.run().await |
| @@ -54,8 +53,8 @@ async fn main(spawner: Spawner) { | |||
| 54 | let sck = p.P0_29; | 53 | let sck = p.P0_29; |
| 55 | let mosi = p.P0_30; | 54 | let mosi = p.P0_30; |
| 56 | let cs = Output::new(p.P0_31, Level::High, OutputDrive::HighDrive); | 55 | let cs = Output::new(p.P0_31, Level::High, OutputDrive::HighDrive); |
| 57 | let handshake = Input::new(p.P1_01.degrade(), Pull::Up); | 56 | let handshake = Input::new(p.P1_01, Pull::Up); |
| 58 | let ready = Input::new(p.P1_04.degrade(), Pull::None); | 57 | let ready = Input::new(p.P1_04, Pull::None); |
| 59 | let reset = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); | 58 | let reset = Output::new(p.P1_05, Level::Low, OutputDrive::Standard); |
| 60 | 59 | ||
| 61 | let mut config = spim::Config::default(); | 60 | let mut config = spim::Config::default(); |
| @@ -64,8 +63,9 @@ async fn main(spawner: Spawner) { | |||
| 64 | let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); | 63 | let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); |
| 65 | let spi = ExclusiveDevice::new(spi, cs, Delay); | 64 | let spi = ExclusiveDevice::new(spi, cs, Delay); |
| 66 | 65 | ||
| 66 | static STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); | ||
| 67 | let (device, mut control, runner) = embassy_net_esp_hosted::new( | 67 | let (device, mut control, runner) = embassy_net_esp_hosted::new( |
| 68 | make_static!(embassy_net_esp_hosted::State::new()), | 68 | STATE.init(embassy_net_esp_hosted::State::new()), |
| 69 | spi, | 69 | spi, |
| 70 | handshake, | 70 | handshake, |
| 71 | ready, | 71 | ready, |
| @@ -85,11 +85,13 @@ async fn main(spawner: Spawner) { | |||
| 85 | let seed = u64::from_le_bytes(seed); | 85 | let seed = u64::from_le_bytes(seed); |
| 86 | 86 | ||
| 87 | // Init network stack | 87 | // Init network stack |
| 88 | let stack = &*make_static!(Stack::new( | 88 | static STACK: StaticCell<Stack<MyDriver>> = StaticCell::new(); |
| 89 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 90 | let stack = &*STACK.init(Stack::new( | ||
| 89 | device, | 91 | device, |
| 90 | Config::dhcpv4(Default::default()), | 92 | Config::dhcpv4(Default::default()), |
| 91 | make_static!(StackResources::<2>::new()), | 93 | RESOURCES.init(StackResources::<2>::new()), |
| 92 | seed | 94 | seed, |
| 93 | )); | 95 | )); |
| 94 | 96 | ||
| 95 | unwrap!(spawner.spawn(net_task(stack))); | 97 | unwrap!(spawner.spawn(net_task(stack))); |
diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml index 52aa74df3..4390a6da1 100644 --- a/tests/perf-client/Cargo.toml +++ b/tests/perf-client/Cargo.toml | |||
| @@ -6,7 +6,7 @@ edition = "2021" | |||
| 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } | 9 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] } |
| 10 | embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", ] } | 10 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", ] } |
| 11 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 11 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 12 | defmt = "0.3.0" | 12 | defmt = "0.3.0" |
diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml index a7b389150..38fb2deec 100644 --- a/tests/riscv32/Cargo.toml +++ b/tests/riscv32/Cargo.toml | |||
| @@ -7,8 +7,8 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | critical-section = { version = "1.1.1", features = ["restore-state-bool"] } | 8 | critical-section = { version = "1.1.1", features = ["restore-state-bool"] } |
| 9 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } | 9 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync" } |
| 10 | embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] } | 10 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-riscv32", "executor-thread"] } |
| 11 | embassy-time = { version = "0.2", path = "../../embassy-time" } | 11 | embassy-time = { version = "0.3.0", path = "../../embassy-time" } |
| 12 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 12 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 13 | 13 | ||
| 14 | riscv-rt = "0.11" | 14 | riscv-rt = "0.11" |
diff --git a/tests/rp/.cargo/config.toml b/tests/rp/.cargo/config.toml index 40b5d7000..de7bb0e56 100644 --- a/tests/rp/.cargo/config.toml +++ b/tests/rp/.cargo/config.toml | |||
| @@ -10,7 +10,7 @@ runner = "teleprobe client run" | |||
| 10 | 10 | ||
| 11 | rustflags = [ | 11 | rustflags = [ |
| 12 | # Code-size optimizations. | 12 | # Code-size optimizations. |
| 13 | "-Z", "trap-unreachable=no", | 13 | #"-Z", "trap-unreachable=no", |
| 14 | "-C", "inline-threshold=5", | 14 | "-C", "inline-threshold=5", |
| 15 | "-C", "no-vectorize-loops", | 15 | "-C", "no-vectorize-loops", |
| 16 | ] | 16 | ] |
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 44fb7bed6..e67f2117d 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -8,12 +8,13 @@ license = "MIT OR Apache-2.0" | |||
| 8 | teleprobe-meta = "1.1" | 8 | teleprobe-meta = "1.1" |
| 9 | 9 | ||
| 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 10 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } |
| 11 | embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 11 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["task-arena-size-32768", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 12 | embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", ] } | 12 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", ] } |
| 13 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } | 13 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = [ "defmt", "unstable-pac", "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 | embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } | 15 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } |
| 16 | embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } | 16 | embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } |
| 17 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal/"} | ||
| 17 | cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } | 18 | cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } |
| 18 | cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } | 19 | cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } |
| 19 | perf-client = { path = "../perf-client" } | 20 | perf-client = { path = "../perf-client" } |
| @@ -24,14 +25,14 @@ defmt-rtt = "0.4" | |||
| 24 | cortex-m = { version = "0.7.6" } | 25 | cortex-m = { version = "0.7.6" } |
| 25 | cortex-m-rt = "0.7.0" | 26 | cortex-m-rt = "0.7.0" |
| 26 | embedded-hal = "0.2.6" | 27 | embedded-hal = "0.2.6" |
| 27 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.2" } | 28 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 28 | embedded-hal-async = { version = "=1.0.0-rc.2" } | 29 | embedded-hal-async = { version = "1.0" } |
| 29 | embedded-hal-bus = { version = "=0.1.0-rc.2", features = ["async"] } | 30 | embedded-hal-bus = { version = "0.1", features = ["async"] } |
| 30 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 31 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } |
| 31 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } | 32 | futures = { version = "0.3.17", default-features = false, features = ["async-await"] } |
| 32 | embedded-io-async = { version = "0.6.1" } | 33 | embedded-io-async = { version = "0.6.1" } |
| 33 | embedded-storage = { version = "0.3" } | 34 | embedded-storage = { version = "0.3" } |
| 34 | static_cell = { version = "2", features = ["nightly"]} | 35 | static_cell = "2" |
| 35 | portable-atomic = { version = "1.5", features = ["critical-section"] } | 36 | portable-atomic = { version = "1.5", features = ["critical-section"] } |
| 36 | pio = "0.2" | 37 | pio = "0.2" |
| 37 | pio-proc = "0.2" | 38 | pio-proc = "0.2" |
diff --git a/tests/rp/build.rs b/tests/rp/build.rs index 93e2a28cf..71c82a70f 100644 --- a/tests/rp/build.rs +++ b/tests/rp/build.rs | |||
| @@ -4,7 +4,7 @@ use std::{env, fs}; | |||
| 4 | 4 | ||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | 5 | fn main() -> Result<(), Box<dyn Error>> { |
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| 7 | fs::write(out.join("link_ram.x"), include_bytes!("link_ram.x")).unwrap(); | 7 | fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap(); |
| 8 | println!("cargo:rustc-link-search={}", out.display()); | 8 | println!("cargo:rustc-link-search={}", out.display()); |
| 9 | println!("cargo:rerun-if-changed=link_ram.x"); | 9 | println!("cargo:rerun-if-changed=link_ram.x"); |
| 10 | 10 | ||
diff --git a/tests/rp/link_ram.x b/tests/rp/link_ram.x deleted file mode 100644 index 86a11e875..000000000 --- a/tests/rp/link_ram.x +++ /dev/null | |||
| @@ -1,255 +0,0 @@ | |||
| 1 | /* ##### EMBASSY NOTE | ||
| 2 | Originally from https://github.com/rust-embedded/cortex-m-rt/blob/master/link.x.in | ||
| 3 | Adjusted to put everything in RAM | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* # Developer notes | ||
| 7 | |||
| 8 | - Symbols that start with a double underscore (__) are considered "private" | ||
| 9 | |||
| 10 | - Symbols that start with a single underscore (_) are considered "semi-public"; they can be | ||
| 11 | overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" { | ||
| 12 | static mut __sbss }`). | ||
| 13 | |||
| 14 | - `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a | ||
| 15 | symbol if not dropped if it appears in or near the front of the linker arguments and "it's not | ||
| 16 | needed" by any of the preceding objects (linker arguments) | ||
| 17 | |||
| 18 | - `PROVIDE` is used to provide default values that can be overridden by a user linker script | ||
| 19 | |||
| 20 | - On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and* | ||
| 21 | the LMA of .data are all 4-byte aligned. These alignments are assumed by the RAM initialization | ||
| 22 | routine. There's also a second benefit: 4-byte aligned boundaries means that you won't see | ||
| 23 | "Address (..) is out of bounds" in the disassembly produced by `objdump`. | ||
| 24 | */ | ||
| 25 | |||
| 26 | /* Provides information about the memory layout of the device */ | ||
| 27 | MEMORY { | ||
| 28 | RAM : ORIGIN = 0x20000000, LENGTH = 256K | ||
| 29 | } | ||
| 30 | |||
| 31 | /* # Entry point = reset vector */ | ||
| 32 | EXTERN(__RESET_VECTOR); | ||
| 33 | EXTERN(Reset); | ||
| 34 | ENTRY(Reset); | ||
| 35 | |||
| 36 | /* # Exception vectors */ | ||
| 37 | /* This is effectively weak aliasing at the linker level */ | ||
| 38 | /* The user can override any of these aliases by defining the corresponding symbol themselves (cf. | ||
| 39 | the `exception!` macro) */ | ||
| 40 | EXTERN(__EXCEPTIONS); /* depends on all the these PROVIDED symbols */ | ||
| 41 | |||
| 42 | EXTERN(DefaultHandler); | ||
| 43 | |||
| 44 | PROVIDE(NonMaskableInt = DefaultHandler); | ||
| 45 | EXTERN(HardFaultTrampoline); | ||
| 46 | PROVIDE(MemoryManagement = DefaultHandler); | ||
| 47 | PROVIDE(BusFault = DefaultHandler); | ||
| 48 | PROVIDE(UsageFault = DefaultHandler); | ||
| 49 | PROVIDE(SecureFault = DefaultHandler); | ||
| 50 | PROVIDE(SVCall = DefaultHandler); | ||
| 51 | PROVIDE(DebugMonitor = DefaultHandler); | ||
| 52 | PROVIDE(PendSV = DefaultHandler); | ||
| 53 | PROVIDE(SysTick = DefaultHandler); | ||
| 54 | |||
| 55 | PROVIDE(DefaultHandler = DefaultHandler_); | ||
| 56 | PROVIDE(HardFault = HardFault_); | ||
| 57 | |||
| 58 | /* # Interrupt vectors */ | ||
| 59 | EXTERN(__INTERRUPTS); /* `static` variable similar to `__EXCEPTIONS` */ | ||
| 60 | |||
| 61 | /* # Pre-initialization function */ | ||
| 62 | /* If the user overrides this using the `pre_init!` macro or by creating a `__pre_init` function, | ||
| 63 | then the function this points to will be called before the RAM is initialized. */ | ||
| 64 | PROVIDE(__pre_init = DefaultPreInit); | ||
| 65 | |||
| 66 | /* # Sections */ | ||
| 67 | SECTIONS | ||
| 68 | { | ||
| 69 | PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM)); | ||
| 70 | |||
| 71 | /* ## Sections in RAM */ | ||
| 72 | /* ### Vector table */ | ||
| 73 | .vector_table ORIGIN(RAM) : | ||
| 74 | { | ||
| 75 | /* Initial Stack Pointer (SP) value */ | ||
| 76 | LONG(_stack_start); | ||
| 77 | |||
| 78 | /* Reset vector */ | ||
| 79 | KEEP(*(.vector_table.reset_vector)); /* this is the `__RESET_VECTOR` symbol */ | ||
| 80 | __reset_vector = .; | ||
| 81 | |||
| 82 | /* Exceptions */ | ||
| 83 | KEEP(*(.vector_table.exceptions)); /* this is the `__EXCEPTIONS` symbol */ | ||
| 84 | __eexceptions = .; | ||
| 85 | |||
| 86 | /* Device specific interrupts */ | ||
| 87 | KEEP(*(.vector_table.interrupts)); /* this is the `__INTERRUPTS` symbol */ | ||
| 88 | } > RAM | ||
| 89 | |||
| 90 | PROVIDE(_stext = ADDR(.vector_table) + SIZEOF(.vector_table)); | ||
| 91 | |||
| 92 | /* ### .text */ | ||
| 93 | .text _stext : | ||
| 94 | { | ||
| 95 | __stext = .; | ||
| 96 | *(.Reset); | ||
| 97 | |||
| 98 | *(.text .text.*); | ||
| 99 | |||
| 100 | /* The HardFaultTrampoline uses the `b` instruction to enter `HardFault`, | ||
| 101 | so must be placed close to it. */ | ||
| 102 | *(.HardFaultTrampoline); | ||
| 103 | *(.HardFault.*); | ||
| 104 | |||
| 105 | . = ALIGN(4); /* Pad .text to the alignment to workaround overlapping load section bug in old lld */ | ||
| 106 | __etext = .; | ||
| 107 | } > RAM | ||
| 108 | |||
| 109 | /* ### .rodata */ | ||
| 110 | .rodata : ALIGN(4) | ||
| 111 | { | ||
| 112 | . = ALIGN(4); | ||
| 113 | __srodata = .; | ||
| 114 | *(.rodata .rodata.*); | ||
| 115 | |||
| 116 | /* 4-byte align the end (VMA) of this section. | ||
| 117 | This is required by LLD to ensure the LMA of the following .data | ||
| 118 | section will have the correct alignment. */ | ||
| 119 | . = ALIGN(4); | ||
| 120 | __erodata = .; | ||
| 121 | } > RAM | ||
| 122 | |||
| 123 | /* ## Sections in RAM */ | ||
| 124 | /* ### .data */ | ||
| 125 | .data : ALIGN(4) | ||
| 126 | { | ||
| 127 | . = ALIGN(4); | ||
| 128 | __sdata = .; | ||
| 129 | __edata = .; | ||
| 130 | *(.data .data.*); | ||
| 131 | . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ | ||
| 132 | } > RAM | ||
| 133 | /* Allow sections from user `memory.x` injected using `INSERT AFTER .data` to | ||
| 134 | * use the .data loading mechanism by pushing __edata. Note: do not change | ||
| 135 | * output region or load region in those user sections! */ | ||
| 136 | . = ALIGN(4); | ||
| 137 | |||
| 138 | /* LMA of .data */ | ||
| 139 | __sidata = LOADADDR(.data); | ||
| 140 | |||
| 141 | /* ### .gnu.sgstubs | ||
| 142 | This section contains the TrustZone-M veneers put there by the Arm GNU linker. */ | ||
| 143 | /* Security Attribution Unit blocks must be 32 bytes aligned. */ | ||
| 144 | /* Note that this pads the RAM usage to 32 byte alignment. */ | ||
| 145 | .gnu.sgstubs : ALIGN(32) | ||
| 146 | { | ||
| 147 | . = ALIGN(32); | ||
| 148 | __veneer_base = .; | ||
| 149 | *(.gnu.sgstubs*) | ||
| 150 | . = ALIGN(32); | ||
| 151 | __veneer_limit = .; | ||
| 152 | } > RAM | ||
| 153 | |||
| 154 | /* ### .bss */ | ||
| 155 | .bss (NOLOAD) : ALIGN(4) | ||
| 156 | { | ||
| 157 | . = ALIGN(4); | ||
| 158 | __sbss = .; | ||
| 159 | *(.bss .bss.*); | ||
| 160 | *(COMMON); /* Uninitialized C statics */ | ||
| 161 | . = ALIGN(4); /* 4-byte align the end (VMA) of this section */ | ||
| 162 | } > RAM | ||
| 163 | /* Allow sections from user `memory.x` injected using `INSERT AFTER .bss` to | ||
| 164 | * use the .bss zeroing mechanism by pushing __ebss. Note: do not change | ||
| 165 | * output region or load region in those user sections! */ | ||
| 166 | . = ALIGN(4); | ||
| 167 | __ebss = .; | ||
| 168 | |||
| 169 | /* ### .uninit */ | ||
| 170 | .uninit (NOLOAD) : ALIGN(4) | ||
| 171 | { | ||
| 172 | . = ALIGN(4); | ||
| 173 | __suninit = .; | ||
| 174 | *(.uninit .uninit.*); | ||
| 175 | . = ALIGN(4); | ||
| 176 | __euninit = .; | ||
| 177 | } > RAM | ||
| 178 | |||
| 179 | /* Place the heap right after `.uninit` in RAM */ | ||
| 180 | PROVIDE(__sheap = __euninit); | ||
| 181 | |||
| 182 | /* ## .got */ | ||
| 183 | /* Dynamic relocations are unsupported. This section is only used to detect relocatable code in | ||
| 184 | the input files and raise an error if relocatable code is found */ | ||
| 185 | .got (NOLOAD) : | ||
| 186 | { | ||
| 187 | KEEP(*(.got .got.*)); | ||
| 188 | } | ||
| 189 | |||
| 190 | /* ## Discarded sections */ | ||
| 191 | /DISCARD/ : | ||
| 192 | { | ||
| 193 | /* Unused exception related info that only wastes space */ | ||
| 194 | *(.ARM.exidx); | ||
| 195 | *(.ARM.exidx.*); | ||
| 196 | *(.ARM.extab.*); | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | /* Do not exceed this mark in the error messages below | */ | ||
| 201 | /* # Alignment checks */ | ||
| 202 | ASSERT(ORIGIN(RAM) % 4 == 0, " | ||
| 203 | ERROR(cortex-m-rt): the start of the RAM region must be 4-byte aligned"); | ||
| 204 | |||
| 205 | ASSERT(__sdata % 4 == 0 && __edata % 4 == 0, " | ||
| 206 | BUG(cortex-m-rt): .data is not 4-byte aligned"); | ||
| 207 | |||
| 208 | ASSERT(__sidata % 4 == 0, " | ||
| 209 | BUG(cortex-m-rt): the LMA of .data is not 4-byte aligned"); | ||
| 210 | |||
| 211 | ASSERT(__sbss % 4 == 0 && __ebss % 4 == 0, " | ||
| 212 | BUG(cortex-m-rt): .bss is not 4-byte aligned"); | ||
| 213 | |||
| 214 | ASSERT(__sheap % 4 == 0, " | ||
| 215 | BUG(cortex-m-rt): start of .heap is not 4-byte aligned"); | ||
| 216 | |||
| 217 | /* # Position checks */ | ||
| 218 | |||
| 219 | /* ## .vector_table */ | ||
| 220 | ASSERT(__reset_vector == ADDR(.vector_table) + 0x8, " | ||
| 221 | BUG(cortex-m-rt): the reset vector is missing"); | ||
| 222 | |||
| 223 | ASSERT(__eexceptions == ADDR(.vector_table) + 0x40, " | ||
| 224 | BUG(cortex-m-rt): the exception vectors are missing"); | ||
| 225 | |||
| 226 | ASSERT(SIZEOF(.vector_table) > 0x40, " | ||
| 227 | ERROR(cortex-m-rt): The interrupt vectors are missing. | ||
| 228 | Possible solutions, from most likely to less likely: | ||
| 229 | - Link to a svd2rust generated device crate | ||
| 230 | - Check that you actually use the device/hal/bsp crate in your code | ||
| 231 | - Disable the 'device' feature of cortex-m-rt to build a generic application (a dependency | ||
| 232 | may be enabling it) | ||
| 233 | - Supply the interrupt handlers yourself. Check the documentation for details."); | ||
| 234 | |||
| 235 | /* ## .text */ | ||
| 236 | ASSERT(ADDR(.vector_table) + SIZEOF(.vector_table) <= _stext, " | ||
| 237 | ERROR(cortex-m-rt): The .text section can't be placed inside the .vector_table section | ||
| 238 | Set _stext to an address greater than the end of .vector_table (See output of `nm`)"); | ||
| 239 | |||
| 240 | ASSERT(_stext + SIZEOF(.text) < ORIGIN(RAM) + LENGTH(RAM), " | ||
| 241 | ERROR(cortex-m-rt): The .text section must be placed inside the RAM memory. | ||
| 242 | Set _stext to an address smaller than 'ORIGIN(RAM) + LENGTH(RAM)'"); | ||
| 243 | |||
| 244 | /* # Other checks */ | ||
| 245 | ASSERT(SIZEOF(.got) == 0, " | ||
| 246 | ERROR(cortex-m-rt): .got section detected in the input object files | ||
| 247 | Dynamic relocations are not supported. If you are linking to C code compiled using | ||
| 248 | the 'cc' crate then modify your build script to compile the C code _without_ | ||
| 249 | the -fPIC flag. See the documentation of the `cc::Build.pic` method for details."); | ||
| 250 | /* Do not exceed this mark in the error messages above | */ | ||
| 251 | |||
| 252 | |||
| 253 | /* Provides weak aliases (cf. PROVIDED) for device specific interrupt handlers */ | ||
| 254 | /* This will usually be provided by a device crate generated using svd2rust (see `device.x`) */ | ||
| 255 | INCLUDE device.x \ No newline at end of file | ||
diff --git a/tests/rp/memory.x b/tests/rp/memory.x new file mode 100644 index 000000000..bf0041d7d --- /dev/null +++ b/tests/rp/memory.x | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | /* Provides information about the memory layout of the device */ | ||
| 2 | MEMORY { | ||
| 3 | RAM : ORIGIN = 0x20000000, LENGTH = 256K | ||
| 4 | } | ||
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs index de29c06dd..b46ae670a 100644 --- a/tests/rp/src/bin/cyw43-perf.rs +++ b/tests/rp/src/bin/cyw43-perf.rs | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | teleprobe_meta::target!(b"rpi-pico"); | 3 | teleprobe_meta::target!(b"rpi-pico"); |
| 5 | 4 | ||
| 6 | use cyw43_pio::PioSpi; | 5 | use cyw43_pio::PioSpi; |
| @@ -8,10 +7,10 @@ use defmt::{panic, *}; | |||
| 8 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 9 | use embassy_net::{Config, Stack, StackResources}; | 8 | use embassy_net::{Config, Stack, StackResources}; |
| 10 | use embassy_rp::gpio::{Level, Output}; | 9 | use embassy_rp::gpio::{Level, Output}; |
| 11 | use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; | 10 | use embassy_rp::peripherals::{DMA_CH0, PIO0}; |
| 12 | use embassy_rp::pio::{InterruptHandler, Pio}; | 11 | use embassy_rp::pio::{InterruptHandler, Pio}; |
| 13 | use embassy_rp::{bind_interrupts, rom_data}; | 12 | use embassy_rp::{bind_interrupts, rom_data}; |
| 14 | use static_cell::make_static; | 13 | use static_cell::StaticCell; |
| 15 | use {defmt_rtt as _, panic_probe as _}; | 14 | use {defmt_rtt as _, panic_probe as _}; |
| 16 | 15 | ||
| 17 | bind_interrupts!(struct Irqs { | 16 | bind_interrupts!(struct Irqs { |
| @@ -25,9 +24,7 @@ const WIFI_NETWORK: &str = "EmbassyTest"; | |||
| 25 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; | 24 | const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud"; |
| 26 | 25 | ||
| 27 | #[embassy_executor::task] | 26 | #[embassy_executor::task] |
| 28 | async fn wifi_task( | 27 | async fn wifi_task(runner: cyw43::Runner<'static, Output<'static>, PioSpi<'static, PIO0, 0, DMA_CH0>>) -> ! { |
| 29 | runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, | ||
| 30 | ) -> ! { | ||
| 31 | runner.run().await | 28 | runner.run().await |
| 32 | } | 29 | } |
| 33 | 30 | ||
| @@ -58,7 +55,8 @@ async fn main(spawner: Spawner) { | |||
| 58 | let mut pio = Pio::new(p.PIO0, Irqs); | 55 | let mut pio = Pio::new(p.PIO0, Irqs); |
| 59 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); | 56 | let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0); |
| 60 | 57 | ||
| 61 | let state = make_static!(cyw43::State::new()); | 58 | static STATE: StaticCell<cyw43::State> = StaticCell::new(); |
| 59 | let state = STATE.init(cyw43::State::new()); | ||
| 62 | let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; | 60 | let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await; |
| 63 | unwrap!(spawner.spawn(wifi_task(runner))); | 61 | unwrap!(spawner.spawn(wifi_task(runner))); |
| 64 | 62 | ||
| @@ -71,11 +69,13 @@ async fn main(spawner: Spawner) { | |||
| 71 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. | 69 | let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random. |
| 72 | 70 | ||
| 73 | // Init network stack | 71 | // Init network stack |
| 74 | let stack = &*make_static!(Stack::new( | 72 | static STACK: StaticCell<Stack<cyw43::NetDriver<'static>>> = StaticCell::new(); |
| 73 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 74 | let stack = &*STACK.init(Stack::new( | ||
| 75 | net_device, | 75 | net_device, |
| 76 | Config::dhcpv4(Default::default()), | 76 | Config::dhcpv4(Default::default()), |
| 77 | make_static!(StackResources::<2>::new()), | 77 | RESOURCES.init(StackResources::<2>::new()), |
| 78 | seed | 78 | seed, |
| 79 | )); | 79 | )); |
| 80 | 80 | ||
| 81 | unwrap!(spawner.spawn(net_task(stack))); | 81 | unwrap!(spawner.spawn(net_task(stack))); |
diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs index a4d253b3c..5d5547773 100644 --- a/tests/rp/src/bin/ethernet_w5100s_perf.rs +++ b/tests/rp/src/bin/ethernet_w5100s_perf.rs | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | #![no_std] | 1 | #![no_std] |
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | #![feature(type_alias_impl_trait)] | ||
| 4 | teleprobe_meta::target!(b"w5100s-evb-pico"); | 3 | teleprobe_meta::target!(b"w5100s-evb-pico"); |
| 5 | teleprobe_meta::timeout!(120); | 4 | teleprobe_meta::timeout!(120); |
| 6 | 5 | ||
| @@ -11,12 +10,12 @@ use embassy_net_wiznet::chip::W5100S; | |||
| 11 | use embassy_net_wiznet::*; | 10 | use embassy_net_wiznet::*; |
| 12 | use embassy_rp::clocks::RoscRng; | 11 | use embassy_rp::clocks::RoscRng; |
| 13 | use embassy_rp::gpio::{Input, Level, Output, Pull}; | 12 | use embassy_rp::gpio::{Input, Level, Output, Pull}; |
| 14 | use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; | 13 | use embassy_rp::peripherals::SPI0; |
| 15 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; | 14 | use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; |
| 16 | use embassy_time::Delay; | 15 | use embassy_time::Delay; |
| 17 | use embedded_hal_bus::spi::ExclusiveDevice; | 16 | use embedded_hal_bus::spi::ExclusiveDevice; |
| 18 | use rand::RngCore; | 17 | use rand::RngCore; |
| 19 | use static_cell::make_static; | 18 | use static_cell::StaticCell; |
| 20 | use {defmt_rtt as _, panic_probe as _}; | 19 | use {defmt_rtt as _, panic_probe as _}; |
| 21 | 20 | ||
| 22 | #[embassy_executor::task] | 21 | #[embassy_executor::task] |
| @@ -24,9 +23,9 @@ async fn ethernet_task( | |||
| 24 | runner: Runner< | 23 | runner: Runner< |
| 25 | 'static, | 24 | 'static, |
| 26 | W5100S, | 25 | W5100S, |
| 27 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static, PIN_17>, Delay>, | 26 | ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>, |
| 28 | Input<'static, PIN_21>, | 27 | Input<'static>, |
| 29 | Output<'static, PIN_20>, | 28 | Output<'static>, |
| 30 | >, | 29 | >, |
| 31 | ) -> ! { | 30 | ) -> ! { |
| 32 | runner.run().await | 31 | runner.run().await |
| @@ -51,7 +50,8 @@ async fn main(spawner: Spawner) { | |||
| 51 | let w5500_reset = Output::new(p.PIN_20, Level::High); | 50 | let w5500_reset = Output::new(p.PIN_20, Level::High); |
| 52 | 51 | ||
| 53 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; | 52 | let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; |
| 54 | let state = make_static!(State::<8, 8>::new()); | 53 | static STATE: StaticCell<State<8, 8>> = StaticCell::new(); |
| 54 | let state = STATE.init(State::<8, 8>::new()); | ||
| 55 | let (device, runner) = embassy_net_wiznet::new( | 55 | let (device, runner) = embassy_net_wiznet::new( |
| 56 | mac_addr, | 56 | mac_addr, |
| 57 | state, | 57 | state, |
| @@ -66,11 +66,13 @@ async fn main(spawner: Spawner) { | |||
| 66 | let seed = rng.next_u64(); | 66 | let seed = rng.next_u64(); |
| 67 | 67 | ||
| 68 | // Init network stack | 68 | // Init network stack |
| 69 | let stack = &*make_static!(Stack::new( | 69 | static STACK: StaticCell<Stack<Device<'static>>> = StaticCell::new(); |
| 70 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 71 | let stack = &*STACK.init(Stack::new( | ||
| 70 | device, | 72 | device, |
| 71 | embassy_net::Config::dhcpv4(Default::default()), | 73 | embassy_net::Config::dhcpv4(Default::default()), |
| 72 | make_static!(StackResources::<2>::new()), | 74 | RESOURCES.init(StackResources::<2>::new()), |
| 73 | seed | 75 | seed, |
| 74 | )); | 76 | )); |
| 75 | 77 | ||
| 76 | // Launch network task | 78 | // Launch network task |
diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs index 8aed9b80c..e9c6f3122 100644 --- a/tests/rp/src/bin/gpio_multicore.rs +++ b/tests/rp/src/bin/gpio_multicore.rs | |||
| @@ -21,10 +21,14 @@ static CHANNEL1: Channel<CriticalSectionRawMutex, (), 1> = Channel::new(); | |||
| 21 | #[cortex_m_rt::entry] | 21 | #[cortex_m_rt::entry] |
| 22 | fn main() -> ! { | 22 | fn main() -> ! { |
| 23 | let p = embassy_rp::init(Default::default()); | 23 | let p = embassy_rp::init(Default::default()); |
| 24 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | 24 | spawn_core1( |
| 25 | let executor1 = EXECUTOR1.init(Executor::new()); | 25 | p.CORE1, |
| 26 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1)))); | 26 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, |
| 27 | }); | 27 | move || { |
| 28 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 29 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task(p.PIN_1)))); | ||
| 30 | }, | ||
| 31 | ); | ||
| 28 | let executor0 = EXECUTOR0.init(Executor::new()); | 32 | let executor0 = EXECUTOR0.init(Executor::new()); |
| 29 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0)))); | 33 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task(p.PIN_0)))); |
| 30 | } | 34 | } |
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs index 77d628cf6..9615007bd 100644 --- a/tests/rp/src/bin/i2c.rs +++ b/tests/rp/src/bin/i2c.rs | |||
| @@ -3,7 +3,10 @@ | |||
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 3 | teleprobe_meta::target!(b"rpi-pico"); |
| 4 | 4 | ||
| 5 | use defmt::{assert_eq, info, panic, unwrap}; | 5 | use defmt::{assert_eq, info, panic, unwrap}; |
| 6 | use embassy_executor::Executor; | 6 | use embassy_embedded_hal::SetConfig; |
| 7 | use embassy_executor::{Executor, Spawner}; | ||
| 8 | use embassy_rp::clocks::{PllConfig, XoscConfig}; | ||
| 9 | use embassy_rp::config::Config as rpConfig; | ||
| 7 | use embassy_rp::multicore::{spawn_core1, Stack}; | 10 | use embassy_rp::multicore::{spawn_core1, Stack}; |
| 8 | use embassy_rp::peripherals::{I2C0, I2C1}; | 11 | use embassy_rp::peripherals::{I2C0, I2C1}; |
| 9 | use embassy_rp::{bind_interrupts, i2c, i2c_slave}; | 12 | use embassy_rp::{bind_interrupts, i2c, i2c_slave}; |
| @@ -13,7 +16,6 @@ use static_cell::StaticCell; | |||
| 13 | use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; | 16 | use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _}; |
| 14 | 17 | ||
| 15 | static mut CORE1_STACK: Stack<1024> = Stack::new(); | 18 | static mut CORE1_STACK: Stack<1024> = Stack::new(); |
| 16 | static EXECUTOR0: StaticCell<Executor> = StaticCell::new(); | ||
| 17 | static EXECUTOR1: StaticCell<Executor> = StaticCell::new(); | 19 | static EXECUTOR1: StaticCell<Executor> = StaticCell::new(); |
| 18 | 20 | ||
| 19 | use crate::i2c::AbortReason; | 21 | use crate::i2c::AbortReason; |
| @@ -44,10 +46,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 44 | Ok(x) => match x { | 46 | Ok(x) => match x { |
| 45 | i2c_slave::ReadStatus::Done => break, | 47 | i2c_slave::ReadStatus::Done => break, |
| 46 | i2c_slave::ReadStatus::NeedMoreBytes => count += 1, | 48 | i2c_slave::ReadStatus::NeedMoreBytes => count += 1, |
| 47 | i2c_slave::ReadStatus::LeftoverBytes(x) => { | 49 | i2c_slave::ReadStatus::LeftoverBytes(x) => panic!("tried to write {} extra bytes", x), |
| 48 | info!("tried to write {} extra bytes", x); | ||
| 49 | break; | ||
| 50 | } | ||
| 51 | }, | 50 | }, |
| 52 | Err(e) => match e { | 51 | Err(e) => match e { |
| 53 | embassy_rp::i2c_slave::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n), | 52 | embassy_rp::i2c_slave::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n), |
| @@ -80,7 +79,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 80 | _ => panic!("Invalid write length {}", len), | 79 | _ => panic!("Invalid write length {}", len), |
| 81 | }, | 80 | }, |
| 82 | Ok(i2c_slave::Command::WriteRead(len)) => { | 81 | Ok(i2c_slave::Command::WriteRead(len)) => { |
| 83 | info!("device recieved write read: {:x}", buf[..len]); | 82 | info!("device received write read: {:x}", buf[..len]); |
| 84 | match buf[0] { | 83 | match buf[0] { |
| 85 | 0xC2 => { | 84 | 0xC2 => { |
| 86 | let resp_buff = [0xD1, 0xD2, 0xD3, 0xD4]; | 85 | let resp_buff = [0xD1, 0xD2, 0xD3, 0xD4]; |
| @@ -92,6 +91,8 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 92 | resp_buff[i] = i as u8; | 91 | resp_buff[i] = i as u8; |
| 93 | } | 92 | } |
| 94 | dev.respond_to_read(&resp_buff).await.unwrap(); | 93 | dev.respond_to_read(&resp_buff).await.unwrap(); |
| 94 | // reset count for next round of tests | ||
| 95 | count = 0xD0; | ||
| 95 | } | 96 | } |
| 96 | x => panic!("Invalid Write Read {:x}", x), | 97 | x => panic!("Invalid Write Read {:x}", x), |
| 97 | } | 98 | } |
| @@ -104,8 +105,7 @@ async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! { | |||
| 104 | } | 105 | } |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | #[embassy_executor::task] | 108 | async fn controller_task(con: &mut i2c::I2c<'static, I2C0, i2c::Async>) { |
| 108 | async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) { | ||
| 109 | info!("Device start"); | 109 | info!("Device start"); |
| 110 | 110 | ||
| 111 | { | 111 | { |
| @@ -179,33 +179,59 @@ async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) { | |||
| 179 | info!("large write_read - OK") | 179 | info!("large write_read - OK") |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | info!("Test OK"); | 182 | #[embassy_executor::main] |
| 183 | cortex_m::asm::bkpt(); | 183 | async fn main(_core0_spawner: Spawner) { |
| 184 | } | 184 | let mut config = rpConfig::default(); |
| 185 | 185 | // Configure clk_sys to 48MHz to support 1kHz scl. | |
| 186 | #[cortex_m_rt::entry] | 186 | // In theory it can go lower, but we won't bother to test below 1kHz. |
| 187 | fn main() -> ! { | 187 | config.clocks.xosc = Some(XoscConfig { |
| 188 | let p = embassy_rp::init(Default::default()); | 188 | hz: 12_000_000, |
| 189 | info!("Hello World!"); | 189 | delay_multiplier: 128, |
| 190 | 190 | sys_pll: Some(PllConfig { | |
| 191 | let d_sda = p.PIN_19; | 191 | refdiv: 1, |
| 192 | let d_scl = p.PIN_18; | 192 | fbdiv: 120, |
| 193 | let mut config = i2c_slave::Config::default(); | 193 | post_div1: 6, |
| 194 | config.addr = DEV_ADDR as u16; | 194 | post_div2: 5, |
| 195 | let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); | 195 | }), |
| 196 | 196 | usb_pll: Some(PllConfig { | |
| 197 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | 197 | refdiv: 1, |
| 198 | let executor1 = EXECUTOR1.init(Executor::new()); | 198 | fbdiv: 120, |
| 199 | executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device)))); | 199 | post_div1: 6, |
| 200 | }); | 200 | post_div2: 5, |
| 201 | }), | ||
| 202 | }); | ||
| 203 | |||
| 204 | let p = embassy_rp::init(config); | ||
| 205 | info!("Hello World!"); | ||
| 206 | |||
| 207 | let d_sda = p.PIN_19; | ||
| 208 | let d_scl = p.PIN_18; | ||
| 209 | let mut config = i2c_slave::Config::default(); | ||
| 210 | config.addr = DEV_ADDR as u16; | ||
| 211 | let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config); | ||
| 212 | |||
| 213 | spawn_core1( | ||
| 214 | p.CORE1, | ||
| 215 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, | ||
| 216 | move || { | ||
| 217 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 218 | executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device)))); | ||
| 219 | }, | ||
| 220 | ); | ||
| 201 | 221 | ||
| 202 | let executor0 = EXECUTOR0.init(Executor::new()); | 222 | let c_sda = p.PIN_21; |
| 223 | let c_scl = p.PIN_20; | ||
| 224 | let mut controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, Default::default()); | ||
| 203 | 225 | ||
| 204 | let c_sda = p.PIN_21; | 226 | for freq in [1000, 100_000, 400_000, 1_000_000] { |
| 205 | let c_scl = p.PIN_20; | 227 | info!("testing at {}hz", freq); |
| 206 | let mut config = i2c::Config::default(); | 228 | let mut config = i2c::Config::default(); |
| 207 | config.frequency = 5_000; | 229 | config.frequency = freq; |
| 208 | let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config); | 230 | controller.set_config(&config).unwrap(); |
| 231 | controller_task(&mut controller).await; | ||
| 232 | } | ||
| 209 | 233 | ||
| 210 | executor0.run(|spawner| unwrap!(spawner.spawn(controller_task(controller)))); | 234 | info!("Test OK"); |
| 235 | cortex_m::asm::bkpt(); | ||
| 236 | } | ||
| 211 | } | 237 | } |
diff --git a/tests/rp/src/bin/multicore.rs b/tests/rp/src/bin/multicore.rs index 60d9f85ec..783ea0f27 100644 --- a/tests/rp/src/bin/multicore.rs +++ b/tests/rp/src/bin/multicore.rs | |||
| @@ -19,10 +19,14 @@ static CHANNEL1: Channel<CriticalSectionRawMutex, bool, 1> = Channel::new(); | |||
| 19 | #[cortex_m_rt::entry] | 19 | #[cortex_m_rt::entry] |
| 20 | fn main() -> ! { | 20 | fn main() -> ! { |
| 21 | let p = embassy_rp::init(Default::default()); | 21 | let p = embassy_rp::init(Default::default()); |
| 22 | spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || { | 22 | spawn_core1( |
| 23 | let executor1 = EXECUTOR1.init(Executor::new()); | 23 | p.CORE1, |
| 24 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); | 24 | unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, |
| 25 | }); | 25 | move || { |
| 26 | let executor1 = EXECUTOR1.init(Executor::new()); | ||
| 27 | executor1.run(|spawner| unwrap!(spawner.spawn(core1_task()))); | ||
| 28 | }, | ||
| 29 | ); | ||
| 26 | let executor0 = EXECUTOR0.init(Executor::new()); | 30 | let executor0 = EXECUTOR0.init(Executor::new()); |
| 27 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); | 31 | executor0.run(|spawner| unwrap!(spawner.spawn(core0_task()))); |
| 28 | } | 32 | } |
diff --git a/tests/rp/src/bin/uart.rs b/tests/rp/src/bin/uart.rs index f4d641175..6e6e5517b 100644 --- a/tests/rp/src/bin/uart.rs +++ b/tests/rp/src/bin/uart.rs | |||
| @@ -21,7 +21,7 @@ fn read1<const N: usize>(uart: &mut UartRx<'_, impl Instance, Blocking>) -> Resu | |||
| 21 | Ok(buf) | 21 | Ok(buf) |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option<bool>) { | 24 | async fn send(pin: &mut Output<'_>, v: u8, parity: Option<bool>) { |
| 25 | pin.set_low(); | 25 | pin.set_low(); |
| 26 | Timer::after_millis(1).await; | 26 | Timer::after_millis(1).await; |
| 27 | for i in 0..8 { | 27 | for i in 0..8 { |
| @@ -116,7 +116,7 @@ async fn main(_spawner: Spawner) { | |||
| 116 | config.parity = Parity::ParityEven; | 116 | config.parity = Parity::ParityEven; |
| 117 | let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); | 117 | let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); |
| 118 | 118 | ||
| 119 | async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u8) { | 119 | async fn chr(pin: &mut Output<'_>, v: u8, parity: u8) { |
| 120 | send(pin, v, Some(parity != 0)).await; | 120 | send(pin, v, Some(parity != 0)).await; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| @@ -142,7 +142,7 @@ async fn main(_spawner: Spawner) { | |||
| 142 | config.baudrate = 1000; | 142 | config.baudrate = 1000; |
| 143 | let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); | 143 | let mut uart = UartRx::new_blocking(&mut uart, &mut rx, config); |
| 144 | 144 | ||
| 145 | async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) { | 145 | async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { |
| 146 | if good { | 146 | if good { |
| 147 | send(pin, v, None).await; | 147 | send(pin, v, None).await; |
| 148 | } else { | 148 | } else { |
diff --git a/tests/rp/src/bin/uart_buffered.rs b/tests/rp/src/bin/uart_buffered.rs index 14647e44a..d68c23cbd 100644 --- a/tests/rp/src/bin/uart_buffered.rs +++ b/tests/rp/src/bin/uart_buffered.rs | |||
| @@ -36,7 +36,7 @@ async fn read1<const N: usize>(uart: &mut BufferedUartRx<'_, impl Instance>) -> | |||
| 36 | } | 36 | } |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option<bool>) { | 39 | async fn send(pin: &mut Output<'_>, v: u8, parity: Option<bool>) { |
| 40 | pin.set_low(); | 40 | pin.set_low(); |
| 41 | Timer::after_millis(1).await; | 41 | Timer::after_millis(1).await; |
| 42 | for i in 0..8 { | 42 | for i in 0..8 { |
| @@ -161,7 +161,7 @@ async fn main(_spawner: Spawner) { | |||
| 161 | let rx_buf = &mut [0u8; 16]; | 161 | let rx_buf = &mut [0u8; 16]; |
| 162 | let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); | 162 | let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); |
| 163 | 163 | ||
| 164 | async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u32) { | 164 | async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { |
| 165 | send(pin, v, Some(parity != 0)).await; | 165 | send(pin, v, Some(parity != 0)).await; |
| 166 | } | 166 | } |
| 167 | 167 | ||
| @@ -208,7 +208,7 @@ async fn main(_spawner: Spawner) { | |||
| 208 | let rx_buf = &mut [0u8; 16]; | 208 | let rx_buf = &mut [0u8; 16]; |
| 209 | let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); | 209 | let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config); |
| 210 | 210 | ||
| 211 | async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) { | 211 | async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { |
| 212 | if good { | 212 | if good { |
| 213 | send(pin, v, None).await; | 213 | send(pin, v, None).await; |
| 214 | } else { | 214 | } else { |
diff --git a/tests/rp/src/bin/uart_dma.rs b/tests/rp/src/bin/uart_dma.rs index 130d8599e..edc87175a 100644 --- a/tests/rp/src/bin/uart_dma.rs +++ b/tests/rp/src/bin/uart_dma.rs | |||
| @@ -27,7 +27,7 @@ async fn read1<const N: usize>(uart: &mut UartRx<'_, impl Instance, Async>) -> R | |||
| 27 | Ok(buf) | 27 | Ok(buf) |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | async fn send(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: Option<bool>) { | 30 | async fn send(pin: &mut Output<'_>, v: u8, parity: Option<bool>) { |
| 31 | pin.set_low(); | 31 | pin.set_low(); |
| 32 | Timer::after_millis(1).await; | 32 | Timer::after_millis(1).await; |
| 33 | for i in 0..8 { | 33 | for i in 0..8 { |
| @@ -160,7 +160,7 @@ async fn main(_spawner: Spawner) { | |||
| 160 | config.parity = Parity::ParityEven; | 160 | config.parity = Parity::ParityEven; |
| 161 | let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); | 161 | let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); |
| 162 | 162 | ||
| 163 | async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u32) { | 163 | async fn chr(pin: &mut Output<'_>, v: u8, parity: u32) { |
| 164 | send(pin, v, Some(parity != 0)).await; | 164 | send(pin, v, Some(parity != 0)).await; |
| 165 | } | 165 | } |
| 166 | 166 | ||
| @@ -205,7 +205,7 @@ async fn main(_spawner: Spawner) { | |||
| 205 | config.baudrate = 1000; | 205 | config.baudrate = 1000; |
| 206 | let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); | 206 | let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config); |
| 207 | 207 | ||
| 208 | async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) { | 208 | async fn chr(pin: &mut Output<'_>, v: u8, good: bool) { |
| 209 | if good { | 209 | if good { |
| 210 | send(pin, v, None).await; | 210 | send(pin, v, None).await; |
| 211 | } else { | 211 | } else { |
diff --git a/tests/stm32/.cargo/config.toml b/tests/stm32/.cargo/config.toml index 2e3f055d4..528bd3451 100644 --- a/tests/stm32/.cargo/config.toml +++ b/tests/stm32/.cargo/config.toml | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | [unstable] | 1 | [unstable] |
| 2 | build-std = ["core"] | 2 | #build-std = ["core"] |
| 3 | build-std-features = ["panic_immediate_abort"] | 3 | #build-std-features = ["panic_immediate_abort"] |
| 4 | 4 | ||
| 5 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] | 5 | [target.'cfg(all(target_arch = "arm", target_os = "none"))'] |
| 6 | runner = "teleprobe client run" | 6 | runner = "teleprobe client run" |
| @@ -8,16 +8,16 @@ runner = "teleprobe client run" | |||
| 8 | 8 | ||
| 9 | rustflags = [ | 9 | rustflags = [ |
| 10 | # Code-size optimizations. | 10 | # Code-size optimizations. |
| 11 | "-Z", "trap-unreachable=no", | 11 | #"-Z", "trap-unreachable=no", |
| 12 | "-C", "inline-threshold=5", | 12 | "-C", "inline-threshold=5", |
| 13 | "-C", "no-vectorize-loops", | 13 | "-C", "no-vectorize-loops", |
| 14 | ] | 14 | ] |
| 15 | 15 | ||
| 16 | [build] | 16 | [build] |
| 17 | target = "thumbv6m-none-eabi" | 17 | #target = "thumbv6m-none-eabi" |
| 18 | #target = "thumbv7m-none-eabi" | 18 | #target = "thumbv7m-none-eabi" |
| 19 | #target = "thumbv7em-none-eabi" | 19 | target = "thumbv7em-none-eabi" |
| 20 | #target = "thumbv8m.main-none-eabihf" | 20 | #target = "thumbv8m.main-none-eabihf" |
| 21 | 21 | ||
| 22 | [env] | 22 | [env] |
| 23 | DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,smoltcp=info" \ No newline at end of file | 23 | DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,smoltcp=info" |
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 4f53e84f0..e42470004 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -13,35 +13,41 @@ stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] | |||
| 13 | stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] | 13 | stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] |
| 14 | stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] | 14 | stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] |
| 15 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] | 15 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] |
| 16 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac"] | 16 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] |
| 17 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng"] | 17 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan"] |
| 18 | stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng"] | 18 | stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "hash"] |
| 19 | stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng"] | 19 | stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] |
| 20 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng"] | 20 | stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "chrono", "not-gpdma", "eth", "dac", "rng", "fdcan", "hash", "cryp"] |
| 21 | stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng"] | 21 | stm32h7a3zi = ["embassy-stm32/stm32h7a3zi", "not-gpdma", "rng", "fdcan"] |
| 22 | stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"] | 22 | stm32l073rz = ["embassy-stm32/stm32l073rz", "cm0", "not-gpdma", "rng"] |
| 23 | stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] | 23 | stm32l152re = ["embassy-stm32/stm32l152re", "chrono", "not-gpdma"] |
| 24 | stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] | 24 | stm32l496zg = ["embassy-stm32/stm32l496zg", "not-gpdma", "rng"] |
| 25 | stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng"] | 25 | stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "chrono", "not-gpdma", "rng", "hash"] |
| 26 | stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] | 26 | stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "chrono", "not-gpdma", "rng"] |
| 27 | stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng"] | 27 | stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma", "rng", "hash"] |
| 28 | stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng"] | 28 | stm32u585ai = ["embassy-stm32/stm32u585ai", "chrono", "rng", "hash"] |
| 29 | stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "chrono", "rng"] | 29 | stm32u5a5zj = ["embassy-stm32/stm32u5a5zj", "chrono", "rng", "hash"] |
| 30 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] | 30 | stm32wb55rg = ["embassy-stm32/stm32wb55rg", "chrono", "not-gpdma", "ble", "mac" , "rng"] |
| 31 | stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng"] | 31 | stm32wba52cg = ["embassy-stm32/stm32wba52cg", "chrono", "rng", "hash"] |
| 32 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] | 32 | stm32wl55jc = ["embassy-stm32/stm32wl55jc-cm4", "not-gpdma", "rng", "chrono"] |
| 33 | stm32f091rc = ["embassy-stm32/stm32f091rc", "cm0", "not-gpdma", "chrono"] | ||
| 34 | stm32h503rb = ["embassy-stm32/stm32h503rb", "rng"] | ||
| 33 | 35 | ||
| 36 | cryp = [] | ||
| 37 | hash = [] | ||
| 34 | eth = ["embassy-executor/task-arena-size-16384"] | 38 | eth = ["embassy-executor/task-arena-size-16384"] |
| 35 | rng = [] | 39 | rng = [] |
| 36 | sdmmc = [] | 40 | sdmmc = [] |
| 37 | stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"] | 41 | stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"] |
| 38 | chrono = ["embassy-stm32/chrono", "dep:chrono"] | 42 | chrono = ["embassy-stm32/chrono", "dep:chrono"] |
| 39 | can = [] | 43 | can = [] |
| 44 | fdcan = [] | ||
| 40 | ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"] | 45 | ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"] |
| 41 | mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] | 46 | mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] |
| 42 | embassy-stm32-wpan = [] | 47 | embassy-stm32-wpan = [] |
| 43 | not-gpdma = [] | 48 | not-gpdma = [] |
| 44 | dac = [] | 49 | dac = [] |
| 50 | ucpd = [] | ||
| 45 | 51 | ||
| 46 | cm0 = ["portable-atomic/unsafe-assume-single-core"] | 52 | cm0 = ["portable-atomic/unsafe-assume-single-core"] |
| 47 | 53 | ||
| @@ -49,12 +55,12 @@ cm0 = ["portable-atomic/unsafe-assume-single-core"] | |||
| 49 | teleprobe-meta = "1" | 55 | teleprobe-meta = "1" |
| 50 | 56 | ||
| 51 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } | 57 | embassy-sync = { version = "0.5.0", path = "../../embassy-sync", features = ["defmt"] } |
| 52 | embassy-executor = { version = "0.4.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } | 58 | embassy-executor = { version = "0.5.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 53 | embassy-time = { version = "0.2", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } | 59 | embassy-time = { version = "0.3.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } |
| 54 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } | 60 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any"] } |
| 55 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 61 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 56 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } | 62 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } |
| 57 | embassy-net = { version = "0.2.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } | 63 | embassy-net = { version = "0.4.0", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } |
| 58 | perf-client = { path = "../perf-client" } | 64 | perf-client = { path = "../perf-client" } |
| 59 | 65 | ||
| 60 | defmt = "0.3.0" | 66 | defmt = "0.3.0" |
| @@ -63,16 +69,20 @@ defmt-rtt = "0.4" | |||
| 63 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } | 69 | cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } |
| 64 | cortex-m-rt = "0.7.0" | 70 | cortex-m-rt = "0.7.0" |
| 65 | embedded-hal = "0.2.6" | 71 | embedded-hal = "0.2.6" |
| 66 | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.2" } | 72 | embedded-hal-1 = { package = "embedded-hal", version = "1.0" } |
| 67 | embedded-hal-async = { version = "=1.0.0-rc.2" } | 73 | embedded-hal-async = { version = "1.0" } |
| 74 | embedded-can = { version = "0.4" } | ||
| 68 | micromath = "2.0.0" | 75 | micromath = "2.0.0" |
| 69 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } | 76 | panic-probe = { version = "0.3.0", features = ["print-defmt"] } |
| 70 | rand_core = { version = "0.6", default-features = false } | 77 | rand_core = { version = "0.6", default-features = false } |
| 71 | rand_chacha = { version = "0.3", default-features = false } | 78 | rand_chacha = { version = "0.3", default-features = false } |
| 72 | static_cell = { version = "2", features = ["nightly"] } | 79 | static_cell = "2" |
| 73 | portable-atomic = { version = "1.5", features = [] } | 80 | portable-atomic = { version = "1.5", features = [] } |
| 74 | 81 | ||
| 75 | chrono = { version = "^0.4", default-features = false, optional = true} | 82 | chrono = { version = "^0.4", default-features = false, optional = true} |
| 83 | sha2 = { version = "0.10.8", default-features = false } | ||
| 84 | hmac = "0.12.1" | ||
| 85 | aes-gcm = {version = "0.10.3", default-features = false, features = ["aes", "heapless"] } | ||
| 76 | 86 | ||
| 77 | # BEGIN TESTS | 87 | # BEGIN TESTS |
| 78 | # Generated by gen_test.py. DO NOT EDIT. | 88 | # Generated by gen_test.py. DO NOT EDIT. |
| @@ -82,6 +92,11 @@ path = "src/bin/can.rs" | |||
| 82 | required-features = [ "can",] | 92 | required-features = [ "can",] |
| 83 | 93 | ||
| 84 | [[bin]] | 94 | [[bin]] |
| 95 | name = "cryp" | ||
| 96 | path = "src/bin/cryp.rs" | ||
| 97 | required-features = [ "cryp",] | ||
| 98 | |||
| 99 | [[bin]] | ||
| 85 | name = "dac" | 100 | name = "dac" |
| 86 | path = "src/bin/dac.rs" | 101 | path = "src/bin/dac.rs" |
| 87 | required-features = [ "dac",] | 102 | required-features = [ "dac",] |
| @@ -97,11 +112,21 @@ path = "src/bin/eth.rs" | |||
| 97 | required-features = [ "eth",] | 112 | required-features = [ "eth",] |
| 98 | 113 | ||
| 99 | [[bin]] | 114 | [[bin]] |
| 115 | name = "fdcan" | ||
| 116 | path = "src/bin/fdcan.rs" | ||
| 117 | required-features = [ "fdcan",] | ||
| 118 | |||
| 119 | [[bin]] | ||
| 100 | name = "gpio" | 120 | name = "gpio" |
| 101 | path = "src/bin/gpio.rs" | 121 | path = "src/bin/gpio.rs" |
| 102 | required-features = [] | 122 | required-features = [] |
| 103 | 123 | ||
| 104 | [[bin]] | 124 | [[bin]] |
| 125 | name = "hash" | ||
| 126 | path = "src/bin/hash.rs" | ||
| 127 | required-features = [ "hash",] | ||
| 128 | |||
| 129 | [[bin]] | ||
| 105 | name = "rng" | 130 | name = "rng" |
| 106 | path = "src/bin/rng.rs" | 131 | path = "src/bin/rng.rs" |
| 107 | required-features = [ "rng",] | 132 | required-features = [ "rng",] |
| @@ -137,6 +162,11 @@ path = "src/bin/timer.rs" | |||
| 137 | required-features = [] | 162 | required-features = [] |
| 138 | 163 | ||
| 139 | [[bin]] | 164 | [[bin]] |
| 165 | name = "ucpd" | ||
| 166 | path = "src/bin/ucpd.rs" | ||
| 167 | required-features = [ "ucpd",] | ||
| 168 | |||
| 169 | [[bin]] | ||
| 140 | name = "usart" | 170 | name = "usart" |
| 141 | path = "src/bin/usart.rs" | 171 | path = "src/bin/usart.rs" |
| 142 | required-features = [] | 172 | required-features = [] |
diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs index c5d0e40d6..176adff62 100644 --- a/tests/stm32/build.rs +++ b/tests/stm32/build.rs | |||
| @@ -4,7 +4,7 @@ use std::{env, fs}; | |||
| 4 | 4 | ||
| 5 | fn main() -> Result<(), Box<dyn Error>> { | 5 | fn main() -> Result<(), Box<dyn Error>> { |
| 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); | 6 | let out = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| 7 | fs::write(out.join("link_ram.x"), include_bytes!("link_ram.x")).unwrap(); | 7 | fs::write(out.join("link_ram.x"), include_bytes!("../link_ram_cortex_m.x")).unwrap(); |
| 8 | println!("cargo:rustc-link-search={}", out.display()); | 8 | println!("cargo:rustc-link-search={}", out.display()); |
| 9 | println!("cargo:rustc-link-arg-bins=--nmagic"); | 9 | println!("cargo:rustc-link-arg-bins=--nmagic"); |
| 10 | 10 | ||
| @@ -16,6 +16,9 @@ fn main() -> Result<(), Box<dyn Error>> { | |||
| 16 | feature = "stm32l073rz", | 16 | feature = "stm32l073rz", |
| 17 | // wrong ram size in stm32-data | 17 | // wrong ram size in stm32-data |
| 18 | feature = "stm32wl55jc", | 18 | feature = "stm32wl55jc", |
| 19 | feature = "stm32u5a5zj", | ||
| 20 | // no VTOR, so interrupts can't work when running from RAM | ||
| 21 | feature = "stm32f091rc", | ||
| 19 | )) { | 22 | )) { |
| 20 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); | 23 | println!("cargo:rustc-link-arg-bins=-Tlink.x"); |
| 21 | println!("cargo:rerun-if-changed=link.x"); | 24 | println!("cargo:rerun-if-changed=link.x"); |
diff --git a/tests/stm32/src/bin/can.rs b/tests/stm32/src/bin/can.rs index f4effa244..c08c69a3b 100644 --- a/tests/stm32/src/bin/can.rs +++ b/tests/stm32/src/bin/can.rs | |||
| @@ -9,8 +9,8 @@ use common::*; | |||
| 9 | use defmt::assert; | 9 | use defmt::assert; |
| 10 | use embassy_executor::Spawner; | 10 | use embassy_executor::Spawner; |
| 11 | use embassy_stm32::bind_interrupts; | 11 | use embassy_stm32::bind_interrupts; |
| 12 | use embassy_stm32::can::bxcan::filter::Mask32; | 12 | use embassy_stm32::can::bx::filter::Mask32; |
| 13 | use embassy_stm32::can::bxcan::{Fifo, Frame, StandardId}; | 13 | use embassy_stm32::can::bx::{Fifo, Frame, StandardId}; |
| 14 | use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler}; | 14 | use embassy_stm32::can::{Can, Rx0InterruptHandler, Rx1InterruptHandler, SceInterruptHandler, TxInterruptHandler}; |
| 15 | use embassy_stm32::gpio::{Input, Pull}; | 15 | use embassy_stm32::gpio::{Input, Pull}; |
| 16 | use embassy_stm32::peripherals::CAN1; | 16 | use embassy_stm32::peripherals::CAN1; |
| @@ -60,7 +60,7 @@ async fn main(_spawner: Spawner) { | |||
| 60 | 60 | ||
| 61 | let mut i: u8 = 0; | 61 | let mut i: u8 = 0; |
| 62 | loop { | 62 | loop { |
| 63 | let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), [i]); | 63 | let tx_frame = Frame::new_data(unwrap!(StandardId::new(i as _)), &[i]).unwrap(); |
| 64 | 64 | ||
| 65 | info!("Transmitting frame..."); | 65 | info!("Transmitting frame..."); |
| 66 | let tx_ts = Instant::now(); | 66 | let tx_ts = Instant::now(); |
| @@ -70,7 +70,7 @@ async fn main(_spawner: Spawner) { | |||
| 70 | info!("Frame received!"); | 70 | info!("Frame received!"); |
| 71 | 71 | ||
| 72 | info!("loopback time {}", envelope.ts); | 72 | info!("loopback time {}", envelope.ts); |
| 73 | info!("loopback frame {=u8}", envelope.frame.data().unwrap()[0]); | 73 | info!("loopback frame {=u8}", envelope.frame.data()[0]); |
| 74 | 74 | ||
| 75 | let latency = envelope.ts.saturating_duration_since(tx_ts); | 75 | let latency = envelope.ts.saturating_duration_since(tx_ts); |
| 76 | info!("loopback latency {} us", latency.as_micros()); | 76 | info!("loopback latency {} us", latency.as_micros()); |
diff --git a/tests/stm32/src/bin/cryp.rs b/tests/stm32/src/bin/cryp.rs new file mode 100644 index 000000000..60778bdaa --- /dev/null +++ b/tests/stm32/src/bin/cryp.rs | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | // required-features: cryp | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | |||
| 8 | use aes_gcm::aead::heapless::Vec; | ||
| 9 | use aes_gcm::aead::{AeadInPlace, KeyInit}; | ||
| 10 | use aes_gcm::Aes128Gcm; | ||
| 11 | use common::*; | ||
| 12 | use embassy_executor::Spawner; | ||
| 13 | use embassy_stm32::cryp::{self, *}; | ||
| 14 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 15 | use {defmt_rtt as _, panic_probe as _}; | ||
| 16 | |||
| 17 | bind_interrupts!(struct Irqs { | ||
| 18 | CRYP => cryp::InterruptHandler<peripherals::CRYP>; | ||
| 19 | }); | ||
| 20 | |||
| 21 | #[embassy_executor::main] | ||
| 22 | async fn main(_spawner: Spawner) { | ||
| 23 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | ||
| 24 | |||
| 25 | const PAYLOAD1: &[u8] = b"payload data 1 ;zdfhzdfhS;GKJASBDG;ASKDJBAL,zdfhzdfhzdfhzdfhvljhb,jhbjhb,sdhsdghsdhsfhsghzdfhzdfhzdfhzdfdhsdthsthsdhsgaadfhhgkdgfuoyguoft6783567"; | ||
| 26 | const PAYLOAD2: &[u8] = b"payload data 2 ;SKEzdfhzdfhzbhgvljhb,jhbjhb,sdhsdghsdhsfhsghshsfhshstsdthadfhsdfjhsfgjsfgjxfgjzdhgDFghSDGHjtfjtjszftjzsdtjhstdsdhsdhsdhsdhsdthsthsdhsgfh"; | ||
| 27 | const AAD1: &[u8] = b"additional data 1 stdargadrhaethaethjatjatjaetjartjstrjsfkk;'jopofyuisrteytweTASTUIKFUKIXTRDTEREharhaeryhaterjartjarthaethjrtjarthaetrhartjatejatrjsrtjartjyt1"; | ||
| 28 | const AAD2: &[u8] = b"additional data 2 stdhthsthsthsrthsrthsrtjdykjdukdyuldadfhsdghsdghsdghsadghjk'hioethjrtjarthaetrhartjatecfgjhzdfhgzdfhzdfghzdfhzdfhzfhjatrjsrtjartjytjfytjfyg"; | ||
| 29 | |||
| 30 | let in_dma = peri!(p, CRYP_IN_DMA); | ||
| 31 | let out_dma = peri!(p, CRYP_OUT_DMA); | ||
| 32 | |||
| 33 | let mut hw_cryp = Cryp::new(p.CRYP, in_dma, out_dma, Irqs); | ||
| 34 | let key: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; | ||
| 35 | let mut ciphertext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()]; | ||
| 36 | let mut plaintext: [u8; PAYLOAD1.len() + PAYLOAD2.len()] = [0; PAYLOAD1.len() + PAYLOAD2.len()]; | ||
| 37 | let iv: [u8; 12] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; | ||
| 38 | |||
| 39 | // Encrypt in hardware using AES-GCM 128-bit in blocking mode. | ||
| 40 | let aes_gcm = AesGcm::new(&key, &iv); | ||
| 41 | let mut gcm_encrypt = hw_cryp.start_blocking(&aes_gcm, Direction::Encrypt); | ||
| 42 | hw_cryp.aad_blocking(&mut gcm_encrypt, AAD1, false); | ||
| 43 | hw_cryp.aad_blocking(&mut gcm_encrypt, AAD2, true); | ||
| 44 | hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD1, &mut ciphertext[..PAYLOAD1.len()], false); | ||
| 45 | hw_cryp.payload_blocking(&mut gcm_encrypt, PAYLOAD2, &mut ciphertext[PAYLOAD1.len()..], true); | ||
| 46 | let encrypt_tag = hw_cryp.finish_blocking(gcm_encrypt); | ||
| 47 | |||
| 48 | // Decrypt in hardware using AES-GCM 128-bit in async (DMA) mode. | ||
| 49 | let mut gcm_decrypt = hw_cryp.start(&aes_gcm, Direction::Decrypt).await; | ||
| 50 | hw_cryp.aad(&mut gcm_decrypt, AAD1, false).await; | ||
| 51 | hw_cryp.aad(&mut gcm_decrypt, AAD2, true).await; | ||
| 52 | hw_cryp | ||
| 53 | .payload(&mut gcm_decrypt, &ciphertext, &mut plaintext, true) | ||
| 54 | .await; | ||
| 55 | let decrypt_tag = hw_cryp.finish(gcm_decrypt).await; | ||
| 56 | |||
| 57 | info!("AES-GCM Ciphertext: {:?}", ciphertext); | ||
| 58 | info!("AES-GCM Plaintext: {:?}", plaintext); | ||
| 59 | defmt::assert!(PAYLOAD1 == &plaintext[..PAYLOAD1.len()]); | ||
| 60 | defmt::assert!(PAYLOAD2 == &plaintext[PAYLOAD1.len()..]); | ||
| 61 | defmt::assert!(encrypt_tag == decrypt_tag); | ||
| 62 | |||
| 63 | // Encrypt in software using AES-GCM 128-bit | ||
| 64 | let mut payload_vec: Vec<u8, { PAYLOAD1.len() + PAYLOAD2.len() + 16 }> = Vec::from_slice(&PAYLOAD1).unwrap(); | ||
| 65 | payload_vec.extend_from_slice(&PAYLOAD2).unwrap(); | ||
| 66 | let cipher = Aes128Gcm::new(&key.into()); | ||
| 67 | let mut aad: Vec<u8, { AAD1.len() + AAD2.len() }> = Vec::from_slice(&AAD1).unwrap(); | ||
| 68 | aad.extend_from_slice(&AAD2).unwrap(); | ||
| 69 | let _ = cipher.encrypt_in_place(&iv.into(), &aad, &mut payload_vec); | ||
| 70 | |||
| 71 | defmt::assert!(ciphertext == payload_vec[0..ciphertext.len()]); | ||
| 72 | defmt::assert!(encrypt_tag == payload_vec[ciphertext.len()..ciphertext.len() + encrypt_tag.len()]); | ||
| 73 | |||
| 74 | // Decrypt in software using AES-GCM 128-bit | ||
| 75 | let _ = cipher.decrypt_in_place(&iv.into(), &aad, &mut payload_vec); | ||
| 76 | |||
| 77 | info!("Test OK"); | ||
| 78 | cortex_m::asm::bkpt(); | ||
| 79 | } | ||
diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs index 754354944..7c02f0354 100644 --- a/tests/stm32/src/bin/eth.rs +++ b/tests/stm32/src/bin/eth.rs | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | // required-features: eth | 1 | // required-features: eth |
| 2 | #![no_std] | 2 | #![no_std] |
| 3 | #![no_main] | 3 | #![no_main] |
| 4 | #![feature(type_alias_impl_trait)] | ||
| 5 | 4 | ||
| 6 | #[path = "../common.rs"] | 5 | #[path = "../common.rs"] |
| 7 | mod common; | 6 | mod common; |
| @@ -14,7 +13,7 @@ use embassy_stm32::peripherals::ETH; | |||
| 14 | use embassy_stm32::rng::Rng; | 13 | use embassy_stm32::rng::Rng; |
| 15 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; | 14 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng}; |
| 16 | use rand_core::RngCore; | 15 | use rand_core::RngCore; |
| 17 | use static_cell::make_static; | 16 | use static_cell::StaticCell; |
| 18 | use {defmt_rtt as _, panic_probe as _}; | 17 | use {defmt_rtt as _, panic_probe as _}; |
| 19 | 18 | ||
| 20 | teleprobe_meta::timeout!(120); | 19 | teleprobe_meta::timeout!(120); |
| @@ -71,8 +70,9 @@ async fn main(spawner: Spawner) { | |||
| 71 | #[cfg(not(feature = "stm32f207zg"))] | 70 | #[cfg(not(feature = "stm32f207zg"))] |
| 72 | const PACKET_QUEUE_SIZE: usize = 4; | 71 | const PACKET_QUEUE_SIZE: usize = 4; |
| 73 | 72 | ||
| 73 | static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new(); | ||
| 74 | let device = Ethernet::new( | 74 | let device = Ethernet::new( |
| 75 | make_static!(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()), | 75 | PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()), |
| 76 | p.ETH, | 76 | p.ETH, |
| 77 | Irqs, | 77 | Irqs, |
| 78 | p.PA1, | 78 | p.PA1, |
| @@ -99,11 +99,13 @@ async fn main(spawner: Spawner) { | |||
| 99 | //}); | 99 | //}); |
| 100 | 100 | ||
| 101 | // Init network stack | 101 | // Init network stack |
| 102 | let stack = &*make_static!(Stack::new( | 102 | static STACK: StaticCell<Stack<Device>> = StaticCell::new(); |
| 103 | static RESOURCES: StaticCell<StackResources<2>> = StaticCell::new(); | ||
| 104 | let stack = &*STACK.init(Stack::new( | ||
| 103 | device, | 105 | device, |
| 104 | config, | 106 | config, |
| 105 | make_static!(StackResources::<2>::new()), | 107 | RESOURCES.init(StackResources::<2>::new()), |
| 106 | seed | 108 | seed, |
| 107 | )); | 109 | )); |
| 108 | 110 | ||
| 109 | // Launch network task | 111 | // Launch network task |
diff --git a/tests/stm32/src/bin/fdcan.rs b/tests/stm32/src/bin/fdcan.rs new file mode 100644 index 000000000..c7373e294 --- /dev/null +++ b/tests/stm32/src/bin/fdcan.rs | |||
| @@ -0,0 +1,239 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | // required-features: fdcan | ||
| 5 | |||
| 6 | #[path = "../common.rs"] | ||
| 7 | mod common; | ||
| 8 | use common::*; | ||
| 9 | use defmt::assert; | ||
| 10 | use embassy_executor::Spawner; | ||
| 11 | use embassy_stm32::peripherals::*; | ||
| 12 | use embassy_stm32::{bind_interrupts, can, Config}; | ||
| 13 | use embassy_time::{Duration, Instant}; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | bind_interrupts!(struct Irqs2 { | ||
| 17 | FDCAN2_IT0 => can::IT0InterruptHandler<FDCAN2>; | ||
| 18 | FDCAN2_IT1 => can::IT1InterruptHandler<FDCAN2>; | ||
| 19 | }); | ||
| 20 | bind_interrupts!(struct Irqs1 { | ||
| 21 | FDCAN1_IT0 => can::IT0InterruptHandler<FDCAN1>; | ||
| 22 | FDCAN1_IT1 => can::IT1InterruptHandler<FDCAN1>; | ||
| 23 | }); | ||
| 24 | |||
| 25 | struct TestOptions { | ||
| 26 | config: Config, | ||
| 27 | max_latency: Duration, | ||
| 28 | second_fifo_working: bool, | ||
| 29 | } | ||
| 30 | |||
| 31 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi", feature = "stm32h563zi"))] | ||
| 32 | fn options() -> TestOptions { | ||
| 33 | use embassy_stm32::rcc; | ||
| 34 | info!("H75 config"); | ||
| 35 | let mut c = config(); | ||
| 36 | c.rcc.hse = Some(rcc::Hse { | ||
| 37 | freq: embassy_stm32::time::Hertz(25_000_000), | ||
| 38 | mode: rcc::HseMode::Oscillator, | ||
| 39 | }); | ||
| 40 | c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; | ||
| 41 | TestOptions { | ||
| 42 | config: c, | ||
| 43 | max_latency: Duration::from_micros(1200), | ||
| 44 | second_fifo_working: false, | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | #[cfg(any(feature = "stm32h7a3zi"))] | ||
| 49 | fn options() -> TestOptions { | ||
| 50 | use embassy_stm32::rcc; | ||
| 51 | info!("H7a config"); | ||
| 52 | let mut c = config(); | ||
| 53 | c.rcc.hse = Some(rcc::Hse { | ||
| 54 | freq: embassy_stm32::time::Hertz(25_000_000), | ||
| 55 | mode: rcc::HseMode::Oscillator, | ||
| 56 | }); | ||
| 57 | c.rcc.mux.fdcansel = rcc::mux::Fdcansel::HSE; | ||
| 58 | TestOptions { | ||
| 59 | config: c, | ||
| 60 | max_latency: Duration::from_micros(1200), | ||
| 61 | second_fifo_working: false, | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | #[cfg(any(feature = "stm32g491re", feature = "stm32g431cb"))] | ||
| 66 | fn options() -> TestOptions { | ||
| 67 | info!("G4 config"); | ||
| 68 | TestOptions { | ||
| 69 | config: config(), | ||
| 70 | max_latency: Duration::from_micros(500), | ||
| 71 | second_fifo_working: true, | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | #[embassy_executor::main] | ||
| 76 | async fn main(_spawner: Spawner) { | ||
| 77 | //let peripherals = embassy_stm32::init(config()); | ||
| 78 | |||
| 79 | let options = options(); | ||
| 80 | let peripherals = embassy_stm32::init(options.config); | ||
| 81 | |||
| 82 | let mut can = can::FdcanConfigurator::new(peripherals.FDCAN1, peripherals.PB8, peripherals.PB9, Irqs1); | ||
| 83 | let mut can2 = can::FdcanConfigurator::new(peripherals.FDCAN2, peripherals.PB12, peripherals.PB13, Irqs2); | ||
| 84 | |||
| 85 | // 250k bps | ||
| 86 | can.set_bitrate(250_000); | ||
| 87 | can2.set_bitrate(250_000); | ||
| 88 | |||
| 89 | can.set_extended_filter( | ||
| 90 | can::filter::ExtendedFilterSlot::_0, | ||
| 91 | can::filter::ExtendedFilter::accept_all_into_fifo1(), | ||
| 92 | ); | ||
| 93 | can2.set_extended_filter( | ||
| 94 | can::filter::ExtendedFilterSlot::_0, | ||
| 95 | can::filter::ExtendedFilter::accept_all_into_fifo1(), | ||
| 96 | ); | ||
| 97 | |||
| 98 | let mut can = can.into_internal_loopback_mode(); | ||
| 99 | let mut can2 = can2.into_internal_loopback_mode(); | ||
| 100 | |||
| 101 | info!("CAN Configured"); | ||
| 102 | |||
| 103 | let mut i: u8 = 0; | ||
| 104 | loop { | ||
| 105 | let tx_frame = can::frame::ClassicFrame::new_standard(0x123, &[i; 1]).unwrap(); | ||
| 106 | |||
| 107 | info!("Transmitting frame..."); | ||
| 108 | let tx_ts = Instant::now(); | ||
| 109 | can.write(&tx_frame).await; | ||
| 110 | |||
| 111 | let (frame, timestamp) = can.read().await.unwrap(); | ||
| 112 | info!("Frame received!"); | ||
| 113 | |||
| 114 | // Check data. | ||
| 115 | assert!(i == frame.data()[0], "{} == {}", i, frame.data()[0]); | ||
| 116 | |||
| 117 | info!("loopback time {}", timestamp); | ||
| 118 | info!("loopback frame {=u8}", frame.data()[0]); | ||
| 119 | let latency = timestamp.saturating_duration_since(tx_ts); | ||
| 120 | info!("loopback latency {} us", latency.as_micros()); | ||
| 121 | |||
| 122 | // Theoretical minimum latency is 55us, actual is usually ~80us | ||
| 123 | const MIN_LATENCY: Duration = Duration::from_micros(50); | ||
| 124 | // Was failing at 150 but we are not getting a real time stamp. I'm not | ||
| 125 | // sure if there are other delays | ||
| 126 | assert!( | ||
| 127 | MIN_LATENCY <= latency && latency <= options.max_latency, | ||
| 128 | "{} <= {} <= {}", | ||
| 129 | MIN_LATENCY, | ||
| 130 | latency, | ||
| 131 | options.max_latency | ||
| 132 | ); | ||
| 133 | |||
| 134 | i += 1; | ||
| 135 | if i > 10 { | ||
| 136 | break; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | let mut i: u8 = 0; | ||
| 141 | loop { | ||
| 142 | let tx_frame = can::frame::ClassicFrame::new_standard(0x123, &[i; 1]).unwrap(); | ||
| 143 | |||
| 144 | info!("Transmitting frame..."); | ||
| 145 | let tx_ts = Instant::now(); | ||
| 146 | can2.write(&tx_frame).await; | ||
| 147 | |||
| 148 | let (frame, timestamp) = can2.read().await.unwrap(); | ||
| 149 | info!("Frame received!"); | ||
| 150 | |||
| 151 | //print_regs().await; | ||
| 152 | // Check data. | ||
| 153 | assert!(i == frame.data()[0], "{} == {}", i, frame.data()[0]); | ||
| 154 | |||
| 155 | info!("loopback time {}", timestamp); | ||
| 156 | info!("loopback frame {=u8}", frame.data()[0]); | ||
| 157 | let latency = timestamp.saturating_duration_since(tx_ts); | ||
| 158 | info!("loopback latency {} us", latency.as_micros()); | ||
| 159 | |||
| 160 | // Theoretical minimum latency is 55us, actual is usually ~80us | ||
| 161 | const MIN_LATENCY: Duration = Duration::from_micros(50); | ||
| 162 | // Was failing at 150 but we are not getting a real time stamp. I'm not | ||
| 163 | // sure if there are other delays | ||
| 164 | assert!( | ||
| 165 | MIN_LATENCY <= latency && latency <= options.max_latency, | ||
| 166 | "{} <= {} <= {}", | ||
| 167 | MIN_LATENCY, | ||
| 168 | latency, | ||
| 169 | options.max_latency | ||
| 170 | ); | ||
| 171 | |||
| 172 | i += 1; | ||
| 173 | if i > 10 { | ||
| 174 | break; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | let max_buffered = if options.second_fifo_working { 6 } else { 3 }; | ||
| 179 | |||
| 180 | // Below here, check that we can receive from both FIFO0 and FIFO0 | ||
| 181 | // Above we configured FIFO1 for extended ID packets. There are only 3 slots | ||
| 182 | // in each FIFO so make sure we write enough to fill them both up before reading. | ||
| 183 | for i in 0..3 { | ||
| 184 | // Try filling up the RX FIFO0 buffers with standard packets | ||
| 185 | let tx_frame = can::frame::ClassicFrame::new_standard(0x123, &[i; 1]).unwrap(); | ||
| 186 | info!("Transmitting frame {}", i); | ||
| 187 | can.write(&tx_frame).await; | ||
| 188 | } | ||
| 189 | for i in 3..max_buffered { | ||
| 190 | // Try filling up the RX FIFO0 buffers with extended packets | ||
| 191 | let tx_frame = can::frame::ClassicFrame::new_extended(0x1232344, &[i; 1]).unwrap(); | ||
| 192 | info!("Transmitting frame {}", i); | ||
| 193 | can.write(&tx_frame).await; | ||
| 194 | } | ||
| 195 | |||
| 196 | // Try and receive all 6 packets | ||
| 197 | for i in 0..max_buffered { | ||
| 198 | let (frame, _ts) = can.read().await.unwrap(); | ||
| 199 | match frame.id() { | ||
| 200 | embedded_can::Id::Extended(id) => { | ||
| 201 | info!("Extended received! {:x} {} {}", id.as_raw(), frame.data()[0], i); | ||
| 202 | } | ||
| 203 | embedded_can::Id::Standard(id) => { | ||
| 204 | info!("Standard received! {:x} {} {}", id.as_raw(), frame.data()[0], i); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | // Test again with a split | ||
| 210 | let (mut tx, mut rx) = can.split(); | ||
| 211 | for i in 0..3 { | ||
| 212 | // Try filling up the RX FIFO0 buffers with standard packets | ||
| 213 | let tx_frame = can::frame::ClassicFrame::new_standard(0x123, &[i; 1]).unwrap(); | ||
| 214 | info!("Transmitting frame {}", i); | ||
| 215 | tx.write(&tx_frame).await; | ||
| 216 | } | ||
| 217 | for i in 3..max_buffered { | ||
| 218 | // Try filling up the RX FIFO0 buffers with extended packets | ||
| 219 | let tx_frame = can::frame::ClassicFrame::new_extended(0x1232344, &[i; 1]).unwrap(); | ||
| 220 | info!("Transmitting frame {}", i); | ||
| 221 | tx.write(&tx_frame).await; | ||
| 222 | } | ||
| 223 | |||
| 224 | // Try and receive all 6 packets | ||
| 225 | for i in 0..max_buffered { | ||
| 226 | let (frame, _ts) = rx.read().await.unwrap(); | ||
| 227 | match frame.id() { | ||
| 228 | embedded_can::Id::Extended(id) => { | ||
| 229 | info!("Extended received! {:x} {} {}", id.as_raw(), frame.data()[0], i); | ||
| 230 | } | ||
| 231 | embedded_can::Id::Standard(id) => { | ||
| 232 | info!("Standard received! {:x} {} {}", id.as_raw(), frame.data()[0], i); | ||
| 233 | } | ||
| 234 | } | ||
| 235 | } | ||
| 236 | |||
| 237 | info!("Test OK"); | ||
| 238 | cortex_m::asm::bkpt(); | ||
| 239 | } | ||
diff --git a/tests/stm32/src/bin/hash.rs b/tests/stm32/src/bin/hash.rs new file mode 100644 index 000000000..8cc5d593f --- /dev/null +++ b/tests/stm32/src/bin/hash.rs | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | // required-features: hash | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | |||
| 5 | #[path = "../common.rs"] | ||
| 6 | mod common; | ||
| 7 | use common::*; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_stm32::dma::NoDma; | ||
| 10 | use embassy_stm32::hash::*; | ||
| 11 | use embassy_stm32::{bind_interrupts, hash, peripherals}; | ||
| 12 | use hmac::{Hmac, Mac}; | ||
| 13 | use sha2::{Digest, Sha224, Sha256}; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | type HmacSha256 = Hmac<Sha256>; | ||
| 17 | |||
| 18 | #[cfg(any(feature = "stm32l4a6zg", feature = "stm32h755zi", feature = "stm32h753zi"))] | ||
| 19 | bind_interrupts!(struct Irqs { | ||
| 20 | HASH_RNG => hash::InterruptHandler<peripherals::HASH>; | ||
| 21 | }); | ||
| 22 | |||
| 23 | #[cfg(any( | ||
| 24 | feature = "stm32wba52cg", | ||
| 25 | feature = "stm32l552ze", | ||
| 26 | feature = "stm32h563zi", | ||
| 27 | feature = "stm32h503rb", | ||
| 28 | feature = "stm32u5a5zj", | ||
| 29 | feature = "stm32u585ai" | ||
| 30 | ))] | ||
| 31 | bind_interrupts!(struct Irqs { | ||
| 32 | HASH => hash::InterruptHandler<peripherals::HASH>; | ||
| 33 | }); | ||
| 34 | |||
| 35 | #[embassy_executor::main] | ||
| 36 | async fn main(_spawner: Spawner) { | ||
| 37 | let p: embassy_stm32::Peripherals = embassy_stm32::init(config()); | ||
| 38 | let mut hw_hasher = Hash::new(p.HASH, NoDma, Irqs); | ||
| 39 | |||
| 40 | let test_1: &[u8] = b"as;dfhaslfhas;oifvnasd;nifvnhasd;nifvhndlkfghsd;nvfnahssdfgsdafgsasdfasdfasdfasdfasdfghjklmnbvcalskdjghalskdjgfbaslkdjfgbalskdjgbalskdjbdfhsdfhsfghsfghfgh"; | ||
| 41 | let test_2: &[u8] = b"fdhalksdjfhlasdjkfhalskdjfhgal;skdjfgalskdhfjgalskdjfglafgadfgdfgdafgaadsfgfgdfgadrgsyfthxfgjfhklhjkfgukhulkvhlvhukgfhfsrghzdhxyfufynufyuszeradrtydyytserr"; | ||
| 42 | let test_3: &[u8] = b"a.ewtkluGWEBR.KAJRBTA,RMNRBG,FDMGB.kger.tkasjrbt.akrjtba.krjtba.ktmyna,nmbvtyliasd;gdrtba,sfvs.kgjzshd.gkbsr.tksejb.SDkfBSE.gkfgb>ESkfbSE>gkJSBESE>kbSE>fk"; | ||
| 43 | |||
| 44 | // Start an SHA-256 digest. | ||
| 45 | let mut sha256context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, None); | ||
| 46 | hw_hasher.update_blocking(&mut sha256context, test_1); | ||
| 47 | |||
| 48 | // Interrupt the SHA-256 digest to compute an SHA-224 digest. | ||
| 49 | let mut sha224context = hw_hasher.start(Algorithm::SHA224, DataType::Width8, None); | ||
| 50 | hw_hasher.update_blocking(&mut sha224context, test_3); | ||
| 51 | let mut sha224_digest_buffer: [u8; 28] = [0; 28]; | ||
| 52 | let _ = hw_hasher.finish_blocking(sha224context, &mut sha224_digest_buffer); | ||
| 53 | |||
| 54 | // Finish the SHA-256 digest. | ||
| 55 | hw_hasher.update_blocking(&mut sha256context, test_2); | ||
| 56 | let mut sha256_digest_buffer: [u8; 32] = [0; 32]; | ||
| 57 | let _ = hw_hasher.finish_blocking(sha256context, &mut sha256_digest_buffer); | ||
| 58 | |||
| 59 | // Compute the SHA-256 digest in software. | ||
| 60 | let mut sw_sha256_hasher = Sha256::new(); | ||
| 61 | sw_sha256_hasher.update(test_1); | ||
| 62 | sw_sha256_hasher.update(test_2); | ||
| 63 | let sw_sha256_digest = sw_sha256_hasher.finalize(); | ||
| 64 | |||
| 65 | //Compute the SHA-224 digest in software. | ||
| 66 | let mut sw_sha224_hasher = Sha224::new(); | ||
| 67 | sw_sha224_hasher.update(test_3); | ||
| 68 | let sw_sha224_digest = sw_sha224_hasher.finalize(); | ||
| 69 | |||
| 70 | // Compare the SHA-256 digests. | ||
| 71 | info!("Hardware SHA-256 Digest: {:?}", sha256_digest_buffer); | ||
| 72 | info!("Software SHA-256 Digest: {:?}", sw_sha256_digest[..]); | ||
| 73 | defmt::assert!(sha256_digest_buffer == sw_sha256_digest[..]); | ||
| 74 | |||
| 75 | // Compare the SHA-224 digests. | ||
| 76 | info!("Hardware SHA-256 Digest: {:?}", sha224_digest_buffer); | ||
| 77 | info!("Software SHA-256 Digest: {:?}", sw_sha224_digest[..]); | ||
| 78 | defmt::assert!(sha224_digest_buffer == sw_sha224_digest[..]); | ||
| 79 | |||
| 80 | let hmac_key: [u8; 64] = [0x55; 64]; | ||
| 81 | |||
| 82 | // Compute HMAC in hardware. | ||
| 83 | let mut sha256hmac_context = hw_hasher.start(Algorithm::SHA256, DataType::Width8, Some(&hmac_key)); | ||
| 84 | hw_hasher.update_blocking(&mut sha256hmac_context, test_1); | ||
| 85 | hw_hasher.update_blocking(&mut sha256hmac_context, test_2); | ||
| 86 | let mut hw_hmac: [u8; 32] = [0; 32]; | ||
| 87 | hw_hasher.finish_blocking(sha256hmac_context, &mut hw_hmac); | ||
| 88 | |||
| 89 | // Compute HMAC in software. | ||
| 90 | let mut sw_mac = HmacSha256::new_from_slice(&hmac_key).unwrap(); | ||
| 91 | sw_mac.update(test_1); | ||
| 92 | sw_mac.update(test_2); | ||
| 93 | let sw_hmac = sw_mac.finalize().into_bytes(); | ||
| 94 | |||
| 95 | info!("Hardware HMAC: {:?}", hw_hmac); | ||
| 96 | info!("Software HMAC: {:?}", sw_hmac[..]); | ||
| 97 | defmt::assert!(hw_hmac == sw_hmac[..]); | ||
| 98 | |||
| 99 | info!("Test OK"); | ||
| 100 | cortex_m::asm::bkpt(); | ||
| 101 | } | ||
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs index b9810673a..000296d46 100644 --- a/tests/stm32/src/bin/stop.rs +++ b/tests/stm32/src/bin/stop.rs | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | 2 | ||
| 3 | #![no_std] | 3 | #![no_std] |
| 4 | #![no_main] | 4 | #![no_main] |
| 5 | #![feature(type_alias_impl_trait)] | ||
| 6 | #[path = "../common.rs"] | 5 | #[path = "../common.rs"] |
| 7 | mod common; | 6 | mod common; |
| 8 | 7 | ||
| @@ -15,7 +14,7 @@ use embassy_stm32::rcc::LsConfig; | |||
| 15 | use embassy_stm32::rtc::{Rtc, RtcConfig}; | 14 | use embassy_stm32::rtc::{Rtc, RtcConfig}; |
| 16 | use embassy_stm32::Config; | 15 | use embassy_stm32::Config; |
| 17 | use embassy_time::Timer; | 16 | use embassy_time::Timer; |
| 18 | use static_cell::make_static; | 17 | use static_cell::StaticCell; |
| 19 | 18 | ||
| 20 | #[entry] | 19 | #[entry] |
| 21 | fn main() -> ! { | 20 | fn main() -> ! { |
| @@ -64,7 +63,8 @@ async fn async_main(spawner: Spawner) { | |||
| 64 | 63 | ||
| 65 | rtc.set_datetime(now.into()).expect("datetime not set"); | 64 | rtc.set_datetime(now.into()).expect("datetime not set"); |
| 66 | 65 | ||
| 67 | let rtc = make_static!(rtc); | 66 | static RTC: StaticCell<Rtc> = StaticCell::new(); |
| 67 | let rtc = RTC.init(rtc); | ||
| 68 | 68 | ||
| 69 | stop_with_rtc(rtc); | 69 | stop_with_rtc(rtc); |
| 70 | 70 | ||
diff --git a/tests/stm32/src/bin/ucpd.rs b/tests/stm32/src/bin/ucpd.rs new file mode 100644 index 000000000..c09334ec8 --- /dev/null +++ b/tests/stm32/src/bin/ucpd.rs | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | // required-features: ucpd | ||
| 2 | #![no_std] | ||
| 3 | #![no_main] | ||
| 4 | #[path = "../common.rs"] | ||
| 5 | mod common; | ||
| 6 | |||
| 7 | use common::*; | ||
| 8 | use defmt::{assert, assert_eq}; | ||
| 9 | use embassy_executor::Spawner; | ||
| 10 | use embassy_futures::join::join; | ||
| 11 | use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd}; | ||
| 12 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 13 | use embassy_time::Timer; | ||
| 14 | |||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | UCPD1_2 => ucpd::InterruptHandler<peripherals::UCPD1>, ucpd::InterruptHandler<peripherals::UCPD2>; | ||
| 17 | }); | ||
| 18 | |||
| 19 | static SRC_TO_SNK: [u8; 6] = [0, 1, 2, 3, 4, 5]; | ||
| 20 | static SNK_TO_SRC: [u8; 4] = [9, 8, 7, 6]; | ||
| 21 | |||
| 22 | async fn wait_for_vstate<T: ucpd::Instance>(cc_phy: &mut CcPhy<'_, T>, vstate: CcVState) { | ||
| 23 | let (mut cc1, mut _cc2) = cc_phy.vstate(); | ||
| 24 | while cc1 != vstate { | ||
| 25 | (cc1, _cc2) = cc_phy.wait_for_vstate_change().await; | ||
| 26 | } | ||
| 27 | } | ||
| 28 | |||
| 29 | async fn source( | ||
| 30 | mut ucpd: Ucpd<'static, peripherals::UCPD1>, | ||
| 31 | rx_dma: peripherals::DMA1_CH1, | ||
| 32 | tx_dma: peripherals::DMA1_CH2, | ||
| 33 | ) { | ||
| 34 | debug!("source: setting default current pull-up"); | ||
| 35 | ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb); | ||
| 36 | |||
| 37 | // Wait for default sink. | ||
| 38 | debug!("source: wait for sink"); | ||
| 39 | wait_for_vstate(ucpd.cc_phy(), CcVState::LOW).await; | ||
| 40 | |||
| 41 | // Advertise a higher current by changing the pull-up resistor. | ||
| 42 | debug!("source: sink detected, setting 3.0A current pull-up"); | ||
| 43 | ucpd.cc_phy().set_pull(CcPull::Source3_0A); | ||
| 44 | |||
| 45 | let (_, mut pd_phy) = ucpd.split_pd_phy(rx_dma, tx_dma, CcSel::CC1); | ||
| 46 | |||
| 47 | // Listen for an incoming message | ||
| 48 | debug!("source: wait for message from sink"); | ||
| 49 | let mut snk_to_src_buf = [0_u8; 30]; | ||
| 50 | let n = unwrap!(pd_phy.receive(snk_to_src_buf.as_mut()).await); | ||
| 51 | assert_eq!(n, SNK_TO_SRC.len()); | ||
| 52 | assert_eq!(&snk_to_src_buf[..n], SNK_TO_SRC.as_slice()); | ||
| 53 | |||
| 54 | // Send message | ||
| 55 | debug!("source: message received, sending message"); | ||
| 56 | unwrap!(pd_phy.transmit(SRC_TO_SNK.as_slice()).await); | ||
| 57 | |||
| 58 | // Wait for hard-reset | ||
| 59 | debug!("source: message sent, waiting for hard-reset"); | ||
| 60 | assert!(matches!( | ||
| 61 | pd_phy.receive(snk_to_src_buf.as_mut()).await, | ||
| 62 | Err(RxError::HardReset) | ||
| 63 | )); | ||
| 64 | } | ||
| 65 | |||
| 66 | async fn sink( | ||
| 67 | mut ucpd: Ucpd<'static, peripherals::UCPD2>, | ||
| 68 | rx_dma: peripherals::DMA1_CH3, | ||
| 69 | tx_dma: peripherals::DMA1_CH4, | ||
| 70 | ) { | ||
| 71 | debug!("sink: setting pull down"); | ||
| 72 | ucpd.cc_phy().set_pull(CcPull::Sink); | ||
| 73 | |||
| 74 | // Wait for default source. | ||
| 75 | debug!("sink: waiting for default vstate"); | ||
| 76 | wait_for_vstate(ucpd.cc_phy(), CcVState::LOW).await; | ||
| 77 | |||
| 78 | // Wait higher current pull-up. | ||
| 79 | //debug!("sink: source default vstate detected, waiting for 3.0A vstate"); | ||
| 80 | //wait_for_vstate(ucpd.cc_phy(), CcVState::HIGHEST).await; | ||
| 81 | //debug!("sink: source 3.0A vstate detected"); | ||
| 82 | // TODO: not working yet, why? no idea, replace with timer for now | ||
| 83 | Timer::after_millis(100).await; | ||
| 84 | |||
| 85 | let (_, mut pd_phy) = ucpd.split_pd_phy(rx_dma, tx_dma, CcSel::CC1); | ||
| 86 | |||
| 87 | // Send message | ||
| 88 | debug!("sink: sending message"); | ||
| 89 | unwrap!(pd_phy.transmit(SNK_TO_SRC.as_slice()).await); | ||
| 90 | |||
| 91 | // Listen for an incoming message | ||
| 92 | debug!("sink: message sent, waiting for message from source"); | ||
| 93 | let mut src_to_snk_buf = [0_u8; 30]; | ||
| 94 | let n = unwrap!(pd_phy.receive(src_to_snk_buf.as_mut()).await); | ||
| 95 | assert_eq!(n, SRC_TO_SNK.len()); | ||
| 96 | assert_eq!(&src_to_snk_buf[..n], SRC_TO_SNK.as_slice()); | ||
| 97 | |||
| 98 | // Send hard reset | ||
| 99 | debug!("sink: message received, sending hard-reset"); | ||
| 100 | unwrap!(pd_phy.transmit_hardreset().await); | ||
| 101 | } | ||
| 102 | |||
| 103 | #[embassy_executor::main] | ||
| 104 | async fn main(_spawner: Spawner) { | ||
| 105 | let p = embassy_stm32::init(config()); | ||
| 106 | info!("Hello World!"); | ||
| 107 | |||
| 108 | // Wire between PD0 and PA8 | ||
| 109 | let ucpd1 = Ucpd::new(p.UCPD1, Irqs {}, p.PA8, p.PB15); | ||
| 110 | let ucpd2 = Ucpd::new(p.UCPD2, Irqs {}, p.PD0, p.PD2); | ||
| 111 | |||
| 112 | join( | ||
| 113 | source(ucpd1, p.DMA1_CH1, p.DMA1_CH2), | ||
| 114 | sink(ucpd2, p.DMA1_CH3, p.DMA1_CH4), | ||
| 115 | ) | ||
| 116 | .await; | ||
| 117 | |||
| 118 | info!("Test OK"); | ||
| 119 | cortex_m::asm::bkpt(); | ||
| 120 | } | ||
diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs index f5d618db4..0c110421d 100644 --- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs +++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs | |||
| @@ -74,7 +74,7 @@ async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) | |||
| 74 | } | 74 | } |
| 75 | 75 | ||
| 76 | #[embassy_executor::task] | 76 | #[embassy_executor::task] |
| 77 | async fn receive_task(mut rx: RingBufferedUartRx<'static, peris::UART, peris::UART_RX_DMA>) { | 77 | async fn receive_task(mut rx: RingBufferedUartRx<'static, peris::UART>) { |
| 78 | info!("Ready to receive..."); | 78 | info!("Ready to receive..."); |
| 79 | 79 | ||
| 80 | let mut rng = ChaCha8Rng::seed_from_u64(1337); | 80 | let mut rng = ChaCha8Rng::seed_from_u64(1337); |
diff --git a/tests/stm32/src/bin/wpan_ble.rs b/tests/stm32/src/bin/wpan_ble.rs index ff838471b..82a540d45 100644 --- a/tests/stm32/src/bin/wpan_ble.rs +++ b/tests/stm32/src/bin/wpan_ble.rs | |||
| @@ -15,11 +15,9 @@ use embassy_stm32::rcc::WPAN_DEFAULT; | |||
| 15 | use embassy_stm32_wpan::hci::host::uart::UartHci; | 15 | use embassy_stm32_wpan::hci::host::uart::UartHci; |
| 16 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; | 16 | use embassy_stm32_wpan::hci::host::{AdvertisingFilterPolicy, EncryptionKey, HostHci, OwnAddressType}; |
| 17 | use embassy_stm32_wpan::hci::types::AdvertisingType; | 17 | use embassy_stm32_wpan::hci::types::AdvertisingType; |
| 18 | use embassy_stm32_wpan::hci::vendor::stm32wb::command::gap::{ | 18 | use embassy_stm32_wpan::hci::vendor::command::gap::{AdvertisingDataType, DiscoverableParameters, GapCommands, Role}; |
| 19 | AdvertisingDataType, DiscoverableParameters, GapCommands, Role, | 19 | use embassy_stm32_wpan::hci::vendor::command::gatt::GattCommands; |
| 20 | }; | 20 | use embassy_stm32_wpan::hci::vendor::command::hal::{ConfigData, HalCommands, PowerLevel}; |
| 21 | use embassy_stm32_wpan::hci::vendor::stm32wb::command::gatt::GattCommands; | ||
| 22 | use embassy_stm32_wpan::hci::vendor::stm32wb::command::hal::{ConfigData, HalCommands, PowerLevel}; | ||
| 23 | use embassy_stm32_wpan::hci::BdAddr; | 21 | use embassy_stm32_wpan::hci::BdAddr; |
| 24 | use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp; | 22 | use embassy_stm32_wpan::lhci::LhciC1DeviceInformationCcrp; |
| 25 | use embassy_stm32_wpan::sub::mm; | 23 | use embassy_stm32_wpan::sub::mm; |
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs index 313380b35..c379863a8 100644 --- a/tests/stm32/src/common.rs +++ b/tests/stm32/src/common.rs | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | 2 | ||
| 3 | pub use defmt::*; | 3 | pub use defmt::*; |
| 4 | #[allow(unused)] | 4 | #[allow(unused)] |
| 5 | use embassy_stm32::rcc::*; | ||
| 6 | #[allow(unused)] | ||
| 5 | use embassy_stm32::time::Hertz; | 7 | use embassy_stm32::time::Hertz; |
| 6 | use embassy_stm32::Config; | 8 | use embassy_stm32::Config; |
| 7 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -54,6 +56,10 @@ teleprobe_meta::target!(b"nucleo-stm32l496zg"); | |||
| 54 | teleprobe_meta::target!(b"nucleo-stm32wl55jc"); | 56 | teleprobe_meta::target!(b"nucleo-stm32wl55jc"); |
| 55 | #[cfg(feature = "stm32wba52cg")] | 57 | #[cfg(feature = "stm32wba52cg")] |
| 56 | teleprobe_meta::target!(b"nucleo-stm32wba52cg"); | 58 | teleprobe_meta::target!(b"nucleo-stm32wba52cg"); |
| 59 | #[cfg(feature = "stm32f091rc")] | ||
| 60 | teleprobe_meta::target!(b"nucleo-stm32f091rc"); | ||
| 61 | #[cfg(feature = "stm32h503rb")] | ||
| 62 | teleprobe_meta::target!(b"nucleo-stm32h503rb"); | ||
| 57 | 63 | ||
| 58 | macro_rules! define_peris { | 64 | macro_rules! define_peris { |
| 59 | ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { | 65 | ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => { |
| @@ -85,6 +91,12 @@ macro_rules! define_peris { | |||
| 85 | }; | 91 | }; |
| 86 | } | 92 | } |
| 87 | 93 | ||
| 94 | #[cfg(feature = "stm32f091rc")] | ||
| 95 | define_peris!( | ||
| 96 | UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5, | ||
| 97 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2, | ||
| 98 | @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, | ||
| 99 | ); | ||
| 88 | #[cfg(feature = "stm32f103c8")] | 100 | #[cfg(feature = "stm32f103c8")] |
| 89 | define_peris!( | 101 | define_peris!( |
| 90 | UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5, | 102 | UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5, |
| @@ -128,6 +140,7 @@ define_peris!( | |||
| 128 | ); | 140 | ); |
| 129 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] | 141 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] |
| 130 | define_peris!( | 142 | define_peris!( |
| 143 | CRYP_IN_DMA = DMA1_CH0, CRYP_OUT_DMA = DMA1_CH1, | ||
| 131 | UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, | 144 | UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1, |
| 132 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, | 145 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1, |
| 133 | ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, | 146 | ADC = ADC1, DAC = DAC1, DAC_PIN = PA4, |
| @@ -157,6 +170,12 @@ define_peris!( | |||
| 157 | SPI = SPI4, SPI_SCK = PE12, SPI_MOSI = PE14, SPI_MISO = PE13, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, | 170 | SPI = SPI4, SPI_SCK = PE12, SPI_MOSI = PE14, SPI_MISO = PE13, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, |
| 158 | @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;}, | 171 | @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;}, |
| 159 | ); | 172 | ); |
| 173 | #[cfg(feature = "stm32h503rb")] | ||
| 174 | define_peris!( | ||
| 175 | UART = USART1, UART_TX = PB14, UART_RX = PB15, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1, | ||
| 176 | SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1, | ||
| 177 | @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;}, | ||
| 178 | ); | ||
| 160 | #[cfg(feature = "stm32c031c6")] | 179 | #[cfg(feature = "stm32c031c6")] |
| 161 | define_peris!( | 180 | define_peris!( |
| 162 | UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2, | 181 | UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2, |
| @@ -242,14 +261,68 @@ pub fn config() -> Config { | |||
| 242 | #[allow(unused_mut)] | 261 | #[allow(unused_mut)] |
| 243 | let mut config = Config::default(); | 262 | let mut config = Config::default(); |
| 244 | 263 | ||
| 264 | #[cfg(feature = "stm32c031c6")] | ||
| 265 | { | ||
| 266 | config.rcc.hsi = Some(Hsi { | ||
| 267 | sys_div: HsiSysDiv::DIV1, // 48Mhz | ||
| 268 | ker_div: HsiKerDiv::DIV3, // 16Mhz | ||
| 269 | }); | ||
| 270 | config.rcc.sys = Sysclk::HSISYS; | ||
| 271 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 272 | config.rcc.apb1_pre = APBPrescaler::DIV1; | ||
| 273 | } | ||
| 274 | |||
| 275 | #[cfg(feature = "stm32g071rb")] | ||
| 276 | { | ||
| 277 | config.rcc.hsi = true; | ||
| 278 | config.rcc.pll = Some(Pll { | ||
| 279 | source: PllSource::HSI, | ||
| 280 | prediv: PllPreDiv::DIV1, | ||
| 281 | mul: PllMul::MUL16, | ||
| 282 | divp: None, | ||
| 283 | divq: None, | ||
| 284 | divr: Some(PllRDiv::DIV4), // 16 / 1 * 16 / 4 = 64 Mhz | ||
| 285 | }); | ||
| 286 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 287 | } | ||
| 245 | #[cfg(feature = "stm32wb55rg")] | 288 | #[cfg(feature = "stm32wb55rg")] |
| 246 | { | 289 | { |
| 247 | config.rcc = embassy_stm32::rcc::WPAN_DEFAULT; | 290 | config.rcc = embassy_stm32::rcc::WPAN_DEFAULT; |
| 248 | } | 291 | } |
| 249 | 292 | ||
| 293 | #[cfg(feature = "stm32f091rc")] | ||
| 294 | { | ||
| 295 | config.rcc.hse = Some(Hse { | ||
| 296 | freq: Hertz(8_000_000), | ||
| 297 | mode: HseMode::Bypass, | ||
| 298 | }); | ||
| 299 | config.rcc.pll = Some(Pll { | ||
| 300 | src: PllSource::HSE, | ||
| 301 | prediv: PllPreDiv::DIV1, | ||
| 302 | mul: PllMul::MUL6, | ||
| 303 | }); | ||
| 304 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 305 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 306 | config.rcc.apb1_pre = APBPrescaler::DIV1; | ||
| 307 | } | ||
| 308 | #[cfg(feature = "stm32f103c8")] | ||
| 309 | { | ||
| 310 | config.rcc.hse = Some(Hse { | ||
| 311 | freq: Hertz(8_000_000), | ||
| 312 | mode: HseMode::Oscillator, | ||
| 313 | }); | ||
| 314 | config.rcc.pll = Some(Pll { | ||
| 315 | src: PllSource::HSE, | ||
| 316 | prediv: PllPreDiv::DIV1, | ||
| 317 | mul: PllMul::MUL9, | ||
| 318 | }); | ||
| 319 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 320 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 321 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 322 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 323 | } | ||
| 250 | #[cfg(feature = "stm32f207zg")] | 324 | #[cfg(feature = "stm32f207zg")] |
| 251 | { | 325 | { |
| 252 | use embassy_stm32::rcc::*; | ||
| 253 | // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) | 326 | // By default, HSE on the board comes from a 8 MHz clock signal (not a crystal) |
| 254 | config.rcc.hse = Some(Hse { | 327 | config.rcc.hse = Some(Hse { |
| 255 | freq: Hertz(8_000_000), | 328 | freq: Hertz(8_000_000), |
| @@ -276,9 +349,25 @@ pub fn config() -> Config { | |||
| 276 | config.rcc.apb2_pre = APBPrescaler::DIV2; | 349 | config.rcc.apb2_pre = APBPrescaler::DIV2; |
| 277 | } | 350 | } |
| 278 | 351 | ||
| 352 | #[cfg(feature = "stm32f303ze")] | ||
| 353 | { | ||
| 354 | config.rcc.hse = Some(Hse { | ||
| 355 | freq: Hertz(8_000_000), | ||
| 356 | mode: HseMode::Bypass, | ||
| 357 | }); | ||
| 358 | config.rcc.pll = Some(Pll { | ||
| 359 | src: PllSource::HSE, | ||
| 360 | prediv: PllPreDiv::DIV1, | ||
| 361 | mul: PllMul::MUL9, | ||
| 362 | }); | ||
| 363 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 364 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 365 | config.rcc.apb1_pre = APBPrescaler::DIV2; | ||
| 366 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 367 | } | ||
| 368 | |||
| 279 | #[cfg(feature = "stm32f429zi")] | 369 | #[cfg(feature = "stm32f429zi")] |
| 280 | { | 370 | { |
| 281 | use embassy_stm32::rcc::*; | ||
| 282 | config.rcc.hse = Some(Hse { | 371 | config.rcc.hse = Some(Hse { |
| 283 | freq: Hertz(8_000_000), | 372 | freq: Hertz(8_000_000), |
| 284 | mode: HseMode::Bypass, | 373 | mode: HseMode::Bypass, |
| @@ -299,7 +388,6 @@ pub fn config() -> Config { | |||
| 299 | 388 | ||
| 300 | #[cfg(feature = "stm32f446re")] | 389 | #[cfg(feature = "stm32f446re")] |
| 301 | { | 390 | { |
| 302 | use embassy_stm32::rcc::*; | ||
| 303 | config.rcc.hse = Some(Hse { | 391 | config.rcc.hse = Some(Hse { |
| 304 | freq: Hertz(8_000_000), | 392 | freq: Hertz(8_000_000), |
| 305 | mode: HseMode::Oscillator, | 393 | mode: HseMode::Oscillator, |
| @@ -320,7 +408,6 @@ pub fn config() -> Config { | |||
| 320 | 408 | ||
| 321 | #[cfg(feature = "stm32f767zi")] | 409 | #[cfg(feature = "stm32f767zi")] |
| 322 | { | 410 | { |
| 323 | use embassy_stm32::rcc::*; | ||
| 324 | config.rcc.hse = Some(Hse { | 411 | config.rcc.hse = Some(Hse { |
| 325 | freq: Hertz(8_000_000), | 412 | freq: Hertz(8_000_000), |
| 326 | mode: HseMode::Bypass, | 413 | mode: HseMode::Bypass, |
| @@ -341,7 +428,6 @@ pub fn config() -> Config { | |||
| 341 | 428 | ||
| 342 | #[cfg(feature = "stm32h563zi")] | 429 | #[cfg(feature = "stm32h563zi")] |
| 343 | { | 430 | { |
| 344 | use embassy_stm32::rcc::*; | ||
| 345 | config.rcc.hsi = None; | 431 | config.rcc.hsi = None; |
| 346 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | 432 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG |
| 347 | config.rcc.hse = Some(Hse { | 433 | config.rcc.hse = Some(Hse { |
| @@ -364,9 +450,50 @@ pub fn config() -> Config { | |||
| 364 | config.rcc.voltage_scale = VoltageScale::Scale0; | 450 | config.rcc.voltage_scale = VoltageScale::Scale0; |
| 365 | } | 451 | } |
| 366 | 452 | ||
| 453 | #[cfg(feature = "stm32h503rb")] | ||
| 454 | { | ||
| 455 | config.rcc.hsi = None; | ||
| 456 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | ||
| 457 | config.rcc.hse = Some(Hse { | ||
| 458 | freq: Hertz(24_000_000), | ||
| 459 | mode: HseMode::Oscillator, | ||
| 460 | }); | ||
| 461 | config.rcc.pll1 = Some(Pll { | ||
| 462 | source: PllSource::HSE, | ||
| 463 | prediv: PllPreDiv::DIV6, | ||
| 464 | mul: PllMul::MUL125, | ||
| 465 | divp: Some(PllDiv::DIV2), | ||
| 466 | divq: Some(PllDiv::DIV2), | ||
| 467 | divr: None, | ||
| 468 | }); | ||
| 469 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 470 | config.rcc.apb1_pre = APBPrescaler::DIV1; | ||
| 471 | config.rcc.apb2_pre = APBPrescaler::DIV1; | ||
| 472 | config.rcc.apb3_pre = APBPrescaler::DIV1; | ||
| 473 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 474 | config.rcc.voltage_scale = VoltageScale::Scale0; | ||
| 475 | } | ||
| 476 | |||
| 477 | #[cfg(feature = "stm32g491re")] | ||
| 478 | { | ||
| 479 | config.rcc.hse = Some(Hse { | ||
| 480 | freq: Hertz(24_000_000), | ||
| 481 | mode: HseMode::Oscillator, | ||
| 482 | }); | ||
| 483 | config.rcc.pll = Some(Pll { | ||
| 484 | source: PllSource::HSE, | ||
| 485 | prediv: PllPreDiv::DIV6, | ||
| 486 | mul: PllMul::MUL85, | ||
| 487 | divp: None, | ||
| 488 | divq: Some(PllQDiv::DIV8), // 42.5 Mhz for fdcan. | ||
| 489 | divr: Some(PllRDiv::DIV2), // Main system clock at 170 MHz | ||
| 490 | }); | ||
| 491 | config.rcc.mux.fdcansel = mux::Fdcansel::PLL1_Q; | ||
| 492 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 493 | } | ||
| 494 | |||
| 367 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] | 495 | #[cfg(any(feature = "stm32h755zi", feature = "stm32h753zi"))] |
| 368 | { | 496 | { |
| 369 | use embassy_stm32::rcc::*; | ||
| 370 | config.rcc.hsi = Some(HSIPrescaler::DIV1); | 497 | config.rcc.hsi = Some(HSIPrescaler::DIV1); |
| 371 | config.rcc.csi = true; | 498 | config.rcc.csi = true; |
| 372 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | 499 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG |
| @@ -393,12 +520,15 @@ pub fn config() -> Config { | |||
| 393 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz | 520 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz |
| 394 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz | 521 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz |
| 395 | config.rcc.voltage_scale = VoltageScale::Scale1; | 522 | config.rcc.voltage_scale = VoltageScale::Scale1; |
| 396 | config.rcc.adc_clock_source = AdcClockSource::PLL2_P; | 523 | config.rcc.mux.adcsel = mux::Adcsel::PLL2_P; |
| 524 | #[cfg(any(feature = "stm32h755zi"))] | ||
| 525 | { | ||
| 526 | config.rcc.supply_config = SupplyConfig::DirectSMPS; | ||
| 527 | } | ||
| 397 | } | 528 | } |
| 398 | 529 | ||
| 399 | #[cfg(any(feature = "stm32h7a3zi"))] | 530 | #[cfg(any(feature = "stm32h7a3zi"))] |
| 400 | { | 531 | { |
| 401 | use embassy_stm32::rcc::*; | ||
| 402 | config.rcc.hsi = Some(HSIPrescaler::DIV1); | 532 | config.rcc.hsi = Some(HSIPrescaler::DIV1); |
| 403 | config.rcc.csi = true; | 533 | config.rcc.csi = true; |
| 404 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG | 534 | config.rcc.hsi48 = Some(Default::default()); // needed for RNG |
| @@ -425,13 +555,12 @@ pub fn config() -> Config { | |||
| 425 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 140 Mhz | 555 | config.rcc.apb3_pre = APBPrescaler::DIV2; // 140 Mhz |
| 426 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 140 Mhz | 556 | config.rcc.apb4_pre = APBPrescaler::DIV2; // 140 Mhz |
| 427 | config.rcc.voltage_scale = VoltageScale::Scale0; | 557 | config.rcc.voltage_scale = VoltageScale::Scale0; |
| 428 | config.rcc.adc_clock_source = AdcClockSource::PLL2_P; | 558 | config.rcc.mux.adcsel = mux::Adcsel::PLL2_P; |
| 429 | } | 559 | } |
| 430 | 560 | ||
| 431 | #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] | 561 | #[cfg(any(feature = "stm32l496zg", feature = "stm32l4a6zg", feature = "stm32l4r5zi"))] |
| 432 | { | 562 | { |
| 433 | use embassy_stm32::rcc::*; | 563 | config.rcc.sys = Sysclk::PLL1_R; |
| 434 | config.rcc.mux = ClockSrc::PLL1_R; | ||
| 435 | config.rcc.hsi = true; | 564 | config.rcc.hsi = true; |
| 436 | config.rcc.pll = Some(Pll { | 565 | config.rcc.pll = Some(Pll { |
| 437 | source: PllSource::HSI, | 566 | source: PllSource::HSI, |
| @@ -445,13 +574,12 @@ pub fn config() -> Config { | |||
| 445 | 574 | ||
| 446 | #[cfg(feature = "stm32wl55jc")] | 575 | #[cfg(feature = "stm32wl55jc")] |
| 447 | { | 576 | { |
| 448 | use embassy_stm32::rcc::*; | ||
| 449 | config.rcc.hse = Some(Hse { | 577 | config.rcc.hse = Some(Hse { |
| 450 | freq: Hertz(32_000_000), | 578 | freq: Hertz(32_000_000), |
| 451 | mode: HseMode::Bypass, | 579 | mode: HseMode::Bypass, |
| 452 | prescaler: HsePrescaler::DIV1, | 580 | prescaler: HsePrescaler::DIV1, |
| 453 | }); | 581 | }); |
| 454 | config.rcc.mux = ClockSrc::PLL1_R; | 582 | config.rcc.sys = Sysclk::PLL1_R; |
| 455 | config.rcc.pll = Some(Pll { | 583 | config.rcc.pll = Some(Pll { |
| 456 | source: PllSource::HSE, | 584 | source: PllSource::HSE, |
| 457 | prediv: PllPreDiv::DIV2, | 585 | prediv: PllPreDiv::DIV2, |
| @@ -464,9 +592,8 @@ pub fn config() -> Config { | |||
| 464 | 592 | ||
| 465 | #[cfg(any(feature = "stm32l552ze"))] | 593 | #[cfg(any(feature = "stm32l552ze"))] |
| 466 | { | 594 | { |
| 467 | use embassy_stm32::rcc::*; | ||
| 468 | config.rcc.hsi = true; | 595 | config.rcc.hsi = true; |
| 469 | config.rcc.mux = ClockSrc::PLL1_R; | 596 | config.rcc.sys = Sysclk::PLL1_R; |
| 470 | config.rcc.pll = Some(Pll { | 597 | config.rcc.pll = Some(Pll { |
| 471 | // 110Mhz clock (16 / 4 * 55 / 2) | 598 | // 110Mhz clock (16 / 4 * 55 / 2) |
| 472 | source: PllSource::HSI, | 599 | source: PllSource::HSI, |
| @@ -480,42 +607,46 @@ pub fn config() -> Config { | |||
| 480 | 607 | ||
| 481 | #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))] | 608 | #[cfg(any(feature = "stm32u585ai", feature = "stm32u5a5zj"))] |
| 482 | { | 609 | { |
| 483 | use embassy_stm32::rcc::*; | 610 | config.rcc.hsi = true; |
| 484 | config.rcc.mux = ClockSrc::MSI(Msirange::RANGE_48MHZ); | 611 | config.rcc.pll1 = Some(Pll { |
| 612 | source: PllSource::HSI, // 16 MHz | ||
| 613 | prediv: PllPreDiv::DIV1, | ||
| 614 | mul: PllMul::MUL10, | ||
| 615 | divp: None, | ||
| 616 | divq: None, | ||
| 617 | divr: Some(PllDiv::DIV1), // 160 MHz | ||
| 618 | }); | ||
| 619 | config.rcc.sys = Sysclk::PLL1_R; | ||
| 620 | config.rcc.voltage_range = VoltageScale::RANGE1; | ||
| 621 | config.rcc.hsi48 = Some(Hsi48Config { sync_from_usb: true }); // needed for USB | ||
| 485 | } | 622 | } |
| 486 | 623 | ||
| 487 | #[cfg(feature = "stm32wba52cg")] | 624 | #[cfg(feature = "stm32wba52cg")] |
| 488 | { | 625 | { |
| 489 | use embassy_stm32::rcc::*; | 626 | config.rcc.sys = Sysclk::HSI; |
| 490 | config.rcc.mux = ClockSrc::HSI; | 627 | config.rcc.mux.rngsel = mux::Rngsel::HSI; |
| 491 | |||
| 492 | embassy_stm32::pac::RCC.ccipr2().write(|w| { | ||
| 493 | w.set_rngsel(embassy_stm32::pac::rcc::vals::Rngsel::HSI); | ||
| 494 | }); | ||
| 495 | } | 628 | } |
| 496 | 629 | ||
| 497 | #[cfg(feature = "stm32l073rz")] | 630 | #[cfg(feature = "stm32l073rz")] |
| 498 | { | 631 | { |
| 499 | use embassy_stm32::rcc::*; | ||
| 500 | config.rcc.hsi = true; | 632 | config.rcc.hsi = true; |
| 501 | config.rcc.pll = Some(Pll { | 633 | config.rcc.pll = Some(Pll { |
| 502 | source: PllSource::HSI, | 634 | source: PllSource::HSI, |
| 503 | mul: PllMul::MUL4, | 635 | mul: PllMul::MUL4, |
| 504 | div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) | 636 | div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) |
| 505 | }); | 637 | }); |
| 506 | config.rcc.mux = ClockSrc::PLL1_R; | 638 | config.rcc.sys = Sysclk::PLL1_R; |
| 507 | } | 639 | } |
| 508 | 640 | ||
| 509 | #[cfg(any(feature = "stm32l152re"))] | 641 | #[cfg(any(feature = "stm32l152re"))] |
| 510 | { | 642 | { |
| 511 | use embassy_stm32::rcc::*; | ||
| 512 | config.rcc.hsi = true; | 643 | config.rcc.hsi = true; |
| 513 | config.rcc.pll = Some(Pll { | 644 | config.rcc.pll = Some(Pll { |
| 514 | source: PllSource::HSI, | 645 | source: PllSource::HSI, |
| 515 | mul: PllMul::MUL4, | 646 | mul: PllMul::MUL4, |
| 516 | div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) | 647 | div: PllDiv::DIV2, // 32Mhz clock (16 * 4 / 2) |
| 517 | }); | 648 | }); |
| 518 | config.rcc.mux = ClockSrc::PLL1_R; | 649 | config.rcc.sys = Sysclk::PLL1_R; |
| 519 | } | 650 | } |
| 520 | 651 | ||
| 521 | config | 652 | config |
diff --git a/tests/stm32/teleprobe.sh b/tests/stm32/teleprobe.sh deleted file mode 100755 index 6eec6ca93..000000000 --- a/tests/stm32/teleprobe.sh +++ /dev/null | |||
| @@ -1,12 +0,0 @@ | |||
| 1 | echo Running target=$1 elf=$2 | ||
| 2 | STATUSCODE=$( | ||
| 3 | curl \ | ||
| 4 | -sS \ | ||
| 5 | --output /dev/stderr \ | ||
| 6 | --write-out "%{http_code}" \ | ||
| 7 | -H "Authorization: Bearer $TELEPROBE_TOKEN" \ | ||
| 8 | https://teleprobe.embassy.dev/targets/$1/run --data-binary @$2 | ||
| 9 | ) | ||
| 10 | echo | ||
| 11 | echo HTTP Status code: $STATUSCODE | ||
| 12 | test "$STATUSCODE" -eq 200 | ||
