Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/Debug/

# C gitignore
# Prerequisites
*.d
Expand Down Expand Up @@ -77,6 +79,10 @@ Makefile.in
/install-sh
/missing
/stamp-h1
/src/config.h
/.settings/
/.cproject
/.project

# https://www.gnu.org/software/libtool/

Expand Down
27 changes: 21 additions & 6 deletions src/libswd.h
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,9 @@ typedef enum {
/// How many bits are there in data payload.
#define LIBSWD_DATA_BITLEN 32
/// How long is the command queue by default.
#define LIBSWD_CMDQLEN_DEFAULT 1024;
#define LIBSWD_CMDQLEN_DEFAULT 1024
/// Minimum recommended command queue
#define LIBSWD_CMDQLEN_MINIMUM 16

/** SWD Command Codes definitions.
* Available values: MISO>0, MOSI<0, undefined=0. To check command direction
Expand Down Expand Up @@ -611,6 +613,11 @@ typedef struct libswd_cmd_t {
struct libswd_cmd_t *next; ///< Pointer to the next command.
} libswd_cmd_t;

/** Lib statistics */
typedef struct {
unsigned int cmdqlen; ///< For memory management configured by maxcmdqlen
} libswd_stats_t;

/** Context configuration structure */
typedef struct {
char initialized; ///< Context must be initialized prior use.
Expand Down Expand Up @@ -744,10 +751,15 @@ static const libswd_arm_register_t libswd_arm_debug_CortexM3_SCS_ComponentID[] =

static const libswd_arm_register_t libswd_arm_debug_CPUID[] = {
{ .name="ARM Cortex-M3 r1p2", .default_value=0x411FC231 },
{ .name="ARM Cortex-M3 r2p0", .default_value=0x412FC230 },
{ .name="ARM Cortex-M3 r2p1", .default_value=0x412FC231 },
{ .name="ARM Cortex-M0 r0p0", .default_value=0x410CC200 },
{ .name="ARM Cortex-M0+ r0p0", .default_value=0x410CC600 },
{ .name="ARM Cortex-M4 r0p1", .default_value=0x410FC241 },
{ .name="ARM Cortex-M7 r0p1", .default_value=0x410FC271 },
{ .name="ARM Cortex-M7 r0p2", .default_value=0x410FC272 },
{ .name="ARM Cortex-M7 r1p0", .default_value=0x411FC270 },
{ .name="ARM Cortex-M7 r1p1", .default_value=0x411FC271 },
};

#define LIBSWD_NUM_SUPPORTED_CPUIDS (sizeof(libswd_arm_debug_CPUID) / sizeof(libswd_arm_debug_CPUID[0]))
Expand Down Expand Up @@ -804,6 +816,7 @@ typedef struct libswd_debug {
*/
typedef struct {
libswd_cmd_t *cmdq; ///< Command queue, stores all bus operations.
libswd_stats_t stats; ///< Holds all runtime statistics
libswd_context_config_t config; ///< Target specific configuration.
libswd_driver_t *driver; ///< Pointer to the interface driver structure.
libswd_membuf_t membuf; ///< Memory related scratchpad.
Expand Down Expand Up @@ -832,14 +845,15 @@ char *libswd_bin32_string(int *data);
int libswd_bin8_bitswap(unsigned char *buffer, unsigned int bitcount);
int libswd_bin32_bitswap(unsigned int *buffer, unsigned int bitcount);

int libswd_cmdq_init(libswd_cmd_t *cmdq);
int libswd_cmdq_init(libswd_ctx_t *libswdctx);
libswd_cmd_t* libswd_cmdq_find_head(libswd_cmd_t *cmdq);
libswd_cmd_t* libswd_cmdq_find_tail(libswd_cmd_t *cmdq);
libswd_cmd_t* libswd_cmdq_find_exectail(libswd_cmd_t *cmdq);
int libswd_cmdq_append(libswd_cmd_t *cmdq, libswd_cmd_t *cmd);
int libswd_cmdq_free(libswd_cmd_t *cmdq);
int libswd_cmdq_free_head(libswd_cmd_t *cmdq);
int libswd_cmdq_free_tail(libswd_cmd_t *cmdq);
int libswd_cmdq_append(libswd_ctx_t *libswdctx, libswd_cmd_t *cmd);
int libswd_cmdq_free(libswd_ctx_t *libswdctx);
int libswd_cmdq_free_head(libswd_ctx_t *libswdctx, libswd_cmd_t *cmd);
int libswd_cmdq_free_tail(libswd_ctx_t *libswdctx, libswd_cmd_t *cmd);
int libswd_cmdq_free_one_element(libswd_ctx_t *libswdctx, libswd_cmd_t *cmd);
int libswd_cmdq_flush(libswd_ctx_t *libswdctx, libswd_cmd_t **cmdq, libswd_operation_t operation);

int libswd_cmd_enqueue(libswd_ctx_t *libswdctx, libswd_cmd_t *cmd);
Expand Down Expand Up @@ -888,6 +902,7 @@ extern int libswd_drv_mosi_trn(libswd_ctx_t *libswdctx, int clks);
extern int libswd_drv_miso_trn(libswd_ctx_t *libswdctx, int clks);

extern int libswd_log(libswd_ctx_t *libswdctx, libswd_loglevel_t loglevel, char *msg, ...);
extern int libswd_log_flush(libswd_ctx_t *libswdctx, libswd_loglevel_t loglevel, char *msg, ...);
int libswd_log_internal(libswd_ctx_t *libswdctx, libswd_loglevel_t loglevel, char *msg, ...);
int libswd_log_internal_va(libswd_ctx_t *libswdctx, libswd_loglevel_t loglevel, char *msg, va_list ap);
int libswd_log_level_set(libswd_ctx_t *libswdctx, libswd_loglevel_t loglevel);
Expand Down
9 changes: 9 additions & 0 deletions src/libswd_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -1859,6 +1859,15 @@ int libswd_log(libswd_ctx_t *libswdctx, libswd_loglevel_t loglevel, char *msg, .
return retval;
};

int libswd_log_flush(libswd_ctx_t *libswdctx, libswd_loglevel_t loglevel, char *msg, ...){
int retval;
va_list ap;
va_start(ap, msg);
retval=libswd_log_internal_va(libswdctx, loglevel, msg, ap);
va_end(ap);
fflush(stdout);
return retval;
};

/******************************************************************************
* LIBUSB BASED ASYNCHRONOUS INTERFACE DRIVER FOR FTDI CHIPS *
Expand Down
1 change: 1 addition & 0 deletions src/libswd_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ static int libswdapp_interface_aftdi_transfer_bits(libswdapp_context_t *libswdap
static int libswdapp_interface_aftdi_transfer_bytes(libswdapp_context_t *libswdappctx, int bytes, char *mosidata, char *misodata, int nLSBfirst);

int libswd_log(libswd_ctx_t *libswdctx, libswd_loglevel_t loglevel, char *msg, ...);
int libswd_log_flush(libswd_ctx_t *libswdctx, libswd_loglevel_t loglevel, char *msg, ...);

static const libswdapp_interface_config_t libswdapp_interface_configs[] = {
{
Expand Down
36 changes: 18 additions & 18 deletions src/libswd_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ int libswd_bus_setdir_mosi(libswd_ctx_t *libswdctx){
if ( cmdqtail->prev==NULL || (cmdqtail->cmdtype*LIBSWD_CMDTYPE_MOSI<0) ) {
res=libswd_cmd_enqueue_mosi_trn(libswdctx);
if (res<1) return res;
cmdcnt=+res;
cmdcnt+=res;
}
return cmdcnt;
}
Expand All @@ -80,7 +80,7 @@ int libswd_bus_setdir_miso(libswd_ctx_t *libswdctx){
if (cmdqtail->prev==NULL || (cmdqtail->cmdtype*LIBSWD_CMDTYPE_MISO<0) ) {
res=libswd_cmd_enqueue_miso_trn(libswdctx);
if (res<0) return res;
cmdcnt=+res;
cmdcnt+=res;
}
return cmdcnt;
}
Expand All @@ -104,7 +104,7 @@ int libswd_bus_write_request_raw
/* Bus direction must be MOSI. */
res=libswd_bus_setdir_mosi(libswdctx);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

/* Append request command to the queue. */
res=libswd_cmd_enqueue_mosi_request(libswdctx, request);
Expand All @@ -116,7 +116,7 @@ int libswd_bus_write_request_raw
} else if (operation==LIBSWD_OPERATION_EXECUTE){
res=libswd_cmdq_flush(libswdctx, &libswdctx->cmdq, operation);
if (res<0) return res;
tcmdcnt=+res;
tcmdcnt+=res;
return qcmdcnt+tcmdcnt;
} else return LIBSWD_ERROR_BADOPCODE;
}
Expand Down Expand Up @@ -149,7 +149,7 @@ int libswd_bus_write_request
/* Bus direction must be MOSI. */
res=libswd_bus_setdir_mosi(libswdctx);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

/* Append request command to the queue. */
res=libswd_cmd_enqueue_mosi_request(libswdctx, &request);
Expand All @@ -161,7 +161,7 @@ int libswd_bus_write_request
} else if (operation==LIBSWD_OPERATION_EXECUTE){
res=libswd_cmdq_flush(libswdctx, &libswdctx->cmdq, operation);
if (res<0) return res;
tcmdcnt=+res;
tcmdcnt+=res;
return qcmdcnt+tcmdcnt;
} else return LIBSWD_ERROR_BADOPCODE;
}
Expand Down Expand Up @@ -195,13 +195,13 @@ int libswd_bus_read_ack(libswd_ctx_t *libswdctx, libswd_operation_t operation, c
/* TRN was found at queue tail, so we need to append TRN_MISO command. */
res=libswd_bus_setdir_miso(libswdctx);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;
}
}

res=libswd_cmd_enqueue_miso_ack(libswdctx, ack);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

if (operation==LIBSWD_OPERATION_ENQUEUE){
return qcmdcnt;
Expand Down Expand Up @@ -246,18 +246,18 @@ int libswd_bus_write_data_p

res=libswd_bus_setdir_mosi(libswdctx);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

res=libswd_cmd_enqueue_mosi_data_p(libswdctx, data, parity);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

if (operation==LIBSWD_OPERATION_ENQUEUE){
return qcmdcnt;
} else if (operation==LIBSWD_OPERATION_EXECUTE){
res=libswd_cmdq_flush(libswdctx, &libswdctx->cmdq, operation);
if (res<0) return res;
tcmdcnt=+res;
tcmdcnt+=res;
return qcmdcnt+tcmdcnt;
} else return LIBSWD_ERROR_BADOPCODE;
}
Expand All @@ -279,18 +279,18 @@ int libswd_bus_write_data_ap(libswd_ctx_t *libswdctx, libswd_operation_t operati

res=libswd_bus_setdir_mosi(libswdctx);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

res=libswd_cmd_enqueue_mosi_data_ap(libswdctx, data);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

if (operation==LIBSWD_OPERATION_ENQUEUE){
return qcmdcnt;
} else if (operation==LIBSWD_OPERATION_EXECUTE) {
res=libswd_cmdq_flush(libswdctx, &libswdctx->cmdq, operation);
if (res<0) return res;
tcmdcnt=+res;
tcmdcnt+=res;
return qcmdcnt+tcmdcnt;
} else return LIBSWD_ERROR_BADOPCODE;
}
Expand All @@ -312,11 +312,11 @@ int libswd_bus_read_data_p(libswd_ctx_t *libswdctx, libswd_operation_t operation

res=libswd_bus_setdir_miso(libswdctx);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

res=libswd_cmd_enqueue_miso_data_p(libswdctx, data, parity);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

if (operation==LIBSWD_OPERATION_ENQUEUE){
return qcmdcnt;
Expand Down Expand Up @@ -369,11 +369,11 @@ int libswd_bus_write_control(libswd_ctx_t *libswdctx, libswd_operation_t operati
/* Make sure that bus is in MOSI state. */
res=libswd_bus_setdir_mosi(libswdctx);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

res=libswd_cmd_enqueue_mosi_control(libswdctx, ctlmsg, len);
if (res<0) return res;
qcmdcnt=+res;
qcmdcnt+=res;

if (operation==LIBSWD_OPERATION_ENQUEUE){
return qcmdcnt;
Expand Down
38 changes: 26 additions & 12 deletions src/libswd_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,28 @@

/** Append selected command to a context's command queue (libswdctx->cmdq).
* This function does not update the libswdctx->cmdq pointer (its updated on flush).
* Limitation to CMD queue len is handled here.
* \param *libswdctx swd context pointer containing the command queue.
* \param *cmd command to be appended to the context's command queue.
* \return number of elements appended or LIBSWD_ERROR_CODE on failure.
*/
int libswd_cmd_enqueue(libswd_ctx_t *libswdctx, libswd_cmd_t *cmd){
if (libswdctx==NULL || cmd==NULL) return LIBSWD_ERROR_NULLPOINTER;
int res;
res=libswd_cmdq_append(libswdctx->cmdq, cmd);
if (libswdctx->config.maxcmdqlen!=0){
while (libswdctx->stats.cmdqlen >= libswdctx->config.maxcmdqlen){
libswd_cmd_t *cmd;
cmd=libswd_cmdq_find_head(libswdctx->cmdq);
if ((cmd->done!=1) || (cmd==libswdctx->cmdq)){
//Need to release memory, but this CMD in queue is not yet handled, so we can`t remove it
return LIBSWD_ERROR_OUTOFMEM;
} else {
res=libswd_cmdq_free_one_element(libswdctx, cmd);
if (res<1) return LIBSWD_ERROR_QUEUE;
}
}
}
res=libswd_cmdq_append(libswdctx, cmd);
return res;
}

Expand Down Expand Up @@ -149,7 +163,7 @@ int libswd_cmd_enqueue_miso_nbit(libswd_ctx_t *libswdctx, char **data, int count
}
//If there was problem enqueueing elements, rollback changes on queue.
if (res<1) {
res2=libswd_cmdq_free_tail(oldcmdq);
res2=libswd_cmdq_free_tail(libswdctx, oldcmdq);
if (res2<0) return res2;
return res;
} else return cmdcnt;
Expand Down Expand Up @@ -187,7 +201,7 @@ int i;
}
//If there was problem enqueueing elements, rollback changes on queue.
if (res<1){
res2=libswd_cmdq_free_tail(oldcmdq);
res2=libswd_cmdq_free_tail(libswdctx, oldcmdq);
if (res2<0) return res2;
libswdctx->cmdq=oldcmdq;
return res;
Expand Down Expand Up @@ -284,7 +298,7 @@ int libswd_cmd_enqueue_miso_n_data_p(libswd_ctx_t *libswdctx, int **data, char *
for (i=0;i<=count;i++){
res=libswd_cmd_enqueue_miso_data_p(libswdctx, &data[i], &parity[i]);
if (res<2) return LIBSWD_ERROR_RESULT;
cmdcnt=+res;
cmdcnt+=res;
}
return cmdcnt;
}
Expand Down Expand Up @@ -321,12 +335,12 @@ int libswd_cmd_enqueue_mosi_data_ap(libswd_ctx_t *libswdctx, int *data){
char parity;
res=libswd_cmd_enqueue_mosi_data(libswdctx, data);
if (res<1) return res;
cmdcnt=+res;
cmdcnt+=res;
res=libswd_bin32_parity_even(data, &parity);
if (res<0) return res;
res=libswd_cmd_enqueue_mosi_parity(libswdctx, &parity);
if (res<1) return res;
cmdcnt=+res;
cmdcnt+=res;
return cmdcnt; // should be 2 or 3 on success
}

Expand All @@ -342,10 +356,10 @@ int libswd_cmd_enqueue_mosi_data_p(libswd_ctx_t *libswdctx, int *data, char *par
int res, cmdcnt=0;
res=libswd_cmd_enqueue_mosi_data(libswdctx, data);
if (res<1) return res;
cmdcnt=+res;
cmdcnt+=res;
res=libswd_cmd_enqueue_mosi_parity(libswdctx, parity);
if (res<1) return res;
cmdcnt=+res;
cmdcnt+=res;
return cmdcnt; // should be 2 or 3 on success
}

Expand All @@ -363,7 +377,7 @@ int libswd_cmd_enqueue_mosi_n_data_ap(libswd_ctx_t *libswdctx, int **data, int c
for (i=0;i<count;i++){
res=libswd_cmd_enqueue_mosi_data(libswdctx, data[i]);
if (res<1) return res;
cmdcnt=+res;
cmdcnt+=res;
}
return cmdcnt;
}
Expand All @@ -383,7 +397,7 @@ int libswd_cmd_enqueue_mosi_n_data_p(libswd_ctx_t *libswdctx, int **data, char *
for (i=0;i<count;i++){
res=libswd_cmd_enqueue_mosi_data_p(libswdctx, data[i], parity[i]);
if (res<1) return res;
cmdcnt=+res;
cmdcnt+=res;
}
return cmdcnt;
}
Expand Down Expand Up @@ -432,11 +446,11 @@ int libswd_cmd_enqueue_mosi_control(libswd_ctx_t *libswdctx, char *ctlmsg, int l
cmd->bits=sizeof(ctlmsg[elm])*LIBSWD_DATA_BYTESIZE;
res=libswd_cmd_enqueue(libswdctx, cmd);
if (res<1) break;
cmdcnt=+res;
cmdcnt+=res;
}
//If there was problem enqueueing elements, rollback changes on queue.
if (res<1){
res2=libswd_cmdq_free_tail(oldcmdq);
res2=libswd_cmdq_free_tail(libswdctx, oldcmdq);
if (res2<0) return res2;
libswdctx->cmdq=oldcmdq;
return res;
Expand Down
Loading