glitching stuff

This commit is contained in:
Triss 2021-12-07 04:16:01 +01:00
parent 8b0b7eb0cf
commit cbdd6fb838
10 changed files with 664 additions and 140 deletions

View File

@ -46,6 +46,7 @@ if(FAMILY STREQUAL "rp2040")
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_cmds.c
${CMAKE_CURRENT_SOURCE_DIR}/src/test/piotest.c
${CMAKE_CURRENT_SOURCE_DIR}/src/test/delaytest.c
${CMAKE_CURRENT_SOURCE_DIR}/src/glitch/glitch.c
)
# Example include
@ -55,6 +56,7 @@ if(FAMILY STREQUAL "rp2040")
${CMAKE_CURRENT_SOURCE_DIR}/src/swim/
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/
${CMAKE_CURRENT_SOURCE_DIR}/src/test/
${CMAKE_CURRENT_SOURCE_DIR}/src/glitch/
)
# Example defines

259
src/glitch/glitch.c Normal file
View File

@ -0,0 +1,259 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <RP2040.h>
#include <system_RP2040.h>
#include <core_cm0plus.h>
#include <hardware/structs/iobank0.h>
#include <hardware/clocks.h>
#include <hardware/gpio.h>
#include <hardware/irq.h>
#include <hardware/vreg.h>
#include <pico/multicore.h>
#include <pico/platform.h>
#include <pico/stdlib.h>
#include "glitch.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
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 uint32_t CORE1_FUNC(pcg32_fast)(void) {
uint64_t x = mcg_state;
unsigned count = (unsigned)(x >> 61); // 61 = 64 - 3
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();
}
#define CORE1_PRE_CALC() /* BIG TODO HERE! */ \
uint32_t off = param_cur.offset_min_us + \
(pcg32_fast() % (param_cur.offset_max_us - param_cur.offset_min_us)), \
len = param_cur.length_min_us + \
(pcg32_fast() % (param_cur.length_max_us - param_cur.length_min_us)), \
iom = 1u << param_cur.glitch_out_pin \
#define CORE1_DO_GLITCH() \
do { \
busy_wait_us_32(off); \
sio_hw->gpio_set = iom; \
busy_wait_us_32(len); \
sio_hw->gpio_clr = iom; \
param_cur.offset_cur = off; \
param_cur.length_cur = len; \
} while (0) \
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.trigger_in_pin < 0) {
SCB->SCR &= ~SCB_SCR_SEVONPEND_Msk; // don't resume WFE on interrupt
while (true) {
CORE1_PRE_CALC();
__WFE();
bool arm = *(volatile bool*)&param_cur.armed;
if (!arm) continue;
CORE1_DO_GLITCH();
}
} else {
// init gpio irq
const int gpio = param_cur.trigger_in_pin;
const int irq = IO_IRQ_BANK0;
const int event = GPIO_IRQ_EDGE_RISE;
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);
while (true) {
CORE1_PRE_CALC();
__WFI();
iobank0_hw->intr[gpio>>3] = event << 4*(gpio&7); // acknowledge irq
bool arm = *(volatile bool*)&param_cur.armed;
if (!arm) continue;
irq_set_enabled(irq, false);
//CORE1_DO_GLITCH();
busy_wait_us_32(off);
if (!(sio_hw->gpio_in & (1u<<gpio))) goto cont;
sio_hw->gpio_set = iom;
busy_wait_us_32(len);
sio_hw->gpio_clr = iom;
param_cur.offset_cur = off;
param_cur.length_cur = len;
cont:
irq_set_enabled(irq, true);
}
}
// TODO: PIO variant?
}
#undef CORE1_DO_GLITCH
#undef CORE1_PRE_CALC
static void CORE0_FUNC(glitch_stop_no_clock_chg)(void) {
multicore_reset_core1();
if (param_cur.impl != glitch_impl__none) {
if (param_cur.impl == glitch_impl_pio) {
// TODO: deinit PIO when implemented
}
// deinit GPIO
if (param_cur.trigger_in_pin >= 0) {
hw_write_masked(&padsbank0_hw->io[param_cur.trigger_in_pin]
, (PADS_BANK0_GPIO0_IE_BITS)
| (PADS_BANK0_GPIO0_SCHMITT_BITS)
, (PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS)
| (PADS_BANK0_GPIO0_SCHMITT_BITS)
);
hw_write_masked(&iobank0_hw->io[param_cur.trigger_in_pin].ctrl
, ((uint)GPIO_FUNC_NULL << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
| ((uint)GPIO_OVERRIDE_NORMAL << IO_BANK0_GPIO0_CTRL_INOVER_LSB)
, (IO_BANK0_GPIO0_CTRL_FUNCSEL_BITS)
| (IO_BANK0_GPIO0_CTRL_INOVER_BITS)
);
}
sio_hw->gpio_clr = 1u << param_cur.glitch_out_pin;
sio_hw->gpio_oe_clr = 1u << param_cur.glitch_out_pin;
hw_write_masked(&padsbank0_hw->io[param_cur.glitch_out_pin]
, (PADS_BANK0_GPIO0_IE_BITS)
| ((uint)GPIO_SLEW_RATE_SLOW << PADS_BANK0_GPIO0_SLEWFAST_LSB)
, (PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS)
| (PADS_BANK0_GPIO0_SLEWFAST_BITS)
);
hw_write_masked(&iobank0_hw->io[param_cur.glitch_out_pin].ctrl
, ((uint)GPIO_FUNC_NULL << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
| ((uint)GPIO_OVERRIDE_NORMAL << IO_BANK0_GPIO0_CTRL_OUTOVER_LSB)
, (IO_BANK0_GPIO0_CTRL_FUNCSEL_BITS)
| (IO_BANK0_GPIO0_CTRL_OUTOVER_BITS)
);
}
memset(&param_cur, 0, sizeof param_cur);
}
bool CORE0_FUNC(glitch_ready)(const struct glitch_params* params) {
// check params values
if (params->offset_max_us < params->offset_min_us) return false;
if (params->length_max_us < params->length_min_us) 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;
if (params->glitch_out_pin < 0 || params->glitch_out_pin >= 28
|| (params->glitch_out_pin >= 23 && params->glitch_out_pin <= 25))
return false;
if (params->trigger_in_polarity != glitch_positive
&& 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)
return false;
glitch_stop();
memcpy(&param_cur, params, sizeof param_cur); // apply new params
param_cur.offset_cur = 0;
param_cur.length_cur = 0;
param_cur.armed = 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)
// overclock to 200 MHz
vreg_set_voltage(VREG_VOLTAGE_1_15);
set_sys_clock_khz(200*1000, true);
uint func = GPIO_FUNC_SIO; // TODO: PIO when implemented
if (params->trigger_in_pin >= 0) {
//gpio_set_input_hysteresis_enabled(params->trigger_in_pin, false);
//gpio_set_dir(params->trigger_in_pin, GPIO_IN );
//gpio_set_inover(params->trigger_in_pin,
// params->trigger_in_polarity ? GPIO_OVERRIDE_INVERT : GPIO_OVERRIDE_NORMAL);
//gpio_set_function(params->trigger_in_pin, func);
// perform all of these at once to minimize the amount of spurious edges
sio_hw->gpio_oe_clr = 1u << param_cur.trigger_in_pin;
hw_write_masked(&padsbank0_hw->io[param_cur.trigger_in_pin]
, (PADS_BANK0_GPIO0_IE_BITS)
, (PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS)
| (PADS_BANK0_GPIO0_SCHMITT_BITS)
);
hw_write_masked(&iobank0_hw->io[param_cur.trigger_in_pin].ctrl
, (func << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
| ((uint)(param_cur.trigger_in_polarity ? GPIO_OVERRIDE_INVERT
: GPIO_OVERRIDE_NORMAL) << IO_BANK0_GPIO0_CTRL_INOVER_LSB)
, (IO_BANK0_GPIO0_CTRL_FUNCSEL_BITS)
| (IO_BANK0_GPIO0_CTRL_INOVER_BITS)
);
}
//gpio_put(params->glitch_out_pin, false);
//gpio_set_slew_rate(params->glitch_out_pin, GPIO_SLEW_RATE_FAST);
//gpio_set_dir(params->glitch_out_pin, GPIO_OUT);
//gpio_set_outover(params->glitch_out_pin,
// params->glitch_out_polarity ? GPIO_OVERRIDE_INVERT : GPIO_OVERRIDE_NORMAL);
//gpio_set_function(params->glitch_out_pin, func);
// perform all of these at once to minimize the amount of spurious glitches
sio_hw->gpio_clr = 1u << param_cur.glitch_out_pin;
sio_hw->gpio_oe_set = 1u << param_cur.glitch_out_pin;
hw_write_masked(&padsbank0_hw->io[param_cur.glitch_out_pin]
, (PADS_BANK0_GPIO0_IE_BITS)
| ((uint)GPIO_SLEW_RATE_FAST << PADS_BANK0_GPIO0_SLEWFAST_LSB)
, (PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS)
| (PADS_BANK0_GPIO0_SLEWFAST_BITS)
);
hw_write_masked(&iobank0_hw->io[param_cur.glitch_out_pin].ctrl
, (func << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB)
| ((uint)(param_cur.glitch_out_polarity ? GPIO_OVERRIDE_INVERT
: GPIO_OVERRIDE_NORMAL) << IO_BANK0_GPIO0_CTRL_OUTOVER_LSB)
, (IO_BANK0_GPIO0_CTRL_FUNCSEL_BITS)
| (IO_BANK0_GPIO0_CTRL_OUTOVER_BITS)
);
multicore_launch_core1(glitch_core1_thread);
return true;
}
void CORE0_FUNC(glitch_stop)(void) {
glitch_stop_no_clock_chg();
set_sys_clock_khz(125*1000, true);
vreg_set_voltage(VREG_VOLTAGE_DEFAULT);
}

54
src/glitch/glitch.h Normal file
View File

@ -0,0 +1,54 @@
#ifndef GLITCH_H_
#define GLITCH_H_
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
enum glitch_polarity {
glitch_positive,
glitch_negative,
};
enum glitch_impl {
glitch_impl__none,
glitch_impl_core1,
glitch_impl_pio
};
struct glitch_params {
uint32_t offset_min_us;
uint32_t offset_max_us;
uint32_t length_min_us;
uint32_t length_max_us;
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;
bool armed;
};
extern struct glitch_params glitch_param_cur;
// return false: something wrong about the parameters
bool glitch_ready(const struct glitch_params* params);
void glitch_stop(void);
static inline void glitch_trigger_sw_core1(void) {
asm volatile("sev");
}
static inline void glitch_trigger_sw_pio(void) {
// TODO: implement
}
static inline void glitch_arm(void) {
glitch_param_cur.armed = true;
}
static inline void glitch_disarm(void) {
glitch_param_cur.armed = false;
}
#endif

View File

@ -11,6 +11,7 @@
#include "msp430dbg.h"
#include "tool78_hw.h"
#include "tool78_cmds.h"
#include "glitch.h"
void piotest(void);
void delaytest(void);
@ -30,41 +31,51 @@ static uint16_t DATA_vectors[0x10] = {
static uint16_t dumpmem_ram[256>>1];
static uint16_t dumpmem_flash[8192>>1];*/
/*static uint8_t DATA_test_rom[256] = { // RL78
0xce, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6e, 0x7f, 0xe8,
0x85, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xd9,
0x00, 0xfd, 0xdd, 0x00, 0xfd, 0xee, 0x00, 0xef, 0xfe, 0x71, 0x7b, 0xfa, 0xd7,
0x71, 0x38, 0x23, 0xff, 0x71, 0x38, 0x33, 0x00, 0x71, 0x68, 0x77, 0x00, 0x71,
0x38, 0x53, 0x00, 0xd7, 0x71, 0x30, 0x03, 0xff, 0x00, 0x00, 0x71, 0x38, 0x03,
0xff, 0xef, 0xf4, 0xd7, 0xd7, 0xff, 0xff, 0xff, 0xff
};*/
static uint8_t shellcode_test[] = {
/*0x71,0x38,0x23,0xff, // clr1 !0xfff23.3
//0x71,0x38,0x33,0x00, // clr1 !0xf0033.3
//0x71,0x68,0x77,0x00, // clr1 !0xf0077.6
//0x71,0x38,0x53,0x00, // clr1 !0xf0053.3
0x71,0x30,0x03,0xff, // set1 !0xfff03.3*/
/*static uint8_t shellcode_test[] = {
0x51, 0x61, // mov a, #97
0xfc, 0xa1, 0xff, 0x0e, // call !!effa1
0xd7, // ret
};*/
//static uint8_t DATA_test_dbg[7/*85*/] = {
// /*0xe0, 0x07, 0x52,*/ 0x51, 0x61, 0xfc, 0xa1, 0xff, 0x0e,
// 0xd7,
// /*0x71, 0x7b, 0xfa, 0xf5,
// 0xf0, 0x02, 0xf5, 0x78, 0x00, 0x71, 0x6a, 0xa4, 0xcf, 0x76, 0x00, 0x01, 0xce,
// 0x22, 0x00, 0xf5, 0x62, 0x00, 0xf5, 0x77, 0x00, 0xf5, 0x79, 0x00, 0xf5, 0x75,
// 0x00, 0xf5, 0x7c, 0x00, 0xce, 0x02, 0x00, 0xce, 0x02, 0xff, 0x30, 0x00, 0xf9,
// 0x16, 0x52, 0x00, 0x53, 0xff, 0x51, 0x00, 0x81, 0x93, 0xdf, 0xfc, 0x92, 0x61,
// 0xf9, 0xdf, 0xf3, 0xce, 0x02, 0x00, 0x52, 0x00, 0x92, 0x61, 0xe9, 0xfc, 0xa1,
// 0xff, 0x0e, 0xd2, 0xdf, 0xf6, 0xef, 0xd9*/
//};
static uint8_t exec_jmp_to_ram[] = {
0xfc, 0x00, 0xf9, 0x0f, // call !!ff900
0xd7, // ret
};
static uint8_t DATA_test_dbg[102] = {
0x71, 0x7b, 0xfa, 0xf5, 0xf0, 0x02, 0xf5, 0x78, 0x00, 0x71, 0x6a, 0xa4, 0xcf,
0x76, 0x00, 0x01, 0xce, 0x22, 0x00, 0xf5, 0x62, 0x00, 0xf5, 0x77, 0x00, 0xf5,
0x79, 0x00, 0xf5, 0x75, 0x00, 0xf5, 0x7c, 0x00, 0xce, 0x02, 0x00, 0xce, 0x02,
0xff, 0x30, 0x00, 0xfa, 0x16, 0x52, 0x00, 0x53, 0xff, 0x51, 0x00, 0x81, 0x93,
0xdf, 0xfc, 0x92, 0x61, 0xf9, 0xdf, 0xf3, 0xce, 0x02, 0x00, 0x52, 0x18, 0x53,
0xff, 0x93, 0xdf, 0xfd, 0x92, 0xdf, 0xf8, 0x51, 0x48, 0xfc, 0xa1, 0xff, 0x0e,
0x51, 0x69, 0xfc, 0xa1, 0xff, 0x0e, 0x50, 0xaa, 0x52, 0x00, 0x92, 0x61, 0xe9,
0x61, 0x78, 0xfc, 0xa1, 0xff, 0x0e, 0xd2, 0xdf, 0xf4, 0xef, 0xbf
};
/*static uint8_t DATA_test_dbg[85] = {
0x71, 0x7b, 0xfa, 0xf5, 0xf0, 0x02, 0xf5, 0x78, 0x00, 0x71, 0x6a, 0xa4, 0xcf,
0x76, 0x00, 0x01, 0xce, 0x22, 0x00, 0xf5, 0x62, 0x00, 0xf5, 0x77, 0x00, 0xf5,
0x79, 0x00, 0xf5, 0x75, 0x00, 0xf5, 0x7c, 0x00, 0xce, 0x02, 0x00, 0xce, 0x02,
0xff, 0x30, 0x00, 0xfa, 0x16, 0x52, 0x00, 0x53, 0xff, 0x51, 0x00, 0x81, 0x93,
0xdf, 0xfc, 0x92, 0x61, 0xf9, 0xdf, 0xf3, 0xce, 0x02, 0x00, 0x52, 0x18, 0x53,
0xff, 0x93, 0xdf, 0xfd, 0x92, 0xdf, 0xf8, 0x51, 0x48, 0xfc, 0xa1, 0xff, 0x0e,
0x51, 0x69, 0xfc, 0xa1, 0xff, 0x0e, 0xd7
};*/
static void test_sbw(void) {
gpio_init(PINOUT_SBW_TCK);
gpio_set_function(PINOUT_SBW_TCK, GPIO_FUNC_SIO);
@ -256,40 +267,224 @@ blank check: 0x06
static void tool78_ocdtest() {
uint8_t passwd[10] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint16_t ver=0;
enum tool78_stat st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd);
printf("result: 0x%02x ver=%04x\n", st, ver);
uint16_t ver;
enum tool78_stat st;
int rr;
static uint8_t checkbuf[256];
bool first = true;
// hw addr len data
restart:
/*glitch_disarm();
busy_wait_ms(40);*/
ver=0;
st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd);
//printf("result: 0x%02x ver=%04x\n", st, ver);
// can't write too much at 0xf07e0 as 0xf0800 and up contains OCD state,
// overwrite this and suddenly the OCD system resets itself
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0x07e0,
sizeof(shellcode_test), shellcode_test);
printf("write res 0x%02x\n", st);
uint8_t shbuf[sizeof(shellcode_test)];
memset(shbuf, 0, sizeof shbuf);
st = tool78_ocd_read(&tool78_hw_rl78_uart1, 0x07e0,
sizeof(shellcode_test), shbuf);
printf("read res 0x%02x\n", st);
for (size_t i = 0; i < sizeof shellcode_test; ++i)
printf("%02x ", shbuf[i]);
printf("%c", '\n');
sizeof(exec_jmp_to_ram), exec_jmp_to_ram);
//printf("write trampoline res 0x%02x\n", st);
if (st != 0) {
printf("trampoline write failed: %d\n", st);
goto deinit_bad;
}
st = tool78_ocd_write(&tool78_hw_rl78_uart1, 0xf900,
sizeof(DATA_test_dbg), DATA_test_dbg);
//printf("write code res 0x%02x\n", st);
if (st != 0) {
printf("code write failed: %d\n", st);
goto deinit_bad;
}
st = tool78_ocd_exec(&tool78_hw_rl78_uart1);
printf("exec res 0x%02x\n", st);
//printf("exec res 0x%02x\n", st);
if (st != 0) {
printf("exec failed: %d\n", st);
goto deinit_bad;
}
uint8_t stuff[16];
int rr = tool78_hw_rl78_uart1.recv(1, stuff, 1000);
// test custom tool_tx call
/*rr = tool78_hw_rl78_uart1.recv(1, checkbuf, 1000);
printf("rr=%d\n", rr);
if (rr == 1) printf("0x%02x %c\n", stuff[0], stuff[0]);
if (rr == 1) printf("0x%02x %c\n", stuff[0], stuff[0]);*/
st = tool78_ocd_version(&tool78_hw_rl78_uart1, &ver);
printf("ver res 0x%02x %04x\n", st, ver);
// wait for completion
rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 120*1000);
if (rr != 2) {
printf("exec code: no response :/ (%d)\n", rr);
goto deinit_bad;
}
if (checkbuf[0] != 'H' && checkbuf[1] != 'i') {
printf("bad response: %02x %02x\n", checkbuf[0], checkbuf[1]);
goto deinit_bad;
}
rr = tool78_hw_rl78_uart1.recv(256, checkbuf, 120*1000);
if (rr != 256) {
printf("exec code: no data sendback (%d)\n", rr);
goto deinit_bad;
}
for (size_t i = 0; i < 256; ++i) {
if (checkbuf[i] != (0xff^0xaa)) {
printf("bad value at index %zu: %02x\n", i, checkbuf[i]^0xaa);
goto deinit_bad;
}
}
if (first) printf("all set, let's go\n");
first = false;
while (true) {
glitch_arm();
rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 120*1000);
glitch_disarm();
if (rr == 2 && (checkbuf[0] != 'H' || checkbuf[1] != 'i')) rr = 0;
if (rr == 2) {
rr = tool78_hw_rl78_uart1.recv(256, checkbuf, 120*1000);
}
if (rr <= 0) {
// timeout or something
printf("X");
tool78_hw_rl78_uart1.deinit();
goto restart;
} else {
int firstbad = -1, lastbad = -1;
for (int i = 0; i < rr; ++i) {
if (checkbuf[i] != (0xaa^0xff)) {
if (firstbad == -1) firstbad = i;
lastbad = i;
}
}
if (firstbad >= 0) {
volatile uint32_t
*off = (volatile uint32_t*)&glitch_param_cur.offset_cur,
*len = (volatile uint32_t*)&glitch_param_cur.length_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(".");
}
}
deinit_bad:
tool78_hw_rl78_uart1.deinit();
return;
/*glitch_arm();
while (true) {
int rr;
rr = tool78_hw_rl78_uart1.recv(2, stuff, 120*1000);
if (rr > 0) {
if (stuff[0] != 'H' && stuff[1] != 'i') goto bad;
rr = tool78_hw_rl78_uart1.recv(256, stuff, 120*1000);
int firstbad = -1, lastbad = -1;
for (int iii = 0; iii < rr; ++iii) {
if (stuff[iii] != (0xaa^0xff)) {
if (firstbad == -1) firstbad = iii;
lastbad = iii;
}
}
if (rr > 0) {
glitch_disarm();
if (firstbad == -1) printf(".");
else {
volatile uint32_t
*off = (volatile uint32_t*)&glitch_param_cur.offset_cur,
*len = (volatile uint32_t*)&glitch_param_cur.length_cur;
printf("glitch first=%d last=%d off=%lu len=%lu rr=%d v=%02x\n",
firstbad, lastbad, *off, *len, rr, stuff[firstbad]);
}
glitch_arm();
} else {
glitch_disarm();
printf("%s", "[huh?]");
goto timeout;
}
} else {
bad:
glitch_disarm();
timeout:
printf(":");
tool78_hw_rl78_uart1.deinit();
goto restart;
}
}*/
}
int main() {
static const struct glitch_params gparam = (struct glitch_params){
.offset_min_us = 0,
.offset_max_us = 35433,
.length_min_us = 1,
.length_max_us = 20,
.trigger_in_pin = 14,
.glitch_out_pin = 15,
.trigger_in_polarity = glitch_positive,
.glitch_out_polarity = glitch_positive,
.impl = glitch_impl_core1,
.offset_cur = 0, .length_cur = 0
};
glitch_ready(&gparam);
stdio_init_all();
/*while (!stdio_usb_connected()) ;
printf("hi\n");*/
//tool78_testtest();
//tool78_prototest();
//tool78_ocdtest();
tool78_ocdtest();
//piotest();
delaytest();
//delaytest();
return 0;
}
/*
* glitch first=10 last=10 off=22783 len=1
* glitch first=12 last=12 off=9424 len=1 rr=256 v=cd
* glitch first=19 last=19 off=2669 len=1
* glitch first=22 last=22 off=6951 len=1
* glitch first=28 last=28 off=22042 len=1
* glitch first=46 last=46 off=27750 len=1
* glitch first=85 last=85 off=11875 len=1
* glitch first=87 last=87 off=12156 len=1
* glitch first=89 last=89 off=12425 len=1
* glitch first=89 last=89 off=12455 len=1
* glitch first=102 last=102 off=14235 len=1
* glitch first=116 last=116 off=18322 len=1
* glitch first=127 last=127 off=17741 len=1
* glitch first=137 last=137 off=19063 len=1
* glitch first=141 last=141 off=15229 len=1
* glitch first=142 last=142 off=19730 len=1
* glitch first=151 last=151 off=13497 len=1
* glitch first=152 last=152 off=21188 len=1
* glitch first=164 last=164 off=22897 len=1
* glitch first=169 last=169 off=12642 len=1
* glitch first=174 last=174 off=9874 len=1
* glitch first=176 last=176 off=24439 len=1
* glitch first=179 last=179 off=24973 len=1
* glitch first=179 last=179 off=24874 len=1 rr=256 v=86
* glitch first=185 last=185 off=25816 len=1
* glitch first=187 last=187 off=26077 len=1 rr=256 v=78
* glitch first=192 last=192 off=26777 len=1
* glitch first=193 last=193 off=26804 len=1
* glitch first=197 last=197 off=7173 len=1
* glitch first=211 last=211 off=29314 len=1
* glitch first=213 last=213 off=9849 len=1 rr=256 v=dc
* glitch first=217 last=217 off=27374 len=1 rr=256 v=00
* glitch first=226 last=226 off=5818 len=1
* glitch first=227 last=227 off=31555 len=1
* glitch first=231 last=231 off=1403 len=1
* glitch first=233 last=233 off=813 len=1
* glitch first=233 last=233 off=32463 len=1
* glitch first=234 last=234 off=13276 len=1
* glitch first=238 last=238 off=33053 len=1 rr=256 v=ba
* glitch first=239 last=239 off=15442 len=1 rr=256 v=1e
* glitch first=250 last=250 off=21711 len=1
* glitch first=254 last=254 off=35394 len=1 rr=256 v=40
*
*
*/

View File

@ -335,13 +335,16 @@ static test_fn tests[] = {
// 360 340 360 300 300 380 380 280 300 340
//(240 300 340 360 360 300 400 300 260 380
// 360 320 260 260 340 380 260 360 340 340)
// => 2 cycle delay (movs str)
[test_gpio_busyloop] = t_gpio_busyloop,
// 1520 1520 1520 1500 1500 1500 1520 1520 1500 1500
// 1500 1480 1500 1500 1520 1500 1500 1500 1500 1520
// 1500 1480 1500 1500 15You can bookmark topics for future reference. Select the checkbox for any bookmark you wish to delete, then press the Remove marked bookmarks button.20 1500 1500 1500 1500 1520
// => irq adds extra 10 cycles (push r4-r6,lr movs movs lsls lsls movs : 5+5 cyc)
[test_gpio_irq_handle] = t_gpio_irq_handle,
// 360 380 380 380 380 380 380 380 380 360
//(380 360 380 400 380 380 380 380 380 380
// 420 400 400 400 360 380 400 380 400 380)
// => 3 cycle delay (movs movs str)
[test_gpio_irq_wfi] = t_gpio_irq_wfi,
// these depend on the PIO SM wake insn resuming and then setting the irq
@ -351,14 +354,17 @@ static test_fn tests[] = {
// 620 520 540 540 540 540 600 560 500 480
// 520 600 600 520 620 480 600 640 600 620
// 620 660 580 680 660 620 560 480 580 540
// => 6 cycle delay (movs movs mov lsls lsls str)
[test_pio_if_busyloop] = t_pio_if_busyloop,
// 1380 1460 1480 1480 1460 1360 1400 1460 1480 1480
// 1400 1460 1440 1360 1460 1460 1460 1440 1380 1500
// => irq adds extra 10 cycles (push r4-r6,lr movs movs lsls lsls movs : 5+5 cyc)
[test_pio_if_irq_handle] = t_pio_if_irq_handle,
// 560 540 560 560 520 580 540 540 540 560
// 560 0 540 540 560 540 560 560 560 560 580
//(540 560 220 560 540 560 560 540 540 540
// 560 560 540 520 540 560 540 540 560 520)
// => 3 cycle delay (movs movs str)
[test_pio_if_irq_wfi] = t_pio_if_irq_wfi,
//(500 500 520 520 500 520 520 500 520 520
@ -415,7 +421,7 @@ static test_fn tests[] = {
// 1540 1520 1520 1520 1520 1500 1540 1500 1500 1520)
// gpio hi then fifo write: (str | movs str) 1200
// fifo write then gpio hi: (str | str) 1040
// => 28 cycles irq->GPIO (push r4-r6,lr movs movs lsls lsls movs : 5+n cyc)
// => 28 cycles irq->GPIO (push r4-r6,lr movs movs lsls lsls movs : 5+5 cyc)
// ==> 18 cycles delay? (=> push timings?)
[test_core0_fifo_irq_handle] = t_core0_fifo_irq_handle,
//(780 760 800 800 780 800 780 780 780 800
@ -454,7 +460,7 @@ void delaytest(void) {
SCB->SCR &= ~SCB_SCR_SEVONPEND_Msk;
const enum test t = test_core0_fifo_busyloop;
const enum test t = test_pio_if_irq_handle;
if (t <= test_core0_mem || t >= test_core0_wfe)
__disable_irq();
@ -489,7 +495,6 @@ void delaytest(void) {
busy_wait_us_32(100);
irq_set_enabled(irq, true);*/
}
} else while (true) ;
}

View File

@ -808,14 +808,18 @@ int tool78_ocd_read(struct tool78_hw* hw, uint16_t off, uint8_t len,
uint8_t hdr[4];
hdr[0] = tool78ocd_cmd_read;
hdr[1] = off & 0xff;
hdr[2] = off >> 8;
hdr[1] = off & 0xff;
hdr[3] = len;
printf("rd len=%u\n", len);
int rr = hw->send(sizeof hdr, hdr, -1);
rr = hw->recv(1, &hdr[2], 1000);
// last byte of header sent echoed back
if (rr != 1 || hdr[2] != hdr[3]) return -2;
if (rr != 1 || hdr[2] != hdr[3]) {
printf("rd recv=%02x\n", hdr[2]);
return -2;
}
rr = hw->recv(len, data, 1000*len);
//printf("ocd read %d\n", rr);
@ -851,7 +855,7 @@ int tool78_ocd_exec(struct tool78_hw* hw) {
rr = hw->recv(2, hdr, 1000);
if (rr != 1 && rr != 2) return -1;
printf("h[0]=0x%02x, h[1]=0x%02x\n", hdr[0], hdr[1]);
//printf("h[0]=0x%02x, h[1]=0x%02x\n", hdr[0], hdr[1]);
return (hdr[0] == tool78ocd_cmd_exec) ? 0 : -2;
}
@ -878,7 +882,7 @@ static enum tool78_stat tool78_init_common(struct tool78_hw* hw) {
enum tool78_stat st = tool78_stat_ack;
for (size_t i = 0; i < 16; ++i) {
if (!hw->init()) return tool78_stat_fatal_hw_error;
printf("init %zu ok\n", i);
//printf("init %zu ok\n", i);
if ((hw->target & tool78_mcu_mask) != tool78_mcu_rl78) {
st = tool78_do_reset(hw);
@ -891,7 +895,7 @@ static enum tool78_stat tool78_init_common(struct tool78_hw* hw) {
break;
}
if (st != tool78_stat_ack) return st;
printf("hw inited\n");
//printf("hw inited\n");
st = tool78_do_generic_baudrate(hw);
//printf("baudrate result=0x%02x\n", st);

View File

@ -22,7 +22,7 @@ def main():
parser = argparse.ArgumentParser(
description="Convert data files into byte arrays in a C header")
parser.add_argument('--width', type=int, default=16, help="data width")
parser.add_argument('--width', type=int, default=8, help="data width")
parser.add_argument('input', nargs='*', action='append',
help="Input data file to convert to a header file. If "
+"none are specified, data is read from standard input.")

View File

@ -1,3 +1,4 @@
/* vim: set ft=gas: */
#define P0 0xfff00
#define P2 0xfff02
@ -14,6 +15,10 @@
#define RXD1 0xfff46
#define SDR03 0xfff46
#define CMC 0xfffa0
#define CSC 0xfffa1
#define CKC 0xfffa4
; PMC: processor mode control
#define PU0 0xf0030
@ -36,6 +41,7 @@
#define PIOR2 0xf0075
#define PIOR3 0xf007c
#define ADPC 0xf0076
#define IAWCTL 0xf0078
#define PMS 0xf007b
@ -67,6 +73,10 @@
#define SOL0 0xf0134
#define SSC0 0xf0138
#define CRC0CTL 0xf02f0
#define INTFE 0xf0448
#define tool_tx 0xeffa1

View File

@ -4,18 +4,17 @@ ENTRY(_start)
MEMORY
{
ram (rwx) : ORIGIN = 0xf07e0, LENGTH = 0x100/*idk*/
ram (rwx) : ORIGIN = 0xff900, LENGTH = 0x5e0/*idk*/
}
SECTIONS {
.hdr :
/*.hdr :
{
BYTE(0xe0); BYTE(0x07); /* address */
BYTE(0xe0); BYTE(0x07); / * address * /
BYTE(SIZEOF(.text));
} > ram
} > ram*/
.text :
{
/*ABSOLUTE(.) = 0xf07e3;*/
*(.text* .rodata* .data*)
} > ram
.bss :

View File

@ -2,97 +2,93 @@
/*#include "romhdr.S"*/
#include "hw.S"
/*
ch2&3: TxD1,RxD1
*/
/* allegedly there's a subroutine at 0xEFFA1 that sends a single byte over the TOOL0 line */
.global _start
_start:
mov a, #'a'
call !!0xeffa1
ret
;mov a, #'a'
;call !!0xeffa1
;ret
; call !hw_init
;1: call !glitch_mainloop
; br $1b
call !hw_init
call !port_init
call !port_toggle
1: br $1b
;1: br $1b
hw_init:
di
; systeminit
; PIOR = 0
; ADPC = 1
; PMC bit = 0
clrb !CRC0CTL
clrb !IAWCTL
;CRC0CTL = 0 ; f02f0
;IAWCTL = 0 ; f0078
; PM1 = 6(?)
; CMC = 0
; MSTOP,XTSTOP bits = 1,1
; MCM0 bit = 0 ; hi-speed OCO clock as main clock
; CSS bit = 0 ; main system clock = periph clock
; CSC=fffa1
; CKC=fffa4
;CMC = 0 ; 0xfffa0
;MSTOP = 1 ; CSC.7
;MCM0 = 0 ; CKC.4
;XTSTOP = 0 ; CSC.6
;OSMC = 0 ; f00f3
;CSS = 0 ; CKC.6 ;!
set1 CKC.6
;HIOSTOP = 0 ; CSC.0
; PER0 SAU1EN bit (3) = 1
; SPS0 = 0x44 ; or *12? ; CK00,CK01 @ 2MHz
mov !ADPC, #1
;ADPC = 1 ; f0076
mov PM2, #0
; ST0 = 0xf ; stop all channels
; STMK0,STIF0 bits = 1,0 ; disable interrupts
; SRMK0,SRIF0 bits = 1,0 ; disable interrupts
; SREK0,SREF0 bits = 1,0 ; disable interrupts
; SMR00 = 0x22 ; ch0clock = CK00, start trig=sw falling edge, UART mode, xferend irq en
; SCR00 = 0x8297 ; tx only, clock type 1, error irq en, even parity, lsbfirst, 8bit data, 1bit stop
; SDR00 = 0xce00 ; opclk/208
; NFEN0 = 0x0001 ; RxD noise filter enable
; SIR01 = 0x0007 ; clear error
; SMR01 = 0x0122 ; ch1clock = CK00; start trig=RxD falling edge, UART mode, xferend irq en
; SCR01 = 0x4697 ; rx only, clock type 1, error irq en, even parity, lsbfirst, 8bit data, 1bit stop
; SDR01 = 0xce00 ; opclk/208 ; use opclk/17 (0x0f00) instead for 115.2kbaud?
; SO00,SOE00 bits = 1,1 ; prepare using ch0
; PM1 PM11 bit = 1 ; RxD pin as input
; P1,PM1 P12,PM12 bits = 1,0 ; TxD as output
clrb !PMC2
clrb !PIOR0
clrb !PIOR1
clrb !PIOR2
clrb !PIOR3
; SO00 bit = 1 ; TxD output level
; SOE00 bit = 1 ; enable UART
; SS00,SS01 bits = 1,1 ; enable UART
mov P2, #0
; ret
; TXD0 = data ; xmit
glitch_mainloop:
mov P2, #0xff
;ei ; nah
ret
movw ax, #0xfa00
movw hl, ax
port_init:
; P33 as output using GPIO
; PM3 bit 3 = 0
; PU3 bit 3 = 0 (no pullup)
; PMC3 bit 3 = 0 (digital IO)
; PIOR0 bit 6 = 0
; POM3 bit 3 = 0
; toggle P3 bit 3
clr1 !PM3.3
clr1 !PU3.3
clr1 !PIOR0.6
clr1 !POM3.3
ret
mov c, #0
2: mov b, #0xff
mov a, #0
1: inc a
dec b
bnz $1b
dec c
mov [hl+c], a
bnz $2b
port_toggle:
set1 !P3.3
nop
nop
clr1 !P3.3
br $port_toggle
mov P2, #0
uart_init:
;; PMC00=0 PM00=1 ; RxD1 en
; PIO2.3 = 1
; PMC20=0 PM20=0 P20=1 ; TxD1 en
ret
; wait a bit
mov c, #0x18
4: mov b, #0xff
5: dec b
bnz $5b
dec c
bnz $4b
uart_send_byte:
; todo
; TODO: wait for sent?
ret
mov a, #'H'
call !!tool_tx
mov a, #'i'
call !!tool_tx
mov x, #0xaa
mov c, #0
3: dec c
mov a, [hl+c]
xor a, x
call !!tool_tx
cmp0 c
bnz $3b
br $glitch_mainloop
;ret
;data: