rp2/machine_bitstream: Implement bitstream for RISC-V using mcycle.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2024-08-08 22:26:37 +10:00
parent ea2eed1b23
commit fa15ae4503
1 changed files with 44 additions and 2 deletions

View File

@ -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);
}