Compare commits
No commits in common. "269a04d5f5b42e8f54ba6b3d57dee99ab1fe54ec" and "e4936abb5313bb1766a97f9487823da14e114a5b" have entirely different histories.
269a04d5f5
...
e4936abb53
@ -21,13 +21,6 @@ SECTIONS
|
|||||||
*(.rodata*)
|
*(.rodata*)
|
||||||
} > RAM
|
} > RAM
|
||||||
|
|
||||||
.init :
|
|
||||||
{
|
|
||||||
__init_array_start = .;
|
|
||||||
KEEP(*(.init_array*))
|
|
||||||
__init_array_end = .;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bss (NOLOAD) :
|
.bss (NOLOAD) :
|
||||||
{
|
{
|
||||||
_bss_begin = .;
|
_bss_begin = .;
|
||||||
|
@ -63,6 +63,9 @@ async::task<> echo() {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
#define XUL_SR_RX_FIFO_FULL 0x02 /* receive FIFO full */
|
||||||
|
#define XUL_SR_RX_FIFO_VALID_DATA 0x01 /* data in receive FIFO */
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
SetupUart();
|
SetupUart();
|
||||||
UartWriteCrash("uart setup done\r\n");
|
UartWriteCrash("uart setup done\r\n");
|
||||||
@ -96,6 +99,10 @@ int main() {
|
|||||||
#include "itoa.h"
|
#include "itoa.h"
|
||||||
#include "lock.h"
|
#include "lock.h"
|
||||||
|
|
||||||
|
#ifndef SBRK_STATS
|
||||||
|
#define SBRK_STATS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
extern unsigned char _heap_begin, _heap_end;
|
extern unsigned char _heap_begin, _heap_end;
|
||||||
|
|
||||||
extern "C" void* _sbrk(int increment) {
|
extern "C" void* _sbrk(int increment) {
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
#include "buffer.h"
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "intc.h"
|
|
||||||
#include "interrupts.h"
|
|
||||||
#include "pol0.h"
|
|
||||||
#include "timer.h"
|
|
||||||
#include "trace.h"
|
|
||||||
#include "uart2.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
Timer* timer0;
|
|
||||||
|
|
||||||
void Uart0Isr() {
|
|
||||||
// ToggleLed(7);
|
|
||||||
HandleUartIsr();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer0Isr() {
|
|
||||||
SetLed(6);
|
|
||||||
__builtin_trap();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupUart() {
|
|
||||||
InitUarts();
|
|
||||||
|
|
||||||
intc::SetIsr(UART0_IRQN, Uart0Isr);
|
|
||||||
intc::SetIrqEnabled(UART0_IRQN, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupTimer() {
|
|
||||||
timer0 = Timer::Instance(TIMER0_BASE);
|
|
||||||
// timer0->SetupAsWdt(100'000 * 1000);
|
|
||||||
timer0->EnableT1();
|
|
||||||
|
|
||||||
intc::SetIsr(TIMER0_IRQN, Timer0Isr);
|
|
||||||
intc::SetIrqEnabled(TIMER0_IRQN, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupInterrupts() {
|
|
||||||
intc::EnableInterrupts();
|
|
||||||
SetExternalInterruptHandler(intc::InterruptHandler);
|
|
||||||
EnableExternalInterrupts();
|
|
||||||
EnableInterrupts(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
SetupUart();
|
|
||||||
UartWriteCrash("uart setup done\r\n");
|
|
||||||
SetupTimer();
|
|
||||||
UartWriteCrash("timer setup done\r\n");
|
|
||||||
|
|
||||||
SetupInterrupts();
|
|
||||||
|
|
||||||
UartWriteCrash("init done. starting main loop\r\n");
|
|
||||||
|
|
||||||
UartEcho();
|
|
||||||
|
|
||||||
// should never get here
|
|
||||||
}
|
|
||||||
|
|
||||||
/// stdlib stuff
|
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "itoa.h"
|
|
||||||
#include "lock.h"
|
|
||||||
|
|
||||||
extern unsigned char _heap_begin, _heap_end;
|
|
||||||
|
|
||||||
extern "C" void* _sbrk(int increment) {
|
|
||||||
static unsigned char* heap = &_heap_begin;
|
|
||||||
unsigned char* prev_heap = heap;
|
|
||||||
if (heap + increment >= &_heap_end) {
|
|
||||||
UartWriteCrash("Heap overflow!\r\n");
|
|
||||||
return reinterpret_cast<void*>(-1);
|
|
||||||
}
|
|
||||||
heap += increment;
|
|
||||||
return prev_heap;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int _gettimeofday(struct timeval* tv, void* tzvp) {
|
|
||||||
(void)tzvp;
|
|
||||||
uint32_t ticks = timer0->GetT1Ticks();
|
|
||||||
tv->tv_sec = ticks / 100000000;
|
|
||||||
tv->tv_usec = (ticks % 100000000) / 100;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" uint8_t __atomic_exchange_1(volatile void* ptr, uint8_t val,
|
|
||||||
int memorder) {
|
|
||||||
(void)memorder;
|
|
||||||
auto* dest = reinterpret_cast<volatile uint8_t*>(ptr);
|
|
||||||
bool ret;
|
|
||||||
|
|
||||||
{
|
|
||||||
InterruptLock lock;
|
|
||||||
ret = *dest;
|
|
||||||
*dest = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
#include "lock.h"
|
#include "lock.h"
|
||||||
@ -7,9 +8,9 @@
|
|||||||
struct RingBuffer {
|
struct RingBuffer {
|
||||||
std::span<std::byte> buffer;
|
std::span<std::byte> buffer;
|
||||||
|
|
||||||
size_t read_ptr = 0;
|
std::atomic<size_t> read_ptr = 0;
|
||||||
size_t write_ptr = 0;
|
std::atomic<size_t> write_ptr = 0;
|
||||||
size_t used = 0;
|
std::atomic<bool> full = 0;
|
||||||
|
|
||||||
bool Store(std::span<const std::byte> data) {
|
bool Store(std::span<const std::byte> data) {
|
||||||
InterruptLock lock;
|
InterruptLock lock;
|
||||||
@ -52,7 +53,9 @@ struct RingBuffer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
write_ptr = (write_ptr + amount) % buffer.size();
|
write_ptr = (write_ptr + amount) % buffer.size();
|
||||||
used = used + amount;
|
if (read_ptr == write_ptr) {
|
||||||
|
full = true;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,20 +66,25 @@ struct RingBuffer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
read_ptr = (read_ptr + amount) % buffer.size();
|
read_ptr = (read_ptr + amount) % buffer.size();
|
||||||
used = used - amount;
|
if (amount > 0) {
|
||||||
|
full = false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t FreeSpace() const {
|
size_t FreeSpace() const {
|
||||||
InterruptLock lock;
|
InterruptLock lock;
|
||||||
|
|
||||||
return buffer.size() - used;
|
return buffer.size() - AvailableData();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AvailableData() const {
|
size_t AvailableData() const {
|
||||||
InterruptLock lock;
|
InterruptLock lock;
|
||||||
|
|
||||||
return used;
|
if (read_ptr == write_ptr) {
|
||||||
|
return full ? buffer.size() : 0;
|
||||||
|
}
|
||||||
|
return (buffer.size() + write_ptr - read_ptr) % buffer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* RawReadPointer() const {
|
uint8_t* RawReadPointer() const {
|
||||||
@ -85,21 +93,16 @@ struct RingBuffer {
|
|||||||
return reinterpret_cast<uint8_t*>(buffer.data() + read_ptr);
|
return reinterpret_cast<uint8_t*>(buffer.data() + read_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* RawWritePointer() const {
|
|
||||||
InterruptLock lock;
|
|
||||||
|
|
||||||
return reinterpret_cast<uint8_t*>(buffer.data() + write_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ContiguousFreeSpace() const {
|
|
||||||
InterruptLock lock;
|
|
||||||
|
|
||||||
return std::min(FreeSpace(), buffer.size() - write_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ContiguousAvailableData() const {
|
size_t ContiguousAvailableData() const {
|
||||||
InterruptLock lock;
|
InterruptLock lock;
|
||||||
|
|
||||||
return std::min(AvailableData(), buffer.size() - read_ptr);
|
if (read_ptr < write_ptr) {
|
||||||
|
return AvailableData();
|
||||||
|
}
|
||||||
|
if (full) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.size() - read_ptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -27,8 +27,6 @@ std::array<std::byte, kUartTxBufferSize> tx_buffer = {};
|
|||||||
RingBuffer tx_ring_buffer{.buffer = tx_buffer};
|
RingBuffer tx_ring_buffer{.buffer = tx_buffer};
|
||||||
|
|
||||||
XUartLite* uart0 = &uart0_inst;
|
XUartLite* uart0 = &uart0_inst;
|
||||||
|
|
||||||
bool sending;
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void InitUarts() {
|
void InitUarts() {
|
||||||
@ -37,12 +35,9 @@ void InitUarts() {
|
|||||||
XUartLite_SetSendHandler(uart0, HandleUartTxFromIsr, nullptr);
|
XUartLite_SetSendHandler(uart0, HandleUartTxFromIsr, nullptr);
|
||||||
XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr);
|
XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr);
|
||||||
XUartLite_EnableInterrupt(uart0);
|
XUartLite_EnableInterrupt(uart0);
|
||||||
|
|
||||||
sending = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UartWriteCrash(std::span<const std::byte> data) {
|
void UartWriteCrash(std::span<const std::byte> data) {
|
||||||
XUartLite_DisableInterrupt(uart0);
|
|
||||||
while (data.size() > 0) {
|
while (data.size() > 0) {
|
||||||
while (XUartLite_IsSending(uart0)) {
|
while (XUartLite_IsSending(uart0)) {
|
||||||
}
|
}
|
||||||
@ -53,7 +48,6 @@ void UartWriteCrash(std::span<const std::byte> data) {
|
|||||||
}
|
}
|
||||||
while (XUartLite_IsSending(uart0)) {
|
while (XUartLite_IsSending(uart0)) {
|
||||||
}
|
}
|
||||||
XUartLite_EnableInterrupt(uart0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async::task<> UartWrite(std::span<const std::byte> data) {
|
async::task<> UartWrite(std::span<const std::byte> data) {
|
||||||
@ -85,11 +79,10 @@ async::task<> UartWriteLoop(
|
|||||||
|
|
||||||
{
|
{
|
||||||
InterruptLock lock;
|
InterruptLock lock;
|
||||||
if (!sending) {
|
if (!XUartLite_IsSending(uart0)) {
|
||||||
tracing::trace(tracing::TraceEvent::kUartSend);
|
tracing::trace(tracing::TraceEvent::kUartSend);
|
||||||
XUartLite_Send(uart0, tx_ring_buffer.RawReadPointer(),
|
XUartLite_Send(uart0, tx_ring_buffer.RawReadPointer(),
|
||||||
tx_ring_buffer.ContiguousAvailableData());
|
tx_ring_buffer.ContiguousAvailableData());
|
||||||
sending = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,13 +139,11 @@ async::task<buffer> UartRead(int size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HandleUartTxFromIsr(void*, unsigned int transmitted) {
|
void HandleUartTxFromIsr(void*, unsigned int transmitted) {
|
||||||
sending = false;
|
|
||||||
tx_ring_buffer.Pop(transmitted);
|
tx_ring_buffer.Pop(transmitted);
|
||||||
if (tx_ring_buffer.AvailableData() > 0) {
|
if (tx_ring_buffer.AvailableData() > 0) {
|
||||||
tracing::trace(tracing::TraceEvent::kUartSend);
|
tracing::trace(tracing::TraceEvent::kUartSend);
|
||||||
XUartLite_Send(uart0, tx_ring_buffer.RawReadPointer(),
|
XUartLite_Send(uart0, tx_ring_buffer.RawReadPointer(),
|
||||||
tx_ring_buffer.ContiguousAvailableData());
|
tx_ring_buffer.ContiguousAvailableData());
|
||||||
sending = true;
|
|
||||||
}
|
}
|
||||||
async::resume(AwaitableType::kUartTx);
|
async::resume(AwaitableType::kUartTx);
|
||||||
}
|
}
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
#include "uart2.h"
|
|
||||||
|
|
||||||
#include "gpio.h"
|
|
||||||
#include "lock.h"
|
|
||||||
#include "pol0.h"
|
|
||||||
#include "ring_buffer.h"
|
|
||||||
#include "xuartlite.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr uintptr_t kUart0BaseAddress = UART0_BASE;
|
|
||||||
XUartLite uart0_inst;
|
|
||||||
XUartLite_Config uart0_config = {
|
|
||||||
.DeviceId = 0,
|
|
||||||
.RegBaseAddr = kUart0BaseAddress,
|
|
||||||
.BaudRate = 115200,
|
|
||||||
.UseParity = false,
|
|
||||||
.DataBits = 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr size_t kUartRxBufferSize = 256;
|
|
||||||
std::array<std::byte, kUartRxBufferSize> rx_buffer = {};
|
|
||||||
RingBuffer rx_ring_buffer{.buffer = rx_buffer};
|
|
||||||
|
|
||||||
constexpr size_t kUartTxBufferSize = 256;
|
|
||||||
std::array<std::byte, kUartTxBufferSize> tx_buffer = {};
|
|
||||||
RingBuffer tx_ring_buffer{.buffer = tx_buffer};
|
|
||||||
|
|
||||||
XUartLite* uart0 = &uart0_inst;
|
|
||||||
|
|
||||||
volatile int sending = 0;
|
|
||||||
|
|
||||||
void StartReceiving() {
|
|
||||||
while (1) {
|
|
||||||
if (rx_ring_buffer.FreeSpace() < 1) {
|
|
||||||
// woops, full. discard some data
|
|
||||||
// TODO: keep track of overrun stats
|
|
||||||
rx_ring_buffer.Pop(1);
|
|
||||||
}
|
|
||||||
if (XUartLite_Recv(uart0, rx_ring_buffer.RawWritePointer(), 1) < 1) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rx_ring_buffer.Push(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartSending() {
|
|
||||||
if (tx_ring_buffer.AvailableData() > 0 && sending < 1) {
|
|
||||||
sending += 1;
|
|
||||||
XUartLite_Send(uart0, tx_ring_buffer.RawReadPointer(), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::byte UartReadByte() {
|
|
||||||
std::byte c;
|
|
||||||
while (!rx_ring_buffer.Load(std::span{&c, 1})) {
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UartWriteByte(std::byte c) {
|
|
||||||
while (!tx_ring_buffer.Store(std::span{&c, 1})) {
|
|
||||||
}
|
|
||||||
{
|
|
||||||
InterruptLock lock;
|
|
||||||
StartSending();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void InitUarts() {
|
|
||||||
XUartLite_CfgInitialize(uart0, &uart0_config, uart0_config.RegBaseAddr);
|
|
||||||
|
|
||||||
XUartLite_SetSendHandler(uart0, HandleUartTxFromIsr, nullptr);
|
|
||||||
XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr);
|
|
||||||
StartReceiving();
|
|
||||||
XUartLite_EnableInterrupt(uart0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UartWriteCrash(std::span<const std::byte> data) {
|
|
||||||
XUartLite_DisableInterrupt(uart0);
|
|
||||||
while (data.size() > 0) {
|
|
||||||
while (XUartLite_IsSending(uart0)) {
|
|
||||||
}
|
|
||||||
auto* dat =
|
|
||||||
reinterpret_cast<uint8_t*>(const_cast<std::byte*>(data.data()));
|
|
||||||
uint8_t sent = XUartLite_Send(uart0, dat, data.size());
|
|
||||||
data = data.subspan(sent);
|
|
||||||
}
|
|
||||||
while (XUartLite_IsSending(uart0)) {
|
|
||||||
}
|
|
||||||
XUartLite_EnableInterrupt(uart0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UartEcho() {
|
|
||||||
while (1) {
|
|
||||||
gpio0->data = tx_ring_buffer.AvailableData();
|
|
||||||
|
|
||||||
std::byte c = UartReadByte();
|
|
||||||
UartWriteByte(c);
|
|
||||||
|
|
||||||
//gpio0->data = uart0->Stats.ReceiveOverrunErrors;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleUartTxFromIsr(void*, unsigned int transmitted) {
|
|
||||||
sending -= 1;
|
|
||||||
tx_ring_buffer.Pop(transmitted);
|
|
||||||
StartSending();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleUartRxFromIsr(void*, unsigned int transmitted) {
|
|
||||||
rx_ring_buffer.Push(transmitted);
|
|
||||||
StartReceiving();
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleUartIsr() { XUartLite_InterruptHandler(uart0); }
|
|
@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <span>
|
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
void InitUarts();
|
|
||||||
|
|
||||||
// send and poll the uart until transmitted
|
|
||||||
void UartWriteCrash(std::span<const std::byte> data);
|
|
||||||
inline void UartWriteCrash(std::string_view s) {
|
|
||||||
return UartWriteCrash(std::as_bytes(std::span{s.data(), s.size()}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UartEcho();
|
|
||||||
|
|
||||||
void HandleUartTxFromIsr(void*, unsigned int transmitted);
|
|
||||||
void HandleUartRxFromIsr(void*, unsigned int);
|
|
||||||
void HandleUartIsr();
|
|
4
mbv/configure
vendored
4
mbv/configure
vendored
@ -304,9 +304,9 @@ all = [
|
|||||||
app_image("async", sources=[
|
app_image("async", sources=[
|
||||||
"apps/async/async.cc",
|
"apps/async/async.cc",
|
||||||
"apps/async/lock.cc",
|
"apps/async/lock.cc",
|
||||||
"apps/async/main2.cc",
|
"apps/async/main.cc",
|
||||||
"apps/async/trace.cc",
|
"apps/async/trace.cc",
|
||||||
"apps/async/uart2.cc",
|
"apps/async/uart.cc",
|
||||||
]),
|
]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
extern "C" uint32_t _bss_begin, _bss_end, _initial_stack_pointer;
|
extern "C" uint32_t _bss_begin, _bss_end, _initial_stack_pointer;
|
||||||
extern "C" int main();
|
extern "C" int main();
|
||||||
extern "C" void __libc_init_array();
|
|
||||||
|
|
||||||
__attribute__((section(".start"), used, naked)) void _start() {
|
__attribute__((section(".start"), used, naked)) void _start() {
|
||||||
// clear .bss
|
// clear .bss
|
||||||
@ -12,8 +11,6 @@ __attribute__((section(".start"), used, naked)) void _start() {
|
|||||||
|
|
||||||
asm volatile("la sp, _initial_stack_pointer");
|
asm volatile("la sp, _initial_stack_pointer");
|
||||||
|
|
||||||
__libc_init_array();
|
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -387,7 +387,8 @@ int XUartLite_IsSending(XUartLite *InstancePtr)
|
|||||||
/*
|
/*
|
||||||
* Read the status register to determine if the transmitter is empty
|
* Read the status register to determine if the transmitter is empty
|
||||||
*/
|
*/
|
||||||
StatusRegister = XUartLite_GetSR(InstancePtr);
|
StatusRegister = XUartLite_ReadReg(InstancePtr->RegBaseAddress,
|
||||||
|
XUL_STATUS_REG_OFFSET);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the transmitter is not empty then indicate that the UART is still
|
* If the transmitter is not empty then indicate that the UART is still
|
||||||
|
@ -143,7 +143,8 @@ void XUartLite_InterruptHandler(XUartLite *InstancePtr)
|
|||||||
* Read the status register to determine which, coulb be both
|
* Read the status register to determine which, coulb be both
|
||||||
* interrupt is active
|
* interrupt is active
|
||||||
*/
|
*/
|
||||||
IsrStatus = XUartLite_GetSR(InstancePtr);
|
IsrStatus = XUartLite_ReadReg(InstancePtr->RegBaseAddress,
|
||||||
|
XUL_STATUS_REG_OFFSET);
|
||||||
|
|
||||||
if ((IsrStatus & (XUL_SR_RX_FIFO_FULL |
|
if ((IsrStatus & (XUL_SR_RX_FIFO_FULL |
|
||||||
XUL_SR_RX_FIFO_VALID_DATA)) != 0) {
|
XUL_SR_RX_FIFO_VALID_DATA)) != 0) {
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
import argparse
|
|
||||||
import random
|
|
||||||
import serial
|
|
||||||
import sys
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
|
|
||||||
tty = "/dev/ttyUSB1"
|
|
||||||
baud = 115200
|
|
||||||
|
|
||||||
|
|
||||||
def sendrecv(s, size, timeout=5):
|
|
||||||
"""Send some data and recv until the same data was received back."""
|
|
||||||
data = random.randbytes(size)
|
|
||||||
return sendcheck(s, data, timeout)
|
|
||||||
|
|
||||||
|
|
||||||
def sendcheck(s, data, timeout=5):
|
|
||||||
s.write(data)
|
|
||||||
received = 0
|
|
||||||
start = time.time()
|
|
||||||
got = bytearray()
|
|
||||||
while received < len(data):
|
|
||||||
r = s.read()
|
|
||||||
got += r
|
|
||||||
try:
|
|
||||||
assert(r == data[received: received + len(r)])
|
|
||||||
assert(time.time() < start + timeout)
|
|
||||||
except:
|
|
||||||
fr = received - 10
|
|
||||||
to = received + len(r) + 1
|
|
||||||
sdat = data[fr: to]
|
|
||||||
rdat = bytes(got[fr: to])
|
|
||||||
print(f"failed after receiving {received} correct bytes")
|
|
||||||
print(f"expected {sdat}")
|
|
||||||
print(f" got {rdat}")
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
received += len(r)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
return parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
args = parse_args()
|
|
||||||
|
|
||||||
s = serial.Serial(tty, baud, timeout=1)
|
|
||||||
for i in range(12):
|
|
||||||
size = 2**i
|
|
||||||
print(f"Trying with {size} bytes")
|
|
||||||
sendrecv(s, size)
|
|
||||||
data = b'ze%s\x96:M#\xd8\x98\x9d\x96\xf5?\x80c\xc6\xa7\x03\xe0i\x04V\xcb\xa3\x95#GC\xabf\x98'
|
|
||||||
#sendcheck(s, data)
|
|
||||||
|
|
||||||
print("All sizes passed.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
Loading…
Reference in New Issue
Block a user