summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2024-08-08 22:26:37 +1000
committerDamien George <damien@micropython.org>2024-10-15 12:18:51 +1100
commitfa15ae4503d87933c619a32110f8bd5e8817aece (patch)
tree88457c88a1285a0b38b6e73006044cc67ae02ddf
parentea2eed1b2307ae561e27997be86d7fc4494ed8e4 (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.c46
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);
}