bitbang: split jtag and swd operations
The split in OpenOCD between SWD and JTAG has been already fully implemented. The bitbang driver still keeps a single API write() to drive the output lines. Introduce a new SWD specific API swd_write(). Move the existing SWD bitbang drivers to the new API by extracting the available conditional implementation. Cleanup some function prototype. Remove the now unused global swd_mode, handled implicitly. Rename bitbang_exchange() as bitbang_swd_exchange() to track its scope for SWD only. Change-Id: Ie53080b941cb1ac7a34a1f80bad8bee4e304454d Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: http://openocd.zylin.com/5555 Tested-by: jenkins
This commit is contained in:
parent
49232a80d2
commit
964680ecff
|
@ -54,6 +54,7 @@ static int bcm2835gpio_write(int tck, int tms, int tdi);
|
|||
|
||||
static int bcm2835_swdio_read(void);
|
||||
static void bcm2835_swdio_drive(bool is_output);
|
||||
static int bcm2835gpio_swd_write(int swclk, int swdio);
|
||||
|
||||
static int bcm2835gpio_init(void);
|
||||
static int bcm2835gpio_quit(void);
|
||||
|
@ -63,6 +64,7 @@ static struct bitbang_interface bcm2835gpio_bitbang = {
|
|||
.write = bcm2835gpio_write,
|
||||
.swdio_read = bcm2835_swdio_read,
|
||||
.swdio_drive = bcm2835_swdio_drive,
|
||||
.swd_write = bcm2835gpio_swd_write,
|
||||
.blink = NULL
|
||||
};
|
||||
|
||||
|
@ -108,10 +110,10 @@ static int bcm2835gpio_write(int tck, int tms, int tdi)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int bcm2835gpio_swd_write(int tck, int tms, int tdi)
|
||||
static int bcm2835gpio_swd_write(int swclk, int swdio)
|
||||
{
|
||||
uint32_t set = tck<<swclk_gpio | tdi<<swdio_gpio;
|
||||
uint32_t clear = !tck<<swclk_gpio | !tdi<<swdio_gpio;
|
||||
uint32_t set = swclk << swclk_gpio | swdio << swdio_gpio;
|
||||
uint32_t clear = !swclk << swclk_gpio | !swdio << swdio_gpio;
|
||||
|
||||
GPIO_SET = set;
|
||||
GPIO_CLR = clear;
|
||||
|
@ -533,10 +535,6 @@ static int bcm2835gpio_init(void)
|
|||
"tdo %d trst %d srst %d", tck_gpio_mode, tms_gpio_mode,
|
||||
tdi_gpio_mode, tdo_gpio_mode, trst_gpio_mode, srst_gpio_mode);
|
||||
|
||||
if (swd_mode) {
|
||||
bcm2835gpio_bitbang.write = bcm2835gpio_swd_write;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -382,28 +382,24 @@ int bitbang_execute_queue(void)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
bool swd_mode;
|
||||
static int queued_retval;
|
||||
|
||||
static int bitbang_swd_init(void)
|
||||
{
|
||||
LOG_DEBUG("bitbang_swd_init");
|
||||
swd_mode = true;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static void bitbang_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsigned int bit_cnt)
|
||||
static void bitbang_swd_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsigned int bit_cnt)
|
||||
{
|
||||
LOG_DEBUG("bitbang_exchange");
|
||||
int tdi;
|
||||
LOG_DEBUG("bitbang_swd_exchange");
|
||||
|
||||
for (unsigned int i = offset; i < bit_cnt + offset; i++) {
|
||||
int bytec = i/8;
|
||||
int bcval = 1 << (i % 8);
|
||||
tdi = !rnw && (buf[bytec] & bcval);
|
||||
int swdio = !rnw && (buf[bytec] & bcval);
|
||||
|
||||
bitbang_interface->write(0, 0, tdi);
|
||||
bitbang_interface->swd_write(0, swdio);
|
||||
|
||||
if (rnw && buf) {
|
||||
if (bitbang_interface->swdio_read())
|
||||
|
@ -412,7 +408,7 @@ static void bitbang_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsig
|
|||
buf[bytec] &= ~bcval;
|
||||
}
|
||||
|
||||
bitbang_interface->write(1, 0, tdi);
|
||||
bitbang_interface->swd_write(1, swdio);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -423,15 +419,15 @@ static int bitbang_swd_switch_seq(enum swd_special_seq seq)
|
|||
switch (seq) {
|
||||
case LINE_RESET:
|
||||
LOG_DEBUG("SWD line reset");
|
||||
bitbang_exchange(false, (uint8_t *)swd_seq_line_reset, 0, swd_seq_line_reset_len);
|
||||
bitbang_swd_exchange(false, (uint8_t *)swd_seq_line_reset, 0, swd_seq_line_reset_len);
|
||||
break;
|
||||
case JTAG_TO_SWD:
|
||||
LOG_DEBUG("JTAG-to-SWD");
|
||||
bitbang_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);
|
||||
bitbang_swd_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);
|
||||
break;
|
||||
case SWD_TO_JTAG:
|
||||
LOG_DEBUG("SWD-to-JTAG");
|
||||
bitbang_exchange(false, (uint8_t *)swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len);
|
||||
bitbang_swd_exchange(false, (uint8_t *)swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("Sequence %d not supported", seq);
|
||||
|
@ -461,10 +457,10 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay
|
|||
uint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)];
|
||||
|
||||
cmd |= SWD_CMD_START | (1 << 7);
|
||||
bitbang_exchange(false, &cmd, 0, 8);
|
||||
bitbang_swd_exchange(false, &cmd, 0, 8);
|
||||
|
||||
bitbang_interface->swdio_drive(false);
|
||||
bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 32 + 1 + 1);
|
||||
bitbang_swd_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 32 + 1 + 1);
|
||||
bitbang_interface->swdio_drive(true);
|
||||
|
||||
int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);
|
||||
|
@ -488,7 +484,7 @@ static void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay
|
|||
if (value)
|
||||
*value = data;
|
||||
if (cmd & SWD_CMD_APnDP)
|
||||
bitbang_exchange(true, NULL, 0, ap_delay_clk);
|
||||
bitbang_swd_exchange(true, NULL, 0, ap_delay_clk);
|
||||
return;
|
||||
case SWD_ACK_WAIT:
|
||||
LOG_DEBUG("SWD_ACK_WAIT");
|
||||
|
@ -522,12 +518,12 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay
|
|||
buf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1 + 32, 1, parity_u32(value));
|
||||
|
||||
cmd |= SWD_CMD_START | (1 << 7);
|
||||
bitbang_exchange(false, &cmd, 0, 8);
|
||||
bitbang_swd_exchange(false, &cmd, 0, 8);
|
||||
|
||||
bitbang_interface->swdio_drive(false);
|
||||
bitbang_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 1);
|
||||
bitbang_swd_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 1);
|
||||
bitbang_interface->swdio_drive(true);
|
||||
bitbang_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1);
|
||||
bitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1);
|
||||
|
||||
int ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);
|
||||
LOG_DEBUG("%s %s %s reg %X = %08"PRIx32,
|
||||
|
@ -540,7 +536,7 @@ static void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay
|
|||
switch (ack) {
|
||||
case SWD_ACK_OK:
|
||||
if (cmd & SWD_CMD_APnDP)
|
||||
bitbang_exchange(true, NULL, 0, ap_delay_clk);
|
||||
bitbang_swd_exchange(true, NULL, 0, ap_delay_clk);
|
||||
return;
|
||||
case SWD_ACK_WAIT:
|
||||
LOG_DEBUG("SWD_ACK_WAIT");
|
||||
|
@ -563,7 +559,7 @@ static int bitbang_swd_run_queue(void)
|
|||
LOG_DEBUG("bitbang_swd_run_queue");
|
||||
/* A transaction must be followed by another transaction or at least 8 idle cycles to
|
||||
* ensure that data is clocked through the AP. */
|
||||
bitbang_exchange(true, NULL, 0, 8);
|
||||
bitbang_swd_exchange(true, NULL, 0, 8);
|
||||
|
||||
int retval = queued_retval;
|
||||
queued_retval = ERROR_OK;
|
||||
|
|
|
@ -62,12 +62,13 @@ struct bitbang_interface {
|
|||
|
||||
/** Set direction of SWDIO. */
|
||||
void (*swdio_drive)(bool on);
|
||||
|
||||
/** Set SWCLK and SWDIO to the given value. */
|
||||
int (*swd_write)(int swclk, int swdio);
|
||||
};
|
||||
|
||||
extern const struct swd_driver bitbang_swd;
|
||||
|
||||
extern bool swd_mode;
|
||||
|
||||
int bitbang_execute_queue(void);
|
||||
|
||||
extern struct bitbang_interface *bitbang_interface;
|
||||
|
|
|
@ -87,6 +87,7 @@ static int imx_gpio_write(int tck, int tms, int tdi);
|
|||
|
||||
static int imx_gpio_swdio_read(void);
|
||||
static void imx_gpio_swdio_drive(bool is_output);
|
||||
static int imx_gpio_swd_write(int swclk, int swdio);
|
||||
|
||||
static int imx_gpio_init(void);
|
||||
static int imx_gpio_quit(void);
|
||||
|
@ -96,6 +97,7 @@ static struct bitbang_interface imx_gpio_bitbang = {
|
|||
.write = imx_gpio_write,
|
||||
.swdio_read = imx_gpio_swdio_read,
|
||||
.swdio_drive = imx_gpio_swdio_drive,
|
||||
.swd_write = imx_gpio_swd_write,
|
||||
.blink = NULL
|
||||
};
|
||||
|
||||
|
@ -143,10 +145,10 @@ static int imx_gpio_write(int tck, int tms, int tdi)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int imx_gpio_swd_write(int tck, int tms, int tdi)
|
||||
static int imx_gpio_swd_write(int swclk, int swdio)
|
||||
{
|
||||
tdi ? gpio_set(swdio_gpio) : gpio_clear(swdio_gpio);
|
||||
tck ? gpio_set(swclk_gpio) : gpio_clear(swclk_gpio);
|
||||
swdio ? gpio_set(swdio_gpio) : gpio_clear(swdio_gpio);
|
||||
swclk ? gpio_set(swclk_gpio) : gpio_clear(swclk_gpio);
|
||||
|
||||
for (unsigned int i = 0; i < jtag_delay; i++)
|
||||
asm volatile ("");
|
||||
|
@ -550,10 +552,6 @@ static int imx_gpio_init(void)
|
|||
"tdo %d trst %d srst %d", tck_gpio_mode, tms_gpio_mode,
|
||||
tdi_gpio_mode, tdo_gpio_mode, trst_gpio_mode, srst_gpio_mode);
|
||||
|
||||
if (swd_mode) {
|
||||
imx_gpio_bitbang.write = imx_gpio_swd_write;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -230,7 +230,7 @@ static int sysfsgpio_swdio_read(void)
|
|||
return buf[0] != '0';
|
||||
}
|
||||
|
||||
static void sysfsgpio_swdio_write(int swclk, int swdio)
|
||||
static int sysfsgpio_swd_write(int swclk, int swdio)
|
||||
{
|
||||
const char one[] = "1";
|
||||
const char zero[] = "0";
|
||||
|
@ -255,6 +255,8 @@ static void sysfsgpio_swdio_write(int swclk, int swdio)
|
|||
last_swdio = swdio;
|
||||
last_swclk = swclk;
|
||||
last_stored = true;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -287,11 +289,6 @@ static bb_value_t sysfsgpio_read(void)
|
|||
*/
|
||||
static int sysfsgpio_write(int tck, int tms, int tdi)
|
||||
{
|
||||
if (swd_mode) {
|
||||
sysfsgpio_swdio_write(tck, tdi);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
const char one[] = "1";
|
||||
const char zero[] = "0";
|
||||
|
||||
|
@ -572,6 +569,7 @@ static struct bitbang_interface sysfsgpio_bitbang = {
|
|||
.write = sysfsgpio_write,
|
||||
.swdio_read = sysfsgpio_swdio_read,
|
||||
.swdio_drive = sysfsgpio_swdio_drive,
|
||||
.swd_write = sysfsgpio_swd_write,
|
||||
.blink = 0
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue