ftdi bsp files skeleton

This commit is contained in:
Triss 2021-09-07 03:19:14 +02:00
parent 210f74dbc5
commit 1e9cac1ace
12 changed files with 391 additions and 49 deletions

View File

@ -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)

View File

@ -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;
}

78
bsp/rp2040/m_ftdi/base.c Normal file
View File

@ -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: ? */ }

View File

@ -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;
}

21
bsp/rp2040/m_ftdi/fifo.c Normal file
View File

@ -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;
}

View File

@ -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) {
}

74
bsp/rp2040/m_ftdi/mpsse.c Normal file
View File

@ -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) {
}

View File

@ -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;
}

23
bsp/rp2040/m_ftdi/uart.c Normal file
View File

@ -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;
}

View File

@ -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

View File

@ -1,7 +1,10 @@
// vim: set et:
#include "tusb_config.h"
#include <tusb.h>
#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);

View File

@ -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