From 5bb4e23c863ac1b189bd337f1d24dab95efb1650 Mon Sep 17 00:00:00 2001 From: Matthew Mets Date: Thu, 11 Aug 2022 01:32:38 +0200 Subject: [PATCH] Add rpi pico based programmer --- iceprog/Makefile | 5 +- iceprog/iceprog.c | 8 +- iceprog/rpi_pico_interface.c | 298 +++++++++++++++++++++++++++++++++++ iceprog/rpi_pico_interface.h | 13 ++ 4 files changed, 321 insertions(+), 3 deletions(-) create mode 100644 iceprog/rpi_pico_interface.c create mode 100644 iceprog/rpi_pico_interface.h diff --git a/iceprog/Makefile b/iceprog/Makefile index 62e2078..3d2995e 100644 --- a/iceprog/Makefile +++ b/iceprog/Makefile @@ -7,11 +7,14 @@ CFLAGS += $(shell for pkg in libftdi1 libftdi; do $(PKG_CONFIG) --silence-errors else LDLIBS += $(shell for pkg in libftdi1 libftdi; do $(PKG_CONFIG) --silence-errors --libs $$pkg && exit; done; echo -lftdi; ) CFLAGS += $(shell for pkg in libftdi1 libftdi; do $(PKG_CONFIG) --silence-errors --cflags $$pkg && exit; done; ) + +CFLAGS += -lhidapi-libusb +LDLIBS += -lhidapi-libusb endif all: $(PROGRAM_PREFIX)iceprog$(EXE) -$(PROGRAM_PREFIX)iceprog$(EXE): iceprog.o mpsse.o ftdi_interface.o +$(PROGRAM_PREFIX)iceprog$(EXE): iceprog.o mpsse.o ftdi_interface.o rpi_pico_interface.o $(CC) -o $@ $(LDFLAGS) $^ $(LDLIBS) install: all diff --git a/iceprog/iceprog.c b/iceprog/iceprog.c index 292520f..e145245 100644 --- a/iceprog/iceprog.c +++ b/iceprog/iceprog.c @@ -43,6 +43,7 @@ #include "mpsse.h" #include "interface.h" #include "ftdi_interface.h" +#include "rpi_pico_interface.h" static bool verbose = false; @@ -835,8 +836,11 @@ int main(int argc, char **argv) fprintf(stderr, "init..\n"); - ftdi_interface_init(ifnum, devstr, slow_clock); - interface = &ftdi_interface; +// ftdi_interface_init(ifnum, devstr, slow_clock); +// interface = &ftdi_interface; + + rpi_pico_interface_init(); + interface = &rpi_pico_interface; fprintf(stderr, "cdone: %s\n", interface->get_cdone() ? "high" : "low"); diff --git a/iceprog/rpi_pico_interface.c b/iceprog/rpi_pico_interface.c new file mode 100644 index 0000000..880e521 --- /dev/null +++ b/iceprog/rpi_pico_interface.c @@ -0,0 +1,298 @@ +#include "rpi_pico_interface.h" +#include +#include +#include +#include + +#define VENDOR_ID 0xcafe +#define PRODUCT_ID 0x4004 + +static hid_device * handle; + +static void led_set(bool value) { + + uint8_t buf[3]; + buf[0] = 0; + buf[1] = 0x00; + buf[2] = (value ? 1:0); + +// printf("led_set ["); +// for(int i = 0; i < sizeof(buf); i++) { +// printf("%02x, ", buf[i]); +// } +// printf("]\n"); + + hid_write(handle, buf, sizeof(buf)); +} + +static void pin_set_direction(uint8_t pin, bool direction) { + const uint32_t mask = (1<> 24) & 0xff; + buf[3] = (mask >> 16) & 0xff; + buf[4] = (mask >> 8) & 0xff; + buf[5] = (mask >> 0) & 0xff; + buf[6] = (val >> 24) & 0xff; + buf[7] = (val >> 16) & 0xff; + buf[8] = (val >> 8) & 0xff; + buf[9] = (val >> 0) & 0xff; + +// printf("pin_set_direction ["); +// for(int i = 0; i < sizeof(buf); i++) { +// printf("%02x, ", buf[i]); +// } +// printf("]\n"); + + hid_write(handle, buf, sizeof(buf)); +} + +static void pinmask_write(uint32_t mask, uint32_t val) { + uint8_t buf[10]; + buf[0] = 0; + buf[1] = 0x20; + buf[2] = (mask >> 24) & 0xff; + buf[3] = (mask >> 16) & 0xff; + buf[4] = (mask >> 8) & 0xff; + buf[5] = (mask >> 0) & 0xff; + buf[6] = (val >> 24) & 0xff; + buf[7] = (val >> 16) & 0xff; + buf[8] = (val >> 8) & 0xff; + buf[9] = (val >> 0) & 0xff; + +// printf("pin_write ["); +// for(int i = 0; i < sizeof(buf); i++) { +// printf("%02x, ", buf[i]); +// } +// printf("]\n"); + + hid_write(handle, buf, sizeof(buf)); + +} + +static void pin_write(uint8_t pin, bool value) { + const uint32_t mask = (1< MAX_BYTES_PER_TRANSFER) { + printf("bit count too high\n"); + exit(1); + } + +// printf("bitbang_spi byte_count:%i bit_count:%i\n", byte_count, bit_count); + + uint8_t buf[9+MAX_BYTES_PER_TRANSFER]; + memset(buf, 0xFF, sizeof(buf)); + + buf[0] = 0; + buf[1] = 0x40; + buf[2] = sck_pin; + buf[3] = mosi_pin; + buf[4] = miso_pin; + buf[5] = (bit_count >> 24) & 0xff; + buf[6] = (bit_count >> 16) & 0xff; + buf[7] = (bit_count >> 8) & 0xff; + buf[8] = (bit_count >> 0) & 0xff; + + + memcpy(&buf[9], buffer, byte_count); // TODO: memory length + +// printf(" send:["); +// for(int i = 0; i < (8+byte_count); i++) { +// printf("%02x, ", buf[i]); +// } +// printf("]\n"); + + uint8_t ret_buf[64]; + + hid_write(handle, buf, sizeof(buf)); + + const int bytes_read = hid_read_timeout(handle, ret_buf, 64, 4000); + if(bytes_read != 64) { + printf("error reading, got:%i\n", bytes_read); + exit(1); + } + +// printf(" receive:["); +// for(int i = 0; i < (5+byte_count); i++) { +// printf("%02x, ", ret_buf[i]); +// } +// printf("]\n"); + memcpy(buffer, &ret_buf[5], byte_count); +} + +#define PIN_POWER 7 +#define PIN_SCK 10 +#define PIN_MOSI 13 +#define PIN_SS 12 +#define PIN_MISO 11 +#define PIN_CRESET 14 +#define PIN_CDONE 15 + +// ********* iceprog API **************** + +// TODO +static void close() { +// pin_write(PIN_POWER, false); + led_set(false); + printf("closing\n"); + + hid_close(handle); + handle = NULL; +} + +// TODO +static void error(int status) { + close(); + exit(status); +} + +// TODO +static void set_cs_creset(int cs_b, int creset_b) { + pinmask_write( + (1<0?1:0)<0?1:0)< MAX_BYTES_PER_TRANSFER) { + bytes_to_transfer = MAX_BYTES_PER_TRANSFER; + } +// printf(" byte_index:%i bytes_to_transfer:%i\n", byte_index, bytes_to_transfer); + + bitbang_spi(PIN_SCK, PIN_MOSI, PIN_MISO, bytes_to_transfer*8, data+byte_index); + byte_index += bytes_to_transfer; + } +} + +// TODO +static void send_spi(uint8_t *data, int n) { + uint8_t buf[n]; + memcpy(buf,data,sizeof(buf)); + xfer_spi(buf,n); +} + +// TODO +static void send_dummy_bytes(uint8_t n) { + uint8_t buf[n]; + memset(buf, 0, sizeof(buf)); + xfer_spi(buf, sizeof(buf)); +} + + +// TODO +static void send_dummy_bit(void) { + xfer_spi_bits(0, 1); +} + + +const interface_t rpi_pico_interface = { + .close = close, + .error = error, + + .set_cs_creset = set_cs_creset, + .get_cdone = get_cdone, + + .send_spi = send_spi, + .xfer_spi = xfer_spi, + .xfer_spi_bits = xfer_spi_bits, + + .send_dummy_bytes = send_dummy_bytes, + .send_dummy_bit = send_dummy_bit, +}; + +void rpi_pico_interface_init() { + hid_init(); + + handle = hid_open( VENDOR_ID, PRODUCT_ID, NULL); + if(handle == NULL) { + printf("Failure!\n"); + + hid_exit(); + exit(-1); + } + + led_set(true); + + + pin_set_direction(PIN_POWER, true); + pin_set_direction(PIN_SCK, true); + pin_set_direction(PIN_MOSI, true); + pin_set_direction(PIN_SS, true); + pin_set_direction(PIN_MISO, false); + pin_set_direction(PIN_CRESET, true); + pin_set_direction(PIN_CDONE, false); + + pin_write(PIN_POWER, true); +} + +// ********* API **************** diff --git a/iceprog/rpi_pico_interface.h b/iceprog/rpi_pico_interface.h new file mode 100644 index 0000000..63386d6 --- /dev/null +++ b/iceprog/rpi_pico_interface.h @@ -0,0 +1,13 @@ +#ifndef RPI_PICO_INTERFACE_H +#define RPI_PICO_INTERFACE_H + +#include +#include +#include "interface.h" + + +extern const interface_t rpi_pico_interface; + +void rpi_pico_interface_init(); + +#endif