more stuff
This commit is contained in:
parent
a15ba940f2
commit
2fa28c4313
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
notes.txt
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue