From 25f1a519d0793dd9046eccffab5cc984d9727827 Mon Sep 17 00:00:00 2001 From: sys64738 Date: Sat, 27 Aug 2022 22:21:58 +0200 Subject: [PATCH] use IRQ to feed glitch params to PIO instead of core1 (freeing up core1) --- src/cli/rl78-glitch.c | 10 +-- src/glitch/glitch.c | 177 +++++++++----------------------------- src/glitch/glitch.h | 19 ++-- src/glitch/glitch_param.c | 8 +- src/glitch/glitch_param.h | 10 ++- src/glitch/trigctl.pio | 6 +- 6 files changed, 65 insertions(+), 165 deletions(-) diff --git a/src/cli/rl78-glitch.c b/src/cli/rl78-glitch.c index 364c025..e2d4687 100644 --- a/src/cli/rl78-glitch.c +++ b/src/cli/rl78-glitch.c @@ -25,9 +25,9 @@ void cli_tool78_glitch_param_g10(void); void cli_tool78_glitch_ocd_g10(void); #define USE_PICOEMP 0 -#define LEN_USE_ADC 0 +#define LEN_USE_ADC 1 -#define DUMP_OFFSET /*0*//*0xee000*/ +#define DUMP_OFFSET /*0*/0xee000 #define DUMP_SIZE /*0x100*/8192/*65536*/ // test with decoupling caps: length in 20..500(..1500) -> ok @@ -276,7 +276,7 @@ static void cli_tool78_glitch_dump_base(size_t pl_size, const uint8_t* payload) for (size_t iii = 0; iii < DUMP_SIZE + DUMP_OFFSET; ++iii) { // wait for completion size_t off = (iii < DUMP_OFFSET) ? 0 : (iii - DUMP_OFFSET); - rr = tool78_hw_rl78_uart1.recv(1, &databuf[off], 120*1000*1000); + rr = tool78_hw_rl78_uart1.recv(1, &databuf[iii], 120*1000*1000); if (rr != 1) { printf("exec code: no response :/ (%d)\n", rr); goto deinit_bad; @@ -643,7 +643,7 @@ success:; for (size_t iii = 0; iii < DUMP_SIZE + DUMP_OFFSET; ++iii) { // wait for completion size_t off = (iii < DUMP_OFFSET) ? 0 : (iii - DUMP_OFFSET); - rr = tool78_hw_rl78_uart1.recv(1, &databuf[off], 120*1000*1000); + rr = tool78_hw_rl78_uart1.recv(1, &databuf[iii], 120*1000*1000); if (rr != 1) { printf("exec code: no response :/ (%d)\n", rr); goto deinit_bad; @@ -890,7 +890,7 @@ success:; for (size_t iii = 0; iii < DUMP_SIZE + DUMP_OFFSET; ++iii) { // wait for completion size_t off = (iii < DUMP_OFFSET) ? 0 : (iii - DUMP_OFFSET); - rr = tool78_hw_rl78_uart1.recv(1, &databuf[off], 120*1000*1000); + rr = tool78_hw_rl78_uart1.recv(1, &databuf[iii], 120*1000*1000); if (rr != 1) { printf("exec code: no response :/ (%d)\n", rr); goto deinit_bad; diff --git a/src/glitch/glitch.c b/src/glitch/glitch.c index 9e10773..89d522a 100644 --- a/src/glitch/glitch.c +++ b/src/glitch/glitch.c @@ -23,12 +23,12 @@ #include "trigctl.pio.h" -volatile struct glitch_params glitch_param_cur = {0}; +volatile struct glitch_params CORE0_FUNC(glitch_param_cur) = {0}; #define param_cur glitch_param_cur -static PIO trigctl_pio = NULL; -static uint trigctl_sm, trigctl_off; +static PIO CORE0_FUNC(trigctl_pio) = NULL; +static uint CORE0_FUNC(trigctl_sm), trigctl_off; static int trigctl_pio_can_init(void) { if (pio_can_add_program(pio0, &trigctl_program)) { @@ -71,149 +71,50 @@ static void trigctl_pio_deinit(void) { trigctl_off = trigctl_sm = ~(uint32_t)0; } -#define CORE1_PRE_CALC() \ +#define push_param(void) do{\ uint32_t len = param_cur.length_ns.getter(param_cur.length_ns.ud), \ - off = param_cur.offset_ns.getter(param_cur.offset_ns.ud), \ - iom = 1u << param_cur.glitch_out_pin; \ + off = param_cur.offset_ns.getter(param_cur.offset_ns.ud); \ + \ + trigctl_push_off_len(trigctl_pio, trigctl_sm, off>>2, len>>2); \ + param_cur.offset_ns.cur = off; \ + param_cur.length_ns.cur = len; \ +} while (0) \ - -//#define CORE1_BUSYLOOP(v) do { \ -// uint32_t counter = (v)/*((v) >> 2) / 3*/; \ -// asm volatile( \ -// "1: sub %[counter], #12\n" \ -// "bgt 1b\n" \ -// :[counter]"+r"(counter) \ -// :: \ -// ); \ -//} while (0) \ -// -//#undef CORE1_BUSYLOOP -#define CORE1_BUSYLOOP(v) busy_wait_us_32((v)/1000) - -#define CORE1_DO_GLITCH() \ - do { \ - CORE1_BUSYLOOP(off); \ - param_cur.offset_ns.cur = off; \ - param_cur.length_ns.cur = len; \ - sio_hw->gpio_set = iom; \ - CORE1_BUSYLOOP(len); \ - sio_hw->gpio_clr = iom; \ - } while (0) \ - -__attribute__((__noreturn__)) -static void CORE1_FUNC(glitch_core1_thread_core1_fifoirq)(void) { - SCB->SCR &= ~SCB_SCR_SEVONPEND_Msk; // don't resume WFE on interrupt - - const int irq = SIO_IRQ_PROC1; - - irq_set_enabled(irq, false); - multicore_fifo_clear_irq(); - irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY); - //delayt1_irq_enable(pio0); - //irq_set_exclusive_handler(irq, core1_irq); - __disable_irq(); - irq_set_enabled(irq, true); - - while (true) { - CORE1_PRE_CALC(); - bool arm = *(volatile bool*)¶m_cur.armed; - - __WFI(); - irq_set_enabled(irq, false); - if (!arm) goto continue_; - arm = *(volatile bool*)¶m_cur.armed; - if (!arm) goto continue_; - - CORE1_DO_GLITCH(); - multicore_fifo_drain(); - multicore_fifo_clear_irq(); - //gpio_put(25, true); - continue_: - irq_set_enabled(irq, true); +static void glitch_pio_seed(void) { + if (pio_sm_is_tx_fifo_empty(trigctl_pio, trigctl_sm)) { + push_param(); } } -__attribute__((__noreturn__)) -static void CORE1_FUNC(glitch_core1_thread_core1_gpio)(void) { - // init gpio irq - const int gpio = param_cur.trigger_in_pin; - const int irq = IO_IRQ_BANK0; - // always rising edge: already using input direction override in case - // of negative trigger input polarity - const int event = /*(param_cur.trigger_in_polarity == glitch_positive) - ?*/ GPIO_IRQ_EDGE_RISE /*: GPIO_IRQ_EDGE_FALL*/; - irq_set_enabled(irq, false); - iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq - irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY); - hw_set_bits(&iobank0_hw->proc1_irq_ctrl.inte[gpio>>3], event << 4*(gpio&7)); - irq_set_enabled(irq, true); +void CORE0_FUNC(glitch_pio_isr)(void) { + trigctl_ack_glitch_irq(trigctl_pio, trigctl_sm); - while (true) { - CORE1_PRE_CALC(); + push_param(); - __WFI(); - //while (!(sio_hw->gpio_in & (1u<intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq - bool arm = *(volatile bool*)¶m_cur.armed; - if (!arm) continue; - - irq_set_enabled(irq, false); - //CORE1_DO_GLITCH(); - CORE1_BUSYLOOP(off); - if (!(sio_hw->gpio_in & (1u<gpio_set = iom; - CORE1_BUSYLOOP(len); - sio_hw->gpio_clr = iom; - cont: - irq_set_enabled(irq, true); - //while ((sio_hw->gpio_in & (1u<gpio_togl = 1u<<22; } -__attribute__((__noreturn__)) -static void CORE1_FUNC(glitch_core1_thread_pio)(void) { + +static void glitch_pio_isr_init(void) { const int irq = (trigctl_pio == pio0) ? PIO0_IRQ_1 : PIO1_IRQ_1; irq_set_enabled(irq, false); trigctl_ack_glitch_irq(trigctl_pio, trigctl_sm); trigctl_set_glitch_irq_enabled(trigctl_pio, trigctl_sm, 1, true); irq_set_priority(irq, PICO_HIGHEST_IRQ_PRIORITY); + irq_set_exclusive_handler(irq, glitch_pio_isr); + + glitch_pio_seed(); // kick off first transfer + irq_set_enabled(irq, true); - - while (true) { - //gpio_put(25, gpio_get(10)); - CORE1_PRE_CALC(); - (void)iom; - param_cur.offset_ns.cur = off; - param_cur.length_ns.cur = len; - trigctl_push_off_len(trigctl_pio, trigctl_sm, off>>2, len>>2); - - trigctl_wait_glitch_irq(trigctl_pio, trigctl_sm, true); - //sio_hw->gpio_togl = 1u<<25; - trigctl_ack_glitch_irq(trigctl_pio, trigctl_sm); - } +} +static void glitch_pio_isr_deinit(void) { + const int irq = (trigctl_pio == pio0) ? PIO0_IRQ_1 : PIO1_IRQ_1; + irq_set_enabled(irq, false); + irq_remove_handler(irq, glitch_pio_isr); + trigctl_set_glitch_irq_enabled(trigctl_pio, trigctl_sm, 1, false); } -__attribute__((__noreturn__)) -static void CORE1_FUNC(glitch_core1_thread)(void) { - __disable_irq(); - if (param_cur.impl == glitch_impl_pio) { - glitch_core1_thread_pio(); - } else if (param_cur.impl == glitch_impl_core1) { - if (param_cur.trigger_in_pin < 0) { - glitch_core1_thread_core1_fifoirq(); - } else { - glitch_core1_thread_core1_gpio(); - } - } - -} - -#undef CORE1_DO_GLITCH -#undef CORE1_PRE_CALC - -static void CORE0_FUNC(glitch_stop_no_clock_chg)(void) { - multicore_reset_core1(); +static void glitch_stop_no_clock_chg(void) { + glitch_pio_isr_deinit(); if (param_cur.impl != glitch_impl__none) { if (param_cur.impl == glitch_impl_pio) { @@ -256,7 +157,7 @@ static void CORE0_FUNC(glitch_stop_no_clock_chg)(void) { memset(¶m_cur, 0, sizeof param_cur); } -bool CORE0_FUNC(glitch_ready)(const struct glitch_params* params) { +bool glitch_ready(const struct glitch_params* params) { /*printf("params: off = %p %p ; len = %p %p\n", params->offset_ns.getter, params->offset_ns.ud, params->length_ns.getter, params->length_ns.ud); @@ -277,7 +178,7 @@ bool CORE0_FUNC(glitch_ready)(const struct glitch_params* params) { && params->trigger_in_polarity != glitch_negative) return false; if (params->glitch_out_polarity != glitch_positive && params->glitch_out_polarity != glitch_negative) return false; - if (params->impl != glitch_impl_core1 && params->impl != glitch_impl_pio) + if (params->impl != glitch_impl_pio) return false; int r = 0x99990; @@ -296,10 +197,14 @@ bool CORE0_FUNC(glitch_ready)(const struct glitch_params* params) { param_cur.length_ns.cur = 0; param_cur.armed = false; - gpio_init(25); + /*gpio_init(22); + gpio_set_dir(22, GPIO_OUT); + gpio_set_function(22, GPIO_FUNC_SIO); + gpio_put(22, false);*/ + /*gpio_init(25); gpio_set_dir(25, GPIO_OUT); gpio_set_function(25, GPIO_FUNC_SIO); - gpio_put(25, false); + gpio_put(25, false);*/ // let's not care about impl and always use core1 for now // TODO: if pio: check SM availability etc (& clear param_cur if fails) @@ -378,12 +283,12 @@ bool CORE0_FUNC(glitch_ready)(const struct glitch_params* params) { ); //printf("glitch out init: func %d on pin %d\n", func, param_cur.glitch_out_pin); - multicore_launch_core1(glitch_core1_thread); + glitch_pio_isr_init(); return true; } -void CORE0_FUNC(glitch_stop)(void) { +void glitch_stop(void) { glitch_stop_no_clock_chg(); set_sys_clock_khz(125*1000, true); vreg_set_voltage(VREG_VOLTAGE_DEFAULT); diff --git a/src/glitch/glitch.h b/src/glitch/glitch.h index d385194..05ab3f7 100644 --- a/src/glitch/glitch.h +++ b/src/glitch/glitch.h @@ -16,7 +16,6 @@ enum glitch_polarity { }; enum glitch_impl { glitch_impl__none, - glitch_impl_core1, glitch_impl_pio }; @@ -39,10 +38,6 @@ extern volatile struct glitch_params glitch_param_cur; bool glitch_ready(const struct glitch_params* params); void glitch_stop(void); -static inline void glitch_trigger_sw_core1(void) { - //asm volatile("sev"); - sio_hw->fifo_wr = 1; -} static inline void glitch_trigger_sw_pio(void) { glitch_param_cur.trigctl_pio->irq_force = 1 << ((glitch_param_cur.trigctl_sm + 1) & 3); @@ -51,18 +46,16 @@ static inline void glitch_trigger_sw_pio(void) { } static inline void glitch_arm(void) { + pio_sm_set_enabled(glitch_param_cur.trigctl_pio, + glitch_param_cur.trigctl_sm, true); + glitch_param_cur.armed = true; - if (glitch_param_cur.impl == glitch_impl_pio) { - pio_sm_set_enabled(glitch_param_cur.trigctl_pio, - glitch_param_cur.trigctl_sm, true); - } } static inline void glitch_disarm(void) { + pio_sm_set_enabled(glitch_param_cur.trigctl_pio, + glitch_param_cur.trigctl_sm, false); + glitch_param_cur.armed = false; - if (glitch_param_cur.impl == glitch_impl_pio) { - pio_sm_set_enabled(glitch_param_cur.trigctl_pio, - glitch_param_cur.trigctl_sm, false); - } } #endif diff --git a/src/glitch/glitch_param.c b/src/glitch/glitch_param.c index c84c764..ca959d4 100644 --- a/src/glitch/glitch_param.c +++ b/src/glitch/glitch_param.c @@ -23,15 +23,15 @@ inline static uint32_t pcg32_next(uint64_t* st) { return (uint32_t)(x >> (22 + count)); } -uint32_t CORE1_FUNC(glitch_param_const_fn)(void* p) { +uint32_t CORE0_FUNC(glitch_param_const_fn)(void* p) { return ((struct glitch_param_const*)p)->value; } -uint32_t CORE1_FUNC(glitch_param_randrange_fn)(void* p_) { +uint32_t CORE0_FUNC(glitch_param_randrange_fn)(void* p_) { struct glitch_param_randrange* p = (struct glitch_param_randrange*)p_; return p->min + pcg32_next(&p->rand_state) % p->max/*actually delta now*/; } -uint32_t CORE1_FUNC(glitch_param_sweep_fn)(void* p_) { +uint32_t CORE0_FUNC(glitch_param_sweep_fn)(void* p_) { struct glitch_param_sweep* p = (struct glitch_param_sweep*)p_; uint32_t rv = p->min + p->step * p->cur_index; @@ -44,7 +44,7 @@ uint32_t CORE1_FUNC(glitch_param_sweep_fn)(void* p_) { return rv; } -uint32_t CORE1_FUNC(glitch_param_adc_fn)(void* p_) { +uint32_t CORE0_FUNC(glitch_param_adc_fn)(void* p_) { struct glitch_param_adc* p = (struct glitch_param_adc*)p_; uint16_t av; diff --git a/src/glitch/glitch_param.h b/src/glitch/glitch_param.h index 6e646c7..b439c61 100644 --- a/src/glitch/glitch_param.h +++ b/src/glitch/glitch_param.h @@ -4,11 +4,13 @@ #include + #define __STRINGIFY(f) #f #define STRINGIFY(f) __STRINGIFY(f) #define CORE0_FUNC(f) __scratch_x(STRINGIFY(f)) f #define CORE1_FUNC(f) __scratch_y(STRINGIFY(f)) f + typedef uint32_t (*glitch_param_fn)(void*); struct glitch_param { @@ -37,10 +39,10 @@ struct glitch_param_adc { int adc_index; }; -uint32_t CORE1_FUNC(glitch_param_const_fn)(void* p); -uint32_t CORE1_FUNC(glitch_param_randrange_fn)(void* p); -uint32_t CORE1_FUNC(glitch_param_sweep_fn)(void* p); -uint32_t CORE1_FUNC(glitch_param_adc_fn)(void* p); +uint32_t CORE0_FUNC(glitch_param_const_fn)(void* p); +uint32_t CORE0_FUNC(glitch_param_randrange_fn)(void* p); +uint32_t CORE0_FUNC(glitch_param_sweep_fn)(void* p); +uint32_t CORE0_FUNC(glitch_param_adc_fn)(void* p); inline static void glitch_param_const_init(struct glitch_param_const* p) { (void)p; } inline static void glitch_param_sweep_init(struct glitch_param_sweep* p) { (void)p; } diff --git a/src/glitch/trigctl.pio b/src/glitch/trigctl.pio index e02001b..bafafbe 100644 --- a/src/glitch/trigctl.pio +++ b/src/glitch/trigctl.pio @@ -88,20 +88,20 @@ static inline void trigctl_pio_init(PIO pio, uint sm, uint prog_offs, } // ony use "use_wfi" when the corresponding IRQ is enabled in the NVIC -static inline void trigctl_wait_glitch_irq(PIO pio, uint sm, bool use_wfi) { +/*static inline void trigctl_wait_glitch_irq(PIO pio, uint sm, bool use_wfi) { uint mask = 1u << ((sm + 0) & 3); if (use_wfi) { while (!(pio->irq & mask)) __WFE(); } else { while (!(pio->irq & mask)) ; } -} +}*/ static inline void trigctl_ack_glitch_irq(PIO pio, uint sm) { hw_set_bits(&pio->irq, 1 << ((sm + 0) & 3)); } // nvic_irqno: corresponding NVIC IRQ will be PIO${pio}_IRQ_${nvic_irqno} static inline void trigctl_set_glitch_irq_enabled(PIO pio, uint sm, uint nvic_irqno, bool en) { - pio_set_irqn_source_enabled(pio, nvic_irqno, (sm + 0) & 3, en); + pio_set_irqn_source_enabled(pio, nvic_irqno, PIO_INTR_SM0_LSB + ((sm + 0) & 3), en); } /*static inline void trigctl_send_trig_irq(PIO pio, uint sm) {