mirror of
https://github.com/laanwj/k210-sdk-stuff.git
synced 2024-11-22 09:26:21 +04:00
rust: UART/network optimizations
This commit is contained in:
parent
2840ec0cf9
commit
f8f7235daa
@ -10,9 +10,10 @@ use core::sync::atomic::{AtomicUsize, Ordering};
|
|||||||
use k210_hal::pac;
|
use k210_hal::pac;
|
||||||
use k210_shared::soc::sysctl;
|
use k210_shared::soc::sysctl;
|
||||||
use pac::interrupt::Interrupt;
|
use pac::interrupt::Interrupt;
|
||||||
|
use riscv::asm;
|
||||||
use riscv::register::{mcause, mhartid, mie, mip, mstatus};
|
use riscv::register::{mcause, mhartid, mie, mip, mstatus};
|
||||||
|
|
||||||
const UART_BUFSIZE: usize = 4096;
|
const UART_BUFSIZE: usize = 8192;
|
||||||
/** UART ring buffer */
|
/** UART ring buffer */
|
||||||
struct UartInstance {
|
struct UartInstance {
|
||||||
buf: [u8; UART_BUFSIZE],
|
buf: [u8; UART_BUFSIZE],
|
||||||
@ -57,12 +58,17 @@ fn interrupt_uart1() {
|
|||||||
UART_INTERRUPT_RECEIVE | UART_INTERRUPT_CHARACTER_TIMEOUT => {
|
UART_INTERRUPT_RECEIVE | UART_INTERRUPT_CHARACTER_TIMEOUT => {
|
||||||
// Read recv FIFO into receive ringbuffer
|
// Read recv FIFO into receive ringbuffer
|
||||||
let mut head = irecv.head.load(Ordering::SeqCst);
|
let mut head = irecv.head.load(Ordering::SeqCst);
|
||||||
|
let tail = irecv.head.load(Ordering::SeqCst);
|
||||||
while ((*uart).lsr.read().bits() & 1) != 0 {
|
while ((*uart).lsr.read().bits() & 1) != 0 {
|
||||||
irecv.buf[head] = ((*uart).rbr_dll_thr.read().bits() & 0xff) as u8;
|
irecv.buf[head] = ((*uart).rbr_dll_thr.read().bits() & 0xff) as u8;
|
||||||
head += 1;
|
head += 1;
|
||||||
if head == UART_BUFSIZE {
|
if head == UART_BUFSIZE {
|
||||||
head = 0;
|
head = 0;
|
||||||
}
|
}
|
||||||
|
// TODO: signal overflows in a less catastropic way ?
|
||||||
|
if head == tail {
|
||||||
|
panic!("UART recv buffer overflow");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
irecv.head.store(head, Ordering::SeqCst);
|
irecv.head.store(head, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
@ -193,7 +199,7 @@ fn uart_enable_intr(recv: bool) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Send data to UART */
|
/** Send data to UART (blocking) */
|
||||||
pub fn send(s: &[u8]) {
|
pub fn send(s: &[u8]) {
|
||||||
let uart = pac::UART1::ptr();
|
let uart = pac::UART1::ptr();
|
||||||
for &c in s {
|
for &c in s {
|
||||||
@ -205,10 +211,13 @@ pub fn send(s: &[u8]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Receive data from UART (non-blocking, returns number of bytes received) */
|
/** Receive data from UART (non-blocking, returns number of bytes received) */
|
||||||
pub fn recv(s: &mut [u8]) -> usize {
|
pub fn recv_nb(s: &mut [u8]) -> usize {
|
||||||
let irecv = unsafe { &mut UART1_INSTANCE_RECV };
|
let irecv = unsafe { &mut UART1_INSTANCE_RECV };
|
||||||
let head = irecv.head.load(Ordering::SeqCst);
|
let head = irecv.head.load(Ordering::SeqCst);
|
||||||
let mut tail = irecv.tail.load(Ordering::SeqCst);
|
let mut tail = irecv.tail.load(Ordering::SeqCst);
|
||||||
|
if head == tail { // Early-out without tail.store if ring buffer empty
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
let mut ptr = 0;
|
let mut ptr = 0;
|
||||||
while ptr < s.len() && tail != head {
|
while ptr < s.len() && tail != head {
|
||||||
s[ptr] = irecv.buf[tail];
|
s[ptr] = irecv.buf[tail];
|
||||||
@ -222,6 +231,21 @@ pub fn recv(s: &mut [u8]) -> usize {
|
|||||||
ptr
|
ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Receive data from UART (blocks for at least one byte if the buffer can hold one, returns number
|
||||||
|
* of bytes received) */
|
||||||
|
pub fn recv(s: &mut [u8]) -> usize {
|
||||||
|
if s.len() == 0 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
let n = recv_nb(s);
|
||||||
|
if n != 0 {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
unsafe { asm::wfi(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Initialize interrupts and buffered UART handling */
|
/** Initialize interrupts and buffered UART handling */
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -27,7 +27,6 @@ use buffered_uart;
|
|||||||
mod config;
|
mod config;
|
||||||
|
|
||||||
const DEFAULT_BAUD: u32 = 115_200;
|
const DEFAULT_BAUD: u32 = 115_200;
|
||||||
const TIMEOUT: usize = 390_000_000 * 40 / 115200;
|
|
||||||
|
|
||||||
struct WriteAdapter;
|
struct WriteAdapter;
|
||||||
|
|
||||||
@ -106,7 +105,7 @@ fn main() -> ! {
|
|||||||
sh.start(false).unwrap();
|
sh.start(false).unwrap();
|
||||||
writeln!(console, "∙ Connecting to AP").unwrap();
|
writeln!(console, "∙ Connecting to AP").unwrap();
|
||||||
|
|
||||||
let mut serial_buf = [0u8; 8192];
|
let mut serial_buf = [0u8; 3000]; // needs to accomodate one whole response which is 2*TCP MSS(=2920)+some
|
||||||
let mut ofs: usize = 0;
|
let mut ofs: usize = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -27,7 +27,6 @@ use buffered_uart;
|
|||||||
mod config;
|
mod config;
|
||||||
|
|
||||||
const DEFAULT_BAUD: u32 = 115_200;
|
const DEFAULT_BAUD: u32 = 115_200;
|
||||||
const TIMEOUT: usize = 390_000_000 * 40 / 115200;
|
|
||||||
|
|
||||||
struct WriteAdapter;
|
struct WriteAdapter;
|
||||||
|
|
||||||
@ -106,7 +105,7 @@ fn main() -> ! {
|
|||||||
sh.start(false).unwrap();
|
sh.start(false).unwrap();
|
||||||
writeln!(console, "∙ Connecting to AP").unwrap();
|
writeln!(console, "∙ Connecting to AP").unwrap();
|
||||||
|
|
||||||
let mut serial_buf = [0u8; 8192];
|
let mut serial_buf = [0u8; 3000]; // needs to accomodate one whole response which is 2*TCP MSS(=2920)+some
|
||||||
let mut ofs: usize = 0;
|
let mut ofs: usize = 0;
|
||||||
|
|
||||||
let mut cur_link = 0;
|
let mut cur_link = 0;
|
||||||
|
@ -128,8 +128,8 @@ where
|
|||||||
Response::Echo(data) => {
|
Response::Echo(data) => {
|
||||||
writeln!(debug, "→ {}", str::from_utf8(data).unwrap_or("???")).unwrap();
|
writeln!(debug, "→ {}", str::from_utf8(data).unwrap_or("???")).unwrap();
|
||||||
}
|
}
|
||||||
Response::Data(link, _) => {
|
Response::Data(link, d) => {
|
||||||
writeln!(debug, "← Data({}, [...])", link).unwrap();
|
writeln!(debug, "← Data({}, [...] {})", link, d.len()).unwrap();
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
writeln!(debug, "← {:?}", resp).unwrap();
|
writeln!(debug, "← {:?}", resp).unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user