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/swim/swim_hw.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_helpers.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_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.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/tool78/tool78_hw_78k0_uart2_extclk.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_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