156 lines
5.6 KiB
C

/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
* Copyright (C) 2018 Uwe Bonnes (non@elektron.ikp.physik.tu-darmstadt.de)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FTDI_BMP_H
#define __FTDI_BMP_H
#include "cl_utils.h"
#include "jtagtap.h"
#include "bmp_hosted.h"
typedef struct data_desc_s {
int16_t data_low;
int16_t ddr_low;
int16_t data_high;
int16_t ddr_high;
}data_desc_t;
typedef struct pin_settings_s {
uint8_t set_data_low;
uint8_t clr_data_low;
uint8_t set_data_high;
uint8_t clr_data_high;
}pin_settings_t;
typedef struct cable_desc_s {
int vendor;
int product;
int interface;
/* Initial (C|D)(Bus|Ddr) values for additional pins.
* MPSSE_CS|DI|DO|SK are initialized accordig to mode.*/
data_desc_t init;
/* MPSSE command to read TMS/SWDIO in bitbanging SWD.
* In many cases this is the TMS port, so then use "GET_PIN_LOW".*/
uint8_t bb_swdio_in_port_cmd;
/* bus bit to read TMS/SWDIO in bitbanging SWD.
* In many cases this is the TMS port, so then use "MPSSE_CS".*/
uint8_t bb_swdio_in_pin;
/* Bus data to allow bitbanging switched SWD read.
* TMS is routed to bb_swdio_in_port/pin.*/
pin_settings_t bb_swd_read;
/* Bus data to allow bitbanging switched SWD write.
* TMS is routed to MPSSE_CS.*/
pin_settings_t bb_swd_write;
/* dbus_data, dbus_ddr, cbus_data, cbus_ddr value to assert SRST.
* E.g. with CBUS Pin 1 low,
* give data_high = ~PIN1, ddr_high = PIN1 */
data_desc_t assert_srst;
/* Bus_data, dbus_ddr, cbus_data, cbus_ddr value to release SRST.
* E.g. with CBUS Pin 1 floating with internal pull up,
* give data_high = PIN1, ddr_high = ~PIN1 */
data_desc_t deassert_srst;
/* Command to read back SRST. If 0, port from assert_srst is used*/
uint8_t srst_get_port_cmd;
/* PIN to read back as SRST. if 0 port from assert_srst is ised.
* Use PINX if active high, use Complement (~PINX) if active low*/
uint8_t srst_get_pin;
/* Bbus data for pure MPSSE SWD read.
* Use together with swd_write if by some bits on DBUS,
* SWDIO can be routed to TDI and TDO.
* If both mpsse_swd_read|write and
* bitbang_swd_dbus_read_data/bitbang_tms_in_port_cmd/bitbang_tms_in_pin
* are provided, pure MPSSE SWD is choosen.
* If neither a complete set of swd_read|write or
* bitbang_swd_dbus_read_data/bitbang_tms_in_port_cmd/bitbang_tms_in_pin
* are provided, SWD can not be done.
* swd_read.set_data_low == swd_write.set_data_low == MPSSE_DO
* indicated resistor SWD and inhibits Jtag.*/
pin_settings_t mpsse_swd_read;
/* dbus data for pure MPSSE SWD write.*/
pin_settings_t mpsse_swd_write;
/* dbus data for jtag.*/
pin_settings_t jtag;
/* Command to read port to check target voltage.*/
uint8_t target_voltage_cmd;
/* Pin to check target voltage.*/
uint8_t target_voltage_pin;
/* USB readable description of the device.*/
char *description;
/* Command line argument to -c option to select this device.*/
char * name;
}cable_desc_t;
#if HOSTED_BMP_ONLY == 1
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter"
int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) {return -1;};
int libftdi_swdptap_init(ADIv5_DP_t *dp) {return -1;};
int libftdi_jtagtap_init(jtag_proc_t *jtag_proc) {return 0;};
void libftdi_buffer_flush(void) {};
int libftdi_buffer_write(const uint8_t *data, int size) {return size;};
int libftdi_buffer_read(uint8_t *data, int size) {return size;};
const char *libftdi_target_voltage(void) {return "ERROR";};
void libftdi_jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks) {};
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd) {return false;};
void libftdi_max_frequency_set(uint32_t freq) {};
uint32_t libftdi_max_frequency_get(void) {return 0;};
void libftdi_srst_set_val(bool assert){};
bool libftdi_srst_get_val(void) { return false;};
# pragma GCC diagnostic pop
#else
#include <ftdi.h>
extern cable_desc_t cable_desc[];
extern cable_desc_t *active_cable;
extern struct ftdi_context *ftdic;
extern data_desc_t active_state;
int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info);
int libftdi_swdptap_init(ADIv5_DP_t *dp);
int libftdi_jtagtap_init(jtag_proc_t *jtag_proc);
void libftdi_buffer_flush(void);
int libftdi_buffer_write(const uint8_t *data, int size);
int libftdi_buffer_read(uint8_t *data, int size);
const char *libftdi_target_voltage(void);
void libftdi_jtagtap_tdi_tdo_seq(
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks);
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd);
void libftdi_max_frequency_set(uint32_t freq);
uint32_t libftdi_max_frequency_get(void);
void libftdi_srst_set_val(bool assert);
bool libftdi_srst_get_val(void);
#endif
#define MPSSE_SK 1
#define PIN0 1
#define MPSSE_DO 2
#define PIN1 2
#define MPSSE_DI 4
#define PIN2 4
#define MPSSE_CS 8
#define PIN3 8
#define PIN4 0x10
#define PIN5 0x20
#define PIN6 0x40
#define PIN7 0x80
#endif