#include "async.h" #include "buffer.h" #include "gpio.h" #include "intc.h" #include "interrupts.h" #include "pol0.h" #include "timer.h" #include "trace.h" #include "uart.h" #include "uart_async.h" namespace { using async::AwaitableType; 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); } async::task<> echo() { async::task reader = UartReadLoop(); async::gimme> feeder; async::task<> writer = UartWriteLoop(feeder); writer.h.resume(); // advance to first yield while (1) { SetLed(1); uint8_t c = co_await reader; ClearLed(1); ToggleLed(2); feeder.feed(std::as_bytes(std::span{&c, 1})); } } } // 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() { SetupUart(); UartWriteCrash("uart setup done\r\n"); SetupTimer(); UartWriteCrash("timer setup done\r\n"); gpio0->data = 0; SetupInterrupts(); async::schedule(echo().h); UartWriteCrash("init done. starting main loop\r\n"); async::main_loop([]() { static int cnt = 0; timer0->Pet(); if ((cnt++ % 100000) == 0) { ToggleLed(0); } return false; }); // should never get here } /// stdlib stuff #include #include #include "itoa.h" #include "lock.h" #ifndef SBRK_STATS #define SBRK_STATS 0 #endif 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(-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(ptr); bool ret; { InterruptLock lock; ret = *dest; *dest = val; } return ret; }