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_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_morse(target *t, int argc, 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"},
|
||||
{"jtag_scan", (cmd_handler)cmd_jtag_scan, "Scan JTAG chain 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" },
|
||||
{"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)" },
|
||||
|
@ -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)
|
||||
{
|
||||
(void)context;
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "platform.h"
|
||||
#include "platform_support.h"
|
||||
|
||||
extern uint32_t delay_cnt;
|
||||
|
||||
enum BMP_DEBUG {
|
||||
BMP_DEBUG_NONE = 0,
|
||||
BMP_DEBUG_INFO = 1,
|
||||
|
@ -48,6 +50,8 @@ enum BMP_DEBUG {
|
|||
BMP_DEBUG_STDOUT = 0x8000,
|
||||
};
|
||||
|
||||
#define FREQ_FIXED 0xffffffff
|
||||
|
||||
#if PC_HOSTED == 0
|
||||
/* For BMP debug output on a firmware BMP platform, using
|
||||
* 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);
|
||||
void platform_target_set_power(bool power);
|
||||
void platform_request_boot(void);
|
||||
void platform_max_frequency_set(uint32_t frequency);
|
||||
uint32_t platform_max_frequency_get(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ struct platform_timeout {
|
|||
uint32_t time;
|
||||
};
|
||||
|
||||
extern int32_t swj_delay_cnt;
|
||||
uint32_t platform_time_ms(void);
|
||||
|
||||
#endif /* __TIMING_H */
|
||||
|
|
|
@ -70,12 +70,15 @@ static void jtagtap_reset(void)
|
|||
static uint8_t jtagtap_next(uint8_t dTMS, uint8_t dTDI)
|
||||
{
|
||||
uint16_t ret;
|
||||
register volatile int32_t cnt;
|
||||
|
||||
gpio_set_val(TMS_PORT, TMS_PIN, dTMS);
|
||||
gpio_set_val(TDI_PORT, TDI_PIN, dTDI);
|
||||
gpio_set(TCK_PORT, TCK_PIN);
|
||||
for(cnt = swd_delay_cnt -2 ; cnt > 0; cnt--);
|
||||
ret = gpio_get(TDO_PORT, TDO_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);
|
||||
|
||||
|
@ -86,13 +89,27 @@ static void jtagtap_tms_seq(uint32_t MS, int ticks)
|
|||
{
|
||||
gpio_set_val(TDI_PORT, TDI_PIN, 1);
|
||||
int data = MS & 1;
|
||||
while(ticks) {
|
||||
gpio_set_val(TMS_PORT, TMS_PIN, data);
|
||||
gpio_set(TCK_PORT, TCK_PIN);
|
||||
MS >>= 1;
|
||||
data = MS & 1;
|
||||
ticks--;
|
||||
gpio_clear(TCK_PORT, TCK_PIN);
|
||||
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) {
|
||||
gpio_set_val(TMS_PORT, TMS_PIN, data);
|
||||
gpio_set(TCK_PORT, TCK_PIN);
|
||||
MS >>= 1;
|
||||
data = MS & 1;
|
||||
ticks--;
|
||||
gpio_clear(TCK_PORT, TCK_PIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,42 +119,81 @@ static void jtagtap_tdi_tdo_seq(
|
|||
uint8_t index = 1;
|
||||
gpio_set_val(TMS_PORT, TMS_PIN, 0);
|
||||
uint8_t res = 0;
|
||||
while(ticks > 1) {
|
||||
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
||||
gpio_set(TCK_PORT, TCK_PIN);
|
||||
if (gpio_get(TDO_PORT, TDO_PIN)) {
|
||||
res |= index;
|
||||
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--);
|
||||
}
|
||||
if(!(index <<= 1)) {
|
||||
*DO = res;
|
||||
res = 0;
|
||||
index = 1;
|
||||
DI++; DO++;
|
||||
} else {
|
||||
while(ticks > 1) {
|
||||
gpio_set_val(TDI_PORT, TDI_PIN, *DI & index);
|
||||
gpio_set(TCK_PORT, TCK_PIN);
|
||||
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);
|
||||
}
|
||||
ticks--;
|
||||
gpio_clear(TCK_PORT, TCK_PIN);
|
||||
}
|
||||
gpio_set_val(TMS_PORT, TMS_PIN, 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 (gpio_get(TDO_PORT, TDO_PIN)) {
|
||||
res |= index;
|
||||
}
|
||||
*DO = res;
|
||||
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)
|
||||
{
|
||||
uint8_t index = 1;
|
||||
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);
|
||||
if(!(index <<= 1)) {
|
||||
index = 1;
|
||||
DI++;
|
||||
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--) {
|
||||
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);
|
||||
if(!(index <<= 1)) {
|
||||
index = 1;
|
||||
DI++;
|
||||
}
|
||||
gpio_clear(TCK_PORT, TCK_PIN);
|
||||
}
|
||||
gpio_clear(TCK_PORT, TCK_PIN);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "general.h"
|
||||
#include "swdptap.h"
|
||||
#include "timing.h"
|
||||
|
||||
enum {
|
||||
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 int olddir = SWDIO_STATUS_FLOAT;
|
||||
register volatile int32_t cnt;
|
||||
|
||||
/* Don't turnaround if direction not changing */
|
||||
if(dir == olddir) return;
|
||||
|
@ -51,10 +53,9 @@ static void swdptap_turnaround(int dir)
|
|||
if(dir == SWDIO_STATUS_FLOAT)
|
||||
SWDIO_MODE_FLOAT();
|
||||
gpio_set(SWCLK_PORT, SWCLK_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_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||
if(dir == SWDIO_STATUS_DRIVE)
|
||||
SWDIO_MODE_DRIVE();
|
||||
}
|
||||
|
@ -64,21 +65,30 @@ static uint32_t swdptap_seq_in(int ticks)
|
|||
uint32_t index = 1;
|
||||
uint32_t ret = 0;
|
||||
int len = ticks;
|
||||
register volatile int32_t cnt;
|
||||
|
||||
swdptap_turnaround(SWDIO_STATUS_FLOAT);
|
||||
while (len--) {
|
||||
int res;
|
||||
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);
|
||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||
if (res)
|
||||
ret |= index;
|
||||
index <<= 1;
|
||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
if (swd_delay_cnt) {
|
||||
while (len--) {
|
||||
int res;
|
||||
res = gpio_get(SWDIO_PORT, SWDIO_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);
|
||||
ret |= (res) ? index : 0;
|
||||
index <<= 1;
|
||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SWD_BITS
|
||||
for (int i = 0; i < len; i++)
|
||||
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;
|
||||
bool bit;
|
||||
int len = ticks;
|
||||
register volatile int32_t cnt;
|
||||
|
||||
swdptap_turnaround(SWDIO_STATUS_FLOAT);
|
||||
while (len--) {
|
||||
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);
|
||||
if (bit)
|
||||
res |= index;
|
||||
index <<= 1;
|
||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
if (swd_delay_cnt) {
|
||||
while (len--) {
|
||||
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||
res |= (bit) ? index : 0;
|
||||
index <<= 1;
|
||||
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);
|
||||
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||
if (bit)
|
||||
parity++;
|
||||
else
|
||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||
parity += (bit) ? 1 : 0;
|
||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||
#ifdef DEBUG_SWD_BITS
|
||||
for (int i = 0; i < len; i++)
|
||||
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++)
|
||||
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
|
||||
#endif
|
||||
register volatile int32_t cnt;
|
||||
swdptap_turnaround(SWDIO_STATUS_DRIVE);
|
||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||
while (ticks--) {
|
||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||
MS >>= 1;
|
||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
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--) {
|
||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||
MS >>= 1;
|
||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||
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++)
|
||||
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
|
||||
#endif
|
||||
register volatile int32_t cnt;
|
||||
swdptap_turnaround(SWDIO_STATUS_DRIVE);
|
||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||
MS >>= 1;
|
||||
while (ticks--) {
|
||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||
MS >>= 1;
|
||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
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--) {
|
||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, MS & 1);
|
||||
MS >>= 1;
|
||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
}
|
||||
}
|
||||
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_clear(SWCLK_PORT, SWCLK_PIN);
|
||||
for(cnt = swd_delay_cnt; --cnt > 0;);
|
||||
}
|
||||
|
||||
swd_proc_t swd_proc;
|
||||
|
|
|
@ -128,6 +128,40 @@ bool remote_srst_get_val(void)
|
|||
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)
|
||||
{
|
||||
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_srst_set_val(bool assert);
|
||||
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);
|
||||
void remote_adiv5_dp_defaults(ADIv5_DP_t *dp);
|
||||
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:
|
||||
exit(-1);
|
||||
}
|
||||
if (cl_opts.opt_max_swj_frequency)
|
||||
platform_max_frequency_set(cl_opts.opt_max_swj_frequency);
|
||||
int ret = -1;
|
||||
if (cl_opts.opt_mode != BMP_MODE_DEBUG) {
|
||||
ret = cl_execute(&cl_opts);
|
||||
|
@ -318,6 +320,32 @@ bool platform_srst_get_val(void)
|
|||
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)
|
||||
{
|
||||
switch (info.bmp_type) {
|
||||
|
|
|
@ -37,6 +37,8 @@ volatile platform_timeout * volatile head_timeout;
|
|||
uint8_t running_status;
|
||||
static volatile uint32_t time_ms;
|
||||
|
||||
uint32_t swd_delay_cnt = 0;
|
||||
|
||||
void sys_tick_handler(void)
|
||||
{
|
||||
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) "
|
||||
|
||||
extern uint8_t running_status;
|
||||
extern uint32_t swd_delay_cnt;
|
||||
|
||||
#define TMS_PORT GPIOA_BASE
|
||||
#define TMS_PIN GPIO3
|
||||
|
|
|
@ -138,6 +138,7 @@ static void cl_help(char **argv)
|
|||
DEBUG_WARN("Run mode related options:\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-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-t\t\t: Scan SWD or JTAG and display information about \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_flash_size = 16 * 1024 *1024;
|
||||
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) {
|
||||
case 'c':
|
||||
if (optarg)
|
||||
|
@ -200,6 +202,21 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
|||
if (optarg)
|
||||
opt->opt_device = optarg;
|
||||
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':
|
||||
if (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");
|
||||
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)
|
||||
|
|
|
@ -54,6 +54,7 @@ typedef struct BMP_CL_OPTIONS_s {
|
|||
int opt_debuglevel;
|
||||
int opt_target_dev;
|
||||
uint32_t opt_flash_start;
|
||||
uint32_t opt_max_swj_frequency;
|
||||
size_t opt_flash_size;
|
||||
}BMP_CL_OPTIONS_t;
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
uint8_t running_status;
|
||||
static volatile uint32_t time_ms;
|
||||
uint32_t swd_delay_cnt = 0;
|
||||
|
||||
void platform_timing_init(void)
|
||||
{
|
||||
|
@ -60,3 +61,29 @@ uint32_t platform_time_ms(void)
|
|||
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
|
||||
#define __TIMING_STM32_H
|
||||
|
||||
extern uint32_t swd_delay_cnt;
|
||||
extern uint8_t running_status;
|
||||
|
||||
void platform_timing_init(void);
|
||||
|
|
|
@ -269,6 +269,7 @@ void remotePacketProcessGEN(uint8_t i, char *packet)
|
|||
|
||||
{
|
||||
(void)i;
|
||||
uint32_t freq;
|
||||
switch (packet[1]) {
|
||||
case REMOTE_VOLTAGE:
|
||||
_respondS(REMOTE_RESP_OK,platform_target_voltage());
|
||||
|
@ -282,6 +283,14 @@ void remotePacketProcessGEN(uint8_t i, char *packet)
|
|||
case REMOTE_SRST_GET:
|
||||
_respond(REMOTE_RESP_OK,platform_srst_get_val());
|
||||
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:
|
||||
#ifdef PLATFORM_HAS_POWER_SWITCH
|
||||
|
|
|
@ -66,6 +66,8 @@
|
|||
#define REMOTE_TDITDO_TMS 'D'
|
||||
#define REMOTE_TDITDO_NOTMS 'd'
|
||||
#define REMOTE_IN_PAR 'I'
|
||||
#define REMOTE_FREQ_SET 'F'
|
||||
#define REMOTE_FREQ_GET 'f'
|
||||
#define REMOTE_IN 'i'
|
||||
#define REMOTE_NEXT 'N'
|
||||
#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_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_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_GET_STR (char []){ REMOTE_SOM, REMOTE_GEN_PACKET, REMOTE_PWR_GET, REMOTE_EOM, 0 }
|
||||
|
||||
|
|
Loading…
Reference in New Issue