glitching stuff
This commit is contained in:
parent
8b0b7eb0cf
commit
cbdd6fb838
|
@ -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
|
||||
|
|
|
@ -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*)¶m_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*)¶m_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(¶m_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(¶m_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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
297
src/main.c
297
src/main.c
|
@ -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
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -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) ;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 :
|
||||
|
|
144
test/rl78/test.S
144
test/rl78/test.S
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue