78k0 spi mode
This commit is contained in:
parent
0987d432f2
commit
42e447f3a8
|
@ -37,6 +37,7 @@ 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_spi.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
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
#include <hardware/gpio.h>
|
||||
#include <hardware/pio.h>
|
||||
#include <pico/time.h>
|
||||
#include <pico/timeout_helper.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 t78k0_spi_xfer(int len, const uint8_t* out, uint8_t* in,
|
||||
int32_t timeout_us) {
|
||||
if (!out && !in) return 0;
|
||||
|
||||
const uint32_t tdr = 12;/*inter-byte delay (us) tDR = 90/8M s */
|
||||
|
||||
bool blockinf = timeout_us < 0;
|
||||
absolute_time_t at = make_timeout_time_us(timeout_us);
|
||||
timeout_state_t ts = {0};
|
||||
check_timeout_fn ct = NULL;
|
||||
if (!blockinf) ct = init_single_timeout_until(&ts, at);
|
||||
|
||||
int i = 0;
|
||||
for (; i < len; ++i) {
|
||||
while (pio_sm_is_tx_fifo_full(PINOUT_TOOL78_PIO, vars.smrx)) {
|
||||
if (!blockinf && ct(&ts)) goto end; // whoops, timeout
|
||||
}
|
||||
|
||||
*(volatile uint8_t*)&PINOUT_TOOL78_PIO->txf[vars.smrx] =
|
||||
out ? out[i] : 0xff;
|
||||
|
||||
while (pio_sm_is_rx_fifo_empty(PINOUT_TOOL78_PIO, vars.smrx)) {
|
||||
if (!blockinf && ct(&ts)) goto end; // whoops, timeout
|
||||
}
|
||||
|
||||
uint8_t v = *(volatile uint8_t*)&PINOUT_TOOL78_PIO->rxf[vars.smrx];
|
||||
if (in) in[i] = v;
|
||||
|
||||
// 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 (tdr) busy_wait_us_32(tdr);
|
||||
}
|
||||
|
||||
end:
|
||||
return i;
|
||||
}
|
||||
|
||||
static bool t78k0_spi_init(void) {
|
||||
if (!tool78_hw_init_help(NULL, &tool78_spi_program, &vars)) return false;
|
||||
|
||||
vars.exclusive = false;
|
||||
vars.bitswap = false;
|
||||
|
||||
// extclk between 2 and 20 MHz
|
||||
tool78_entryseq_78k0(tool78k0_spi);
|
||||
|
||||
tool78_spi_program_init(PINOUT_TOOL78_PIO, vars.smrx, vars.rxoff,
|
||||
PINOUT_TOOL78_78K0_CLOCK, PINOUT_TOOL78_78K0_TXMOSI,
|
||||
PINOUT_TOOL78_78K0_RXMISO, 1*1000*1000, true);
|
||||
|
||||
busy_wait_us_32(477768); // tCOM or tR1
|
||||
|
||||
// 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_spi_deinit(void) {
|
||||
tool78_hw_deinit_help(&tool78_spi_program, NULL, &vars);
|
||||
|
||||
tool78_deinit_78k0();
|
||||
}
|
||||
|
||||
static int t78k0_spi_has_available(void) {
|
||||
int r = 1;
|
||||
|
||||
if (tool78_hw_help_check_overrun(&vars)) r = -r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static int t78k0_spi_recv(int len, uint8_t* data, int32_t timeout_us) {
|
||||
return t78k0_spi_xfer(len, NULL, data, timeout_us);
|
||||
}
|
||||
static int t78k0_spi_send(int len, const uint8_t* data, int32_t timeout_us) {
|
||||
return t78k0_spi_xfer(len, data, NULL, timeout_us);
|
||||
}
|
||||
|
||||
struct tool78_hw tool78_hw_78k0_spi = {
|
||||
.target = tool78k0_spi,
|
||||
|
||||
.init = t78k0_spi_init,
|
||||
.deinit = t78k0_spi_deinit,
|
||||
|
||||
.has_available = t78k0_spi_has_available,
|
||||
|
||||
.recv = t78k0_spi_recv,
|
||||
.send = t78k0_spi_send
|
||||
};
|
||||
|
Loading…
Reference in New Issue