Infrastructure for setting maximum SWJ frequency.
Implement for BMP/firmware on STM32.
This commit is contained in:
parent
7365a44989
commit
1ca9f234f7
@ -49,6 +49,7 @@ static bool cmd_help(target *t, int argc, char **argv);
|
|||||||
|
|
||||||
static bool cmd_jtag_scan(target *t, int argc, char **argv);
|
static bool cmd_jtag_scan(target *t, int argc, char **argv);
|
||||||
static bool cmd_swdp_scan(target *t, int argc, char **argv);
|
static bool cmd_swdp_scan(target *t, int argc, char **argv);
|
||||||
|
static bool cmd_frequency(target *t, int argc, char **argv);
|
||||||
static bool cmd_targets(target *t, int argc, char **argv);
|
static bool cmd_targets(target *t, int argc, char **argv);
|
||||||
static bool cmd_morse(target *t, int argc, char **argv);
|
static bool cmd_morse(target *t, int argc, char **argv);
|
||||||
static bool cmd_halt_timeout(target *t, int argc, const char **argv);
|
static bool cmd_halt_timeout(target *t, int argc, const char **argv);
|
||||||
@ -70,6 +71,7 @@ const struct command_s cmd_list[] = {
|
|||||||
{"help", (cmd_handler)cmd_help, "Display help for monitor commands"},
|
{"help", (cmd_handler)cmd_help, "Display help for monitor commands"},
|
||||||
{"jtag_scan", (cmd_handler)cmd_jtag_scan, "Scan JTAG chain for devices" },
|
{"jtag_scan", (cmd_handler)cmd_jtag_scan, "Scan JTAG chain for devices" },
|
||||||
{"swdp_scan", (cmd_handler)cmd_swdp_scan, "Scan SW-DP for devices" },
|
{"swdp_scan", (cmd_handler)cmd_swdp_scan, "Scan SW-DP for devices" },
|
||||||
|
{"frequency", (cmd_handler)cmd_frequency, "set minimum high and low times" },
|
||||||
{"targets", (cmd_handler)cmd_targets, "Display list of available targets" },
|
{"targets", (cmd_handler)cmd_targets, "Display list of available targets" },
|
||||||
{"morse", (cmd_handler)cmd_morse, "Display morse error message" },
|
{"morse", (cmd_handler)cmd_morse, "Display morse error message" },
|
||||||
{"halt_timeout", (cmd_handler)cmd_halt_timeout, "Timeout (ms) to wait until Cortex-M is halted: (Default 2000)" },
|
{"halt_timeout", (cmd_handler)cmd_halt_timeout, "Timeout (ms) to wait until Cortex-M is halted: (Default 2000)" },
|
||||||
@ -258,6 +260,31 @@ bool cmd_swdp_scan(target *t, int argc, char **argv)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cmd_frequency(target *t, int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)t;
|
||||||
|
if (argc == 2) {
|
||||||
|
char *p;
|
||||||
|
uint32_t frequency = strtol(argv[1], &p, 10);
|
||||||
|
switch(*p) {
|
||||||
|
case 'k':
|
||||||
|
frequency *= 1000;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
frequency *= 1000*1000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
platform_max_frequency_set(frequency);
|
||||||
|
}
|
||||||
|
uint32_t freq = platform_max_frequency_get();
|
||||||
|
if (freq == FREQ_FIXED)
|
||||||
|
gdb_outf("SWJ freq fixed\n");
|
||||||
|
else
|
||||||
|
gdb_outf("Max SWJ freq %08" PRIx32 "\n", freq);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void display_target(int i, target *t, void *context)
|
static void display_target(int i, target *t, void *context)
|
||||||
{
|
{
|
||||||
(void)context;
|
(void)context;
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "platform_support.h"
|
#include "platform_support.h"
|
||||||
|
|
||||||
|
extern uint32_t delay_cnt;
|
||||||
|
|
||||||
enum BMP_DEBUG {
|
enum BMP_DEBUG {
|
||||||
BMP_DEBUG_NONE = 0,
|
BMP_DEBUG_NONE = 0,
|
||||||
BMP_DEBUG_INFO = 1,
|
BMP_DEBUG_INFO = 1,
|
||||||
@ -48,6 +50,8 @@ enum BMP_DEBUG {
|
|||||||
BMP_DEBUG_STDOUT = 0x8000,
|
BMP_DEBUG_STDOUT = 0x8000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define FREQ_FIXED 0xffffffff
|
||||||
|
|
||||||
#if PC_HOSTED == 0
|
#if PC_HOSTED == 0
|
||||||
/* For BMP debug output on a firmware BMP platform, using
|
/* For BMP debug output on a firmware BMP platform, using
|
||||||
* BMP PC-Hosted is the preferred way. Printing DEBUG_WARN
|
* BMP PC-Hosted is the preferred way. Printing DEBUG_WARN
|
||||||
|
@ -45,5 +45,8 @@ bool platform_srst_get_val(void);
|
|||||||
bool platform_target_get_power(void);
|
bool platform_target_get_power(void);
|
||||||
void platform_target_set_power(bool power);
|
void platform_target_set_power(bool power);
|
||||||
void platform_request_boot(void);
|
void platform_request_boot(void);
|
||||||
|
void platform_max_frequency_set(uint32_t frequency);
|
||||||
|
uint32_t platform_max_frequency_get(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ struct platform_timeout {
|
|||||||
uint32_t time;
|
uint32_t time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern int32_t swj_delay_cnt;
|
||||||
uint32_t platform_time_ms(void);
|
uint32_t platform_time_ms(void);
|
||||||
|
|
||||||
#endif /* __TIMING_H */
|
#endif /* __TIMING_H */
|
||||||
|
@ -70,12 +70,15 @@ static void jtagtap_reset(void)
|
|||||||
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI)
|
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI)
|
||||||
{
|
{
|
||||||
uint16_t ret;
|
uint16_t ret;
|
||||||
|
register volatile int32_t cnt;
|
||||||
|
|
||||||
gpio_set_val(TMS_PORT, TMS_PIN, dTMS);
|
gpio_set_val(TMS_PORT, TMS_PIN, dTMS);
|
||||||
gpio_set_val(TDI_PORT, TDI_PIN, dTDI);
|
gpio_set_val(TDI_PORT, TDI_PIN, dTDI);
|
||||||
gpio_set(TCK_PORT, TCK_PIN);
|
gpio_set(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||||
ret = gpio_get(TDO_PORT, TDO_PIN);
|
ret = gpio_get(TDO_PORT, TDO_PIN);
|
||||||
gpio_clear(TCK_PORT, TCK_PIN);
|
gpio_clear(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt - 2; cnt > 0; cnt--);
|
||||||
|
|
||||||
//DEBUG("jtagtap_next(TMS = %d, TDI = %d) = %d\n", dTMS, dTDI, ret);
|
//DEBUG("jtagtap_next(TMS = %d, TDI = %d) = %d\n", dTMS, dTDI, ret);
|
||||||
|
|
||||||
@ -86,6 +89,19 @@ static void jtagtap_tms_seq(uint32_t MS, int ticks)
|
|||||||
{
|
{
|
||||||
gpio_set_val(TDI_PORT, TDI_PIN, 1);
|
gpio_set_val(TDI_PORT, TDI_PIN, 1);
|
||||||
int data = MS & 1;
|
int data = MS & 1;
|
||||||
|
register volatile int32_t cnt;
|
||||||
|
if (swd_delay_cnt) {
|
||||||
|
while(ticks) {
|
||||||
|
gpio_set_val(TMS_PORT, TMS_PIN, data);
|
||||||
|
gpio_set(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||||
|
MS >>= 1;
|
||||||
|
data = MS & 1;
|
||||||
|
ticks--;
|
||||||
|
gpio_clear(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
while(ticks) {
|
while(ticks) {
|
||||||
gpio_set_val(TMS_PORT, TMS_PIN, data);
|
gpio_set_val(TMS_PORT, TMS_PIN, data);
|
||||||
gpio_set(TCK_PORT, TCK_PIN);
|
gpio_set(TCK_PORT, TCK_PIN);
|
||||||
@ -94,6 +110,7 @@ static void jtagtap_tms_seq(uint32_t MS, int ticks)
|
|||||||
ticks--;
|
ticks--;
|
||||||
gpio_clear(TCK_PORT, TCK_PIN);
|
gpio_clear(TCK_PORT, TCK_PIN);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jtagtap_tdi_tdo_seq(
|
static void jtagtap_tdi_tdo_seq(
|
||||||
@ -102,6 +119,26 @@ static void jtagtap_tdi_tdo_seq(
|
|||||||
uint8_t index = 1;
|
uint8_t index = 1;
|
||||||
gpio_set_val(TMS_PORT, TMS_PIN, 0);
|
gpio_set_val(TMS_PORT, TMS_PIN, 0);
|
||||||
uint8_t res = 0;
|
uint8_t res = 0;
|
||||||
|
register volatile int32_t cnt;
|
||||||
|
if (swd_delay_cnt) {
|
||||||
|
while(ticks > 1) {
|
||||||
|
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
||||||
|
gpio_set(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||||
|
if (gpio_get(TDO_PORT, TDO_PIN)) {
|
||||||
|
res |= index;
|
||||||
|
}
|
||||||
|
if(!(index <<= 1)) {
|
||||||
|
*DO = res;
|
||||||
|
res = 0;
|
||||||
|
index = 1;
|
||||||
|
DI++; DO++;
|
||||||
|
}
|
||||||
|
ticks--;
|
||||||
|
gpio_clear(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
while(ticks > 1) {
|
while(ticks > 1) {
|
||||||
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
||||||
gpio_set(TCK_PORT, TCK_PIN);
|
gpio_set(TCK_PORT, TCK_PIN);
|
||||||
@ -117,19 +154,37 @@ static void jtagtap_tdi_tdo_seq(
|
|||||||
ticks--;
|
ticks--;
|
||||||
gpio_clear(TCK_PORT, TCK_PIN);
|
gpio_clear(TCK_PORT, TCK_PIN);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
gpio_set_val(TMS_PORT, TMS_PIN, final_tms);
|
gpio_set_val(TMS_PORT, TMS_PIN, final_tms);
|
||||||
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
||||||
gpio_set(TCK_PORT, TCK_PIN);
|
gpio_set(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||||
if (gpio_get(TDO_PORT, TDO_PIN)) {
|
if (gpio_get(TDO_PORT, TDO_PIN)) {
|
||||||
res |= index;
|
res |= index;
|
||||||
}
|
}
|
||||||
*DO = res;
|
*DO = res;
|
||||||
gpio_clear(TCK_PORT, TCK_PIN);
|
gpio_clear(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks)
|
static void jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks)
|
||||||
{
|
{
|
||||||
uint8_t index = 1;
|
uint8_t index = 1;
|
||||||
|
register volatile int32_t cnt;
|
||||||
|
if (swd_delay_cnt) {
|
||||||
|
while(ticks--) {
|
||||||
|
gpio_set_val(TMS_PORT, TMS_PIN, ticks? 0 : final_tms);
|
||||||
|
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
||||||
|
gpio_set(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||||
|
if(!(index <<= 1)) {
|
||||||
|
index = 1;
|
||||||
|
DI++;
|
||||||
|
}
|
||||||
|
gpio_clear(TCK_PORT, TCK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
while(ticks--) {
|
while(ticks--) {
|
||||||
gpio_set_val(TMS_PORT, TMS_PIN, ticks? 0 : final_tms);
|
gpio_set_val(TMS_PORT, TMS_PIN, ticks? 0 : final_tms);
|
||||||
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
||||||
@ -140,4 +195,5 @@ static void jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int tick
|
|||||||
}
|
}
|
||||||
gpio_clear(TCK_PORT, TCK_PIN);
|
gpio_clear(TCK_PORT, TCK_PIN);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include "swdptap.h"
|
#include "swdptap.h"
|
||||||
|
#include "timing.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SWDIO_STATUS_FLOAT = 0,
|
SWDIO_STATUS_FLOAT = 0,
|
||||||
@ -39,6 +40,7 @@ static void swdptap_seq_out_parity(uint32_t MS, int ticks)
|
|||||||
static void swdptap_turnaround(int dir)
|
static void swdptap_turnaround(int dir)
|
||||||
{
|
{
|
||||||
static int olddir = SWDIO_STATUS_FLOAT;
|
static int olddir = SWDIO_STATUS_FLOAT;
|
||||||
|
register volatile int32_t cnt;
|
||||||
|
|
||||||
/* Don't turnaround if direction not changing */
|
/* Don't turnaround if direction not changing */
|
||||||
if(dir == olddir) return;
|
if(dir == olddir) return;
|
||||||
@ -51,10 +53,9 @@ static void swdptap_turnaround(int dir)
|
|||||||
if(dir == SWDIO_STATUS_FLOAT)
|
if(dir == SWDIO_STATUS_FLOAT)
|
||||||
SWDIO_MODE_FLOAT();
|
SWDIO_MODE_FLOAT();
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
if(dir == SWDIO_STATUS_DRIVE)
|
if(dir == SWDIO_STATUS_DRIVE)
|
||||||
SWDIO_MODE_DRIVE();
|
SWDIO_MODE_DRIVE();
|
||||||
}
|
}
|
||||||
@ -64,21 +65,30 @@ static uint32_t swdptap_seq_in(int ticks)
|
|||||||
uint32_t index = 1;
|
uint32_t index = 1;
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
int len = ticks;
|
int len = ticks;
|
||||||
|
register volatile int32_t cnt;
|
||||||
|
|
||||||
swdptap_turnaround(SWDIO_STATUS_FLOAT);
|
swdptap_turnaround(SWDIO_STATUS_FLOAT);
|
||||||
|
if (swd_delay_cnt) {
|
||||||
while (len--) {
|
while (len--) {
|
||||||
int res;
|
int res;
|
||||||
res = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
res = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
|
ret |= (res) ? index : 0;
|
||||||
|
index <<= 1;
|
||||||
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
volatile int res;
|
||||||
|
while (len--) {
|
||||||
|
res = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
ret |= (res) ? index : 0;
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
|
||||||
if (res)
|
|
||||||
ret |= index;
|
|
||||||
index <<= 1;
|
index <<= 1;
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#ifdef DEBUG_SWD_BITS
|
#ifdef DEBUG_SWD_BITS
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
DEBUG("%d", (ret & (1 << i)) ? 1 : 0);
|
DEBUG("%d", (ret & (1 << i)) ? 1 : 0);
|
||||||
@ -92,26 +102,35 @@ static bool swdptap_seq_in_parity(uint32_t *ret, int ticks)
|
|||||||
uint32_t res = 0;
|
uint32_t res = 0;
|
||||||
bool bit;
|
bool bit;
|
||||||
int len = ticks;
|
int len = ticks;
|
||||||
|
register volatile int32_t cnt;
|
||||||
|
|
||||||
swdptap_turnaround(SWDIO_STATUS_FLOAT);
|
swdptap_turnaround(SWDIO_STATUS_FLOAT);
|
||||||
|
if (swd_delay_cnt) {
|
||||||
while (len--) {
|
while (len--) {
|
||||||
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
res |= (bit) ? index : 0;
|
||||||
if (bit)
|
|
||||||
res |= index;
|
|
||||||
index <<= 1;
|
index <<= 1;
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (len--) {
|
||||||
|
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
res |= (bit) ? index : 0;
|
||||||
|
index <<= 1;
|
||||||
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int parity = __builtin_popcount(res);
|
int parity = __builtin_popcount(res);
|
||||||
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
if (bit)
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
parity++;
|
parity += (bit) ? 1 : 0;
|
||||||
else
|
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
#ifdef DEBUG_SWD_BITS
|
#ifdef DEBUG_SWD_BITS
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
DEBUG("%d", (res & (1 << i)) ? 1 : 0);
|
DEBUG("%d", (res & (1 << i)) ? 1 : 0);
|
||||||
@ -128,14 +147,25 @@ static void swdptap_seq_out(uint32_t MS, int ticks)
|
|||||||
for (int i = 0; i < ticks; i++)
|
for (int i = 0; i < ticks; i++)
|
||||||
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
|
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
|
||||||
#endif
|
#endif
|
||||||
|
register volatile int32_t cnt;
|
||||||
swdptap_turnaround(SWDIO_STATUS_DRIVE);
|
swdptap_turnaround(SWDIO_STATUS_DRIVE);
|
||||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||||
|
if (swd_delay_cnt) {
|
||||||
|
while (ticks--) {
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
|
MS >>= 1;
|
||||||
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||||
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
while (ticks--) {
|
while (ticks--) {
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
MS >>= 1;
|
MS >>= 1;
|
||||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,20 +176,32 @@ static void swdptap_seq_out_parity(uint32_t MS, int ticks)
|
|||||||
for (int i = 0; i < ticks; i++)
|
for (int i = 0; i < ticks; i++)
|
||||||
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
|
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
|
||||||
#endif
|
#endif
|
||||||
|
register volatile int32_t cnt;
|
||||||
swdptap_turnaround(SWDIO_STATUS_DRIVE);
|
swdptap_turnaround(SWDIO_STATUS_DRIVE);
|
||||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||||
MS >>= 1;
|
MS >>= 1;
|
||||||
|
if (swd_delay_cnt) {
|
||||||
|
while (ticks--) {
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||||
|
MS >>= 1;
|
||||||
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
while (ticks--) {
|
while (ticks--) {
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||||
MS >>= 1;
|
MS >>= 1;
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, parity & 1);
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, parity & 1);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||||
}
|
}
|
||||||
|
|
||||||
swd_proc_t swd_proc;
|
swd_proc_t swd_proc;
|
||||||
|
@ -128,6 +128,40 @@ bool remote_srst_get_val(void)
|
|||||||
return (construct[1] == '1');
|
return (construct[1] == '1');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void remote_max_frequency_set(uint32_t freq)
|
||||||
|
{
|
||||||
|
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||||
|
int s;
|
||||||
|
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, REMOTE_FREQ_SET_STR,
|
||||||
|
freq);
|
||||||
|
platform_buffer_write(construct, s);
|
||||||
|
|
||||||
|
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||||
|
|
||||||
|
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||||
|
DEBUG_WARN("Update Firmware to allow to set max SWJ frequency\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t remote_max_frequency_get(void)
|
||||||
|
{
|
||||||
|
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||||
|
int s;
|
||||||
|
|
||||||
|
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,"%s",
|
||||||
|
REMOTE_FREQ_GET_STR);
|
||||||
|
platform_buffer_write(construct, s);
|
||||||
|
|
||||||
|
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||||
|
|
||||||
|
if ((!s) || (construct[0] == REMOTE_RESP_ERR))
|
||||||
|
return FREQ_FIXED;
|
||||||
|
|
||||||
|
uint32_t freq[1];
|
||||||
|
unhexify(freq, (const char*)&construct[1], 4);
|
||||||
|
return freq[0];
|
||||||
|
}
|
||||||
|
|
||||||
const char *remote_target_voltage(void)
|
const char *remote_target_voltage(void)
|
||||||
{
|
{
|
||||||
static uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
static uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||||
|
@ -37,6 +37,8 @@ const char *remote_target_voltage(void);
|
|||||||
void remote_target_set_power(bool power);
|
void remote_target_set_power(bool power);
|
||||||
void remote_srst_set_val(bool assert);
|
void remote_srst_set_val(bool assert);
|
||||||
bool remote_srst_get_val(void);
|
bool remote_srst_get_val(void);
|
||||||
|
void remote_max_frequency_set(uint32_t freq);
|
||||||
|
uint32_t remote_max_frequency_get(void);
|
||||||
const char *platform_target_voltage(void);
|
const char *platform_target_voltage(void);
|
||||||
void remote_adiv5_dp_defaults(ADIv5_DP_t *dp);
|
void remote_adiv5_dp_defaults(ADIv5_DP_t *dp);
|
||||||
void remote_add_jtag_dev(int i, const jtag_dev_t *jtag_dev);
|
void remote_add_jtag_dev(int i, const jtag_dev_t *jtag_dev);
|
||||||
|
@ -109,6 +109,8 @@ void platform_init(int argc, char **argv)
|
|||||||
default:
|
default:
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
if (cl_opts.opt_max_swj_frequency)
|
||||||
|
platform_max_frequency_set(cl_opts.opt_max_swj_frequency);
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
if (cl_opts.opt_mode != BMP_MODE_DEBUG) {
|
if (cl_opts.opt_mode != BMP_MODE_DEBUG) {
|
||||||
ret = cl_execute(&cl_opts);
|
ret = cl_execute(&cl_opts);
|
||||||
@ -318,6 +320,32 @@ bool platform_srst_get_val(void)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void platform_max_frequency_set(uint32_t freq)
|
||||||
|
{
|
||||||
|
if (!freq)
|
||||||
|
return;
|
||||||
|
switch (info.bmp_type) {
|
||||||
|
case BMP_TYPE_BMP:
|
||||||
|
remote_max_frequency_set(freq);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUG_WARN("Setting max SWJ frequency not yet implemented\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t platform_max_frequency_get(void)
|
||||||
|
{
|
||||||
|
switch (info.bmp_type) {
|
||||||
|
case BMP_TYPE_BMP:
|
||||||
|
return remote_max_frequency_get();
|
||||||
|
default:
|
||||||
|
DEBUG_WARN("Reading max SWJ frequency not yet implemented\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void platform_buffer_flush(void)
|
void platform_buffer_flush(void)
|
||||||
{
|
{
|
||||||
switch (info.bmp_type) {
|
switch (info.bmp_type) {
|
||||||
|
@ -37,6 +37,8 @@ volatile platform_timeout * volatile head_timeout;
|
|||||||
uint8_t running_status;
|
uint8_t running_status;
|
||||||
static volatile uint32_t time_ms;
|
static volatile uint32_t time_ms;
|
||||||
|
|
||||||
|
uint32_t swd_delay_cnt = 0;
|
||||||
|
|
||||||
void sys_tick_handler(void)
|
void sys_tick_handler(void)
|
||||||
{
|
{
|
||||||
trace_tick();
|
trace_tick();
|
||||||
@ -140,3 +142,12 @@ void platform_request_boot(void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void platform_max_frequency_set(uint32_t freq)
|
||||||
|
{
|
||||||
|
(void)freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t platform_max_frequency_get(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#define PLATFORM_IDENT "(Launchpad ICDI) "
|
#define PLATFORM_IDENT "(Launchpad ICDI) "
|
||||||
|
|
||||||
extern uint8_t running_status;
|
extern uint8_t running_status;
|
||||||
|
extern uint32_t swd_delay_cnt;
|
||||||
|
|
||||||
#define TMS_PORT GPIOA_BASE
|
#define TMS_PORT GPIOA_BASE
|
||||||
#define TMS_PIN GPIO3
|
#define TMS_PIN GPIO3
|
||||||
|
@ -138,6 +138,7 @@ static void cl_help(char **argv)
|
|||||||
DEBUG_WARN("Run mode related options:\n");
|
DEBUG_WARN("Run mode related options:\n");
|
||||||
DEBUG_WARN("\tDefault mode is to start the debug server at :2000\n");
|
DEBUG_WARN("\tDefault mode is to start the debug server at :2000\n");
|
||||||
DEBUG_WARN("\t-j\t\t: Use JTAG. SWD is default.\n");
|
DEBUG_WARN("\t-j\t\t: Use JTAG. SWD is default.\n");
|
||||||
|
DEBUG_WARN("\t-f\t\t: Set minimum high and low times of SWJ waveform.\n");
|
||||||
DEBUG_WARN("\t-C\t\t: Connect under reset\n");
|
DEBUG_WARN("\t-C\t\t: Connect under reset\n");
|
||||||
DEBUG_WARN("\t-t\t\t: Scan SWD or JTAG and display information about \n"
|
DEBUG_WARN("\t-t\t\t: Scan SWD or JTAG and display information about \n"
|
||||||
"\t\t\t connected devices\n");
|
"\t\t\t connected devices\n");
|
||||||
@ -166,7 +167,8 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
|||||||
opt->opt_target_dev = 1;
|
opt->opt_target_dev = 1;
|
||||||
opt->opt_flash_size = 16 * 1024 *1024;
|
opt->opt_flash_size = 16 * 1024 *1024;
|
||||||
opt->opt_flash_start = 0xffffffff;
|
opt->opt_flash_start = 0xffffffff;
|
||||||
while((c = getopt(argc, argv, "eEhHv:d:s:I:c:CnltVtTa:S:jpP:rR")) != -1) {
|
opt->opt_max_swj_frequency = 4000000;
|
||||||
|
while((c = getopt(argc, argv, "eEhHv:d:f:s:I:c:CnltVtTa:S:jpP:rR")) != -1) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
if (optarg)
|
if (optarg)
|
||||||
@ -200,6 +202,21 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
|||||||
if (optarg)
|
if (optarg)
|
||||||
opt->opt_device = optarg;
|
opt->opt_device = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
if (optarg) {
|
||||||
|
char *p;
|
||||||
|
uint32_t frequency = strtol(optarg, &p, 10);
|
||||||
|
switch(*p) {
|
||||||
|
case 'k':
|
||||||
|
frequency *= 1000;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
frequency *= 1000*1000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
opt->opt_max_swj_frequency = frequency;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
if (optarg)
|
if (optarg)
|
||||||
opt->opt_serial = optarg;
|
opt->opt_serial = optarg;
|
||||||
@ -273,6 +290,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
|||||||
DEBUG_WARN("Ignoring filename in reset/test mode\n");
|
DEBUG_WARN("Ignoring filename in reset/test mode\n");
|
||||||
opt->opt_flash_file = NULL;
|
opt->opt_flash_file = NULL;
|
||||||
}
|
}
|
||||||
|
DEBUG_WARN("opt freq %" PRIu32 "\n", opt->opt_max_swj_frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void display_target(int i, target *t, void *context)
|
static void display_target(int i, target *t, void *context)
|
||||||
|
@ -54,6 +54,7 @@ typedef struct BMP_CL_OPTIONS_s {
|
|||||||
int opt_debuglevel;
|
int opt_debuglevel;
|
||||||
int opt_target_dev;
|
int opt_target_dev;
|
||||||
uint32_t opt_flash_start;
|
uint32_t opt_flash_start;
|
||||||
|
uint32_t opt_max_swj_frequency;
|
||||||
size_t opt_flash_size;
|
size_t opt_flash_size;
|
||||||
}BMP_CL_OPTIONS_t;
|
}BMP_CL_OPTIONS_t;
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
uint8_t running_status;
|
uint8_t running_status;
|
||||||
static volatile uint32_t time_ms;
|
static volatile uint32_t time_ms;
|
||||||
|
uint32_t swd_delay_cnt = 0;
|
||||||
|
|
||||||
void platform_timing_init(void)
|
void platform_timing_init(void)
|
||||||
{
|
{
|
||||||
@ -60,3 +61,29 @@ uint32_t platform_time_ms(void)
|
|||||||
return time_ms;
|
return time_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Assume some USED_SWD_CYCLES per clock
|
||||||
|
* and CYCLES_PER_CNT Cycles per delay loop cnt with 2 delay loops per clock
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Values for STM32F103 at 72 MHz */
|
||||||
|
#define USED_SWD_CYCLES 22
|
||||||
|
#define CYCLES_PER_CNT 10
|
||||||
|
void platform_max_frequency_set(uint32_t freq)
|
||||||
|
{
|
||||||
|
int divisor = rcc_ahb_frequency - USED_SWD_CYCLES * freq;
|
||||||
|
if (divisor < 0) {
|
||||||
|
swd_delay_cnt = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
divisor /= 2;
|
||||||
|
swd_delay_cnt = divisor/(CYCLES_PER_CNT * freq);
|
||||||
|
if ((swd_delay_cnt * (CYCLES_PER_CNT * freq)) < (unsigned int)divisor)
|
||||||
|
swd_delay_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t platform_max_frequency_get(void)
|
||||||
|
{
|
||||||
|
uint32_t ret = rcc_ahb_frequency;
|
||||||
|
ret /= USED_SWD_CYCLES + CYCLES_PER_CNT * swd_delay_cnt;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#ifndef __TIMING_STM32_H
|
#ifndef __TIMING_STM32_H
|
||||||
#define __TIMING_STM32_H
|
#define __TIMING_STM32_H
|
||||||
|
|
||||||
|
extern uint32_t swd_delay_cnt;
|
||||||
extern uint8_t running_status;
|
extern uint8_t running_status;
|
||||||
|
|
||||||
void platform_timing_init(void);
|
void platform_timing_init(void);
|
||||||
|
@ -269,6 +269,7 @@ void remotePacketProcessGEN(uint8_t i, char *packet)
|
|||||||
|
|
||||||
{
|
{
|
||||||
(void)i;
|
(void)i;
|
||||||
|
uint32_t freq;
|
||||||
switch (packet[1]) {
|
switch (packet[1]) {
|
||||||
case REMOTE_VOLTAGE:
|
case REMOTE_VOLTAGE:
|
||||||
_respondS(REMOTE_RESP_OK,platform_target_voltage());
|
_respondS(REMOTE_RESP_OK,platform_target_voltage());
|
||||||
@ -282,6 +283,14 @@ void remotePacketProcessGEN(uint8_t i, char *packet)
|
|||||||
case REMOTE_SRST_GET:
|
case REMOTE_SRST_GET:
|
||||||
_respond(REMOTE_RESP_OK,platform_srst_get_val());
|
_respond(REMOTE_RESP_OK,platform_srst_get_val());
|
||||||
break;
|
break;
|
||||||
|
case REMOTE_FREQ_SET:
|
||||||
|
platform_max_frequency_set( remotehston(8, packet + 2));
|
||||||
|
_respond(REMOTE_RESP_OK, 0);
|
||||||
|
break;
|
||||||
|
case REMOTE_FREQ_GET:
|
||||||
|
freq = platform_max_frequency_get();
|
||||||
|
_respond_buf(REMOTE_RESP_OK, (uint8_t*)&freq, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
case REMOTE_PWR_SET:
|
case REMOTE_PWR_SET:
|
||||||
#ifdef PLATFORM_HAS_POWER_SWITCH
|
#ifdef PLATFORM_HAS_POWER_SWITCH
|
||||||
|
@ -66,6 +66,8 @@
|
|||||||
#define REMOTE_TDITDO_TMS 'D'
|
#define REMOTE_TDITDO_TMS 'D'
|
||||||
#define REMOTE_TDITDO_NOTMS 'd'
|
#define REMOTE_TDITDO_NOTMS 'd'
|
||||||
#define REMOTE_IN_PAR 'I'
|
#define REMOTE_IN_PAR 'I'
|
||||||
|
#define REMOTE_FREQ_SET 'F'
|
||||||
|
#define REMOTE_FREQ_GET 'f'
|
||||||
#define REMOTE_IN 'i'
|
#define REMOTE_IN 'i'
|
||||||
#define REMOTE_NEXT 'N'
|
#define REMOTE_NEXT 'N'
|
||||||
#define REMOTE_OUT_PAR 'O'
|
#define REMOTE_OUT_PAR 'O'
|
||||||
@ -106,6 +108,8 @@
|
|||||||
#define REMOTE_VOLTAGE_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_VOLTAGE, REMOTE_EOM, 0 }
|
#define REMOTE_VOLTAGE_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_VOLTAGE, REMOTE_EOM, 0 }
|
||||||
#define REMOTE_SRST_SET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_SRST_SET, '%', 'c', REMOTE_EOM, 0 }
|
#define REMOTE_SRST_SET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_SRST_SET, '%', 'c', REMOTE_EOM, 0 }
|
||||||
#define REMOTE_SRST_GET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_SRST_GET, REMOTE_EOM, 0 }
|
#define REMOTE_SRST_GET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_SRST_GET, REMOTE_EOM, 0 }
|
||||||
|
#define REMOTE_FREQ_SET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_FREQ_SET, '%', '0', '8', 'x', REMOTE_EOM, 0 }
|
||||||
|
#define REMOTE_FREQ_GET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_FREQ_GET, REMOTE_EOM, 0 }
|
||||||
#define REMOTE_PWR_SET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_PWR_SET, '%', 'c', REMOTE_EOM, 0 }
|
#define REMOTE_PWR_SET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_PWR_SET, '%', 'c', REMOTE_EOM, 0 }
|
||||||
#define REMOTE_PWR_GET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_PWR_GET, REMOTE_EOM, 0 }
|
#define REMOTE_PWR_GET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_PWR_GET, REMOTE_EOM, 0 }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user