aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Schodet2013-04-13 00:11:54 +0200
committerNicolas Schodet2015-06-16 16:59:24 +0200
commit21b3aba640e492b49140cb9c994f97a61ca51d29 (patch)
tree29007eb90a841a0c840e552d6eef656855c4f5c2
parent7b230c04b3d4be2ac4d78414efe201dc11415c7c (diff)
dev2: add serial command support for faster communication
-rw-r--r--src/platforms/dev2/platform.h11
-rw-r--r--src/platforms/dev2/swdptap.c128
2 files changed, 76 insertions, 63 deletions
diff --git a/src/platforms/dev2/platform.h b/src/platforms/dev2/platform.h
index c35c839..b87e4d9 100644
--- a/src/platforms/dev2/platform.h
+++ b/src/platforms/dev2/platform.h
@@ -30,7 +30,7 @@
# define alloca __builtin_alloca
#endif
-/* All communications are big endian. */
+/* All communications are little endian. */
/* Reset communication and set all pins as input. */
#define DEV2_OP_RESET_SYNC 0xa5
@@ -59,6 +59,15 @@
/* Request port input. */
#define DEV2_OP_IN 0xb9
+/* Send serial data (data mask as first argument, clock mask as second
+ * argument, data length as third argument, then a number of data lsb first).
+ * This will: set data, toggle clock twice, start again. */
+#define DEV2_OP_SERIAL_OUT 0xc0
+/* Receive serial data (data mask as first argument, clock mask as second
+ * argument, data length as third argument, will response with received data).
+ * This will: read data, toggle clock twice, start again. */
+#define DEV2_OP_SERIAL_IN 0xc1
+
/* Pins definition. */
#define TDI_PIN 0x80
diff --git a/src/platforms/dev2/swdptap.c b/src/platforms/dev2/swdptap.c
index 50f9bbb..e50a612 100644
--- a/src/platforms/dev2/swdptap.c
+++ b/src/platforms/dev2/swdptap.c
@@ -57,34 +57,6 @@ static void swdptap_turnaround(uint8_t dir)
platform_buffer_write(cmd, i);
}
-static uint8_t swdptap_bit_in(void)
-{
- uint8_t cmd[] = {
- DEV2_OP_IN,
- DEV2_OP_OUT_SET, SWCLK_PIN,
- DEV2_OP_OUT_RESET, SWCLK_PIN,
- };
- platform_buffer_write (cmd, sizeof (cmd));
- uint8_t rep[1];
- platform_buffer_read (rep, sizeof (rep));
- int ret = rep[0] & SWDIO_PIN;
-
- DEBUG("%d", ret?1:0);
-
- return ret != 0;
-}
-
-static void swdptap_bit_out(uint8_t val)
-{
- DEBUG("%d", val);
-
- uint8_t cmd[] = {
- DEV2_OP_OUT_CHANGE, SWDIO_PIN, (val ? SWDIO_PIN : 0),
- DEV2_OP_OUT_SET, SWCLK_PIN,
- DEV2_OP_OUT_RESET, SWCLK_PIN,
- };
- platform_buffer_write (cmd, sizeof (cmd));
-}
int swdptap_init(void)
{
@@ -99,73 +71,105 @@ int swdptap_init(void)
}
-void swdptap_reset(void)
+static uint64_t swdptap_seq_in_64(int ticks)
{
- swdptap_turnaround(0);
- /* 50 clocks with TMS high */
- for(int i = 0; i < 50; i++) swdptap_bit_out(1);
-}
+ int i;
+ uint64_t ret = 0;
+ swdptap_turnaround(1);
-uint32_t swdptap_seq_in(int ticks)
-{
- uint32_t index = 1;
- uint32_t ret = 0;
+ uint8_t cmd[] = {
+ DEV2_OP_SERIAL_IN, SWDIO_PIN, SWCLK_PIN, ticks,
+ };
+ platform_buffer_write(cmd, sizeof(cmd));
+ uint8_t rep[8];
+ int bytes = (ticks + 7) / 8;
+ platform_buffer_read(rep, bytes);
- swdptap_turnaround(1);
+ for(i = 0; i < bytes; i++)
+ ret |= (uint64_t) rep[i] << (8 * i);
- while(ticks--) {
- if(swdptap_bit_in()) ret |= index;
- index <<= 1;
- }
+ DEBUG("(0x%0*llx,%d)", (ticks + 3) / 4, ret, ticks);
return ret;
}
+uint32_t swdptap_seq_in(int ticks)
+{
+ return swdptap_seq_in_64(ticks);
+}
+
+
uint8_t swdptap_seq_in_parity(uint32_t *ret, int ticks)
{
- uint32_t index = 1;
+ uint64_t tmp;
uint8_t parity = 0;
- *ret = 0;
+ int i;
- swdptap_turnaround(1);
+ tmp = swdptap_seq_in_64(ticks + 1);
- while(ticks--) {
- if(swdptap_bit_in()) {
- *ret |= index;
+ for(i = 0; i < ticks + 1; i++)
+ {
+ if(tmp & (1ull << i))
parity ^= 1;
- }
- index <<= 1;
}
- if(swdptap_bit_in()) parity ^= 1;
+ *ret = tmp & ((1ull << ticks) - 1);
return parity;
}
-void swdptap_seq_out(uint32_t MS, int ticks)
+static void swdptap_seq_out_64(uint64_t MS, int ticks)
{
swdptap_turnaround(0);
- while(ticks--) {
- swdptap_bit_out(MS & 1);
- MS >>= 1;
+ DEBUG("(0x%0*llx,%d)", (ticks + 3) / 4, MS, ticks);
+
+ uint8_t cmd[12];
+ int i = 0;
+ cmd[i++] = DEV2_OP_SERIAL_OUT;
+ cmd[i++] = SWDIO_PIN;
+ cmd[i++] = SWCLK_PIN;
+ cmd[i++] = ticks;
+ for(; ticks > 0; ticks -= 8)
+ {
+ cmd[i++] = MS & 0xff;
+ MS >>= 8;
}
+ platform_buffer_write(cmd, i);
+}
+
+
+void swdptap_seq_out(uint32_t MS, int ticks)
+{
+ swdptap_seq_out_64(MS, ticks);
}
void swdptap_seq_out_parity(uint32_t MS, int ticks)
{
uint8_t parity = 0;
+ uint64_t tmp;
+ int i;
- swdptap_turnaround(0);
-
- while(ticks--) {
- swdptap_bit_out(MS & 1);
- parity ^= MS;
- MS >>= 1;
+ for(i = 0; i < ticks; i++)
+ {
+ if(MS & (1 << i))
+ parity ^= 1;
}
- swdptap_bit_out(parity & 1);
+ tmp = MS;
+ if(parity)
+ tmp |= 1ull << ticks;
+
+ swdptap_seq_out_64(tmp, ticks + 1);
}
+
+void swdptap_reset(void)
+{
+ /* 50 clocks with TMS high */
+ swdptap_seq_out_64((1ull << 50) - 1, 50);
+}
+
+