78k0 and SWIM stuff that doesn't work

This commit is contained in:
Triss 2022-06-30 02:52:17 +02:00
parent 37a41e5f83
commit 989785e06b
15 changed files with 460 additions and 121 deletions

View File

@ -35,6 +35,7 @@ if(FAMILY STREQUAL "rp2040")
${CMAKE_CURRENT_SOURCE_DIR}/src/msp430/tap.c ${CMAKE_CURRENT_SOURCE_DIR}/src/msp430/tap.c
${CMAKE_CURRENT_SOURCE_DIR}/src/msp430/msp430dbg.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_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_helpers.c
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_test_uart2.c ${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_test_uart2.c
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_78k0_spi.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/glitch/glitch.c
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/cli.c ${CMAKE_CURRENT_SOURCE_DIR}/src/cli/cli.c
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/msp430.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.c
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/rl78-glitch.c ${CMAKE_CURRENT_SOURCE_DIR}/src/cli/rl78-glitch.c
${CMAKE_CURRENT_SOURCE_DIR}/src/cli/dragonzap.c ${CMAKE_CURRENT_SOURCE_DIR}/src/cli/dragonzap.c

View File

@ -10,7 +10,8 @@
#define BREADBOARD_SBW_TDIO 9 #define BREADBOARD_SBW_TDIO 9
#define BREADBOARD_SWIM_PIO pio0 #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 #define BREADBOARD_TOOL78_PIO pio1

View File

@ -5,7 +5,7 @@
#include "breadboard.h" #include "breadboard.h"
#include "zap.h" #include "zap.h"
#define PINOUT_USE_DRAGONZAP 1 #define PINOUT_USE_DRAGONZAP 0
#if PINOUT_USE_DRAGONZAP #if PINOUT_USE_DRAGONZAP
@ -18,7 +18,8 @@
#define PINOUT_SBW_TDIO (ZAP_GPIO_BASE+1) #define PINOUT_SBW_TDIO (ZAP_GPIO_BASE+1)
#define PINOUT_SWIM_PIO BREADBOARD_SWIM_PIO #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 #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_SBW_TDIO BREADBOARD_SBW_TDIO
#define PINOUT_SWIM_PIO BREADBOARD_SWIM_PIO #define PINOUT_SWIM_PIO BREADBOARD_SWIM_PIO
#define PINOUT_SWIM_nRESET BREADBOARD_SWIM_nRESET
#define PINOUT_SWIM BREADBOARD_SWIM_PIN #define PINOUT_SWIM BREADBOARD_SWIM_PIN
#define PINOUT_TOOL78_PIO BREADBOARD_TOOL78_PIO #define PINOUT_TOOL78_PIO BREADBOARD_TOOL78_PIO

26
src/cli/78k0.c Normal file
View File

@ -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();
}

View File

@ -38,6 +38,11 @@ void cli_tool78_glitch_ocd_dump(void);
void cli_tool78_glitch_param_g10(void); void cli_tool78_glitch_param_g10(void);
void cli_tool78_glitch_ocd_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() { static void adc_init_stuff() {
adc_init(); adc_init();
adc_gpio_init(27); adc_gpio_init(27);
@ -87,6 +92,11 @@ static struct cli_cmd cmds[] = {
{ "zap", cli_dragonzap_test }, { "zap", cli_dragonzap_test },
{ "k0sfp", cli_tool78_proto78k0 },
{ "swimphy", cli_swim_phytest },
{ "swim", cli_swim_prototest },
{ NULL, NULL } // final { NULL, NULL } // final
}; };

View File

@ -1,4 +1,3 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -53,17 +52,16 @@ static bool glitch_init_core1_stuff(bool exttrig, uint glitchpin) {
offset.min = 10*1000; offset.min = 10*1000;
offset.max = 35433*1000; offset.max = 35433*1000;
length.min = 100; length.min = 100;
length.max = 10*50/*26*/*1000; length.max = /*10*50*/26*1000;
//length.value = 5*1000; // 5 us //length.value = 5*1000; // 5 us
#if PINOUT_USE_DRAGONZAP #if PINOUT_USE_DRAGONZAP
//length.adc_index = 0;//999; //length.adc_index = 0;//999;
#else #else
#error "a"
//length.adc_index = 999; //length.adc_index = 999;
#endif #endif
glitch_param_randrange_init(&offset); glitch_param_randrange_init(&offset);
glitch_param_const_init(&length); //glitch_param_const_init(&length);
glitch_param_randrange_init(&length); glitch_param_randrange_init(&length);
//glitch_param_adc_init(&length); //glitch_param_adc_init(&length);
@ -237,7 +235,9 @@ deinit_bad:
} }
void cli_tool78_glitch_paramsearch(void) { 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"); printf("bad glitcher params!\n");
return; return;
} }
@ -250,8 +250,12 @@ void cli_tool78_glitch_paramsearch(void) {
bool first = true; bool first = true;
restart: restart:
/*glitch_disarm(); zap_picoemp_set_armed(false);
busy_wait_ms(40);*/ glitch_disarm();
/*busy_wait_ms(40);*/
zap_picoemp_set_armed(true);
while (!zap_picoemp_has_hv()) ;
ver=0; ver=0;
st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd); st = tool78_init_ocd(&tool78_hw_rl78_uart1, &ver, passwd);
@ -332,12 +336,16 @@ restart:
glitch_arm(); glitch_arm();
rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 120*1000); rr = tool78_hw_rl78_uart1.recv(2, checkbuf, 120*1000);
glitch_disarm(); glitch_disarm();
bool first_ = true;
do {
if (rr == 2 && (checkbuf[0] != 'H' || checkbuf[1] != 'i')) rr = 0; if (rr == 2 && (checkbuf[0] != 'H' || checkbuf[1] != 'i')) rr = 0;
if (rr == 2) { if (rr == 2) {
rr = tool78_hw_rl78_uart1.recv(256, checkbuf, 120*1000); rr = tool78_hw_rl78_uart1.recv(256, checkbuf, 120*1000);
} }
if (rr <= 0) { if (rr <= 0) {
if (!first_) break;
// timeout or something // timeout or something
printf("X"); printf("X");
tool78_hw_rl78_uart1.deinit(); tool78_hw_rl78_uart1.deinit();
@ -358,29 +366,23 @@ restart:
firstbad, lastbad, *off, *len, rr, checkbuf[firstbad]^0xaa); firstbad, lastbad, *off, *len, rr, checkbuf[firstbad]^0xaa);
} else { } else {
printf("."); 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: deinit_bad:
zap_picoemp_set_armed(false);
tool78_hw_rl78_uart1.deinit(); tool78_hw_rl78_uart1.deinit();
return; return;
do_reset_stuff: do_reset_stuff:
zap_picoemp_set_armed(false);
tool78_hw_rl78_uart1.deinit(); tool78_hw_rl78_uart1.deinit();
// glitch for way too long to power cycle // glitch for way too long to power cycle

45
src/cli/swim.c Normal file
View File

@ -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();
}

View File

@ -3,36 +3,47 @@
; Pin assignments: ; Pin assignments:
; - SWIM is out/set/side pin 0 ; - 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: start:
pull side 0 nop side 0 [15]
out x, 32 side 0 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 ; pull side 0
; way? ; out x, 32 side 0
iter: ;
out y, 1 side 0 ; get next bit ; ; TODO: can we somehow sleep for a variable amount of cycles in an easier
jmp !y, bit_0 side 0 ; ; way?
;iter:
bit_1: ; out y, 1 side 0 ; get next bit
nop side 1 [2] ; jmp !y, bit_0 side 0
;
;bit_1:
; nop side 1 [2]
PUBLIC bit_1_delay_long: PUBLIC bit_1_delay_long:
nop side 0 [10] ; or 4 ; nop side 0 [10] ; or 4
nop side 0 [10] ; or 4 ; nop side 0 [10] ; or 4
;
jmp iter_next side 0 ; jmp iter_next side 0
;
bit_0: ;bit_0:
PUBLIC bit_0_delay_long: PUBLIC bit_0_delay_long:
nop side 1 [10] ; or 4 ; nop side 1 [10] ; or 4
nop side 1 [10] ; or 4 ; nop side 1 [10] ; or 4
nop side 0 [2] ; nop side 0 [2]
;
;iter_next:
; jmp x--, iter side 0
iter_next: ; 12 instructions
jmp x--, iter side 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -42,8 +53,7 @@ iter_next:
; - SWIM is in pin 0 ; - SWIM is in pin 0
; NOTE: pin needs pullup, either input(+pullup) or output+drivezero ; 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: start:
pull pull
@ -65,6 +75,8 @@ PUBLIC wait_delay:
push push
; 7 instructions
;;;; 19 instructions total ;;;; 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_out_pins(&c, pin_swim, 1);
sm_config_set_set_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_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_clkdiv(&c, (float)clock_get_hz(clk_sys) / swim_clock_freq);
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);
pio_sm_init(pio, sm, prog_offs, &c); 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); pio_sm_config c = swim_rx_program_get_default_config(prog_offs);
sm_config_set_in_pins(&c, pin_swim); 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_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); pio_sm_init(pio, sm, prog_offs, &c);
// SWIM pin is pure input // SWIM pin is pure input

39
src/swim/swim_cmd.c Normal file
View File

@ -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);
}

19
src/swim/swim_cmd.h Normal file
View File

@ -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

View File

@ -7,31 +7,182 @@
#include "pinout.h" #include "pinout.h"
#include "swim_hw.h" #include "swim_hw.h"
#include "swim_cmd.h"
#include "swim.pio.h" #include "swim.pio.h"
int swim_tx_sm = -1, swim_rx_sm = -1, swim_tx_off = -1, swim_rx_off = -1; 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) { void swim_preinit(void) {
// TODO: gpio_disable_pulls(PINOUT_SWIM_nRESET);
// * init GPIO (pulls, dir, out, function) gpio_set_function(PINOUT_SWIM_nRESET, GPIO_FUNC_NULL);
// * do entry sequence (~8 phases?) 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) { bool swim_init(void) {
// TODO: if (!pio_can_add_program(PINOUT_SWIM_PIO, &swim_tx_program))
// for each rx, tx: goto error;
// * allocate PIO program space swim_tx_off = pio_add_program(PINOUT_SWIM_PIO, &swim_tx_program);
// * allocate PIO SMs
// * init PIO SM program & stuff 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; 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) { void swim_deinit(void) {
// TODO: if (swim_tx_sm >= 0) {
// * disable PIO SMs pio_sm_set_enabled(PINOUT_SWIM_PIO, swim_tx_sm, false);
// * deallocate PIO SMs pio_sm_unclaim(PINOUT_SWIM_PIO, swim_tx_sm);
// * deallocate PIO program space }
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) { 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) // 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) { void swim_tx_bits(uint32_t nbits, uint16_t bits) {
// TODO: if (!nbits) return;
// * init PIO SM stuff
// * send length while (!pio_sm_is_tx_fifo_empty(PINOUT_SWIM_PIO, swim_tx_sm))
// * send data ;
// * wait for tx fifo empty
// * wait until finished? (use IRQ?? prolly best sync mechanism) *(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 swim_rx_bits(uint32_t nbits) {
uint16_t r = 0; if (!nbits) return 0xffff;
// TODO: while (!pio_sm_is_tx_fifo_empty(PINOUT_SWIM_PIO, swim_rx_sm))
// * init PIO SM stuff ;
// * send length
// * read data (incl. wait until finished) *(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; return r;
} }
@ -70,23 +237,8 @@ static uint8_t bitswap(uint8_t in) {
return (lut[in&0xf] << 4) | lut[in>>4]; return (lut[in&0xf] << 4) | lut[in>>4];
} }
bool swim_tx_command(uint8_t cmd, size_t datasize, const uint8_t* data) { bool swim_tx_data(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;
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;
}
// start sending data bits // start sending data bits
for (size_t i = 0; i < datasize; ++i) { 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; 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) { bool swim_rx_data(size_t datasize, uint8_t* data) {
uint16_t v = 0, r = 0; uint16_t v = 0, r = 0;

View File

@ -2,6 +2,7 @@
#ifndef SWIM_HW_H_ #ifndef SWIM_HW_H_
#define SWIM_HW_H_ #define SWIM_HW_H_
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@ -11,6 +12,8 @@ void swim_preinit(void);
bool swim_init(void); bool swim_init(void);
void swim_deinit(void); void swim_deinit(void);
void swim_comms_reset(void);
// 'swim_clock_freq' is the frequency of the underlying SWIM clock, // 'swim_clock_freq' is the frequency of the underlying SWIM clock,
// *NOT* the baudrate! in the STM8 device being debugged, this is usually // *NOT* the baudrate! in the STM8 device being debugged, this is usually
// HSI/2 = 8 MHz // 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); void swim_tx_bits(uint32_t nbits, uint16_t bits);
uint16_t swim_rx_bits(uint32_t nbits); 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_tx_command(uint8_t cmd, size_t datasize, const uint8_t* data);
bool swim_rx_data(size_t datasize, uint8_t* data); bool swim_rx_data(size_t datasize, uint8_t* data);

View File

@ -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) { 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); enum tool78_stat st = tool78_cmd_send(hw, tool78_cmd_reset, 0, NULL);
//printf("send st=%02x\n", st); //printf("send st=%02x\n", st);
if (st != tool78_stat_ack) return st; if (st != tool78_stat_ack) return st;

View File

@ -40,7 +40,7 @@ static bool t78k0_uart2_init(void) {
// send 0x00 // send 0x00
// wait t2C (>15k/8M s) // 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; uint8_t byte = 0x00;
t78k0_uart2_send(1, &byte, -1); t78k0_uart2_send(1, &byte, -1);
@ -57,6 +57,8 @@ static bool t78k0_uart2_init(void) {
return true; // all is well! return true; // all is well!
} }
static void t78k0_uart2_deinit(void) { static void t78k0_uart2_deinit(void) {
busy_wait_ms(500);
tool78_hw_deinit_help(&tool78_uart_tx_program, &tool78_uart_rx_program, tool78_hw_deinit_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars); &vars);

View File

@ -57,10 +57,10 @@ bool tool78_hw_init_help(const pio_program_t* prgm_tx,
return true; // all is well! return true; // all is well!
error: 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 (smtx >= 0) pio_sm_unclaim(PINOUT_TOOL78_PIO, smtx);
if (smrx >= 0) pio_sm_unclaim(PINOUT_TOOL78_PIO, smrx); 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; return false;
} }
void tool78_hw_deinit_help(const pio_program_t* prgm_tx, void tool78_hw_deinit_help(const pio_program_t* prgm_tx,