diff --git a/CMakeLists.txt b/CMakeLists.txt index 1383f3f..b623d5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,8 @@ target_sources(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/m_jscan/jscan.c ${CMAKE_CURRENT_SOURCE_DIR}/src/m_sump/_sump.c ${CMAKE_CURRENT_SOURCE_DIR}/src/m_sump/cdc_sump.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/m_ftdi/_ftdi.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/m_ftdi/ftdi.c ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_default/cdc_uart.c ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_default/dap_jtag.c ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_default/dap_swd.c @@ -94,6 +96,14 @@ target_sources(${PROJECT} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_default/tempsensor.c ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_jscan/jscan_hw.c ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_sump/sump_hw.c + ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_ftdi/base.c + ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_ftdi/uart.c + ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_ftdi/mpsse.c + ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_ftdi/asyncbb.c + ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_ftdi/syncbb.c + ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_ftdi/mcuhost.c + ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_ftdi/fifo.c + ${CMAKE_CURRENT_SOURCE_DIR}/bsp/${FAMILY}/m_ftdi/cpufifo.c ) if(USE_USBCDC_FOR_STDIO) target_compile_definitions(${PROJECT} PUBLIC USE_USBCDC_FOR_STDIO=1) diff --git a/bsp/rp2040/m_ftdi/asyncbb.c b/bsp/rp2040/m_ftdi/asyncbb.c new file mode 100644 index 0000000..826bdcd --- /dev/null +++ b/bsp/rp2040/m_ftdi/asyncbb.c @@ -0,0 +1,22 @@ +// vim: set et: + +#include "m_ftdi/ftdi.h" + +void ftdi_if_asyncbb_init(struct ftdi_interface* itf) { + +} +void ftdi_if_asyncbb_deinit(struct ftdi_interface* itf) { + +} +void ftdi_if_asyncbb_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate) { + +} + +void ftdi_if_asyncbb_write(struct ftdi_interface* itf, const uint8_t* data, size_t datasize) { + +} +size_t ftdi_if_asyncbb_read(struct ftdi_interface* itf, uint8_t* data, size_t maxsize) { + return 0; +} + + diff --git a/bsp/rp2040/m_ftdi/base.c b/bsp/rp2040/m_ftdi/base.c new file mode 100644 index 0000000..ee9f0b2 --- /dev/null +++ b/bsp/rp2040/m_ftdi/base.c @@ -0,0 +1,78 @@ +// vim: set et: + +#include "m_ftdi/ftdi.h" + +static void init_mode(struct ftdi_interface* itf, enum ftdi_mode mode) { + switch (mode) { + case ftmode_uart: ftdi_if_uart_init(itf); ftdi_if_uart_set_baudrate(itf, itf->baudrate); break; + case ftmode_mpsse: ftdi_if_mpsse_init(itf); ftdi_if_mpsse_set_baudrate(itf, itf->baudrate); break; + case ftmode_asyncbb: ftdi_if_asyncbb_init(itf); ftdi_if_asyncbb_set_baudrate(itf, itf->baudrate); break; + case ftmode_syncbb: ftdi_if_syncbb_init(itf); ftdi_if_syncbb_set_baudrate(itf, itf->baudrate); break; + case ftmode_mcuhost: ftdi_if_mcuhost_init(itf); ftdi_if_mcuhost_set_baudrate(itf, itf->baudrate); break; + case ftmode_fifo: ftdi_if_fifo_init(itf); ftdi_if_fifo_set_baudrate(itf, itf->baudrate); break; + case ftmode_cpufifo: ftdi_if_cpufifo_init(itf); ftdi_if_cpufifo_set_baudrate(itf, itf->baudrate); break; + default: break; + } +} +static void deinit_mode(struct ftdi_interface* itf, enum ftdi_mode mode) { + switch (mode) { + case ftmode_uart: ftdi_if_uart_deinit(itf); break; + case ftmode_mpsse: ftdi_if_mpsse_deinit(itf); break; + case ftmode_asyncbb: ftdi_if_asyncbb_deinit(itf); break; + case ftmode_syncbb: ftdi_if_syncbb_deinit(itf); break; + case ftmode_mcuhost: ftdi_if_mcuhost_deinit(itf); break; + case ftmode_fifo: ftdi_if_fifo_deinit(itf); break; + case ftmode_cpufifo: ftdi_if_cpufifo_deinit(itf); break; + default: break; + } +} + +void ftdi_if_init(struct ftdi_interface* itf) { + init_mode(itf, ftdi_if_get_mode(itf)); +} +void ftdi_if_deinit(struct ftdi_interface* itf) { + deinit_mode(itf, ftdi_if_get_mode(itf)); +} + +void ftdi_if_set_modemctrl(struct ftdi_interface* itf, uint8_t mask, uint8_t data) { + // TODO: what's this? +} +void ftdi_if_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate) { + switch (ftdi_if_get_mode(itf)) { + case ftmode_uart: ftdi_if_uart_set_baudrate(itf, baudrate); break; + case ftmode_mpsse: ftdi_if_mpsse_set_baudrate(itf, baudrate); break; + case ftmode_asyncbb: ftdi_if_asyncbb_set_baudrate(itf, baudrate); break; + case ftmode_syncbb: ftdi_if_syncbb_set_baudrate(itf, baudrate); break; + case ftmode_mcuhost: ftdi_if_mcuhost_set_baudrate(itf, baudrate); break; + case ftmode_fifo: ftdi_if_fifo_set_baudrate(itf, baudrate); break; + case ftmode_cpufifo: ftdi_if_cpufifo_set_baudrate(itf, baudrate); break; + default: break; + } +} +enum ftdi_sio_modemstat ftdi_if_poll_modemstat(struct ftdi_interface* itf) { + return sio_modem_cts | sio_modem_dts; // TODO: use this to read part of UART flow ctrl? +} +void ftdi_if_set_eventchar(struct ftdi_interface* itf, bool enable, uint8_t evchar) { + // TODO: when is this used? bitmode0-only? also ftd2xx headers make this look like its not just an "event on char" thing +} +void ftdi_if_set_errorchar(struct ftdi_interface* itf, bool enable, uint8_t erchar) { + // TODO: when is this used? bitmode0-only? also ftd2xx headers make this look like its not just an "error on char" thing +} +uint8_t ftdi_if_read_pins(struct ftdi_interface* itf) { + return 0; // TODO: which pins does this return? +} + +void ftdi_if_set_bitbang(struct ftdi_interface* itf, uint8_t dirmask, + enum ftdi_sio_bitmode bitmode, uint8_t olddir, enum ftdi_sio_bitmode oldmode) { + if (bitmode == oldmode && dirmask == olddir) return; // nothing to do + + deinit_mode(itf, ftdi_get_mode_of(oldmode, itf->index ? FTDI_EEP_IFB_MODE : FTDI_EEP_IFA_MODE)); + init_mode(itf, ftdi_if_get_mode(itf)); +} + +void ftdi_if_sio_reset(struct ftdi_interface* itf) { /* TODO: ? */ } +void ftdi_if_sio_tciflush(struct ftdi_interface* itf) { /* TODO: ? */ } +void ftdi_if_sio_tcoflush(struct ftdi_interface* itf) { /* TODO: ? */ } +void ftdi_if_set_latency(struct ftdi_interface* itf, uint8_t latency) { /* TODO: ? */ } +uint8_t ftdi_if_get_latency(struct ftdi_interface* itf) { return itf->latency; /* TODO: ? */ } + diff --git a/bsp/rp2040/m_ftdi/cpufifo.c b/bsp/rp2040/m_ftdi/cpufifo.c new file mode 100644 index 0000000..ffa49ce --- /dev/null +++ b/bsp/rp2040/m_ftdi/cpufifo.c @@ -0,0 +1,21 @@ +// vim: set et: + +#include "m_ftdi/ftdi.h" + +void ftdi_if_cpufifo_init(struct ftdi_interface* itf) { + +} +void ftdi_if_cpufifo_deinit(struct ftdi_interface* itf) { + +} +void ftdi_if_cpufifo_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate) { + +} + +void ftdi_if_cpufifo_write(struct ftdi_interface* itf, const uint8_t* data, size_t datasize) { + +} +size_t ftdi_if_cpufifo_read(struct ftdi_interface* itf, uint8_t* data, size_t maxsize) { + return 0; +} + diff --git a/bsp/rp2040/m_ftdi/fifo.c b/bsp/rp2040/m_ftdi/fifo.c new file mode 100644 index 0000000..a280123 --- /dev/null +++ b/bsp/rp2040/m_ftdi/fifo.c @@ -0,0 +1,21 @@ +// vim: set et: + +#include "m_ftdi/ftdi.h" + +void ftdi_if_fifo_init(struct ftdi_interface* itf) { + +} +void ftdi_if_fifo_deinit(struct ftdi_interface* itf) { + +} +void ftdi_if_fifo_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate) { + +} + +void ftdi_if_fifo_write(struct ftdi_interface* itf, const uint8_t* data, size_t datasize) { + +} +size_t ftdi_if_fifo_read(struct ftdi_interface* itf, uint8_t* data, size_t maxsize) { + return 0; +} + diff --git a/bsp/rp2040/m_ftdi/mcuhost.c b/bsp/rp2040/m_ftdi/mcuhost.c new file mode 100644 index 0000000..f954aff --- /dev/null +++ b/bsp/rp2040/m_ftdi/mcuhost.c @@ -0,0 +1,34 @@ +// vim: set et: + +#include "m_ftdi/ftdi.h" + +void ftdi_if_mcuhost_init(struct ftdi_interface* itf) { + +} +void ftdi_if_mcuhost_deinit(struct ftdi_interface* itf) { + +} +void ftdi_if_mcuhost_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate) { + +} + +void ftdi_if_mcuhost_flush(struct ftdi_interface* itf) { + +} +void ftdi_if_mcuhost_wait_io(struct ftdi_interface* itf, bool level) { + +} + +uint8_t ftdi_if_mcuhost_read8(struct ftdi_interface* itf, uint8_t addr) { + return 0; +} +uint8_t ftdi_if_mcuhost_read16(struct ftdi_interface* itf, uint16_t addr) { + return 0; +} +void ftdi_if_mcuhost_write8(struct ftdi_interface* itf, uint8_t addr, uint8_t value) { + +} +void ftdi_if_mcuhost_write16(struct ftdi_interface* itf, uint16_t addr, uint8_t value) { + +} + diff --git a/bsp/rp2040/m_ftdi/mpsse.c b/bsp/rp2040/m_ftdi/mpsse.c new file mode 100644 index 0000000..134c4a9 --- /dev/null +++ b/bsp/rp2040/m_ftdi/mpsse.c @@ -0,0 +1,74 @@ +// vim: set et: + +#include "m_ftdi/ftdi.h" + +void ftdi_if_mpsse_init(struct ftdi_interface* itf) { + +} +void ftdi_if_mpsse_deinit(struct ftdi_interface* itf) { + +} +void ftdi_if_mpsse_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate) { + +} + + +void ftdi_if_mpsse_flush(struct ftdi_interface* itf) { + +} +void ftdi_if_mpsse_wait_io(struct ftdi_interface* itf, bool level) { + +} + +void ftdi_if_mpsse_set_dirval_lo(struct ftdi_interface* itf, uint8_t dir, uint8_t val) { + +} +void ftdi_if_mpsse_set_dirval_hi(struct ftdi_interface* itf, uint8_t dir, uint8_t val) { + +} +uint8_t ftdi_if_mpsse_read_lo(struct ftdi_interface* itf) { + return 0; +} +uint8_t ftdi_if_mpsse_read_hi(struct ftdi_interface* itf) { + return 0; +} +void ftdi_if_mpsse_loopback(struct ftdi_interface* itf, bool enable) { + +} +void ftdi_if_mpsse_set_clkdiv(struct ftdi_interface* itf, uint16_t div) { + +} + +uint8_t ftdi_if_mpsse_xfer_bits(struct ftdi_interface* itf, int flags, size_t nbits, uint8_t value) { + return 0; +} +void ftdi_if_mpsse_xfer_bytes(struct ftdi_interface* itf, int flags, size_t nbytes, uint8_t* dst, const uint8_t* src) { + +} +uint8_t ftdi_if_mpsse_tms_xfer(struct ftdi_interface* itf, int flags, size_t nbits, uint8_t value) { + return 0; +} + +void ftdi_if_mpsse_div5(struct ftdi_interface* itf, bool enable) { + +} +void ftdi_if_mpsse_data_3ph(struct ftdi_interface* itf, bool enable) { + +} +void ftdi_if_mpsse_adaptive(struct ftdi_interface* itf, bool enable) { + +} + +void ftdi_if_mpsse_clockonly(struct ftdi_interface* itf, uint32_t cycles) { + +} +void ftdi_if_mpsse_clock_wait_io(struct ftdi_interface* itf, bool level) { + +} +void ftdi_if_mpsse_clockonly_wait_io(struct ftdi_interface* itf, bool level, uint32_t cycles) { + +} +void ftdi_if_mpsse_hi_is_tristate(struct ftdi_interface* itf, uint16_t pinmask) { + +} + diff --git a/bsp/rp2040/m_ftdi/syncbb.c b/bsp/rp2040/m_ftdi/syncbb.c new file mode 100644 index 0000000..35a4d14 --- /dev/null +++ b/bsp/rp2040/m_ftdi/syncbb.c @@ -0,0 +1,22 @@ +// vim: set et: + +#include "m_ftdi/ftdi.h" + +void ftdi_if_syncbb_init(struct ftdi_interface* itf) { + +} +void ftdi_if_syncbb_deinit(struct ftdi_interface* itf) { + +} +void ftdi_if_syncbb_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate) { + +} + + +void ftdi_if_syncbb_write(struct ftdi_interface* itf, const uint8_t* data, size_t datasize) { + +} +size_t ftdi_if_syncbb_read(struct ftdi_interface* itf, uint8_t* data, size_t maxsize) { + return 0; +} + diff --git a/bsp/rp2040/m_ftdi/uart.c b/bsp/rp2040/m_ftdi/uart.c new file mode 100644 index 0000000..2ec7a2e --- /dev/null +++ b/bsp/rp2040/m_ftdi/uart.c @@ -0,0 +1,23 @@ +// vim: set et: + +#include "m_ftdi/ftdi.h" + +void ftdi_if_uart_init(struct ftdi_interface* itf); +void ftdi_if_uart_deinit(struct ftdi_interface* itf); +void ftdi_if_uart_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate); + + +void ftdi_if_set_flowctrl(struct ftdi_interface* itf, enum ftdi_flowctrl flow) { + // TODO: bluh +} +void ftdi_if_set_lineprop(struct ftdi_interface* itf, enum ftdi_sio_lineprop lineprop) { + // TODO: break, stop, parity, #bits +} + +void ftdi_if_uart_write(struct ftdi_interface* itf, const uint8_t* data, size_t datasize) { + +} +size_t ftdi_if_uart_read(struct ftdi_interface* itf, uint8_t* data, size_t maxsize) { + return 0; +} + diff --git a/src/m_ftdi/_ftdi.c b/src/m_ftdi/_ftdi.c index 0041f7d..9ed4fc7 100644 --- a/src/m_ftdi/_ftdi.c +++ b/src/m_ftdi/_ftdi.c @@ -11,7 +11,7 @@ #include "m_ftdi/ftdi.h" static bool data_dirty = false; -void ftdi_eeprom_dirty_set(bool v) { data_dirty = true; } +void ftdi_eeprom_dirty_set(bool v) { (void)v; data_dirty = true; } bool ftdi_eeprom_dirty_get(void) { return data_dirty; } #ifdef DBOARD_HAS_FTDI diff --git a/src/m_ftdi/ftdi.c b/src/m_ftdi/ftdi.c index 2afe31c..d1e9cae 100644 --- a/src/m_ftdi/ftdi.c +++ b/src/m_ftdi/ftdi.c @@ -1,7 +1,10 @@ +// vim: set et: #include "tusb_config.h" #include +#include "thread.h" + #include "m_ftdi/bsp-feature.h" #include "m_ftdi/ftdi.h" @@ -68,7 +71,7 @@ #ifdef DBOARD_HAS_FTDI -uint32_t __builtin_ctz(uint32_t v); +int __builtin_ctz(unsigned int v); uint16_t ftdi_eeprom[128]; @@ -88,8 +91,8 @@ void ftdi_init(void) { ftdi_eeprom[10] = 0x0000; // internal chip ftdi_eeprom[0x7f] = ftdi_eeprom_checksum_calc(ftdi_eeprom, 0x7f); - memset(ftdi_ifa, 0, sizeof ftdi_ifa); - memset(ftdi_ifb, 0, sizeof ftdi_ifb); + memset(&ftdi_ifa, 0, sizeof ftdi_ifa); + memset(&ftdi_ifb, 0, sizeof ftdi_ifb); ftdi_ifa.lineprop = sio_bits_8 | sio_stop_1; // 8n1 ftdi_ifb.lineprop = sio_bits_8 | sio_stop_1; // 8n1 ftdi_ifa.index = 0; @@ -98,10 +101,11 @@ void ftdi_init(void) { ftdi_if_init(&ftdi_ifb); } void ftdi_deinit(void) { - // TODO: ??? + ftdi_if_deinit(&ftdi_ifa); + ftdi_if_deinit(&ftdi_ifb); } -static uint8_t vnd_read_byte(struct ftdi_inteface* itf, int itfnum) { +static uint8_t vnd_read_byte(struct ftdi_interface* itf, int itfnum) { while (itf->rxavail <= 0) { if (!tud_vendor_n_mounted(itfnum) || !tud_vendor_n_available(itfnum)) { thread_yield(); @@ -128,14 +132,14 @@ struct ftfifo_fns { ftfifo_read_fn read ; }; static const struct ftfifo_fns fifocbs[] = { - .{ ftdi_if_uart_write, ftdi_if_uart_read }, // technically mpsse - .{ ftdi_if_asyncbb_write, ftdi_if_asyncbb_read }, - .{ ftdi_if_syncbb_write, ftdi_if_syncbb_read }, - .{ NULL, NULL }, // mcuhost - .{ ftdi_if_fifo_write, ftdi_if_fifo_read }, - .{ NULL, NULL }, // opto - .{ ftdi_if_cpufifo_write, ftdi_if_cpufifo_read }, - .{ NULL, NULL }, // ft1284 + { ftdi_if_uart_write, ftdi_if_uart_read }, // technically mpsse + { ftdi_if_asyncbb_write, ftdi_if_asyncbb_read }, + { ftdi_if_syncbb_write, ftdi_if_syncbb_read }, + { NULL, NULL }, // mcuhost + { ftdi_if_fifo_write, ftdi_if_fifo_read }, + { NULL, NULL }, // opto + { ftdi_if_cpufifo_write, ftdi_if_cpufifo_read }, + { NULL, NULL }, // ft1284 }; // for handling USB bulk commands @@ -156,11 +160,11 @@ static void ftdi_task(int itfnum) { enum ftdi_mode mode = ftdi_if_get_mode(itf); struct ftfifo_fns fifocb = fifocbs[(mode == 0) ? 0 : __builtin_ctz(mode)]; uint32_t avail; - uint8_t cmdbyte; + uint8_t cmdbyte = 0; switch (mode) { case ftmode_uart : case ftmode_fifo : case ftmode_cpufifo: case ftmode_asyncbb: case ftmode_syncbb: - if (fifocb.read == NULL || fifocb.write == NULL) goto case default; // welp + if (fifocb.read == NULL || fifocb.write == NULL) goto CASE_DEFAULT; // welp avail = tud_vendor_n_available(itfnum); if (avail) { @@ -222,8 +226,8 @@ static void ftdi_task(int itfnum) { break; case ftmpsse_clock_wait_io_hi: ftdi_if_mpsse_clock_wait_io(itf, true ); break; case ftmpsse_clock_wait_io_lo: ftdi_if_mpsse_clock_wait_io(itf, false); break; - case ftmpsse_clock_adapclk_enable : ftdi_if_mpsse_adaptive(itf, true ); break; - case ftmpsse_clock_adapclk_disable: ftdi_if_mpsse_adaptive(itf, false); break; + case ftmpsse_adapclk_enable : ftdi_if_mpsse_adaptive(itf, true ); break; + case ftmpsse_adapclk_disable: ftdi_if_mpsse_adaptive(itf, false); break; case ftmpsse_clock_bits_wait_io_hi: avail = vnd_read_byte(itf, itfnum); avail |= (uint32_t)vnd_read_byte(itf, itfnum) << 8; @@ -243,24 +247,24 @@ static void ftdi_task(int itfnum) { avail = 0; break; - default: + default: CASE_DEFAULT: if (!(cmdbyte & ftmpsse_specialcmd)) { if (cmdbyte & ftmpsse_tmswrite) { if (cmdbyte & ftmpsse_bitmode) { itf->writebuf[0] = vnd_read_byte(itf, itfnum); // number of bits itf->writebuf[1] = vnd_read_byte(itf, itfnum); // data bits to output itf->readbuf[0] = ftdi_if_mpsse_tms_xfer(itf, cmdbyte, itf->writebuf[0], itf->writebuf[1]); - if (cmdbyte & tdoread) avail = 1; + if (cmdbyte & ftmpsse_tdoread) avail = 1; break; } // else: fallthru to error code } else { - if (cmdbyte & bitmode) { + if (cmdbyte & ftmpsse_bitmode) { itf->writebuf[0] = vnd_read_byte(itf, itfnum); // number of bits if (cmdbyte & ftmpsse_tdiwrite) itf->writebuf[1] = vnd_read_byte(itf, itfnum); // data bits to output itf->readbuf[0] = ftdi_if_mpsse_xfer_bits(itf, cmdbyte, itf->writebuf[0], itf->writebuf[1]); - if (cmdbyte & tdoread) avail = 1; + if (cmdbyte & ftmpsse_tdoread) avail = 1; break; } else { avail = vnd_read_byte(itf, itfnum); @@ -292,30 +296,31 @@ static void ftdi_task(int itfnum) { case ftmode_mcuhost: avail = 0; switch ((cmdbyte = vnd_read_byte(itf, itfnum))) { - case ftmcu_flush: ftdi_if_mcu_flush(itf); break; - case ftmcu_wait_io_hi: ftdi_if_mcu_wait_io(itf, true ); break; - case ftmcu_wait_io_lo: ftdi_if_mcu_wait_io(itf, false); break; + case ftmcu_flush: ftdi_if_mcuhost_flush(itf); break; + case ftmcu_wait_io_hi: ftdi_if_mcuhost_wait_io(itf, true ); break; + case ftmcu_wait_io_lo: ftdi_if_mcuhost_wait_io(itf, false); break; case ftmcu_read8: - itf->readbuf[0] = ftdi_if_mcu_read8(itf, vnd_read_byte(itf, itfnum)); + itf->readbuf[0] = ftdi_if_mcuhost_read8(itf, vnd_read_byte(itf, itfnum)); avail = 1; break; case ftmcu_read16: avail = (uint32_t)vnd_read_byte(itf, itfnum) << 8; avail |= vnd_read_byte(itf, itfnum); - itf->readbuf[0] = ftdi_if_mcu_read16(itf, (uint16_t)avail); + itf->readbuf[0] = ftdi_if_mcuhost_read16(itf, (uint16_t)avail); avail = 1; break; case ftmcu_write8: itf->writebuf[0] = vnd_read_byte(itf, itfnum); itf->writebuf[1] = vnd_read_byte(itf, itfnum); - ftdi_if_mcu_write8(itf, itf->writebuf[0], itf->writebuf[1]); + ftdi_if_mcuhost_write8(itf, itf->writebuf[0], itf->writebuf[1]); break; case ftmcu_write16: avail = (uint32_t)vnd_read_byte(itf, itfnum) << 8; avail |= vnd_read_byte(itf, itfnum); itf->writebuf[0] = vnd_read_byte(itf, itfnum); - ftdi_if_mcu_write8(itf, addr, itf->writebuf[0]); + ftdi_if_mcuhost_write8(itf, avail, itf->writebuf[0]); + avail = 0; break; default: // send error response when command doesn't exist @@ -325,7 +330,7 @@ static void ftdi_task(int itfnum) { break; } - if (avail) tuf_vendor_n_write(itfnum, itf->readbuf, avail); + if (avail) tud_vendor_n_write(itfnum, itf->readbuf, avail); break; default: // drop incoming data so that the pipes don't get clogged. can't do much else avail = tud_vendor_n_available(itfnum); @@ -347,7 +352,7 @@ uint32_t ftdi_if_decode_baudrate(uint32_t enc_brate) { // basically reversing li else if (enc_brate == 2) return FT2232D_CLOCK >> 5; uint32_t div = (enc_brate & 0x7fff) << 3; // integer part - uint32_t div = div | ftdi_brate_frac_lut[(enc_bate >> 14) & 7]; + div = div | ftdi_brate_frac_lut[(enc_brate >> 14) & 7]; uint32_t baud = FT2232D_CLOCK / div; if (baud & 1) baud = (baud >> 1) + 1; // raunding @@ -458,11 +463,14 @@ bool ftdi_control_xfer_cb(uint8_t rhport, uint8_t stage, case sio_getlatency: control_buf[0] = ftdi_if_get_latency(itf); return tud_control_xfer(rhport, req, control_buf, 1); - case sio_setbitbang: + case sio_setbitbang: { + uint8_t olddir = itf->bb_dir; + enum ftdi_sio_bitmode oldmode = itf->bb_mode; ftdi_if_set_bitbang(itf, itf->bb_dir = (req->wValue >> 8), - itf->bb_mode = (req->wValue & 0xff)); - return tud_control_status(rhport, req); + itf->bb_mode = (req->wValue & 0xff), + olddir, oldmode); + } return tud_control_status(rhport, req); case sio_readpins: control_buf[0] = ftdi_if_read_pins(itf); return tud_control_xfer(rhport, req, control_buf, 1); diff --git a/src/m_ftdi/ftdi.h b/src/m_ftdi/ftdi.h index c48dc72..39dedbe 100644 --- a/src/m_ftdi/ftdi.h +++ b/src/m_ftdi/ftdi.h @@ -215,10 +215,10 @@ enum ftdi_mode { // combines EEPROM setting + bitmode ftmode_syncbb = 4, ftmode_mcuhost = 8, - ftmode_fifo = 0x10, - ftmode_opto = 0x20, // not implementing this here - ftmode_cpu = 0x40, - ftmode_ft1284 = 0x80, // not impl. on 2232d + ftmode_fifo = 0x10, + ftmode_opto = 0x20, // not implementing this here + ftmode_cpufifo = 0x40, + ftmode_ft1284 = 0x80, // not impl. on 2232d }; enum ftdi_flowctrl { @@ -264,17 +264,21 @@ extern struct ftdi_interface ftdi_ifa, ftdi_ifb; // interface control stuff -static inline enum ftdi_mode ftdi_if_get_mode(struct ftdi_interface* itf) { - if (itf->bb_mode == 0x10) return ftmode_opto; +static inline enum ftdi_mode ftdi_get_mode_of(enum ftdi_sio_bitmode bb_mode, uint8_t eepmode) { + if (bb_mode == 0x10) return ftmode_opto; - if (itf->bb_mode == sio_mode_reset) { + if (bb_mode == sio_mode_reset) { return (eepmode << 4) & 0xf0; - } else return itf->bb_mode & 0xf; + } else return bb_mode & 0xf; +} +static inline enum ftdi_mode ftdi_if_get_mode(struct ftdi_interface* itf) { + return ftdi_get_mode_of(itf->bb_mode, itf->index ? FTDI_EEP_IFB_MODE : FTDI_EEP_IFA_MODE); } uint32_t ftdi_if_decode_baudrate(uint32_t enc_brate); // control request stuff. implemented by bsp driver void ftdi_if_init(struct ftdi_interface* itf); +void ftdi_if_deinit(struct ftdi_interface* itf); void ftdi_if_sio_reset(struct ftdi_interface* itf); void ftdi_if_sio_tciflush(struct ftdi_interface* itf); @@ -288,7 +292,8 @@ void ftdi_if_set_eventchar(struct ftdi_interface* itf, bool enable, uint8_t evch void ftdi_if_set_errorchar(struct ftdi_interface* itf, bool enable, uint8_t erchar); void ftdi_if_set_latency(struct ftdi_interface* itf, uint8_t latency); uint8_t ftdi_if_get_latency(struct ftdi_interface* itf); -void ftdi_if_set_bitbang(struct ftdi_interface* itf, uint8_t dirmask, enum ftdi_sio_bitmode); +void ftdi_if_set_bitbang(struct ftdi_interface* itf, uint8_t dirmask, enum ftdi_sio_bitmode, + uint8_t olddir, enum ftdi_sio_bitmode oldmode); uint8_t ftdi_if_read_pins(struct ftdi_interface* itf); // bulk commands (also implemented by bsp driver) @@ -333,13 +338,37 @@ void ftdi_if_mpsse_clockonly_wait_io(struct ftdi_interface* itf, bool level, uin void ftdi_if_mpsse_hi_is_tristate(struct ftdi_interface* itf, uint16_t pinmask); -void ftdi_if_mcu_flush(struct ftdi_interface* itf); -void ftdi_if_mcu_wait_io(struct ftdi_interface* itf, bool level); +void ftdi_if_mcuhost_flush(struct ftdi_interface* itf); +void ftdi_if_mcuhost_wait_io(struct ftdi_interface* itf, bool level); -uint8_t ftdi_if_mcu_read8 (struct ftdi_interface* itf, uint8_t addr); -uint8_t ftdi_if_mcu_read16(struct ftdi_interface* itf, uint16_t addr); -void ftdi_if_mcu_write8 (struct ftdi_interface* itf, uint8_t addr, uint8_t value); -void ftdi_if_mcu_write16(struct ftdi_interface* itf, uint16_t addr, uint8_t value); +uint8_t ftdi_if_mcuhost_read8 (struct ftdi_interface* itf, uint8_t addr); +uint8_t ftdi_if_mcuhost_read16(struct ftdi_interface* itf, uint16_t addr); +void ftdi_if_mcuhost_write8 (struct ftdi_interface* itf, uint8_t addr, uint8_t value); +void ftdi_if_mcuhost_write16(struct ftdi_interface* itf, uint16_t addr, uint8_t value); + +void ftdi_if_uart_init(struct ftdi_interface* itf); +void ftdi_if_mpsse_init(struct ftdi_interface* itf); +void ftdi_if_asyncbb_init(struct ftdi_interface* itf); +void ftdi_if_syncbb_init(struct ftdi_interface* itf); +void ftdi_if_mcuhost_init(struct ftdi_interface* itf); +void ftdi_if_fifo_init(struct ftdi_interface* itf); +void ftdi_if_cpufifo_init(struct ftdi_interface* itf); + +void ftdi_if_uart_deinit(struct ftdi_interface* itf); +void ftdi_if_mpsse_deinit(struct ftdi_interface* itf); +void ftdi_if_asyncbb_deinit(struct ftdi_interface* itf); +void ftdi_if_syncbb_deinit(struct ftdi_interface* itf); +void ftdi_if_mcuhost_deinit(struct ftdi_interface* itf); +void ftdi_if_fifo_deinit(struct ftdi_interface* itf); +void ftdi_if_cpufifo_deinit(struct ftdi_interface* itf); + +void ftdi_if_uart_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate); +void ftdi_if_mpsse_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate); +void ftdi_if_asyncbb_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate); +void ftdi_if_syncbb_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate); +void ftdi_if_mcuhost_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate); +void ftdi_if_fifo_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate); +void ftdi_if_cpufifo_set_baudrate(struct ftdi_interface* itf, uint32_t baudrate); #endif