more stuff

This commit is contained in:
Triss 2021-11-03 00:58:52 +01:00
parent a15ba940f2
commit 2fa28c4313
8 changed files with 256 additions and 10 deletions

View File

@ -37,6 +37,8 @@ if(FAMILY STREQUAL "rp2040")
${CMAKE_CURRENT_SOURCE_DIR}/src/swim/swim_hw.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_uart2.c
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_78k0_uart2_extclk.c
${CMAKE_CURRENT_SOURCE_DIR}/src/test/piotest.c
)

1
src/tool78/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
notes.txt

View File

@ -22,19 +22,19 @@
#define PINOUT_TOOL78_RL78_RX 19
enum tool78_target {
tool78k0_kx2_uart2 = 0x12,
tool78k0_kx2_spi = 0x13,
tool78k0_kx2_uart2_extclk = 0x14,
tool78k0_uart2 = 0x12,
tool78k0_spi = 0x13,
tool78k0_uart2_extclk = 0x14,
tool78k0r_kx3l_uart1 = 0x21,
tool78k0r_uart1 = 0x21,
tool78rl_uart1 = 0x31,
tool78rl_uart2 = 0x32,
tool78rl_ocd = 0x38, // FIXME: do this in a better way
tool78_mcu_mask = 0xf0,
tool78_mcu_78k0_kx2 = 0x10,
tool78_mcu_78k0r_kx3l = 0x20,
tool78_mcu_78k0 = 0x10,
tool78_mcu_78k0r = 0x20,
tool78_mcu_rl78 = 0x30,
tool78_phy_mask = 0x0f,

View File

@ -0,0 +1,89 @@
#include <hardware/gpio.h>
#include <hardware/pio.h>
#include <pico/time.h>
#include "tool78_defs.h"
#include "tool78_hw_helpers.h"
#include "tool78.pio.h"
#include "tool78_hw.h"
static struct tool78_pio_vars vars;
int t78k0_uart2_send(int len, const uint8_t* data, int32_t timeout_us);
void t78k0_uart2_deinit(void);
int t78k0_uart2_has_available(void);
int t78k0_uart2_recv(int len, uint8_t* data, int32_t timeout_us);
int t78k0_uart2_send(int len, const uint8_t* data, int32_t timeout_us);
static bool t78k0_uart2_init(void) {
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars)) return false;
vars.exclusive = false;
// extclk between 2 and 20 MHz
tool78_entryseq_78k0(tool78k0_uart2);
tool78_uart_tx_program_init(PINOUT_TOOL78_PIO, vars.smtx, vars.txoff,
PINOUT_TOOL78_78K0_TXMOSI, 9600, true);
tool78_uart_rx_program_init(PINOUT_TOOL78_PIO, vars.smrx, vars.rxoff,
PINOUT_TOOL78_78K0_RXMISO, 9600, true);
// magic initial not-really-commands
// wait tCOM or tR1 (unclear) (>445k/8M s + (2^16)/2M s)
// send 0x00
// wait t12 (>15k/8M s)
// send 0x00
// wait t2C (>15k/8M s)
busy_wait_us_32(477768); // tCOM or tR1
uint8_t byte = 0x00;
t78k0_uart2_send(1, &byte, -1);
busy_wait_us_32(1900); // t12
t78k0_uart2_send(1, &byte, -1);
busy_wait_us_32(1900); // t2C
// now a reset command needs to be sent, but we leave that to the upper
// (command processing) layer as it has to know about those timings anyway
return true; // all is well!
}
void t78k0_uart2_deinit(void) {
tool78_hw_deinit_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars);
tool78_deinit_78k0();
}
int t78k0_uart2_has_available(void) {
return tool78_hw_has_available_help(&vars);
}
int t78k0_uart2_recv(int len, uint8_t* data, int32_t timeout_us) {
return tool78_hw_help_recv(&vars, len, data, timeout_us);
}
int t78k0_uart2_send(int len, const uint8_t* data, int32_t timeout_us) {
return tool78_hw_help_send(&vars, 12/*inter-byte delay (us) tDR = 90/8M s */,
len, data, timeout_us);
}
struct tool78_hw tool78_hw_78k0_uart2 = {
.target = tool78k0_uart2,
.init = t78k0_uart2_init,
.deinit = t78k0_uart2_deinit,
.has_available = t78k0_uart2_has_available,
.recv = t78k0_uart2_recv,
.send = t78k0_uart2_send
};

View File

@ -0,0 +1,81 @@
#include <hardware/gpio.h>
#include <hardware/pio.h>
#include <hardware/pwm.h>
#include <pico/time.h>
#include "tool78_defs.h"
#include "tool78_hw_helpers.h"
#include "tool78.pio.h"
#include "tool78_hw.h"
static struct tool78_pio_vars vars;
int t78k0_uart2_send(int len, const uint8_t* data, int32_t timeout_us);
void t78k0_uart2_deinit(void);
int t78k0_uart2_has_available(void);
int t78k0_uart2_recv(int len, uint8_t* data, int32_t timeout_us);
int t78k0_uart2_send(int len, const uint8_t* data, int32_t timeout_us);
static bool t78k0_uart2_extclk_init(void) {
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars)) return false;
vars.exclusive = false;
// extclk between 2 and 20 MHz, let's do 8 MHz
pwm_config pc = pwm_get_default_config();
pwm_config_set_clkdiv(&pc, (float)clock_get_hz(clk_sys) / 8e6);
pwm_init(pwm_gpio_to_slice_num(PINOUT_TOOL78_78K0_CLOCK), &pc, true);
gpio_set_function(PINOUT_TOOL78_78K0_CLOCK, GPIO_FUNC_PWM);
tool78_entryseq_78k0(tool78k0_uart2_extclk);
tool78_uart_tx_program_init(PINOUT_TOOL78_PIO, vars.smtx, vars.txoff,
PINOUT_TOOL78_78K0_TXMOSI, 9600, true);
tool78_uart_rx_program_init(PINOUT_TOOL78_PIO, vars.smrx, vars.rxoff,
PINOUT_TOOL78_78K0_RXMISO, 9600, true);
// magic initial not-really-commands
// wait tCOM or tR1 (unclear) (>445k/8M s + (2^16)/2M s)
// send 0x00
// wait t12 (>15k/8M s)
// send 0x00
// wait t2C (>15k/8M s)
busy_wait_us_32(477768); // tCOM or tR1
uint8_t byte = 0x00;
t78k0_uart2_send(1, &byte, -1);
busy_wait_us_32(1900); // t12
t78k0_uart2_send(1, &byte, -1);
busy_wait_us_32(1900); // t2C
// now a reset command needs to be sent, but we leave that to the upper
// (command processing) layer as it has to know about those timings anyway
return true; // all is well!
}
static void t78k0_uart2_extclk_deinit(void) {
t78k0_uart2_deinit(); // sets extclk to no func
pwm_set_enabled(pwm_gpio_to_slice_num(PINOUT_TOOL78_78K0_CLOCK), false);
}
struct tool78_hw tool78_hw_78k0_uart2_extclk = {
.target = tool78k0_uart2_extclk,
.init = t78k0_uart2_extclk_init,
.deinit = t78k0_uart2_extclk_deinit,
.has_available = t78k0_uart2_has_available,
.recv = t78k0_uart2_recv,
.send = t78k0_uart2_send
};

View File

@ -145,6 +145,7 @@ int tool78_hw_help_send(const struct tool78_pio_vars* vars, uint32_t sleep_us_be
*(volatile uint8_t*)&PINOUT_TOOL78_PIO->txf[vars->smtx] = bitswap(data[i]);
// FIXME: THIS IS NOT HOW TO WAIT BETWEEN TWO BYTES YOU DOOFUS
if (sleep_us_between_bytes) busy_wait_us_32(sleep_us_between_bytes);
}
@ -153,7 +154,7 @@ end:
// wait until everything is sent before reenabling the RX SM again
while (!pio_sm_is_tx_fifo_empty(PINOUT_TOOL78_PIO, vars->smtx))
; // wait until FIFO is clear
while (!(PINOUT_TOOL78_PIO->fdebug & ((1u << vars.smtx) << PIO_FDEBUG_TXSTALL_LSB)))
while (!(PINOUT_TOOL78_PIO->fdebug & ((1u << vars->smtx) << PIO_FDEBUG_TXSTALL_LSB)))
; // now wait for the SM to hang on the next 'pull'
pio_sm_set_enabled(PINOUT_TOOL78_PIO, vars->smrx, true);
@ -162,3 +163,70 @@ end:
return i;
}
// ------
void tool78_entryseq_78k0(enum tool78_entry typ) {
// set TX, RX (and MISO MOSI nSCK) pullup, not driven
// set nRESET, FLMD0 low ;; set pindir to out ;; set GPIO func to SIO
// wait some time (tDP: >1ms and tRST for reset low >2ms)
// FLMD0 high
// wait some time (tPR: >2ms)
// nRESET high
// wait some time (tRP: 60k/8M s)
// <n> FLMD0 pulses (period/2 = 10us)
// wait some time (end happens 239k/8M s after nRESET high)
// NOTE: datasheet tells to start doing pulses in the middle of the 60k..239k interval
gpio_pull_up(PINOUT_TOOL78_78K0_TXMOSI);
gpio_pull_up(PINOUT_TOOL78_78K0_RXMISO);
gpio_pull_up(PINOUT_TOOL78_78K0_CLOCK );
gpio_set_function(PINOUT_TOOL78_78K0_TXMOSI, GPIO_FUNC_NULL);
gpio_set_function(PINOUT_TOOL78_78K0_RXMISO, GPIO_FUNC_NULL);
gpio_set_function(PINOUT_TOOL78_78K0_CLOCK , GPIO_FUNC_NULL);
gpio_put_masked((1u<<PINOUT_TOOL78_nRESET) | (1u<<PINOUT_TOOL78_78K0_FLMD0), 0u);
gpio_set_dir_out_masked((1u<<PINOUT_TOOL78_nRESET) | (1u<<PINOUT_TOOL78_78K0_FLMD0));
gpio_set_function(PINOUT_TOOL78_nRESET , GPIO_FUNC_SIO);
gpio_set_function(PINOUT_TOOL78_78K0_FLMD0, GPIO_FUNC_SIO);
busy_wait_ms(3); // tDP or tRST
gpio_put(PINOUT_TOOL78_78K0_FLMD0, true);
busy_wait_ms(3); // tPR
gpio_put(PINOUT_TOOL78_nRESET, true);
busy_wait_us_32(37500); // tRPE/2
for (int i = 0; i < (int)typ; ++i) {
gpio_put(PINOUT_TOOL78_78K0_FLMD0, false);
busy_wait_us_32(12);
gpio_put(PINOUT_TOOL78_78K0_FLMD0, true);
busy_wait_us_32(12);
}
busy_wait_us_32(37500); // tRPE/2
}
void tool78_deinit_78k0(void) {
// nRESET low here
gpio_put(PINOUT_TOOL78_nRESET, false);
// start deiniting stuff
gpio_disable_pulls(PINOUT_TOOL78_78K0_TXMOSI);
gpio_disable_pulls(PINOUT_TOOL78_78K0_RXMISO);
gpio_disable_pulls(PINOUT_TOOL78_78K0_CLOCK );
gpio_disable_pulls(PINOUT_TOOL78_78K0_FLMD0 );
gpio_set_function(PINOUT_TOOL78_78K0_TXMOSI, GPIO_FUNC_NULL);
gpio_set_function(PINOUT_TOOL78_78K0_RXMISO, GPIO_FUNC_NULL);
gpio_set_function(PINOUT_TOOL78_78K0_CLOCK , GPIO_FUNC_NULL);
gpio_set_function(PINOUT_TOOL78_78K0_FLMD0 , GPIO_FUNC_NULL);
busy_wait_ms(3);
gpio_pull_down(PINOUT_TOOL78_nRESET);
gpio_set_function(PINOUT_TOOL78_nRESET, GPIO_FUNC_NULL);
}

View File

@ -34,6 +34,11 @@ int tool78_hw_help_recv(const struct tool78_pio_vars* vars,
int tool78_hw_help_send(const struct tool78_pio_vars* vars, uint32_t sleep_us_between_bytes,
int len, const uint8_t* data, int32_t timeout_us);
// performs an entry sequence using SIO
void tool78_entryseq_78k0(enum tool78_entry typ);
// pulls nRESET low & puts other stuff in hi-Z
void tool78_deinit_78k0(void);
#endif

View File

@ -54,7 +54,7 @@ static int test_send(int len, const uint8_t* data, int32_t timeout_us) {
}
struct tool78_hw tool78_hw_test_uart2 = {
.target = tool78k0_kx2_uart2,
.target = tool78k0_uart2,
.init = test_init,
.deinit = test_deinit,