Skip to content

Commit

Permalink
DJTAG2 protocol implementation
Browse files Browse the repository at this point in the history
re-arraged the code in each jtag_transfer functions to open the timing
window as much as possible.
  • Loading branch information
phdussud authored and jeanthom committed Dec 13, 2022
1 parent 1920231 commit e71a6d6
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 27 deletions.
45 changes: 31 additions & 14 deletions src/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/

#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <unicore-mx/usbd/usbd.h>
#include <unicore-mx/stm32/gpio.h>
Expand All @@ -38,6 +39,11 @@ enum CommandIdentifier {
CMD_CLK = 0x06
};

enum CommandModifier {
NO_READ = 0x80,
EXTEND_LENGTH = 0x40
};

enum SignalIdentifier {
SIG_TCK = 1 << 1,
SIG_TDI = 1 << 2,
Expand Down Expand Up @@ -77,7 +83,7 @@ static void cmd_freq(const uint8_t *commands);
* @param usbd_dev USB device
* @param commands Command data
*/
static void cmd_xfer(usbd_device *usbd_dev, const uint8_t *commands);
static void cmd_xfer(usbd_device *usbd_dev, const uint8_t *commands, bool extend_length, bool no_read);

/**
* @brief Handle CMD_SETSIG command
Expand Down Expand Up @@ -106,13 +112,12 @@ static void cmd_getsig(usbd_device *usbd_dev);
*/
static void cmd_clk(const uint8_t *commands);

uint8_t cmd_handle(usbd_device *usbd_dev, const usbd_transfer *transfer) {
uint8_t *commands;

commands = (uint8_t*)transfer->buffer;
uint8_t cmd_handle(usbd_device *usbd_dev, const usbd_transfer *transfer) {
uint8_t *commands= (uint8_t*)transfer->buffer;

while (*commands != CMD_STOP) {
switch (*commands) {
switch ((*commands)&0x0F) {
case CMD_INFO:
cmd_info(usbd_dev);
break;
Expand All @@ -123,8 +128,8 @@ uint8_t cmd_handle(usbd_device *usbd_dev, const usbd_transfer *transfer) {
break;

case CMD_XFER:
cmd_xfer(usbd_dev, commands);
return 0;
cmd_xfer(usbd_dev, commands, *commands & EXTEND_LENGTH, *commands & NO_READ);
return !!(*commands & NO_READ);
break;

case CMD_SETSIG:
Expand Down Expand Up @@ -154,7 +159,7 @@ uint8_t cmd_handle(usbd_device *usbd_dev, const usbd_transfer *transfer) {
}

static void cmd_info(usbd_device *usbd_dev) {
char info_string[64] = "DJTAG1\n";
char info_string[64] = "DJTAG2\n";

usb_send(usbd_dev, (uint8_t*)info_string, 64);
}
Expand All @@ -163,22 +168,34 @@ static void cmd_freq(const uint8_t *commands) {
jtag_set_frequency((commands[1] << 8) | commands[2]);
}

static void cmd_xfer(usbd_device *usbd_dev, const uint8_t *commands) {
uint8_t transferred_bits;
uint8_t output_buffer[32];
static void cmd_xfer(usbd_device *usbd_dev, const uint8_t *commands, bool extend_length, bool no_read) {
uint16_t transferred_bits;
uint8_t output_buffer[64];

/* Fill the output buffer with zeroes */
memset(output_buffer, 0, 32);
if (!no_read) {
memset(output_buffer, 0, sizeof(output_buffer));
}

/* This is the number of transfered bits in one transfer command */
transferred_bits = commands[1];

if (extend_length) {
transferred_bits += 256;
// Ensure we don't do over-read
if (transferred_bits > 62*8) {
return;
}
}
jtag_transfer(transferred_bits, commands+2, output_buffer);

/* Send the transfer response back to host */
usb_send(usbd_dev, output_buffer, 32);
if (!no_read) {
usb_send(usbd_dev, output_buffer, (transferred_bits + 7)/8);
}
}



static void cmd_setsig(const uint8_t *commands) {
uint8_t signal_mask, signal_status;

Expand Down
32 changes: 21 additions & 11 deletions src/jtag.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ void jtag_set_srst(uint8_t value) {



void jtag_transfer_internal(uint8_t length, const uint8_t *in, uint8_t *out) {
void jtag_transfer_internal(uint16_t length, const uint8_t *in, uint8_t *out) {
uint32_t xfer_length, xfer_i;
const uint8_t *xfer_in;
uint8_t *xfer_out;
Expand All @@ -265,13 +265,14 @@ void jtag_transfer_internal(uint8_t length, const uint8_t *in, uint8_t *out) {
while (xfer_i < xfer_length)
{
uint8_t bitmask;

bitmask = 0x80 >> (xfer_i%8) ;

if (xfer_in[xfer_i/8] & bitmask) {
GPIO_BSRR(JTAG_PORT_TDI) = JTAG_PIN_TDI;
GPIO_BSRR(JTAG_PORT_TDI) = JTAG_PIN_TDI;
} else {
GPIO_BSRR(JTAG_PORT_TDI) = JTAG_PIN_TDI << 16;
GPIO_BSRR(JTAG_PORT_TDI) = JTAG_PIN_TDI << 16;
}

GPIO_BSRR(JTAG_PORT_TCK) = JTAG_PIN_TCK;
Expand All @@ -280,19 +281,21 @@ void jtag_transfer_internal(uint8_t length, const uint8_t *in, uint8_t *out) {
xfer_out[xfer_i/8] |= bitmask;
}

GPIO_BSRR(JTAG_PORT_TCK) = JTAG_PIN_TCK << 16;

xfer_i++;


GPIO_BSRR(JTAG_PORT_TCK) = JTAG_PIN_TCK << 16;

}
}
else
{
timer_set_counter(TIM2,0);
TIM_SR(TIM2) = ~TIM_SR_UIF;

while (xfer_i < xfer_length)
{
uint8_t bitmask;
TIM_SR(TIM2) = ~TIM_SR_UIF;

bitmask = 0x80 >> (xfer_i%8) ;

Expand All @@ -302,6 +305,9 @@ void jtag_transfer_internal(uint8_t length, const uint8_t *in, uint8_t *out) {
GPIO_BSRR(JTAG_PORT_TDI) = JTAG_PIN_TDI << 16;
}

while (!(TIM_SR(TIM2) & TIM_SR_UIF));
TIM_SR(TIM2) = ~TIM_SR_UIF;

GPIO_BSRR(JTAG_PORT_TCK) = JTAG_PIN_TCK;

while (!(TIM_SR(TIM2) & TIM_SR_UIF));
Expand All @@ -311,11 +317,13 @@ void jtag_transfer_internal(uint8_t length, const uint8_t *in, uint8_t *out) {
xfer_out[xfer_i/8] |= bitmask;
}

xfer_i++;

GPIO_BSRR(JTAG_PORT_TCK) = JTAG_PIN_TCK << 16;

xfer_i++;



while (!(TIM_SR(TIM2) & TIM_SR_UIF));

}
}
Expand All @@ -330,8 +338,11 @@ void jtag_strobe(uint8_t pulses, bool tms, bool tdi) {
{
while (pulses)
{
//double the writes to slow down the clock rate
GPIO_BSRR(JTAG_PORT_TCK) = JTAG_PIN_TCK;
GPIO_BSRR(JTAG_PORT_TCK) = JTAG_PIN_TCK;
GPIO_BSRR(JTAG_PORT_TCK) = JTAG_PIN_TCK << 16;
GPIO_BSRR(JTAG_PORT_TCK) = JTAG_PIN_TCK << 16;
pulses--;
}
}
Expand All @@ -352,9 +363,9 @@ void jtag_strobe(uint8_t pulses, bool tms, bool tdi) {
}

#if USE_SPI1
void jtag_transfer(uint8_t length, const uint8_t *in, uint8_t *out) {
void jtag_transfer(uint16_t length, const uint8_t *in, uint8_t *out) {
uint32_t byte_length = max_frequency ? length/8 : 0;
uint8_t remaining_length = max_frequency ? length & 7 : length;
uint16_t remaining_length = max_frequency ? length & 7 : length;
uint32_t xfer_in_i = 0;
uint32_t xfer_out_i = 0;

Expand Down Expand Up @@ -398,8 +409,7 @@ void jtag_transfer(uint8_t length, const uint8_t *in, uint8_t *out) {
}

#else
void jtag_transfer(uint8_t length, const uint8_t *in, uint8_t *out) {

void jtag_transfer(uint16_t length, const uint8_t *in, uint8_t *out) {
jtag_transfer_internal(length, in, out);
}

Expand Down
4 changes: 2 additions & 2 deletions src/jtag.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void jtag_set_srst(uint8_t value);
* @param in Input data
* @param out Output data
*/
void jtag_transfer(uint8_t length, const uint8_t *in,
void jtag_transfer(uint16_t length, const uint8_t *in,
uint8_t *out);

/**
Expand All @@ -110,7 +110,7 @@ void jtag_strobe(uint8_t pulses, bool tms, bool tdi);
#define HW_baite 2
#define HW_stlinkv2white 3

#if (PLATFORM == HW_bluepill) || (PLATFORM == HW_stlinkv2white)
#if (PLATFORM == HW_bluepill) || (PLATFORM == HW_stlinkv2white)
#define USE_SPI1 1
#else
#define USE_SPI1 0
Expand Down

0 comments on commit e71a6d6

Please sign in to comment.