better glitch parameter api

This commit is contained in:
Triss 2022-04-07 02:19:58 +02:00
parent 376a6bce7b
commit e0fedc3e60
9 changed files with 228 additions and 98 deletions

View File

@ -47,6 +47,7 @@ if(FAMILY STREQUAL "rp2040")
${CMAKE_CURRENT_SOURCE_DIR}/src/test/piotest.c
${CMAKE_CURRENT_SOURCE_DIR}/src/test/delaytest.c
${CMAKE_CURRENT_SOURCE_DIR}/src/test/piodump.c
${CMAKE_CURRENT_SOURCE_DIR}/src/glitch/glitch_param.c
${CMAKE_CURRENT_SOURCE_DIR}/src/glitch/glitch.c
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/cli.c
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/msp430.c

View File

@ -34,14 +34,14 @@ void cli_dragonzap_test(void) {
zap_crowbar_a_act();
zap_crowbar_b_act();
zap_max_put(true);
sio_hw->gpio_togl = 0x80;
sio_hw->gpio_set = 0x80;
busy_wait_ms(1000);
zap_crowbar_a_hiz();
zap_crowbar_b_hiz();
zap_max_put(false);
sio_hw->gpio_togl = 0x80;
sio_hw->gpio_set = 0x80;
busy_wait_ms(1000);
}

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include <string.h>
#include <hardware/adc.h>
#include <hardware/clocks.h>
#include <hardware/gpio.h>
#include <hardware/pwm.h>
@ -42,15 +43,26 @@ sec: flg=fe bot=03 fsws=0000 fswe=003f
//void trl78_uart1_set_exclusive(bool ex);
static uint8_t databuf[DUMP_SIZE];
static struct glitch_param_randrange offset;
static struct glitch_param_adc length;
static void glitch_init_core1_stuff(bool exttrig) {
offset.min = 10*1000;
offset.max = 35433*1000;
length.min = 10;
length.max = 10*1000;
length.adc_index = 999;
glitch_param_randrange_init(&offset);
glitch_param_adc_init(&length);
// REGC = 2.11V / 0.47..1 uF // WUFM: REGC = 1.80V // BUT: OCD mode: always 2.1!
static struct glitch_params gparam = (struct glitch_params){
.offset_min_ns = 10*1000,
.offset_max_ns = 35433*1000,
//.offset_min_ns = 10*1000,
//.offset_max_ns = 35433*1000,
// with REGC & 10uF Vcc:
.length_min_ns = -1,//10,//-1,//20,
.length_max_ns = 10000,//*8,
//.length_min_ns = -1,//10,//-1,//20,
//.length_max_ns = 10000,//*8,
// with REGC:
/*.length_min_us = 4000,
.length_max_us = 6300,*/
@ -69,7 +81,14 @@ static void glitch_init_core1_stuff(bool exttrig) {
.trigger_in_polarity = glitch_positive,
.glitch_out_polarity = glitch_positive,
.impl = glitch_impl_pio,//core1,
.offset_cur = 0, .length_cur = 0
};
gparam.offset_ns = (struct glitch_param){
.ud = &offset,
.getter = glitch_param_randrange_fn
};
gparam.length_ns = (struct glitch_param){
.ud = &length,
.getter = glitch_param_adc_fn
};
gparam.trigger_in_pin = exttrig ? TRIGGER_IN_PIN : (-1);
glitch_ready(&gparam);
@ -295,11 +314,27 @@ restart:
}
if (firstbad >= 0) {
volatile uint32_t
*off = (volatile uint32_t*)&glitch_param_cur.offset_cur,
*len = (volatile uint32_t*)&glitch_param_cur.length_cur;
*off = (volatile uint32_t*)&glitch_param_cur.offset_ns.cur,
*len = (volatile uint32_t*)&glitch_param_cur.length_ns.cur;
printf("glitch first=%d last=%d off=%lu len=%lu rr=%d v=%02x\n",
firstbad, lastbad, *off, *len, rr, checkbuf[firstbad]^0xaa);
} else printf(".");
} else {
printf(".");
/*volatile uint32_t
*off = (volatile uint32_t*)&glitch_param_cur.offset_ns.cur,
*len = (volatile uint32_t*)&glitch_param_cur.length_ns.cur;
printf("off was %lu, len was %lu, adc=%04x\n",
*off, *len, adc_read());
printf("offset: fn=%p ud=%p\n",
glitch_param_cur.offset_ns.getter,
glitch_param_cur.offset_ns.ud);
printf("len: fn=%p ud=%p\n",
glitch_param_cur.length_ns.getter,
glitch_param_cur.length_ns.ud);
uint32_t ofv = glitch_param_cur.offset_ns.getter(glitch_param_cur.offset_ns.ud);
uint32_t lnv = glitch_param_cur.length_ns.getter(glitch_param_cur.length_ns.ud);
printf("sample: len=%lu off=%lu\n", ofv, lnv);*/
}
}
}
@ -433,7 +468,7 @@ success:;
}
printf("got ver! %04x\n", ver);
printf("glitch len: %lu us\n", *(volatile uint32_t*)&glitch_param_cur.length_cur);
printf("glitch len: %lu us\n", *(volatile uint32_t*)&glitch_param_cur.length_ns.cur);
/*goto do_reset_stuff;*/
st = tool78_ocd_connect(&tool78_hw_rl78_uart1, passwd);

View File

@ -93,7 +93,7 @@ sec: flg=fe bot=03 fsws=0000 fswe=003f
printf("secget: 0x%02x\n", st);
printf("sec: flg=%02x bot=%02x fsws=%04x fswe=%04x\n", sec.flg, sec.bot, sec.fsws, sec.fswe);
//st = tool78_do_security_release(&tool78_hw_rl78_uart1);
/*//st = tool78_do_security_release(&tool78_hw_rl78_uart1);
//printf("sec rel: 0x%02x\n", st);
// one block = 0x400 = 1k
st = tool78_do_block_erase(hw, 0, -1);
@ -104,7 +104,7 @@ sec: flg=fe bot=03 fsws=0000 fswe=003f
printf("programming: 0x%02x\n", st);
st = tool78_do_verify(hw, 0, 0x3ff, datatoflash);
printf("verify: 0x%02x\n", st);
printf("verify: 0x%02x\n", st);*/
/*for (size_t iii = 0; iii < 65536; iii += 0x400) {
st = tool78_do_verify(hw, iii+0, iii+0x3ff, &DATA_wfum_flash[iii]);

View File

@ -2,8 +2,8 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <RP2040.h>
#include <system_RP2040.h>
@ -23,19 +23,10 @@
#include "trigctl.pio.h"
#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
volatile struct glitch_params glitch_param_cur = {0};
#define param_cur glitch_param_cur
// PCG impl lifted from Wikipedia
#define PCG_MULTIPLIER 6364136223846793005uLL
static uint64_t mcg_state = 0xcafef00dd15ea5e5uLL; // Must be odd
static PIO trigctl_pio = NULL;
static uint trigctl_sm, trigctl_off;
@ -80,53 +71,37 @@ static void trigctl_pio_deinit(void) {
trigctl_off = trigctl_sm = ~(uint32_t)0;
}
static uint32_t CORE1_FUNC(pcg32_fast)(void) {
uint64_t x = mcg_state;
unsigned count = (unsigned)(x >> 61); // 61 = 64 - 3
#define CORE1_PRE_CALC() \
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; \
mcg_state = x * PCG_MULTIPLIER;
x ^= x >> 22;
return (uint32_t)(x >> (22 + count)); // 22 = 32 - 3 - 7
}
static void CORE1_FUNC(pcg32_fast_init)(uint64_t seed) {
mcg_state = 2*seed + 1;
(void)pcg32_fast();
}
// ADC value is in low 12 bits of adc_read()
// FIXME: length_min_ns = -1 => adc breaks? | oops was signedness bug
#define CORE1_PRE_CALC() /* BIG TODO HERE! */ \
bool sweep = param_cur.offset_min_ns == param_cur.offset_max_ns \
&& param_cur.length_min_ns >= 0; \
uint32_t len, off = param_cur.offset_min_ns + \
(pcg32_fast() % (param_cur.offset_max_ns - param_cur.offset_min_ns)), \
iom = 1u << param_cur.glitch_out_pin; \
do { \
if (sweep) { \
if (len_prev == param_cur.length_max_ns) len_prev = (len = param_cur.length_min_ns); \
else len = (len_prev = (len_prev + 1));\
} else { \
len = (param_cur.length_min_ns < 0) \
? (((uint64_t)adc_read() * param_cur.length_max_ns) >> 12) \
: (param_cur.length_min_ns + (pcg32_fast() % \
(param_cur.length_max_ns - param_cur.length_min_ns))); \
} \
} 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 { \
busy_wait_us_32(off/1000); \
CORE1_BUSYLOOP(off); \
param_cur.offset_ns.cur = off; \
param_cur.length_ns.cur = len; \
sio_hw->gpio_set = iom; \
busy_wait_us_32(len/1000); \
CORE1_BUSYLOOP(len); \
sio_hw->gpio_clr = iom; \
param_cur.offset_cur = off; \
param_cur.length_cur = len; \
} while (0) \
__attribute__((__noreturn__))
static void CORE1_FUNC(glitch_core1_thread_core1_fifoirq)(void) {
int32_t len_prev = param_cur.length_min_ns - 1;
SCB->SCR &= ~SCB_SCR_SEVONPEND_Msk; // don't resume WFE on interrupt
const int irq = SIO_IRQ_PROC1;
@ -158,8 +133,6 @@ static void CORE1_FUNC(glitch_core1_thread_core1_fifoirq)(void) {
}
__attribute__((__noreturn__))
static void CORE1_FUNC(glitch_core1_thread_core1_gpio)(void) {
int32_t len_prev = param_cur.length_min_ns - 1;
// init gpio irq
const int gpio = param_cur.trigger_in_pin;
const int irq = IO_IRQ_BANK0;
@ -183,31 +156,19 @@ static void CORE1_FUNC(glitch_core1_thread_core1_gpio)(void) {
irq_set_enabled(irq, false);
//CORE1_DO_GLITCH();
busy_wait_us_32(off/1000);
CORE1_BUSYLOOP(off);
if (!(sio_hw->gpio_in & (1u<<gpio))) goto cont;
param_cur.offset_cur = off;
param_cur.length_cur = len;
param_cur.offset_ns.cur = off;
param_cur.length_ns.cur = len;
sio_hw->gpio_set = iom;
len = (len >> 4) / 3;
asm volatile(
// loop is 3 cycles
"1: sub %[counter], #1\n"
//"cmp %[counter], #0\n"
"bne 1b\n"
:[counter]"+r"(len)
::
);
//busy_wait_us_32(len);
CORE1_BUSYLOOP(len);
sio_hw->gpio_clr = iom;
cont:
irq_set_enabled(irq, true);
}
}
__attribute__((__noreturn__))
static void CORE1_FUNC(glitch_core1_thread_pio)(void) {
int32_t len_prev = param_cur.length_min_ns - 1;
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);
@ -218,9 +179,9 @@ static void CORE1_FUNC(glitch_core1_thread_pio)(void) {
while (true) {
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);
param_cur.offset_cur = off;
param_cur.length_cur = len;
trigctl_wait_glitch_irq(trigctl_pio, trigctl_sm, true);
trigctl_ack_glitch_irq(trigctl_pio, trigctl_sm);
@ -229,10 +190,6 @@ static void CORE1_FUNC(glitch_core1_thread_pio)(void) {
__attribute__((__noreturn__))
static void CORE1_FUNC(glitch_core1_thread)(void) {
// use stdlib randomness only for the seed, but use a custom rng sitting in
// SRAM 5 to avoid bus contention
pcg32_fast_init(random());
__disable_irq();
if (param_cur.impl == glitch_impl_pio) {
@ -296,8 +253,8 @@ static void CORE0_FUNC(glitch_stop_no_clock_chg)(void) {
bool CORE0_FUNC(glitch_ready)(const struct glitch_params* params) {
// check params values
if (params->offset_max_ns < params->offset_min_ns) return false;
if (params->length_max_ns < params->length_min_ns) return false;
if (!params->offset_ns.getter || !params->offset_ns.ud) return false;
if (!params->length_ns.getter || !params->length_ns.ud) return false;
if (params->trigger_in_pin < -1 || params->trigger_in_pin >= 28
|| (params->trigger_in_pin >= 23 && params->trigger_in_pin <= 25))
return false;
@ -320,8 +277,8 @@ bool CORE0_FUNC(glitch_ready)(const struct glitch_params* params) {
glitch_stop();
memcpy(&param_cur, params, sizeof param_cur); // apply new params
param_cur.offset_cur = 0;
param_cur.length_cur = 0;
param_cur.offset_ns.cur = 0;
param_cur.length_ns.cur = 0;
param_cur.armed = false;
// let's not care about impl and always use core1 for now
@ -337,7 +294,7 @@ bool CORE0_FUNC(glitch_ready)(const struct glitch_params* params) {
func = (trigctl_pio == pio0) ? GPIO_FUNC_PIO0 : GPIO_FUNC_PIO1;
}
if (params->length_min_ns < 0) {
/*if (params->length_min_ns < 0) {
// FIXME: use a more generic approach (using dragonzap adc)
// ADC1: ADC mode
@ -350,7 +307,7 @@ bool CORE0_FUNC(glitch_ready)(const struct glitch_params* params) {
gpio_set_function(26, GPIO_FUNC_SIO);
} else {
gpio_set_function(26, GPIO_FUNC_NULL);
}
}*/
if (params->trigger_in_pin >= 0) {
//gpio_set_input_hysteresis_enabled(params->trigger_in_pin, false);

View File

@ -8,6 +8,8 @@
#include <hardware/pio.h>
#include "glitch_param.h"
enum glitch_polarity {
glitch_positive,
glitch_negative,
@ -19,18 +21,13 @@ enum glitch_impl {
};
struct glitch_params {
uint32_t offset_min_ns;
uint32_t offset_max_ns;
// FIXME: use a more generic approach (using dragonzap adc)
// for using user-tunable lengths (with physical knobs)
int32_t length_min_ns;
int32_t length_max_ns;
struct glitch_param offset_ns;
struct glitch_param length_ns;
int trigger_in_pin; // use -1 for a signal coming from core 0
int glitch_out_pin;
enum glitch_polarity trigger_in_polarity;
enum glitch_polarity glitch_out_polarity;
enum glitch_impl impl;
uint32_t offset_cur, length_cur;
PIO trigctl_pio;
uint32_t trigctl_sm;
bool armed;

87
src/glitch/glitch_param.c Normal file
View File

@ -0,0 +1,87 @@
#include <stdlib.h>
#include <hardware/structs/iobank0.h>
#include <hardware/adc.h>
#include <hardware/gpio.h>
#include <pico/platform.h>
#include <pico/stdlib.h>
#include "zap_adc.h"
#include "glitch_param.h"
// PCG impl lifted from Wikipedia
#define PCG_MULTIPLIER 6364136223846793005uLL
__attribute__((__force_inline__))
inline static uint32_t pcg32_next(uint64_t* st) {
uint64_t x = *st;
unsigned count = (unsigned)(x >> 61);
*st = x * PCG_MULTIPLIER;
x ^= x >> 22;
return (uint32_t)(x >> (22 + count));
}
uint32_t CORE1_FUNC(glitch_param_const_fn)(void* p) {
return ((struct glitch_param_const*)p)->value;
}
uint32_t CORE1_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_) {
struct glitch_param_sweep* p = (struct glitch_param_sweep*)p_;
uint32_t rv = p->min + p->step * p->cur_index;
if (rv > p->max) {
p->cur_index = 0;
rv = p->min;
} else {
++p->cur_index;
}
return rv;
}
uint32_t CORE1_FUNC(glitch_param_adc_fn)(void* p_) {
struct glitch_param_adc* p = (struct glitch_param_adc*)p_;
uint16_t av;
if (p->adc_index == 0 || p->adc_index == 1) {
av = zap_adc_read(p->adc_index);
} else {
adc_select_input(1);
av = adc_read();
}
uint64_t vvv = ((uint64_t)av * (uint64_t)p->max/*actually delta now*/) >> 12;
return p->min + (uint32_t)vvv;
}
void glitch_param_randrange_init(struct glitch_param_randrange* p) {
//p->rand_state = 0xcafef00dd15ea5e5uLL; // must be odd
// use stdlib randomness only for the seed, but use a custom rng sitting in
// SRAM 5 to avoid bus contention
p->rand_state = 2*random()+1;
pcg32_next(&p->rand_state);
p->max = p->max - p->min;
}
void glitch_param_adc_init(struct glitch_param_adc* p) {
if (p->adc_index == 0 || p->adc_index == 1) {
zap_adc_init();
} else {
// ADC1: ADC mode
adc_init();
adc_gpio_init(27);
adc_select_input(1);
// ADC0 = GPIO26 = fixed high (as vref)
sio_hw->gpio_set = 1u << 26;
sio_hw->gpio_oe_set = 1u << 26;
gpio_set_function(26, GPIO_FUNC_SIO);
}
p->max = p->max - p->min;
}

53
src/glitch/glitch_param.h Normal file
View File

@ -0,0 +1,53 @@
#ifndef GLITCH_PARAM_H_
#define GLITCH_PARAM_H_
#include <stdint.h>
#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 {
glitch_param_fn getter;
void* ud;
uint32_t cur;
};
struct glitch_param_const {
uint32_t value;
};
struct glitch_param_randrange {
uint32_t min;
uint32_t max;
uint64_t rand_state;
};
struct glitch_param_sweep {
uint32_t min;
uint32_t max;
uint32_t step;
uint32_t cur_index;
};
struct glitch_param_adc {
uint32_t min;
uint32_t max;
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);
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; }
// NOTE: call this AFTER initializing min and max!
void glitch_param_randrange_init(struct glitch_param_randrange* p);
// NOTE: call this AFTER initializing min, max and adc_index!
void glitch_param_adc_init(struct glitch_param_adc* p);
#endif

View File

@ -9,9 +9,9 @@
#include "zap_max4619.h"
void zap_max_init(bool inhibit, bool use_jp300) {
const io_rw_32 pinmask = 1u << ZAP_GLITCH_OUT;
const io_rw_32 pinmask = (1u << ZAP_GLITCH_OUT) | (1u << ZAP_MAX_INHIBIT) | (1u << ZAP_MAX_VHI_SW);
sio_hw->gpio_clr = pinmask; // default to low -> JP300
sio_hw->gpio_clr = pinmask; // default to low -> Vdac1
sio_hw->gpio_oe_set = pinmask;
gpio_set_slew_rate(ZAP_GLITCH_OUT, GPIO_SLEW_RATE_FAST);