Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embassy_serial can't transmit a package more than 128bytes #1564

Open
cvbni opened this issue May 18, 2024 · 9 comments
Open

Embassy_serial can't transmit a package more than 128bytes #1564

cvbni opened this issue May 18, 2024 · 9 comments

Comments

@cvbni
Copy link

cvbni commented May 18, 2024

I debug on embassy_serial example,and I fund a question:
The "set_rx_fifo_full_threshold" in esp32-c2 can set to 0x1FF(511),but the UART_FIFO_SIZE is 128,

I changed the UART_FIFO_SIZE to 256 in uart.rs file,but it not work

I want to transmit package more than 128bytes.
Any help ,thanks!!!

@MabezDev
Copy link
Member

Have you actually tried transmitting more than 128 bytes? set_rx_fifo_full_threshold has nothing to do with transmission. write_async should handle the chunking already.

@cvbni
Copy link
Author

cvbni commented May 20, 2024

Have you actually tried transmitting more than 128 bytes? set_rx_fifo_full_threshold has nothing to do with transmission. write_async should handle the chunking already.

Sorry I didn't make it clear. What I mean by this is that UART can't receive more than 128bytes of data

    let mut uart0 = Uart::new_async(peripherals.UART0, &clocks);
    uart0.set_at_cmd(AtCmdConfig::new(None, None, None, 0x04, None));
    uart0.set_rx_fifo_full_threshold(256 as u16).unwrap();//510
    uart0.set_rx_timeout(Some(8)).unwrap();

    let (mut tx0, mut rx0) = uart0.split();
    match select(
        pin!(async move {
            let mut buf = [0u8; 512];
            loop {
                let r = match embedded_io_async::Read::read(&mut rx0, &mut buf[2..]).await {
                    Ok(len) => len,
                    Err(_) => 0 as usize,
                };
                println!("read {} bytes", r);
                println!("read {:?} bytes", &buf[..r]);
                buf[1] = (r & 0xff) as u8;
                buf[0] = ((r >> 8) & 0xff) as u8;
                CH0.send(buf).await;
            }
        }),
        pin!(async move {
            loop {
                println!("\nHello world! Second");
                let buf = CH0.receive().await;
                let b0 = buf[0] as usize;
                let b1 = buf[1] as usize;
                let w = b1 + (b0 << 8);
                println!("b0 {b0} b1 {b1}");
                //println!("{:?}", &buf[2..(w+2)]);//b"Hello async serial\r\n"
                tx0.write_async(&buf[2..(w + 2)]).await.unwrap();
            }
        }),
    )
    .await
    {
        Either::First(_a) => {}
        Either::Second(_b) => {}
    }

not work here,if i send more than 128bytes data from PC uart tool.

                let r = match embedded_io_async::Read::read(&mut rx0, &mut buf[2..]).await {
                    Ok(len) => len,
                    Err(_) => 0 as usize,
                };
                println!("read {} bytes", r);
                println!("read {:?} bytes", &buf[..r]);

@MabezDev
Copy link
Member

What I mean by this is that UART can't receive more than 128bytes of data

When you say this, can you be more clear about "can't receive"? Do you mean in one go? Does the data show up with more calls to read()? What baudrate? Any errors?

Ideally a simple and small reproducible repo would help us figure out what's going on.

@cvbni
Copy link
Author

cvbni commented May 20, 2024

i send 128 hexs
0001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607

It can receive,like this

72 65 61 64 20 31 32 38 20 62 79 74 65 73 0A 

62 30 20 30 20 62 31 20 31 32 38 0A 

00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 05 06 07 08 09 00 01 02 03 04 0A 

48 65 6C 6C 6F 20 77 6F 72 6C 64 21 20 53 65 63 6F 6E 64 0A 6C 64 21 20 53 65 63 6F 6E 64 0A 

show in ascii

read 128 bytes

b0 0 b1 128

�

when i send 129 hex
000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708

it can' receive,like this

72 65 61 64 20 30 20 62 79 74 65 73 0A 

62 30 20 30 20 62 31 20 30 0A 

0A 

48 65 6C 6C 6F 20 77 6F 72 6C 64 21 20 53 65 63 6F 6E 64 0A 

show in ascii

read 0 bytes

b0 0 b1 0



Hello world! Second

@MabezDev
Copy link
Member

Could you provide a minimal reproduction repo so we can attempt to fix it?

@cvbni
Copy link
Author

cvbni commented May 22, 2024

Could you provide a minimal reproduction repo so we can attempt to fix it?

cargo.toml

[package]
name = "c2ntd"
version = "0.1.0"
authors = ["cvbnix"]
edition = "2021"
license = "MIT OR Apache-2.0"

[dependencies]
esp-backtrace = { version = "0.11.0", features = [
    "esp32c2",
    "exception-handler",
    "panic-handler",
    "println",
] }
esp-hal = { version = "0.17.0", features = [
    "esp32c2",
    "async",
    "embassy",
    "embassy-executor-thread",
    "embassy-time-timg0",
] }
esp-println = { version = "0.9.0", features = ["esp32c2", "log", "uart"] }
log = { version = "0.4.20" }
esp-alloc = { version = "0.3.0" }
embedded-svc = { version = "0.27.1", default-features = false, features = [] }
#embedded-io = "0.6.1"
embedded-io-async = "0.6.1"
esp-wifi = { version = "0.5.0", features = [
    "esp32c2",
    #"phy-enable-usb",
    "utils",
    #"wifi",
    "ble",
    "dump-packets",
    "async",
] }
heapless = { version = "0.8.0", default-features = false }
smoltcp = { version = "0.11.0", default-features = false, features = [
    "medium-ethernet",
    "proto-dhcpv4",
    "proto-igmp",
    "proto-ipv4",
    "socket-dhcpv4",
    "socket-icmp",
    "socket-raw",
    "socket-tcp",
    "socket-udp",
] }
#embassy-executor = { version = "0.5.0", features = ["task-arena-size-40960","integrated-timers",] }

embassy-executor = { version = "0.5.0", features = ["integrated-timers"] }
embassy-time = "0.3.0"
embassy-sync = "0.5.0"
embassy-futures = "0.1.1"

[profile.dev]
# Rust debug is too slow. 
# For debug builds always builds with some optimization
opt-level = "s"
[profile.release]
codegen-units = 1        # LLVM can perform better optimizations using a single thread
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 's'
overflow-checks = false

main.rs

#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
#![feature(async_closure)]

use core::pin::pin;
use embassy_executor::Spawner;
use embassy_futures::select::{select, Either};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel;
//use embassy_time::Timer;
use esp_backtrace as _;
use esp_hal::{
    clock::ClockControl,
    embassy,
    peripherals::Peripherals,
    prelude::*,
    timer::TimerGroup,
    uart::{config::AtCmdConfig, Uart}, //, UartRx, UartTx
};
extern crate alloc;
use core::mem::MaybeUninit;
use esp_println::println;
static CH0: Channel<CriticalSectionRawMutex, [u8; 512], 1> = Channel::new();
#[global_allocator]
static ALLOCATOR: esp_alloc::EspHeap = esp_alloc::EspHeap::empty();

fn init_heap() {
    const HEAP_SIZE: usize = 32 * 1024;
    static mut HEAP: MaybeUninit<[u8; HEAP_SIZE]> = MaybeUninit::uninit();
    unsafe {
        ALLOCATOR.init(HEAP.as_mut_ptr() as *mut u8, HEAP_SIZE);
    }
}

#[main]
async fn main(_spawner: Spawner) {
    let peripherals = Peripherals::take();
    let system = peripherals.SYSTEM.split();
    let clocks = ClockControl::max(system.clock_control).freeze();
    let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
    embassy::init(&clocks, timg0);
    init_heap();
    let mut uart0 = Uart::new_async(peripherals.UART0, &clocks);
    uart0.set_at_cmd(AtCmdConfig::new(None, None, None, 0x04, None));
    uart0.set_rx_fifo_full_threshold(256 as u16).unwrap(); //510
    uart0.set_rx_timeout(Some(8)).unwrap();

    let (mut tx0, mut rx0) = uart0.split();

    match select(
        pin!(async move {
            let mut buf = [0u8; 512];
            loop {
                let r = match embedded_io_async::Read::read(&mut rx0, &mut buf[2..]).await {
                    Ok(len) => {
                        println!("read {} bytes", len);
                        len
                    }
                    Err(e) => {
                        println!("read err! {:?} ", e);
                        0 as usize
                    }
                };
                buf[1] = (r & 0xff) as u8;
                buf[0] = ((r >> 8) & 0xff) as u8;
                CH0.send(buf).await;
            }
        }),
        pin!(async move {
            loop {
                println!("\n");
                let buf = CH0.receive().await;
                let b0 = buf[0] as usize;
                let b1 = buf[1] as usize;
                let w = b1 + (b0 << 8);
                println!("print b0 {b0} b1 {b1}");
                tx0.write_async(&buf[2..(w + 2)]).await.unwrap();
            }
        }),
    )
    .await
    {
        Either::First(_a) => {}
        Either::Second(_b) => {}
    }
}

@cvbni
Copy link
Author

cvbni commented May 22, 2024

0001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607
send the 128bytes data by hex

show in hex
图片
show in ascii

图片

00010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809000102030405060708090001020304050607080900010203040506070809

send the 130bytes data by hex

show in hex
图片

show in ascii
图片

@bjoernQ
Copy link
Contributor

bjoernQ commented May 23, 2024

I can reproduce your results but your example should work if you set the rx-fifo-full-threshold to 128 (or less) but you will receive data in multiple chunks.

In theory the UARTs can be configured in a more flexible way regarding their usage of UART RAM:

image

We currently don't support that but that's the reason why the thresholds are 8 bit.

@cvbni
Copy link
Author

cvbni commented May 23, 2024

OK, I understand, thanks, I will modify my program to adapt to 128 byte slices

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Todo
Development

No branches or pull requests

3 participants