diff options
| author | xoviat <[email protected]> | 2025-12-11 09:08:50 -0600 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-11 09:08:50 -0600 |
| commit | 1aadce76847a7686bf66e3a6532e18e05042f78a (patch) | |
| tree | ca42d80e784a6746065bd4e0c676db3ef0f10b93 /tests | |
| parent | 52a9b08f0ca13d23bfb039c884a9101997c10567 (diff) | |
| parent | f650afc33b2d6b39116f27c6545c5f2d9e3c7d06 (diff) | |
Merge branch 'main' into main
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/stm32/Cargo.toml | 6 | ||||
| -rw-r--r-- | tests/stm32/src/bin/sdmmc.rs | 92 | ||||
| -rw-r--r-- | tests/stm32/src/bin/usart.rs | 44 | ||||
| -rw-r--r-- | tests/stm32/src/bin/usart_dma.rs | 18 |
4 files changed, 116 insertions, 44 deletions
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 496a9de18..6ee7f8e84 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -51,8 +51,8 @@ stop = ["embassy-stm32/low-power", "embassy-stm32/low-power-debug-with-sleep"] | |||
| 51 | chrono = ["embassy-stm32/chrono", "dep:chrono"] | 51 | chrono = ["embassy-stm32/chrono", "dep:chrono"] |
| 52 | can = [] | 52 | can = [] |
| 53 | fdcan = [] | 53 | fdcan = [] |
| 54 | ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"] | 54 | ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/wb55_ble"] |
| 55 | mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] | 55 | mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/wb55_mac"] |
| 56 | embassy-stm32-wpan = [] | 56 | embassy-stm32-wpan = [] |
| 57 | not-gpdma = [] | 57 | not-gpdma = [] |
| 58 | dac = [] | 58 | dac = [] |
| @@ -77,7 +77,7 @@ embassy-executor = { version = "0.9.0", path = "../../embassy-executor", feature | |||
| 77 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } | 77 | embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "tick-hz-131_072", "defmt-timestamp-uptime"] } |
| 78 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any", "_allow-disable-rtc"] } | 78 | embassy-stm32 = { version = "0.4.0", path = "../../embassy-stm32", features = [ "defmt", "unstable-pac", "memory-x", "time-driver-any", "_allow-disable-rtc"] } |
| 79 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } | 79 | embassy-futures = { version = "0.1.2", path = "../../embassy-futures" } |
| 80 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } | 80 | embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "wb55_ble"] } |
| 81 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } | 81 | embassy-net = { version = "0.7.1", path = "../../embassy-net", features = ["defmt", "tcp", "udp", "dhcpv4", "medium-ethernet"] } |
| 82 | perf-client = { path = "../perf-client" } | 82 | perf-client = { path = "../perf-client" } |
| 83 | 83 | ||
diff --git a/tests/stm32/src/bin/sdmmc.rs b/tests/stm32/src/bin/sdmmc.rs index 9f9c526e1..07422c42e 100644 --- a/tests/stm32/src/bin/sdmmc.rs +++ b/tests/stm32/src/bin/sdmmc.rs | |||
| @@ -7,7 +7,8 @@ mod common; | |||
| 7 | use common::*; | 7 | use common::*; |
| 8 | use defmt::assert_eq; | 8 | use defmt::assert_eq; |
| 9 | use embassy_executor::Spawner; | 9 | use embassy_executor::Spawner; |
| 10 | use embassy_stm32::sdmmc::{DataBlock, Sdmmc}; | 10 | use embassy_stm32::sdmmc::Sdmmc; |
| 11 | use embassy_stm32::sdmmc::sd::{CmdBlock, DataBlock, StorageDevice}; | ||
| 11 | use embassy_stm32::time::mhz; | 12 | use embassy_stm32::time::mhz; |
| 12 | use embassy_stm32::{bind_interrupts, peripherals, sdmmc}; | 13 | use embassy_stm32::{bind_interrupts, peripherals, sdmmc}; |
| 13 | use {defmt_rtt as _, panic_probe as _}; | 14 | use {defmt_rtt as _, panic_probe as _}; |
| @@ -28,16 +29,16 @@ async fn main(_spawner: Spawner) { | |||
| 28 | // Arbitrary block index | 29 | // Arbitrary block index |
| 29 | let block_idx = 16; | 30 | let block_idx = 16; |
| 30 | 31 | ||
| 31 | let mut pattern1 = DataBlock([0u8; 512]); | 32 | let mut pattern1 = DataBlock::new(); |
| 32 | let mut pattern2 = DataBlock([0u8; 512]); | 33 | let mut pattern2 = DataBlock::new(); |
| 33 | for i in 0..512 { | 34 | for i in 0..512 { |
| 34 | pattern1[i] = i as u8; | 35 | pattern1[i] = i as u8; |
| 35 | pattern2[i] = !i as u8; | 36 | pattern2[i] = !i as u8; |
| 36 | } | 37 | } |
| 37 | let patterns = [pattern1.clone(), pattern2.clone()]; | 38 | let patterns = [pattern1.clone(), pattern2.clone()]; |
| 38 | 39 | ||
| 39 | let mut block = DataBlock([0u8; 512]); | 40 | let mut block = DataBlock::new(); |
| 40 | let mut blocks = [DataBlock([0u8; 512]), DataBlock([0u8; 512])]; | 41 | let mut blocks = [DataBlock::new(), DataBlock::new()]; |
| 41 | 42 | ||
| 42 | // ======== Try 4bit. ============== | 43 | // ======== Try 4bit. ============== |
| 43 | info!("initializing in 4-bit mode..."); | 44 | info!("initializing in 4-bit mode..."); |
| @@ -54,43 +55,80 @@ async fn main(_spawner: Spawner) { | |||
| 54 | Default::default(), | 55 | Default::default(), |
| 55 | ); | 56 | ); |
| 56 | 57 | ||
| 57 | let mut err = None; | 58 | let mut cmd_block = CmdBlock::new(); |
| 58 | loop { | ||
| 59 | match s.init_sd_card(mhz(24)).await { | ||
| 60 | Ok(_) => break, | ||
| 61 | Err(e) => { | ||
| 62 | if err != Some(e) { | ||
| 63 | info!("waiting for card: {:?}", e); | ||
| 64 | err = Some(e); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | 59 | ||
| 70 | let card = unwrap!(s.card()); | 60 | let mut storage = loop { |
| 71 | 61 | if let Ok(storage) = StorageDevice::new_sd_card(&mut s, &mut cmd_block, mhz(24)).await { | |
| 72 | info!("Card: {:#?}", Debug2Format(card)); | 62 | break storage; |
| 73 | info!("Clock: {}", s.clock()); | 63 | } |
| 64 | }; | ||
| 65 | |||
| 66 | let card = storage.card(); | ||
| 67 | |||
| 68 | info!("Card: {:#?}", Debug2Format(&card)); | ||
| 69 | info!("Clock: {}", storage.sdmmc.clock()); | ||
| 70 | |||
| 71 | // card_type: HighCapacity, | ||
| 72 | // ocr: OCR: Operation Conditions Register { | ||
| 73 | // Voltage Window (mV): (2700, 3600), | ||
| 74 | // S18A (UHS-I only): true, | ||
| 75 | // Over 2TB flag (SDUC only): false, | ||
| 76 | // UHS-II Card: false, | ||
| 77 | // Card Capacity Status (CSS): \"SDHC/SDXC/SDUC\", | ||
| 78 | // Busy: false }, | ||
| 79 | // rca: 43690, | ||
| 80 | // cid: CID: Card Identification { Manufacturer ID: 3, | ||
| 81 | // OEM ID: \"SD\", | ||
| 82 | // Product Name: \"SL08G\", | ||
| 83 | // Product Revision: 128, | ||
| 84 | // Product Serial Number: 701445767, | ||
| 85 | // Manufacturing Date: (9, | ||
| 86 | // 2015) }, | ||
| 87 | // csd: CSD: Card Specific Data { Transfer Rate: 50, | ||
| 88 | // Block Count: 15523840, | ||
| 89 | // Card Size (bytes): 7948206080, | ||
| 90 | // Read I (@min VDD): 100 mA, | ||
| 91 | // Write I (@min VDD): 10 mA, | ||
| 92 | // Read I (@max VDD): 5 mA, | ||
| 93 | // Write I (@max VDD): 45 mA, | ||
| 94 | // Erase Size (Blocks): 1 }, | ||
| 95 | // scr: SCR: SD CARD Configuration Register { Version: Unknown, | ||
| 96 | // 1-bit width: false, | ||
| 97 | // 4-bit width: true }, | ||
| 98 | // status: SD Status { Bus Width: One, | ||
| 99 | // Secured Mode: false, | ||
| 100 | // SD Memory Card Type: 0, | ||
| 101 | // Protected Area Size (B): 0, | ||
| 102 | // Speed Class: 0, | ||
| 103 | // Video Speed Class: 0, | ||
| 104 | // Application Performance Class: 0, | ||
| 105 | // Move Performance (MB/s): 0, | ||
| 106 | // AU Size: 0, | ||
| 107 | // Erase Size (units of AU): 0, | ||
| 108 | // Erase Timeout (s): 0, | ||
| 109 | // Discard Support: false } } | ||
| 110 | |||
| 111 | defmt::assert!(card.scr.bus_width_four()); | ||
| 74 | 112 | ||
| 75 | info!("writing pattern1..."); | 113 | info!("writing pattern1..."); |
| 76 | s.write_block(block_idx, &pattern1).await.unwrap(); | 114 | storage.write_block(block_idx, &pattern1).await.unwrap(); |
| 77 | 115 | ||
| 78 | info!("reading..."); | 116 | info!("reading..."); |
| 79 | s.read_block(block_idx, &mut block).await.unwrap(); | 117 | storage.read_block(block_idx, &mut block).await.unwrap(); |
| 80 | assert_eq!(block, pattern1); | 118 | assert_eq!(block, pattern1); |
| 81 | 119 | ||
| 82 | info!("writing pattern2..."); | 120 | info!("writing pattern2..."); |
| 83 | s.write_block(block_idx, &pattern2).await.unwrap(); | 121 | storage.write_block(block_idx, &pattern2).await.unwrap(); |
| 84 | 122 | ||
| 85 | info!("reading..."); | 123 | info!("reading..."); |
| 86 | s.read_block(block_idx, &mut block).await.unwrap(); | 124 | storage.read_block(block_idx, &mut block).await.unwrap(); |
| 87 | assert_eq!(block, pattern2); | 125 | assert_eq!(block, pattern2); |
| 88 | 126 | ||
| 89 | info!("writing blocks [pattern1, pattern2]..."); | 127 | info!("writing blocks [pattern1, pattern2]..."); |
| 90 | s.write_blocks(block_idx, &patterns).await.unwrap(); | 128 | storage.write_blocks(block_idx, &patterns).await.unwrap(); |
| 91 | 129 | ||
| 92 | info!("reading blocks..."); | 130 | info!("reading blocks..."); |
| 93 | s.read_blocks(block_idx, &mut blocks).await.unwrap(); | 131 | storage.read_blocks(block_idx, &mut blocks).await.unwrap(); |
| 94 | assert_eq!(&blocks, &patterns); | 132 | assert_eq!(&blocks, &patterns); |
| 95 | 133 | ||
| 96 | drop(s); | 134 | drop(s); |
diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs index 0b98d3eeb..ef7efe96a 100644 --- a/tests/stm32/src/bin/usart.rs +++ b/tests/stm32/src/bin/usart.rs | |||
| @@ -6,6 +6,7 @@ mod common; | |||
| 6 | use common::*; | 6 | use common::*; |
| 7 | use defmt::{assert, assert_eq, unreachable}; | 7 | use defmt::{assert, assert_eq, unreachable}; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_stm32::mode::Blocking; | ||
| 9 | use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; | 10 | use embassy_stm32::usart::{Config, ConfigError, Error, Uart}; |
| 10 | use embassy_time::{Duration, Instant, block_for}; | 11 | use embassy_time::{Duration, Instant, block_for}; |
| 11 | 12 | ||
| @@ -24,22 +25,41 @@ async fn main(_spawner: Spawner) { | |||
| 24 | let config = Config::default(); | 25 | let config = Config::default(); |
| 25 | let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap(); | 26 | let mut usart = Uart::new_blocking(usart.reborrow(), rx.reborrow(), tx.reborrow(), config).unwrap(); |
| 26 | 27 | ||
| 27 | // We can't send too many bytes, they have to fit in the FIFO. | 28 | let test_usart = async |usart: &mut Uart<'_, Blocking>| -> Result<(), Error> { |
| 28 | // This is because we aren't sending+receiving at the same time. | 29 | // We can't send too many bytes, they have to fit in the FIFO. |
| 30 | // This is because we aren't sending+receiving at the same time. | ||
| 29 | 31 | ||
| 30 | let data = [0xC0, 0xDE]; | 32 | let data = [0xC0, 0xDE]; |
| 31 | usart.blocking_write(&data).unwrap(); | 33 | usart.blocking_write(&data)?; |
| 32 | 34 | ||
| 33 | let mut buf = [0; 2]; | 35 | let mut buf = [0; 2]; |
| 34 | usart.blocking_read(&mut buf).unwrap(); | 36 | usart.blocking_read(&mut buf)?; |
| 35 | assert_eq!(buf, data); | 37 | assert_eq!(buf, data); |
| 36 | 38 | ||
| 37 | // Test flush doesn't hang. | 39 | // Test flush doesn't hang. |
| 38 | usart.blocking_write(&data).unwrap(); | 40 | usart.blocking_write(&data)?; |
| 39 | usart.blocking_flush().unwrap(); | 41 | usart.blocking_flush()?; |
| 40 | 42 | ||
| 41 | // Test flush doesn't hang if there's nothing to flush | 43 | // Test flush doesn't hang if there's nothing to flush |
| 42 | usart.blocking_flush().unwrap(); | 44 | usart.blocking_flush()?; |
| 45 | |||
| 46 | Ok(()) | ||
| 47 | }; | ||
| 48 | |||
| 49 | let mut is_ok = false; | ||
| 50 | for _ in 0..3 { | ||
| 51 | match test_usart(&mut usart).await { | ||
| 52 | Ok(()) => is_ok = true, | ||
| 53 | Err(Error::Noise) => is_ok = false, | ||
| 54 | Err(e) => defmt::panic!("{}", e), | ||
| 55 | } | ||
| 56 | |||
| 57 | if is_ok { | ||
| 58 | break; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | assert!(is_ok); | ||
| 43 | } | 63 | } |
| 44 | 64 | ||
| 45 | // Test error handling with with an overflow error | 65 | // Test error handling with with an overflow error |
diff --git a/tests/stm32/src/bin/usart_dma.rs b/tests/stm32/src/bin/usart_dma.rs index a34498376..9f610739d 100644 --- a/tests/stm32/src/bin/usart_dma.rs +++ b/tests/stm32/src/bin/usart_dma.rs | |||
| @@ -7,7 +7,7 @@ use common::*; | |||
| 7 | use defmt::assert_eq; | 7 | use defmt::assert_eq; |
| 8 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| 9 | use embassy_futures::join::join; | 9 | use embassy_futures::join::join; |
| 10 | use embassy_stm32::usart::{Config, Uart}; | 10 | use embassy_stm32::usart::{Config, Error, Uart}; |
| 11 | 11 | ||
| 12 | #[embassy_executor::main] | 12 | #[embassy_executor::main] |
| 13 | async fn main(_spawner: Spawner) { | 13 | async fn main(_spawner: Spawner) { |
| @@ -32,6 +32,7 @@ async fn main(_spawner: Spawner) { | |||
| 32 | 32 | ||
| 33 | let (mut tx, mut rx) = usart.split(); | 33 | let (mut tx, mut rx) = usart.split(); |
| 34 | 34 | ||
| 35 | let mut noise_count = 0; | ||
| 35 | for n in 0..42 { | 36 | for n in 0..42 { |
| 36 | for i in 0..LEN { | 37 | for i in 0..LEN { |
| 37 | tx_buf[i] = (i ^ n) as u8; | 38 | tx_buf[i] = (i ^ n) as u8; |
| @@ -40,17 +41,30 @@ async fn main(_spawner: Spawner) { | |||
| 40 | let tx_fut = async { | 41 | let tx_fut = async { |
| 41 | tx.write(&tx_buf).await.unwrap(); | 42 | tx.write(&tx_buf).await.unwrap(); |
| 42 | }; | 43 | }; |
| 44 | |||
| 45 | let mut is_noisy = false; | ||
| 43 | let rx_fut = async { | 46 | let rx_fut = async { |
| 44 | rx.read(&mut rx_buf).await.unwrap(); | 47 | match rx.read(&mut rx_buf).await { |
| 48 | Ok(()) => {} | ||
| 49 | Err(Error::Noise) => is_noisy = true, | ||
| 50 | _ => defmt::panic!(), | ||
| 51 | } | ||
| 45 | }; | 52 | }; |
| 46 | 53 | ||
| 47 | // note: rx needs to be polled first, to workaround this bug: | 54 | // note: rx needs to be polled first, to workaround this bug: |
| 48 | // https://github.com/embassy-rs/embassy/issues/1426 | 55 | // https://github.com/embassy-rs/embassy/issues/1426 |
| 49 | join(rx_fut, tx_fut).await; | 56 | join(rx_fut, tx_fut).await; |
| 50 | 57 | ||
| 58 | if is_noisy { | ||
| 59 | noise_count += 1; | ||
| 60 | continue; | ||
| 61 | } | ||
| 62 | |||
| 51 | assert_eq!(tx_buf, rx_buf); | 63 | assert_eq!(tx_buf, rx_buf); |
| 52 | } | 64 | } |
| 53 | 65 | ||
| 66 | defmt::assert!(noise_count < 3); | ||
| 67 | |||
| 54 | // Test flush doesn't hang. Check multiple combinations of async+blocking. | 68 | // Test flush doesn't hang. Check multiple combinations of async+blocking. |
| 55 | tx.write(&tx_buf).await.unwrap(); | 69 | tx.write(&tx_buf).await.unwrap(); |
| 56 | tx.flush().await.unwrap(); | 70 | tx.flush().await.unwrap(); |
