78k0 and SWIM stuff that doesn't work
This commit is contained in:
parent
37a41e5f83
commit
989785e06b
|
@ -35,6 +35,7 @@ if(FAMILY STREQUAL "rp2040")
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/msp430/tap.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/msp430/msp430dbg.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/swim/swim_hw.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/swim/swim_cmd.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_helpers.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_test_uart2.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_78k0_spi.c
|
||||
|
@ -51,6 +52,8 @@ if(FAMILY STREQUAL "rp2040")
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/glitch/glitch.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/cli.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/msp430.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/swim.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/78k0.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/rl78.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/rl78-glitch.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/dragonzap.c
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
#define BREADBOARD_SBW_TDIO 9
|
||||
|
||||
#define BREADBOARD_SWIM_PIO pio0
|
||||
#define BREADBOARD_SWIM_PIN 22
|
||||
#define BREADBOARD_SWIM_PIN /*22*/16
|
||||
#define BREADBOARD_SWIM_nRESET 21
|
||||
|
||||
#define BREADBOARD_TOOL78_PIO pio1
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "breadboard.h"
|
||||
#include "zap.h"
|
||||
|
||||
#define PINOUT_USE_DRAGONZAP 1
|
||||
#define PINOUT_USE_DRAGONZAP 0
|
||||
|
||||
#if PINOUT_USE_DRAGONZAP
|
||||
|
||||
|
@ -18,7 +18,8 @@
|
|||
#define PINOUT_SBW_TDIO (ZAP_GPIO_BASE+1)
|
||||
|
||||
#define PINOUT_SWIM_PIO BREADBOARD_SWIM_PIO
|
||||
#define PINOUT_SWIM ZAP_GPIO_BASE
|
||||
#define PINOUT_SWIM (ZAP_GPIO_BASE+1)
|
||||
#define PINOUT_SWIM_nRESET (ZAP_GPIO_BASE+0)
|
||||
|
||||
#define PINOUT_TOOL78_PIO BREADBOARD_TOOL78_PIO
|
||||
|
||||
|
@ -50,6 +51,7 @@ inline static void bsp_init_stuff(void) {
|
|||
#define PINOUT_SBW_TDIO BREADBOARD_SBW_TDIO
|
||||
|
||||
#define PINOUT_SWIM_PIO BREADBOARD_SWIM_PIO
|
||||
#define PINOUT_SWIM_nRESET BREADBOARD_SWIM_nRESET
|
||||
#define PINOUT_SWIM BREADBOARD_SWIM_PIN
|
||||
|
||||
#define PINOUT_TOOL78_PIO BREADBOARD_TOOL78_PIO
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pico/time.h>
|
||||
|
||||
#include "tool78_hw.h"
|
||||
#include "tool78_cmds.h"
|
||||
|
||||
/*#include "wfum-flash.h"*/
|
||||
|
||||
void cli_tool78_proto78k0(void);
|
||||
|
||||
void cli_tool78_proto78k0(void) {
|
||||
struct tool78_hw* hw = &tool78_hw_78k0_uart2;
|
||||
|
||||
tool78_silicon_sig_t sig;
|
||||
memset(&sig, 0, sizeof sig);
|
||||
enum tool78_stat st = tool78_init_sfp(hw, &sig);
|
||||
printf("result: 0x%02x. sig:\n", st);
|
||||
for (size_t i = 0; i < sizeof(struct tool78_silicon_sig_78k0); ++i)
|
||||
printf("0x%02x ", ((const uint8_t*)&sig)[i]);
|
||||
printf("%c", '\n');
|
||||
|
||||
hw->deinit();
|
||||
}
|
||||
|
|
@ -38,6 +38,11 @@ void cli_tool78_glitch_ocd_dump(void);
|
|||
void cli_tool78_glitch_param_g10(void);
|
||||
void cli_tool78_glitch_ocd_g10(void);
|
||||
|
||||
void cli_tool78_proto78k0(void);
|
||||
|
||||
void cli_swim_phytest(void);
|
||||
void cli_swim_prototest(void);
|
||||
|
||||
static void adc_init_stuff() {
|
||||
adc_init();
|
||||
adc_gpio_init(27);
|
||||
|
@ -87,6 +92,11 @@ static struct cli_cmd cmds[] = {
|
|||
|
||||
{ "zap", cli_dragonzap_test },
|
||||
|
||||
{ "k0sfp", cli_tool78_proto78k0 },
|
||||
|
||||
{ "swimphy", cli_swim_phytest },
|
||||
{ "swim", cli_swim_prototest },
|
||||
|
||||
{ NULL, NULL } // final
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -53,17 +52,16 @@ static bool glitch_init_core1_stuff(bool exttrig, uint glitchpin) {
|
|||
offset.min = 10*1000;
|
||||
offset.max = 35433*1000;
|
||||
length.min = 100;
|
||||
length.max = 10*50/*26*/*1000;
|
||||
length.max = /*10*50*/26*1000;
|
||||
//length.value = 5*1000; // 5 us
|
||||
#if PINOUT_USE_DRAGONZAP
|
||||
//length.adc_index = 0;//999;
|
||||
#else
|
||||
#error "a"
|
||||
//length.adc_index = 999;
|
||||
#endif
|
||||
|
||||
glitch_param_randrange_init(&offset);
|
||||
glitch_param_const_init(&length);
|
||||
//glitch_param_const_init(&length);
|
||||
glitch_param_randrange_init(&length);
|
||||
//glitch_param_adc_init(&length);
|
||||
|
||||
|
@ -237,7 +235,9 @@ deinit_bad:
|
|||
}
|
||||
|
||||
void cli_tool78_glitch_paramsearch(void) {
|
||||
if (!glitch_init_core1_stuff(true, GLITCH_OUT_PIN)) {
|
||||
zap_picoemp_init();
|
||||
|
||||
if (!glitch_init_core1_stuff(true, ZAP_GLITCH_OUT/*GLITCH_OUT_PIN*/)) {
|
||||
printf("bad glitcher params!\n");
|
||||
return;
|
||||
}
|
||||
|
@ -250,8 +250,12 @@ void cli_tool78_glitch_paramsearch(void) {
|
|||
bool first = true;
|
||||
|
||||
restart:
|
||||
/*glitch_disarm();
|
||||
busy_wait_ms(40);*/
|
||||
zap_picoemp_set_armed(false);
|
||||
glitch_disarm();
|
||||
/*busy_wait_ms(40);*/
|
||||
|
||||
zap_picoemp_set_armed(true);
|
||||
while (!zap_picoemp_has_hv()) ;
|
||||
|
||||
ver=0;
|
||||
st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd);
|
||||
|
@ -332,12 +336,16 @@ restart:
|
|||
glitch_arm();
|
||||
rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 120*1000);
|
||||
glitch_disarm();
|
||||
|
||||
bool first_ = true;
|
||||
do {
|
||||
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) {
|
||||
if (!first_) break;
|
||||
// timeout or something
|
||||
printf("X");
|
||||
tool78_hw_rl78_uart1.deinit();
|
||||
|
@ -358,29 +366,23 @@ restart:
|
|||
firstbad, lastbad, *off, *len, rr, checkbuf[firstbad]^0xaa);
|
||||
} 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);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
first_=false;
|
||||
if (!zap_picoemp_has_hv()) {
|
||||
rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 150*1000);
|
||||
} else break;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
deinit_bad:
|
||||
zap_picoemp_set_armed(false);
|
||||
tool78_hw_rl78_uart1.deinit();
|
||||
return;
|
||||
|
||||
do_reset_stuff:
|
||||
zap_picoemp_set_armed(false);
|
||||
tool78_hw_rl78_uart1.deinit();
|
||||
|
||||
// glitch for way too long to power cycle
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pico/time.h>
|
||||
|
||||
#include "swim_hw.h"
|
||||
#include "swim_cmd.h"
|
||||
|
||||
void cli_swim_phytest(void);
|
||||
void cli_swim_prototest(void);
|
||||
|
||||
void cli_swim_phytest(void) {
|
||||
swim_preinit();
|
||||
swim_init();
|
||||
swim_deinit();
|
||||
}
|
||||
void cli_swim_prototest(void) {
|
||||
swim_preinit();
|
||||
swim_init();
|
||||
|
||||
if (!swim_cmd_srst()) {
|
||||
printf("srst error!\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
uint8_t option[0x10], id[0x10];
|
||||
|
||||
if (!swim_cmd_rotf(0x4800, 0x0a, option)) {
|
||||
printf("rotf option error!\n");
|
||||
goto end;
|
||||
}
|
||||
printf("option: %02hhx %02hhx %02hhx ...\n",
|
||||
option[0], option[1], option[2]);
|
||||
|
||||
if (!swim_cmd_rotf(0x4876, 0x10-5, id)) {
|
||||
printf("rotf id error!\n");
|
||||
goto end;
|
||||
}
|
||||
printf("id: %02hhx %02hhx %02hhx ...\n",
|
||||
id[0], id[1], id[2]);
|
||||
|
||||
end:
|
||||
swim_deinit();
|
||||
}
|
||||
|
|
@ -3,36 +3,47 @@
|
|||
|
||||
; Pin assignments:
|
||||
; - SWIM is out/set/side pin 0
|
||||
; NOTE: pin needs pullup, either input(+pullup) or output+drivezero => use set pindirs AND sideset is direction!
|
||||
; NOTE: pin needs pullup, either input(+pullup) or output+drivezero
|
||||
; => use set pindirs AND sideset is direction!
|
||||
;
|
||||
; Autopush and autopull must be enabled, set to 8
|
||||
; Autopull should be enabled, and set to 0
|
||||
|
||||
start:
|
||||
pull side 0
|
||||
out x, 32 side 0
|
||||
nop side 0 [15]
|
||||
nop side 1 [15]
|
||||
nop side 0 [15]
|
||||
nop side 1 [15]
|
||||
.wrap_target
|
||||
nop side 0 [10]
|
||||
.wrap
|
||||
|
||||
; TODO: can we somehow sleep for a variable amount of cycles in an easier
|
||||
; way?
|
||||
iter:
|
||||
out y, 1 side 0 ; get next bit
|
||||
jmp !y, bit_0 side 0
|
||||
|
||||
bit_1:
|
||||
nop side 1 [2]
|
||||
; pull side 0
|
||||
; out x, 32 side 0
|
||||
;
|
||||
; ; TODO: can we somehow sleep for a variable amount of cycles in an easier
|
||||
; ; way?
|
||||
;iter:
|
||||
; out y, 1 side 0 ; get next bit
|
||||
; jmp !y, bit_0 side 0
|
||||
;
|
||||
;bit_1:
|
||||
; nop side 1 [2]
|
||||
PUBLIC bit_1_delay_long:
|
||||
nop side 0 [10] ; or 4
|
||||
nop side 0 [10] ; or 4
|
||||
|
||||
jmp iter_next side 0
|
||||
|
||||
bit_0:
|
||||
; nop side 0 [10] ; or 4
|
||||
; nop side 0 [10] ; or 4
|
||||
;
|
||||
; jmp iter_next side 0
|
||||
;
|
||||
;bit_0:
|
||||
PUBLIC bit_0_delay_long:
|
||||
nop side 1 [10] ; or 4
|
||||
nop side 1 [10] ; or 4
|
||||
nop side 0 [2]
|
||||
; nop side 1 [10] ; or 4
|
||||
; nop side 1 [10] ; or 4
|
||||
; nop side 0 [2]
|
||||
;
|
||||
;iter_next:
|
||||
; jmp x--, iter side 0
|
||||
|
||||
iter_next:
|
||||
jmp x--, iter side 0
|
||||
; 12 instructions
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
@ -42,8 +53,7 @@ iter_next:
|
|||
; - SWIM is in pin 0
|
||||
; NOTE: pin needs pullup, either input(+pullup) or output+drivezero
|
||||
;
|
||||
; Autopush and autopull must be enabled, set to 8
|
||||
|
||||
; Autopush should be enabled, and set to 32
|
||||
|
||||
start:
|
||||
pull
|
||||
|
@ -65,6 +75,8 @@ PUBLIC wait_delay:
|
|||
|
||||
push
|
||||
|
||||
; 7 instructions
|
||||
|
||||
|
||||
;;;; 19 instructions total
|
||||
|
||||
|
@ -80,7 +92,7 @@ static inline void swim_tx_pio_init(PIO pio, uint sm, uint prog_offs,
|
|||
sm_config_set_out_pins(&c, pin_swim, 1);
|
||||
sm_config_set_set_pins(&c, pin_swim, 1);
|
||||
sm_config_set_sideset_pins(&c, pin_swim);
|
||||
sm_config_set_out_shift(&c, false, true, 8);
|
||||
sm_config_set_out_shift(&c, false, true, 0);
|
||||
sm_config_set_clkdiv(&c, (float)clock_get_hz(clk_sys) / swim_clock_freq);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
|
||||
pio_sm_init(pio, sm, prog_offs, &c);
|
||||
|
@ -130,7 +142,7 @@ static inline void swim_rx_pio_init(PIO pio, uint sm, uint prog_offs,
|
|||
pio_sm_config c = swim_rx_program_get_default_config(prog_offs);
|
||||
sm_config_set_in_pins(&c, pin_swim);
|
||||
sm_config_set_clkdiv(&c, (float)clock_get_hz(clk_sys) / swim_clock_freq);
|
||||
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX);
|
||||
sm_config_set_in_shift(&c, false, true, 32);
|
||||
pio_sm_init(pio, sm, prog_offs, &c);
|
||||
|
||||
// SWIM pin is pure input
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
#include "swim_hw.h"
|
||||
|
||||
#include "swim_cmd.h"
|
||||
|
||||
bool swim_cmd_srst(void) {
|
||||
return swim_tx_command(SWIM_CMD_SRST, 0, NULL);
|
||||
}
|
||||
|
||||
bool swim_cmd_rotf(uint32_t addr, uint8_t len, uint8_t* data) {
|
||||
if (!len) return false;
|
||||
|
||||
uint8_t hdr[4];
|
||||
hdr[0] = len;
|
||||
hdr[1] = (addr >> 16) & 0xff;
|
||||
hdr[2] = (addr >> 8) & 0xff;
|
||||
hdr[3] = (addr >> 0) & 0xff;
|
||||
|
||||
bool r = swim_tx_command(SWIM_CMD_ROTF, 4, hdr);
|
||||
if (!r) return false;
|
||||
|
||||
return swim_rx_data(len, data);
|
||||
}
|
||||
|
||||
bool swim_cmd_wotf(uint32_t addr, uint8_t len, const uint8_t* data) {
|
||||
if (!len) return false;
|
||||
|
||||
uint8_t hdr[4];
|
||||
hdr[0] = len;
|
||||
hdr[1] = (addr >> 16) & 0xff;
|
||||
hdr[2] = (addr >> 8) & 0xff;
|
||||
hdr[3] = (addr >> 0) & 0xff;
|
||||
|
||||
bool r = swim_tx_command(SWIM_CMD_WOTF, 4, hdr);
|
||||
if (!r) return false;
|
||||
|
||||
return swim_tx_data(len, data);
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#ifndef SWIM_CMD_H_
|
||||
#define SWIM_CMD_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum swim_cmd {
|
||||
SWIM_CMD_SRST = 0,
|
||||
SWIM_CMD_ROTF = 1,
|
||||
SWIM_CMD_WOTF = 2
|
||||
};
|
||||
|
||||
bool swim_cmd_srst(void);
|
||||
|
||||
bool swim_cmd_rotf(uint32_t addr, uint8_t len, uint8_t* data);
|
||||
bool swim_cmd_wotf(uint32_t addr, uint8_t len, const uint8_t* data);
|
||||
|
||||
#endif
|
||||
|
|
@ -7,31 +7,182 @@
|
|||
#include "pinout.h"
|
||||
|
||||
#include "swim_hw.h"
|
||||
#include "swim_cmd.h"
|
||||
|
||||
#include "swim.pio.h"
|
||||
|
||||
int swim_tx_sm = -1, swim_rx_sm = -1, swim_tx_off = -1, swim_rx_off = -1;
|
||||
|
||||
#define SWIM_DEFAULT_FREQ (8*1000*1000)
|
||||
|
||||
static void initseq_1(void) {
|
||||
// phase 1: set SWIM low for 16 us
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_OUT);
|
||||
busy_wait_us_32(16);
|
||||
|
||||
gpio_set_drive_strength(PINOUT_SWIM, GPIO_DRIVE_STRENGTH_12MA);
|
||||
gpio_set_slew_rate(PINOUT_SWIM, GPIO_SLEW_RATE_FAST);
|
||||
|
||||
gpio_init(20);
|
||||
gpio_set_dir(20, GPIO_OUT);
|
||||
gpio_put(20, true);
|
||||
gpio_set_function(20, GPIO_FUNC_SIO);
|
||||
|
||||
// phase 2: entry sequence
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_IN);
|
||||
busy_wait_us_32(500);
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_OUT);
|
||||
busy_wait_us_32(500);
|
||||
}
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_IN);
|
||||
busy_wait_us_32(250);
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_OUT);
|
||||
busy_wait_us_32(250);
|
||||
}
|
||||
|
||||
sio_hw->gpio_togl = 1u<<20;
|
||||
|
||||
/*for (size_t i = 0; i < 8; ++i) {
|
||||
const int delay = 2;
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_IN);
|
||||
busy_wait_us_32(delay);
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_OUT);
|
||||
busy_wait_us_32(delay);
|
||||
}*/
|
||||
|
||||
// phase 3: line rises again: SWIM activation, hi-speed osc on MCU starts
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_IN);
|
||||
|
||||
// phase 4: SWIM sync: MCU sends 'synchronization frame' (pulls line low
|
||||
// for some time)
|
||||
// TODO: timeouts!
|
||||
/*while (gpio_get(PINOUT_SWIM)) ;
|
||||
while (!gpio_get(PINOUT_SWIM)) ;*/
|
||||
busy_wait_us_32(1000);
|
||||
|
||||
// phase 5: wait a bit
|
||||
busy_wait_us_32(1);
|
||||
}
|
||||
static void initseq_2(void) {
|
||||
sio_hw->gpio_togl = 1u<<20;
|
||||
// phase 6: "write 0x0A0 to SWIM CSR"
|
||||
/*uint8_t data = 0xA0;
|
||||
swim_cmd_wotf(0x007F80, 1, &data);*/
|
||||
swim_tx_bits(4, 0xffff);
|
||||
|
||||
busy_wait_us_32(100);
|
||||
// phase 7: reset release for 1ms. option bytes are read (!)
|
||||
gpio_put(PINOUT_SWIM_nRESET, true);
|
||||
busy_wait_ms(3);
|
||||
|
||||
// phase 8: things are initialized:
|
||||
// * STM8 CPU halted, HSI = 16 MHz
|
||||
// * SWIM clock = HSI/2 = 8 MHz
|
||||
// * SWIM uses low-speed format
|
||||
|
||||
// phase 9: ???
|
||||
}
|
||||
|
||||
void swim_preinit(void) {
|
||||
// TODO:
|
||||
// * init GPIO (pulls, dir, out, function)
|
||||
// * do entry sequence (~8 phases?)
|
||||
gpio_disable_pulls(PINOUT_SWIM_nRESET);
|
||||
gpio_set_function(PINOUT_SWIM_nRESET, GPIO_FUNC_NULL);
|
||||
gpio_set_function(PINOUT_SWIM, GPIO_FUNC_NULL);
|
||||
gpio_pull_up(PINOUT_SWIM);
|
||||
|
||||
// SWIM pin is high before reset release USING PULLUP FROM PADS
|
||||
// to set SWIM pin to 0, set direction to output
|
||||
gpio_put_masked((1u << PINOUT_SWIM_nRESET) | (1u << PINOUT_SWIM), 0);
|
||||
gpio_set_dir(PINOUT_SWIM_nRESET, GPIO_OUT);
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_IN);
|
||||
gpio_set_function(PINOUT_SWIM_nRESET, GPIO_FUNC_SIO);
|
||||
gpio_set_function(PINOUT_SWIM, GPIO_FUNC_SIO);
|
||||
|
||||
// SWIM is now high, reset line is asserted
|
||||
|
||||
busy_wait_ms(3);
|
||||
|
||||
initseq_1();
|
||||
|
||||
// phase 6 and on: do this in swim_init()
|
||||
}
|
||||
|
||||
bool swim_init(void) {
|
||||
// TODO:
|
||||
// for each rx, tx:
|
||||
// * allocate PIO program space
|
||||
// * allocate PIO SMs
|
||||
// * init PIO SM program & stuff
|
||||
if (!pio_can_add_program(PINOUT_SWIM_PIO, &swim_tx_program))
|
||||
goto error;
|
||||
swim_tx_off = pio_add_program(PINOUT_SWIM_PIO, &swim_tx_program);
|
||||
|
||||
if (!pio_can_add_program(PINOUT_SWIM_PIO, &swim_rx_program))
|
||||
goto error;
|
||||
swim_rx_off = pio_add_program(PINOUT_SWIM_PIO, &swim_rx_program);
|
||||
|
||||
swim_tx_sm = pio_claim_unused_sm(PINOUT_SWIM_PIO, false);
|
||||
if (swim_tx_sm == -1) goto error;
|
||||
swim_rx_sm = pio_claim_unused_sm(PINOUT_SWIM_PIO, false);
|
||||
if (swim_rx_sm == -1) goto error;
|
||||
|
||||
swim_tx_pio_init(PINOUT_SWIM_PIO, swim_tx_sm, swim_tx_off, SWIM_DEFAULT_FREQ, PINOUT_SWIM);
|
||||
//swim_rx_pio_init(PINOUT_SWIM_PIO, swim_rx_sm, swim_rx_off, SWIM_DEFAULT_FREQ, PINOUT_SWIM);
|
||||
|
||||
// continue SWIM init sequence:
|
||||
initseq_2();
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
return false;
|
||||
|
||||
// NOTE: you should call swim_deinit(); in this case tho
|
||||
}
|
||||
|
||||
void swim_comms_reset(void) {
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_IN);
|
||||
gpio_put(PINOUT_SWIM, false);
|
||||
gpio_set_function(PINOUT_SWIM, GPIO_FUNC_SIO);
|
||||
|
||||
// comms reset
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_OUT);
|
||||
busy_wait_ms(10);
|
||||
gpio_set_dir(PINOUT_SWIM, GPIO_IN);
|
||||
|
||||
// maybe there's a reply here? UM0470 is confusing about it
|
||||
busy_wait_ms(10);
|
||||
|
||||
// ---
|
||||
|
||||
initseq_1();
|
||||
|
||||
// ---
|
||||
|
||||
gpio_set_function(PINOUT_SWIM,
|
||||
(PINOUT_SWIM_PIO == pio1) ? GPIO_FUNC_PIO1 : GPIO_FUNC_PIO0);
|
||||
|
||||
initseq_2();
|
||||
}
|
||||
|
||||
void swim_deinit(void) {
|
||||
// TODO:
|
||||
// * disable PIO SMs
|
||||
// * deallocate PIO SMs
|
||||
// * deallocate PIO program space
|
||||
if (swim_tx_sm >= 0) {
|
||||
pio_sm_set_enabled(PINOUT_SWIM_PIO, swim_tx_sm, false);
|
||||
pio_sm_unclaim(PINOUT_SWIM_PIO, swim_tx_sm);
|
||||
}
|
||||
if (swim_rx_sm >= 0) {
|
||||
pio_sm_set_enabled(PINOUT_SWIM_PIO, swim_rx_sm, false);
|
||||
pio_sm_unclaim(PINOUT_SWIM_PIO, swim_rx_sm);
|
||||
}
|
||||
if (!~swim_tx_off) pio_remove_program(PINOUT_SWIM_PIO, &swim_tx_program, swim_tx_off);
|
||||
if (!~swim_rx_off) pio_remove_program(PINOUT_SWIM_PIO, &swim_rx_program, swim_rx_off);
|
||||
|
||||
gpio_put(PINOUT_SWIM_nRESET, false);
|
||||
|
||||
gpio_disable_pulls(PINOUT_SWIM);
|
||||
gpio_disable_pulls(PINOUT_SWIM_nRESET);
|
||||
gpio_set_function(PINOUT_SWIM, GPIO_FUNC_NULL);
|
||||
|
||||
busy_wait_ms(1);
|
||||
|
||||
gpio_pull_down(PINOUT_SWIM_nRESET);
|
||||
gpio_set_function(PINOUT_SWIM_nRESET, GPIO_FUNC_NULL);
|
||||
}
|
||||
|
||||
void swim_set_speed(float swim_clock_freq, bool fast) {
|
||||
|
@ -43,20 +194,36 @@ void swim_set_speed(float swim_clock_freq, bool fast) {
|
|||
|
||||
// SWIM only sends up to 10 bits at once before changing direction (for an ack)
|
||||
void swim_tx_bits(uint32_t nbits, uint16_t bits) {
|
||||
// TODO:
|
||||
// * init PIO SM stuff
|
||||
// * send length
|
||||
// * send data
|
||||
// * wait for tx fifo empty
|
||||
// * wait until finished? (use IRQ?? prolly best sync mechanism)
|
||||
if (!nbits) return;
|
||||
|
||||
while (!pio_sm_is_tx_fifo_empty(PINOUT_SWIM_PIO, swim_tx_sm))
|
||||
;
|
||||
|
||||
*(volatile uint32_t*)&PINOUT_SWIM_PIO->txf[swim_tx_sm] = nbits - 1;
|
||||
*(volatile uint16_t*)&PINOUT_SWIM_PIO->txf[swim_tx_sm] = bits;
|
||||
|
||||
while (!pio_sm_is_tx_fifo_empty(PINOUT_SWIM_PIO, swim_tx_sm))
|
||||
;
|
||||
while (!(PINOUT_SWIM_PIO->fdebug & ((1u << swim_tx_sm) << PIO_FDEBUG_TXSTALL_LSB)))
|
||||
;
|
||||
}
|
||||
uint16_t swim_rx_bits(uint32_t nbits) {
|
||||
uint16_t r = 0;
|
||||
if (!nbits) return 0xffff;
|
||||
|
||||
// TODO:
|
||||
// * init PIO SM stuff
|
||||
// * send length
|
||||
// * read data (incl. wait until finished)
|
||||
while (!pio_sm_is_tx_fifo_empty(PINOUT_SWIM_PIO, swim_rx_sm))
|
||||
;
|
||||
|
||||
*(volatile uint32_t*)&PINOUT_SWIM_PIO->txf[swim_rx_sm] = nbits - 1;
|
||||
|
||||
while (!pio_sm_is_tx_fifo_empty(PINOUT_SWIM_PIO, swim_rx_sm))
|
||||
;
|
||||
while (pio_sm_is_rx_fifo_empty(PINOUT_SWIM_PIO, swim_rx_sm))
|
||||
;
|
||||
|
||||
uint16_t r = *(volatile uint16_t*)&PINOUT_SWIM_PIO->rxf[swim_rx_sm];
|
||||
|
||||
while (!(PINOUT_SWIM_PIO->fdebug & ((1u << swim_rx_sm) << PIO_FDEBUG_TXSTALL_LSB)))
|
||||
;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -70,23 +237,8 @@ static uint8_t bitswap(uint8_t in) {
|
|||
return (lut[in&0xf] << 4) | lut[in>>4];
|
||||
}
|
||||
|
||||
bool swim_tx_command(uint8_t cmd, size_t datasize, const uint8_t* data) {
|
||||
// cmd is 0 bit, 3 data bits, parity bit, responded by an ack bit
|
||||
uint16_t r = 0, v = (0<<15) | ((cmd&1)<<14) | ((cmd&2)<<12) | ((cmd&4)<<10);
|
||||
// add parity bit
|
||||
v |= (((cmd>>0)^(cmd>>1)^(cmd>>2)) & 1) << 11;
|
||||
|
||||
for (size_t i = 0; i < 10; ++i) {
|
||||
swim_tx_bits(5, v);
|
||||
|
||||
r = swim_rx_bits(1); // ack bit
|
||||
if (r) break;
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
// oops, no ack!
|
||||
return false;
|
||||
}
|
||||
bool swim_tx_data(size_t datasize, const uint8_t* data) {
|
||||
uint16_t r = 0, v = 0;
|
||||
|
||||
// start sending data bits
|
||||
for (size_t i = 0; i < datasize; ++i) {
|
||||
|
@ -111,6 +263,26 @@ bool swim_tx_command(uint8_t cmd, size_t datasize, const uint8_t* data) {
|
|||
|
||||
return true;
|
||||
}
|
||||
bool swim_tx_command(uint8_t cmd, size_t datasize, const uint8_t* data) {
|
||||
// cmd is 0 bit, 3 data bits, parity bit, responded by an ack bit
|
||||
uint16_t r = 0, v = (0<<15) | ((cmd&1)<<14) | ((cmd&2)<<12) | ((cmd&4)<<10);
|
||||
// add parity bit
|
||||
v |= (((cmd>>0)^(cmd>>1)^(cmd>>2)) & 1) << 11;
|
||||
|
||||
for (size_t i = 0; i < 10; ++i) {
|
||||
swim_tx_bits(5, v);
|
||||
|
||||
r = swim_rx_bits(1); // ack bit
|
||||
if (r) break;
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
// oops, no ack!
|
||||
return false;
|
||||
}
|
||||
|
||||
return swim_tx_data(datasize, data);
|
||||
}
|
||||
|
||||
bool swim_rx_data(size_t datasize, uint8_t* data) {
|
||||
uint16_t v = 0, r = 0;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#ifndef SWIM_HW_H_
|
||||
#define SWIM_HW_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -11,6 +12,8 @@ void swim_preinit(void);
|
|||
bool swim_init(void);
|
||||
void swim_deinit(void);
|
||||
|
||||
void swim_comms_reset(void);
|
||||
|
||||
// 'swim_clock_freq' is the frequency of the underlying SWIM clock,
|
||||
// *NOT* the baudrate! in the STM8 device being debugged, this is usually
|
||||
// HSI/2 = 8 MHz
|
||||
|
@ -21,6 +24,7 @@ void swim_set_speed(float swim_clock_freq, bool fast);
|
|||
void swim_tx_bits(uint32_t nbits, uint16_t bits);
|
||||
uint16_t swim_rx_bits(uint32_t nbits);
|
||||
|
||||
bool swim_tx_data(size_t datasize, const uint8_t* data);
|
||||
bool swim_tx_command(uint8_t cmd, size_t datasize, const uint8_t* data);
|
||||
bool swim_rx_data(size_t datasize, uint8_t* data);
|
||||
|
||||
|
|
|
@ -287,6 +287,8 @@ static enum tool78_stat tool78_wait_status/*__impl*/(struct tool78_hw* hw, int l
|
|||
// ----
|
||||
|
||||
enum tool78_stat tool78_do_reset(struct tool78_hw* hw) {
|
||||
//busy_wait_ms(100);
|
||||
|
||||
enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_reset, 0, NULL);
|
||||
//printf("send st=%02x\n", st);
|
||||
if (st != tool78_stat_ack) return st;
|
||||
|
|
|
@ -40,7 +40,7 @@ static bool t78k0_uart2_init(void) {
|
|||
// send 0x00
|
||||
// wait t2C (>15k/8M s)
|
||||
|
||||
busy_wait_us_32(477768); // tCOM or tR1
|
||||
busy_wait_us_32(477768/*>>3*/); // tCOM or tR1
|
||||
|
||||
uint8_t byte = 0x00;
|
||||
t78k0_uart2_send(1, &byte, -1);
|
||||
|
@ -57,6 +57,8 @@ static bool t78k0_uart2_init(void) {
|
|||
return true; // all is well!
|
||||
}
|
||||
static void t78k0_uart2_deinit(void) {
|
||||
busy_wait_ms(500);
|
||||
|
||||
tool78_hw_deinit_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
|
||||
&vars);
|
||||
|
||||
|
|
|
@ -57,10 +57,10 @@ bool tool78_hw_init_help(const pio_program_t* prgm_tx,
|
|||
return true; // all is well!
|
||||
|
||||
error:
|
||||
if (!~txoff) pio_remove_program(PINOUT_TOOL78_PIO, prgm_tx, txoff);
|
||||
if (!~rxoff) pio_remove_program(PINOUT_TOOL78_PIO, prgm_rx, rxoff);
|
||||
if (smtx >= 0) pio_sm_unclaim(PINOUT_TOOL78_PIO, smtx);
|
||||
if (smrx >= 0) pio_sm_unclaim(PINOUT_TOOL78_PIO, smrx);
|
||||
if (!~txoff) pio_remove_program(PINOUT_TOOL78_PIO, prgm_tx, txoff);
|
||||
if (!~rxoff) pio_remove_program(PINOUT_TOOL78_PIO, prgm_rx, rxoff);
|
||||
return false;
|
||||
}
|
||||
void tool78_hw_deinit_help(const pio_program_t* prgm_tx,
|
||||
|
|
Loading…
Reference in New Issue