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

View File

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

View File

@ -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
@ -49,8 +50,9 @@ inline static void bsp_init_stuff(void) {
#define PINOUT_SBW_TCK BREADBOARD_SBW_TCK
#define PINOUT_SBW_TDIO BREADBOARD_SBW_TDIO
#define PINOUT_SWIM_PIO BREADBOARD_SWIM_PIO
#define PINOUT_SWIM BREADBOARD_SWIM_PIN
#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

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_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
};

View File

@ -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,55 +336,53 @@ restart:
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 do_reset_stuff;
} 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;
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();
goto do_reset_stuff;
} 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_ns.cur,
*len = (volatile uint32_t*)&glitch_param_cur.length_ns.cur;
printf("glitch first=%d last=%d off=%lu len=%lu rr=%d v=%02x\n",
firstbad, lastbad, *off, *len, rr, checkbuf[firstbad]^0xaa);
} else {
printf(".");
}
}
if (firstbad >= 0) {
volatile uint32_t
*off = (volatile uint32_t*)&glitch_param_cur.offset_ns.cur,
*len = (volatile uint32_t*)&glitch_param_cur.length_ns.cur;
printf("glitch first=%d last=%d off=%lu len=%lu rr=%d v=%02x\n",
firstbad, lastbad, *off, *len, rr, checkbuf[firstbad]^0xaa);
} else {
printf(".");
/*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

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:
; - 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

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 "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;

View File

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

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) {
//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;

View File

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

View File

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