diff options
author | Damien George <damien@micropython.org> | 2024-08-08 22:26:37 +1000 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-10-15 12:18:51 +1100 |
commit | fa15ae4503d87933c619a32110f8bd5e8817aece (patch) | |
tree | 88457c88a1285a0b38b6e73006044cc67ae02ddf | |
parent | ea2eed1b2307ae561e27997be86d7fc4494ed8e4 (diff) |
rp2/machine_bitstream: Implement bitstream for RISC-V using mcycle.
Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r-- | ports/rp2/machine_bitstream.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/ports/rp2/machine_bitstream.c b/ports/rp2/machine_bitstream.c index 8240fdad6..4ef97f0c8 100644 --- a/ports/rp2/machine_bitstream.c +++ b/ports/rp2/machine_bitstream.c @@ -34,6 +34,25 @@ #define MP_HAL_BITSTREAM_NS_OVERHEAD (9) +#if PICO_RISCV + +__attribute__((naked)) void mcycle_init(void) { + __asm volatile ( + "li a0, 4\n" + "csrw mcountinhibit, a0\n" + "ret\n" + ); +} + +__attribute__((naked)) uint32_t mcycle_get(void) { + __asm volatile ( + "csrr a0, mcycle\n" + "ret\n" + ); +} + +#endif + void __time_critical_func(machine_bitstream_high_low)(mp_hal_pin_obj_t pin, uint32_t *timing_ns, const uint8_t *buf, size_t len) { uint32_t fcpu_mhz = mp_hal_get_cpu_freq() / 1000000; // Convert ns to clock ticks [high_time_0, period_0, high_time_1, period_1]. @@ -49,14 +68,16 @@ void __time_critical_func(machine_bitstream_high_low)(mp_hal_pin_obj_t pin, uint } mp_hal_pin_output(pin); + uint32_t irq_state = mp_hal_quiet_timing_enter(); + + #if PICO_ARM + // Set systick reset value. systick_hw->rvr = 0x00FFFFFF; // Enable the systick counter, source CPU clock. systick_hw->csr = 5; - uint32_t irq_state = mp_hal_quiet_timing_enter(); - for (size_t i = 0; i < len; ++i) { uint8_t b = buf[i]; for (size_t j = 0; j < 8; ++j) { @@ -72,6 +93,27 @@ void __time_critical_func(machine_bitstream_high_low)(mp_hal_pin_obj_t pin, uint } } + #elif PICO_RISCV + + mcycle_init(); + + for (size_t i = 0; i < len; ++i) { + uint8_t b = buf[i]; + for (size_t j = 0; j < 8; ++j) { + uint32_t *t = &timing_ns[b >> 6 & 2]; + uint32_t start_ticks = mcycle_get(); + mp_hal_pin_high(pin); + while ((mcycle_get() - start_ticks) < t[0]) { + } + b <<= 1; + mp_hal_pin_low(pin); + while ((mcycle_get() - start_ticks) < t[1]) { + } + } + } + + #endif + mp_hal_quiet_timing_exit(irq_state); } |