more tool78 phy stuff, only missing 78k0 spi

This commit is contained in:
Triss 2021-11-03 21:33:18 +01:00
parent 2fa28c4313
commit 0987d432f2
9 changed files with 365 additions and 24 deletions

View File

@ -39,6 +39,9 @@ if(FAMILY STREQUAL "rp2040")
${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/tool78/tool78_hw_78k0r_uart1.c
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_rl78_uart1.c
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_rl78_uart2.c
${CMAKE_CURRENT_SOURCE_DIR}/src/test/piotest.c
)

View File

@ -12,18 +12,14 @@
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 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;
vars.bitswap = true;
// extclk between 2 and 20 MHz
tool78_entryseq_78k0(tool78k0_uart2);
@ -56,21 +52,21 @@ static bool t78k0_uart2_init(void) {
return true; // all is well!
}
void t78k0_uart2_deinit(void) {
static 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) {
static 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) {
static 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) {
static 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);
}

View File

@ -13,17 +13,14 @@
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 int t78k0_uart2_extclk_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;
vars.bitswap = true;
// extclk between 2 and 20 MHz, let's do 8 MHz
pwm_config pc = pwm_get_default_config();
@ -48,11 +45,11 @@ static bool t78k0_uart2_extclk_init(void) {
busy_wait_us_32(477768); // tCOM or tR1
uint8_t byte = 0x00;
t78k0_uart2_send(1, &byte, -1);
t78k0_uart2_extclk_send(1, &byte, -1);
busy_wait_us_32(1900); // t12
t78k0_uart2_send(1, &byte, -1);
t78k0_uart2_extclk_send(1, &byte, -1);
busy_wait_us_32(1900); // t2C
@ -62,20 +59,36 @@ static bool t78k0_uart2_extclk_init(void) {
return true; // all is well!
}
static void t78k0_uart2_extclk_deinit(void) {
t78k0_uart2_deinit(); // sets extclk to no func
tool78_hw_deinit_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars);
tool78_deinit_78k0();
pwm_set_enabled(pwm_gpio_to_slice_num(PINOUT_TOOL78_78K0_CLOCK), false);
}
static int t78k0_uart2_extclk_has_available(void) {
return tool78_hw_has_available_help(&vars);
}
static int t78k0_uart2_extclk_recv(int len, uint8_t* data, int32_t timeout_us) {
return tool78_hw_help_recv(&vars, len, data, timeout_us);
}
static int t78k0_uart2_extclk_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_extclk = {
.target = tool78k0_uart2_extclk,
.init = t78k0_uart2_extclk_init,
.deinit = t78k0_uart2_extclk_deinit,
.has_available = t78k0_uart2_has_available,
.has_available = t78k0_uart2_extclk_has_available,
.recv = t78k0_uart2_recv,
.send = t78k0_uart2_send
.recv = t78k0_uart2_extclk_recv,
.send = t78k0_uart2_extclk_send
};

View File

@ -0,0 +1,83 @@
#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;
static void t78k0r_uart1_deinit(void);
static int t78k0r_uart1_recv(int len, uint8_t* data, int32_t timeout_us);
static int t78k0r_uart1_send(int len, const uint8_t* data, int32_t timeout_us);
static bool t78k0r_uart1_init(void) {
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars)) return false;
vars.exclusive = true;
vars.bitswap = true;
tool78_entryseq_78k0r(tool78_entry_78k0r_uart1);
tool78_uart_tx_program_init(PINOUT_TOOL78_PIO, vars.smtx, vars.txoff,
PINOUT_TOOL78_78K0R_TOOL0, 9600, true);
tool78_uart_rx_program_init(PINOUT_TOOL78_PIO, vars.smrx, vars.rxoff,
PINOUT_TOOL78_78K0R_TOOL0, 9600, true);
// wait for 0x00 byte
uint8_t byte = 0xff;
size_t s = t78k0r_uart1_recv(1, &byte, 50*1000);
if (s == 0 || byte != 0x00) {
t78k0r_uart1_deinit();
return false;
}
busy_wait_us_32(120); // t01
byte = 0;
t78k0r_uart1_send(1, &byte, -1);
busy_wait_us_32(610); // 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 t78k0r_uart1_deinit(void) {
tool78_hw_deinit_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars);
tool78_deinit_78k0r();
}
static int t78k0r_uart1_has_available(void) {
return tool78_hw_has_available_help(&vars);
}
static int t78k0r_uart1_recv(int len, uint8_t* data, int32_t timeout_us) {
return tool78_hw_help_recv(&vars, len, data, timeout_us);
}
static int t78k0r_uart1_send(int len, const uint8_t* data, int32_t timeout_us) {
return tool78_hw_help_send(&vars, 10/*inter-byte delay (us) */,
len, data, timeout_us);
}
struct tool78_hw tool78_hw_78k0r_uart1 = {
.target = tool78rl_uart1,
.init = t78k0r_uart1_init,
.deinit = t78k0r_uart1_deinit,
.has_available = t78k0r_uart1_has_available,
.recv = t78k0r_uart1_recv,
.send = t78k0r_uart1_send
};

View File

@ -118,7 +118,8 @@ int tool78_hw_help_recv(const struct tool78_pio_vars* vars,
// TODO: sleep a bit? idk
}
data[i] = bitswap(*(volatile uint8_t*)&PINOUT_TOOL78_PIO->rxf[vars->smrx]);
data[i] = *(volatile uint8_t*)&PINOUT_TOOL78_PIO->rxf[vars->smrx];
if (vars->bitswap) data[i] = bitswap(data[i]);
}
end:
@ -143,9 +144,12 @@ int tool78_hw_help_send(const struct tool78_pio_vars* vars, uint32_t sleep_us_be
if (!blockinf && ct(&ts)) goto end; // whoops, timeout
}
*(volatile uint8_t*)&PINOUT_TOOL78_PIO->txf[vars->smtx] = bitswap(data[i]);
*(volatile uint8_t*)&PINOUT_TOOL78_PIO->txf[vars->smtx] =
vars->bitswap ? bitswap(data[i]) : data[i];
// FIXME: THIS IS NOT HOW TO WAIT BETWEEN TWO BYTES YOU DOOFUS
// (ok maybe it might work because of bad reasons, so let's fix this
// once it causes problems)
if (sleep_us_between_bytes) busy_wait_us_32(sleep_us_between_bytes);
}
@ -230,3 +234,86 @@ void tool78_deinit_78k0(void) {
gpio_set_function(PINOUT_TOOL78_nRESET, GPIO_FUNC_NULL);
}
void tool78_entryseq_78k0r(enum tool78_entry typ) {
gpio_pull_up(PINOUT_TOOL78_78K0R_TOOL0);
gpio_set_function(PINOUT_TOOL78_78K0R_TOOL0, GPIO_FUNC_NULL);
gpio_put_masked((1u<<PINOUT_TOOL78_nRESET) | (1u<<PINOUT_TOOL78_78K0R_FLMD0), 0u);
gpio_set_dir_out_masked((1u<<PINOUT_TOOL78_nRESET) | (1u<<PINOUT_TOOL78_78K0R_FLMD0));
gpio_set_function(PINOUT_TOOL78_nRESET , GPIO_FUNC_SIO);
gpio_set_function(PINOUT_TOOL78_78K0R_FLMD0, GPIO_FUNC_SIO);
busy_wait_us_32(50); // tDP
gpio_put(PINOUT_TOOL78_78K0R_FLMD0, true);
busy_wait_ms(3); // tPR
gpio_put(PINOUT_TOOL78_nRESET, true);
busy_wait_ms(2); // tR0/2
for (int i = 0; i < (int)typ; ++i) {
gpio_put(PINOUT_TOOL78_78K0R_FLMD0, false);
busy_wait_us_32(12); // TODO
gpio_put(PINOUT_TOOL78_78K0R_FLMD0, true);
busy_wait_us_32(12); // TODO
}
busy_wait_ms(2); // tR0/2
}
void tool78_deinit_78k0r(void) {
gpio_put(PINOUT_TOOL78_nRESET, false);
// start deiniting stuff
gpio_disable_pulls(PINOUT_TOOL78_78K0R_TOOL0);
gpio_disable_pulls(PINOUT_TOOL78_78K0R_FLMD0);
gpio_set_function(PINOUT_TOOL78_78K0R_TOOL0, GPIO_FUNC_NULL);
gpio_set_function(PINOUT_TOOL78_78K0R_FLMD0, GPIO_FUNC_NULL);
busy_wait_us(500); // TODO
gpio_pull_down(PINOUT_TOOL78_nRESET);
gpio_set_function(PINOUT_TOOL78_nRESET, GPIO_FUNC_NULL);
}
void tool78_entryseq_rl78(enum tool78_entry typ) {
(void)typ;
gpio_pull_up(PINOUT_TOOL78_RL78_TX);
gpio_pull_up(PINOUT_TOOL78_RL78_RX);
gpio_set_function(PINOUT_TOOL78_RL78_TX, GPIO_FUNC_NULL);
gpio_set_function(PINOUT_TOOL78_RL78_RX, GPIO_FUNC_NULL);
gpio_put_masked((1u<<PINOUT_TOOL78_nRESET) | (1u<<PINOUT_TOOL78_RL78_TOOL0), 0u);
gpio_set_dir_out_masked((1u<<PINOUT_TOOL78_nRESET) | (1u<<PINOUT_TOOL78_RL78_TOOL0));
gpio_set_function(PINOUT_TOOL78_nRESET , GPIO_FUNC_SIO);
gpio_set_function(PINOUT_TOOL78_RL78_TOOL0, GPIO_FUNC_SIO);
busy_wait_us_32(500); // tSU
gpio_put(PINOUT_TOOL78_nRESET, true);
busy_wait_us_32(500); // 750us + tHD
gpio_put(PINOUT_TOOL78_RL78_TOOL0, true);
busy_wait_us_32(20); // tTM
}
void tool78_deinit_rl78(void) {
gpio_put(PINOUT_TOOL78_nRESET, false);
// start deiniting stuff
gpio_disable_pulls(PINOUT_TOOL78_RL78_TX );
gpio_disable_pulls(PINOUT_TOOL78_RL78_RX );
gpio_disable_pulls(PINOUT_TOOL78_RL78_TOOL0);
gpio_set_function(PINOUT_TOOL78_RL78_TX , GPIO_FUNC_NULL);
gpio_set_function(PINOUT_TOOL78_RL78_RX , GPIO_FUNC_NULL);
gpio_set_function(PINOUT_TOOL78_RL78_TOOL0, GPIO_FUNC_NULL);
busy_wait_us(500); // unknown?
gpio_pull_down(PINOUT_TOOL78_nRESET);
gpio_set_function(PINOUT_TOOL78_nRESET, GPIO_FUNC_NULL);
}

View File

@ -12,7 +12,7 @@ struct tool78_pio_vars {
int smtx, smrx;
// temporarily disable rx when doing tx (typically desired when doing
// single-wire UART, as otherwise the data would be echoing back)
bool exclusive;
bool exclusive, bitswap;
};
// claims and inits program space & state machines, saves the offsets & SMs
@ -39,6 +39,12 @@ void tool78_entryseq_78k0(enum tool78_entry typ);
// pulls nRESET low & puts other stuff in hi-Z
void tool78_deinit_78k0(void);
void tool78_entryseq_78k0r(enum tool78_entry typ);
void tool78_deinit_78k0r(void);
void tool78_entryseq_rl78(enum tool78_entry typ);
void tool78_deinit_rl78(void);
#endif

View File

@ -0,0 +1,73 @@
#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;
static int trl78_uart1_send(int len, const uint8_t* data, int32_t timeout_us);
static bool trl78_uart1_init(void) {
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars)) return false;
vars.exclusive = true;
vars.bitswap = true;
tool78_entryseq_rl78(tool78_entry_rl78_uart1);
tool78_uart_tx_program_init(PINOUT_TOOL78_PIO, vars.smtx, vars.txoff,
PINOUT_TOOL78_RL78_TOOL0, 115200, true);
tool78_uart_rx_program_init(PINOUT_TOOL78_PIO, vars.smrx, vars.rxoff,
PINOUT_TOOL78_RL78_TOOL0, 115200, true);
uint8_t byte = (uint8_t)tool78_entry_rl78_uart1;
trl78_uart1_send(1, &byte, -1);
busy_wait_us_32(70); // tMB
// now a baudrate set 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 trl78_uart1_deinit(void) {
tool78_hw_deinit_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars);
tool78_deinit_rl78();
}
static int trl78_uart1_has_available(void) {
return tool78_hw_has_available_help(&vars);
}
static int trl78_uart1_recv(int len, uint8_t* data, int32_t timeout_us) {
return tool78_hw_help_recv(&vars, len, data, timeout_us);
}
static int trl78_uart1_send(int len, const uint8_t* data, int32_t timeout_us) {
// TODO: tDR changes after first baudrate set
return tool78_hw_help_send(&vars, 190/*inter-byte delay (us) tDR = 90/8M s */,
len, data, timeout_us);
}
struct tool78_hw tool78_hw_rl78_uart1 = {
.target = tool78rl_uart1,
.init = trl78_uart1_init,
.deinit = trl78_uart1_deinit,
.has_available = trl78_uart1_has_available,
.recv = trl78_uart1_recv,
.send = trl78_uart1_send
};

View File

@ -0,0 +1,79 @@
#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;
static int trl78_uart2_send(int len, const uint8_t* data, int32_t timeout_us);
static bool trl78_uart2_init(void) {
if (!tool78_hw_init_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars)) return false;
vars.exclusive = false;
vars.bitswap = true;
tool78_entryseq_rl78(tool78_entry_rl78_uart2);
// init TX first on TOOL0 for stuff
tool78_uart_tx_program_init(PINOUT_TOOL78_PIO, vars.smtx, vars.txoff,
PINOUT_TOOL78_RL78_TOOL0, 115200, true);
uint8_t byte = (uint8_t)tool78_entry_rl78_uart2;
trl78_uart2_send(1, &byte, -1);
busy_wait_us_32(70); // tMB
// now init the real UART lines
tool78_uart_tx_program_init(PINOUT_TOOL78_PIO, vars.smtx, vars.txoff,
PINOUT_TOOL78_RL78_TX, 115200, true);
tool78_uart_rx_program_init(PINOUT_TOOL78_PIO, vars.smrx, vars.rxoff,
PINOUT_TOOL78_RL78_RX, 115200, true);
gpio_set_function(PINOUT_TOOL78_RL78_TOOL0, GPIO_FUNC_SIO);
// now a baudrate set 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 trl78_uart2_deinit(void) {
tool78_hw_deinit_help(&tool78_uart_tx_program, &tool78_uart_rx_program,
&vars);
tool78_deinit_rl78();
}
static int trl78_uart2_has_available(void) {
return tool78_hw_has_available_help(&vars);
}
static int trl78_uart2_recv(int len, uint8_t* data, int32_t timeout_us) {
return tool78_hw_help_recv(&vars, len, data, timeout_us);
}
static int trl78_uart2_send(int len, const uint8_t* data, int32_t timeout_us) {
// TODO: tDR changes after first baudrate set
return tool78_hw_help_send(&vars, 190/*inter-byte delay (us) tDR = 90/8M s */,
len, data, timeout_us);
}
struct tool78_hw tool78_hw_rl78_uart2 = {
.target = tool78rl_uart2,
.init = trl78_uart2_init,
.deinit = trl78_uart2_deinit,
.has_available = trl78_uart2_has_available,
.recv = trl78_uart2_recv,
.send = trl78_uart2_send
};

View File

@ -20,6 +20,7 @@ static bool test_init(void) {
&vars)) return false;
vars.exclusive = false;
vars.bitswap = true;
// TODO: entry sequence here