esp-hal/hil-test/tests/uart_uhci.rs
Szybet 9fe02b819c
UART using DMA (via UHCI) (#3871)
* working rx

* very sketchy working tx

* uart uhci qa example

* move it

* cleanout

* read working great, write outputs the whole buffer

* tx working but rx can freeze

* fix freezes

* dont use vec

* cleaning

* async weird and not working

* async working?

* into async

* Apply suggested changes

* it compiles

* it also works with 'd

* split into seperate structs

* Add uart config configuration after uhci consumed it

* working Uhci normal

* again aaa sorry

* Apply suggested changes (That I knew how to implement)

* Add proper publicity, reimplement wrappers for internal functions using a macro, repair examples

* Moved to config, uhci normal example doesn't echo

* still not working

* hacky works normal

* apply suggested changes

* Initial docs

* fix messing up rx tx, still doesn't work

* Workaround, working but well

* change back to not pub (Maybe redo to public later, for now just to not mess with the workaround)

* now its working

* forgot to push

* Revert 2 commits, implement drop to showcase problem

* apply some suggested changes

* apply more suggested fixes (async/blocking)

* Everything works

* clearing out warnings

* handle errors

* merge from upstream, make it compile (not sure)

* Apply almost all suggestions

* re add wait for done

* Move errors out of wait_for_done, formating, changelog

* Apply suggested changes

* apply lint suggestions

* docs

* No longer public

* hil tests, rx tx transfer

* implement split

* forgot to format

* apply suggested changes

* Add top level module doc

* cicd now working?

* format, cicd maybe now

* apply suggestion

* format fix

* modify to write
2025-08-29 08:05:17 +00:00

157 lines
13 KiB
Rust

//! UART UHCI test, async
//% CHIPS: esp32c6
//% FEATURES: unstable embassy
#![no_std]
#![no_main]
use esp_hal::{
Blocking,
dma::{DmaRxBuf, DmaTxBuf},
dma_buffers,
uart::{self, Uart, uhci::Uhci},
};
struct Context {
uhci: Uhci<'static, Blocking>,
dma_rx: DmaRxBuf,
dma_tx: DmaTxBuf,
}
#[cfg(test)]
#[embedded_test::tests(default_timeout = 3, executor = hil_test::Executor::new())]
mod tests {
use super::*;
#[init]
async fn init() -> Context {
let peripherals = esp_hal::init(esp_hal::Config::default());
let (rx, tx) = hil_test::common_test_pins!(peripherals);
let uart = Uart::new(peripherals.UART0, uart::Config::default())
.unwrap()
.with_tx(tx)
.with_rx(rx);
let (rx_buffer, rx_descriptors, tx_buffer, tx_descriptors) = dma_buffers!(4092);
let dma_rx = DmaRxBuf::new(rx_descriptors, rx_buffer).unwrap();
let dma_tx = DmaTxBuf::new(tx_descriptors, tx_buffer).unwrap();
let mut uhci = Uhci::new(uart, peripherals.UHCI0, peripherals.DMA_CH0);
uhci.apply_config(&uart::uhci::Config::default().with_chunk_limit(dma_rx.len() as u16))
.unwrap();
Context {
uhci,
dma_rx,
dma_tx,
}
}
#[test]
fn test_send_receive(mut ctx: Context) {
const SEND: &[u8] = b"Hello ESP32";
ctx.dma_tx.as_mut_slice()[0..SEND.len()].copy_from_slice(&SEND);
ctx.dma_tx.set_length(SEND.len());
let (uhci_rx, uhci_tx) = ctx.uhci.split();
let transfer_rx = uhci_rx
.read(ctx.dma_rx)
.unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0));
let transfer_tx = uhci_tx
.write(ctx.dma_tx)
.unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0));
let (res, _uhci_tx, _dma_tx) = transfer_tx.wait();
res.unwrap();
let (res, _uhci_rx, dma_rx) = transfer_rx.wait();
res.unwrap();
assert_eq!(
&dma_rx.as_slice()[0..dma_rx.number_of_received_bytes()],
SEND
);
}
#[test]
fn test_long_strings(mut ctx: Context) {
const LONG_TEST_STRING: &str = "Loremipsumdolorsitamet,consecteturadipiscingelit.Suspendissemetusnisl,pretiumsedeuismodeget,bibendumeusem.Donecaccumsanrisusnibh,etefficiturnisivehiculatempus.Etiamegestasenimatduieleifendmaximus.Nuncinsemperest.Etiamvelodioultrices,interdumeratsed,dignissimmetus.Phasellusexleo,eleifendquisexid,laciniavenenatisneque.Sednuncdiam,molestieveltinciduntnec,ornareetnisi.Maecenasetmolestietortor.Nullaeupulvinarquam.Aeneanmolestieliberoquistortorviverralobortis.Praesentlaoreetlectusattinciduntscelerisque.Suspendisseegeterateleifend,posuerenuncvenenatis,faucibusdolor.Nuncvitaeluctusmetus.Nullamultriciesarcuvitaeestfermentumeleifend.Suspendisselaoreetmaximuslacus,utlaoreetnisiiaculisvitae.Nullamscelerisqueporttitorpulvinar.Intinciduntipsummauris,velaliquetmetusdictumut.Nunceratelit,suscipitacnisiac,volutpatporttitormauris.Aliquampretiumnisidiam,molestietemporlacusplaceratid.Mauristinciduntmattisturpis,velconvallisurnatempusnon.Integermattismetusnoneuismodcursus.Namideratetmassapretiumfinibus.Praesentfermentumnuncurna,quissagittismaurisimperdieteu.InLoremipsumdolorsitamet,consecteturadipiscingelit.Suspendissemetusnisl,pretiumsedeuismodeget,bibendumeusem.Donecaccumsanrisusnibh,etefficiturnisivehiculatempus.Etiamegestasenimatduieleifendmaximus.Nuncinsemperest.Etiamvelodioultrices,interdumeratsed,dignissimmetus.Phasellusexleo,eleifendquisexid,laciniavenenatisneque.Sednuncdiam,molestieveltinciduntnec,ornareetnisi.Maecenasetmolestietortor.Nullaeupulvinarquam.Aeneanmolestieliberoquistortorviverralobortis.Praesentlaoreetlectusattinciduntscelerisque.Suspendisseegeterateleifend,posuerenuncvenenatis,faucibusdolor.Nuncvitaeluctusmetus.Nullamultriciesarcuvitaeestfermentumeleifend.Suspendisselaoreetmaximuslacus,utlaoreetnisiiaculisvitae.Nullamscelerisqueporttitorpulvinar.Intinciduntipsummauris,velaliquetmetusdictumut.Nunceratelit,suscipitacnisiac,volutpatporttitormauris.Aliquampretiumnisidiam,molestietemporlacusplaceratid.Mauristinciduntmattisturpis,velconvallisurnatempusnon.Integermattismetusnoneuismodcursus.Namideratetmassapretiumfinibus.Praesentfermentumnuncurna,quissagittismaurisimperdieteu.Inefficituraliquamdui.Phasellussempermaurisacconvallismollis.Suspendisseintellusanuncvariusiaculisutegetlibero.Inmalesuada,nislquisconsecteturposuere,nullaipsumfringillaeros,egetrhoncussapienarcunecenim.Proinvenenatistortorveltristiquealiquam.Utelementumtellusligula,velauctorexfermentuma.Vestibulummaximusanteinvulputateornare.Sedquisnislaligulaporttitorfacilisismattissedmi.Crasconsecteturexegetsagittisfeugiat.Invenenatisminectinciduntaliquet.Sedcommodonecorciidvenenatis.Vestibulumanteipsumprimisinfaucibusorciluctusetultricesposuerecubiliacurae;Phasellusinterdumorcefficituraliquamdui.Phasellussempermaurisacconvallismollis.Suspendisseintellusanuncvariusiaculisutegetlibero.Inmalesuada,nislquisconsecteturposuere,nullaipsumfringillaeros,egetrhoncussapienarcunecenim.Proinvenenatistortorveltristiquealiquam.Utelementumtellusligula,velauctorexfermentuma.Vestibulummaximusanteinvulputateornare.Sedquisnislaligulaporttitorfacilisismattissedmi.Crasconsecteturexegetsagittisfeugiat.Invenenatisminectinciduntaliquet.Sedcommodonecorciidvenenatis.Vestibulumanteipsumprimisinfaucibusorciluctusetultricesposuerecubiliacurae;Phasellusinterdumorcrtis.Praesentlaoreetlectusattinciduntscelerisque.Suspendisseegeterateleifend,posuerenuncvenenatis,faucibusdolor.Nuncvitaeluctusmetus.Nullamultriciesarcuvitaeestfermentumeleifend.Suspendisselaoreetmaximuslacus,utlaoreetnisiiaculisvitae.Nullamscelerisqueporttitorpulvinar.Intinciduntipsummauris,velaliquetmetusdictumut.Nunceratelit,suscipitacnisiac,volutpatporttitormauris.Aliquampretiumnisidiam,molestietemporlacusplaceratid.Mauristinciduntmattisturpis,velconvallisurnatempusnon.Integermattismetusnoneuismodcursus.Namideratetmassapretiumfinibus.Praesentfermentumnuncurna,quissagittismaurisimperdieteu.Inefficituraliquamdui.Phasellussempermaurisacconvallismollis.Suspendisseintellusanuncvariusiaculisutegetlibero.Inmalesuada,nislquisconsecteturposuere,nullaipsumfringillaeros,egetrhoncussapienarcunece";
ctx.dma_tx.as_mut_slice()[0..LONG_TEST_STRING.len()]
.copy_from_slice(&LONG_TEST_STRING.as_bytes());
ctx.dma_tx.set_length(LONG_TEST_STRING.len());
let (uhci_rx, uhci_tx) = ctx.uhci.split();
let transfer_rx = uhci_rx
.read(ctx.dma_rx)
.unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0));
let transfer_tx = uhci_tx
.write(ctx.dma_tx)
.unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0));
let (res, _uhci_tx, _dma_tx) = transfer_tx.wait();
res.unwrap();
let (res, _uhci_rx, dma_rx) = transfer_rx.wait();
res.unwrap();
assert_eq!(
&dma_rx.as_slice()[0..dma_rx.number_of_received_bytes()],
LONG_TEST_STRING.as_bytes()
);
}
#[test]
async fn test_send_receive_async(mut ctx: Context) {
let uhci = ctx.uhci.into_async();
const SEND: &[u8] = b"Hello ESP32";
ctx.dma_tx.as_mut_slice()[0..SEND.len()].copy_from_slice(&SEND);
ctx.dma_tx.set_length(SEND.len());
let (uhci_rx, uhci_tx) = uhci.split();
let mut transfer_rx = uhci_rx
.read(ctx.dma_rx)
.unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0));
let mut transfer_tx = uhci_tx
.write(ctx.dma_tx)
.unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0));
transfer_tx.wait_for_done().await;
let (res, _uhci_tx, _dma_tx) = transfer_tx.wait();
res.unwrap();
transfer_rx.wait_for_done().await;
let (res, _uhci_rx, dma_rx) = transfer_rx.wait();
res.unwrap();
assert_eq!(
&dma_rx.as_slice()[0..dma_rx.number_of_received_bytes()],
SEND
);
}
#[test]
async fn test_long_strings_async(mut ctx: Context) {
let uhci = ctx.uhci.into_async();
const LONG_TEST_STRING: &str = "Loremipsumdolorsitamet,consecteturadipiscingelit.Suspendissemetusnisl,pretiumsedeuismodeget,bibendumeusem.Donecaccumsanrisusnibh,etefficiturnisivehiculatempus.Etiamegestasenimatduieleifendmaximus.Nuncinsemperest.Etiamvelodioultrices,interdumeratsed,dignissimmetus.Phasellusexleo,eleifendquisexid,laciniavenenatisneque.Sednuncdiam,molestieveltinciduntnec,ornareetnisi.Maecenasetmolestietortor.Nullaeupulvinarquam.Aeneanmolestieliberoquistortorviverralobortis.Praesentlaoreetlectusattinciduntscelerisque.Suspendisseegeterateleifend,posuerenuncvenenatis,faucibusdolor.Nuncvitaeluctusmetus.Nullamultriciesarcuvitaeestfermentumeleifend.Suspendisselaoreetmaximuslacus,utlaoreetnisiiaculisvitae.Nullamscelerisqueporttitorpulvinar.Intinciduntipsummauris,velaliquetmetusdictumut.Nunceratelit,suscipitacnisiac,volutpatporttitormauris.Aliquampretiumnisidiam,molestietemporlacusplaceratid.Mauristinciduntmattisturpis,velconvallisurnatempusnon.Integermattismetusnoneuismodcursus.Namideratetmassapretiumfinibus.Praesentfermentumnuncurna,quissagittismaurisimperdieteu.InLoremipsumdolorsitamet,consecteturadipiscingelit.Suspendissemetusnisl,pretiumsedeuismodeget,bibendumeusem.Donecaccumsanrisusnibh,etefficiturnisivehiculatempus.Etiamegestasenimatduieleifendmaximus.Nuncinsemperest.Etiamvelodioultrices,interdumeratsed,dignissimmetus.Phasellusexleo,eleifendquisexid,laciniavenenatisneque.Sednuncdiam,molestieveltinciduntnec,ornareetnisi.Maecenasetmolestietortor.Nullaeupulvinarquam.Aeneanmolestieliberoquistortorviverralobortis.Praesentlaoreetlectusattinciduntscelerisque.Suspendisseegeterateleifend,posuerenuncvenenatis,faucibusdolor.Nuncvitaeluctusmetus.Nullamultriciesarcuvitaeestfermentumeleifend.Suspendisselaoreetmaximuslacus,utlaoreetnisiiaculisvitae.Nullamscelerisqueporttitorpulvinar.Intinciduntipsummauris,velaliquetmetusdictumut.Nunceratelit,suscipitacnisiac,volutpatporttitormauris.Aliquampretiumnisidiam,molestietemporlacusplaceratid.Mauristinciduntmattisturpis,velconvallisurnatempusnon.Integermattismetusnoneuismodcursus.Namideratetmassapretiumfinibus.Praesentfermentumnuncurna,quissagittismaurisimperdieteu.Inefficituraliquamdui.Phasellussempermaurisacconvallismollis.Suspendisseintellusanuncvariusiaculisutegetlibero.Inmalesuada,nislquisconsecteturposuere,nullaipsumfringillaeros,egetrhoncussapienarcunecenim.Proinvenenatistortorveltristiquealiquam.Utelementumtellusligula,velauctorexfermentuma.Vestibulummaximusanteinvulputateornare.Sedquisnislaligulaporttitorfacilisismattissedmi.Crasconsecteturexegetsagittisfeugiat.Invenenatisminectinciduntaliquet.Sedcommodonecorciidvenenatis.Vestibulumanteipsumprimisinfaucibusorciluctusetultricesposuerecubiliacurae;Phasellusinterdumorcefficituraliquamdui.Phasellussempermaurisacconvallismollis.Suspendisseintellusanuncvariusiaculisutegetlibero.Inmalesuada,nislquisconsecteturposuere,nullaipsumfringillaeros,egetrhoncussapienarcunecenim.Proinvenenatistortorveltristiquealiquam.Utelementumtellusligula,velauctorexfermentuma.Vestibulummaximusanteinvulputateornare.Sedquisnislaligulaporttitorfacilisismattissedmi.Crasconsecteturexegetsagittisfeugiat.Invenenatisminectinciduntaliquet.Sedcommodonecorciidvenenatis.Vestibulumanteipsumprimisinfaucibusorciluctusetultricesposuerecubiliacurae;Phasellusinterdumorcrtis.Praesentlaoreetlectusattinciduntscelerisque.Suspendisseegeterateleifend,posuerenuncvenenatis,faucibusdolor.Nuncvitaeluctusmetus.Nullamultriciesarcuvitaeestfermentumeleifend.Suspendisselaoreetmaximuslacus,utlaoreetnisiiaculisvitae.Nullamscelerisqueporttitorpulvinar.Intinciduntipsummauris,velaliquetmetusdictumut.Nunceratelit,suscipitacnisiac,volutpatporttitormauris.Aliquampretiumnisidiam,molestietemporlacusplaceratid.Mauristinciduntmattisturpis,velconvallisurnatempusnon.Integermattismetusnoneuismodcursus.Namideratetmassapretiumfinibus.Praesentfermentumnuncurna,quissagittismaurisimperdieteu.Inefficituraliquamdui.Phasellussempermaurisacconvallismollis.Suspendisseintellusanuncvariusiaculisutegetlibero.Inmalesuada,nislquisconsecteturposuere,nullaipsumfringillaeros,egetrhoncussapienarcunece";
ctx.dma_tx.as_mut_slice()[0..LONG_TEST_STRING.len()]
.copy_from_slice(&LONG_TEST_STRING.as_bytes());
ctx.dma_tx.set_length(LONG_TEST_STRING.len());
let (uhci_rx, uhci_tx) = uhci.split();
let mut transfer_rx = uhci_rx
.read(ctx.dma_rx)
.unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0));
let mut transfer_tx = uhci_tx
.write(ctx.dma_tx)
.unwrap_or_else(|x| panic!("Something went horribly wrong: {:?}", x.0));
transfer_tx.wait_for_done().await;
let (res, _uhci_tx, _dma_tx) = transfer_tx.wait();
res.unwrap();
transfer_rx.wait_for_done().await;
let (res, _uhci_rx, dma_rx) = transfer_rx.wait();
res.unwrap();
assert_eq!(
&dma_rx.as_slice()[0..dma_rx.number_of_received_bytes()],
LONG_TEST_STRING.as_bytes()
);
}
}