From 140227bcb88802ef69694f3b5b9db65c7ea9dd0d Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sat, 13 Apr 2013 00:19:31 +0200 Subject: digital/dev2: use serial commands to speed up SWD communications --- digital/dev2/src/common/gpio.c | 90 ++++++++++++++++++++++++++++++++++-- digital/dev2/src/common/gpio_proto.h | 12 ++++- digital/dev2/tools/blackmagic | 2 +- 3 files changed, 97 insertions(+), 7 deletions(-) (limited to 'digital/dev2') diff --git a/digital/dev2/src/common/gpio.c b/digital/dev2/src/common/gpio.c index 5733b86f..5b3f94e6 100644 --- a/digital/dev2/src/common/gpio.c +++ b/digital/dev2/src/common/gpio.c @@ -40,7 +40,7 @@ struct gpio_t /* Currently handled operation, or 0 if none. */ uint8_t op; /* Arguments being received. */ - uint8_t args[5]; + uint8_t args[11]; /* Number of arguments to receive. */ uint8_t args_nb; /* Number of received arguments. */ @@ -66,18 +66,76 @@ gpio_uninit (void) } static void -gpio_bin_send (uint8_t c) +gpio_bin_send (uint8_t *c, uint8_t n) { Endpoint_SelectEndpoint (GPIO_TX_EPNUM); while (!Endpoint_ReadWriteAllowed ()) ; - Endpoint_Write_Byte (c); + while (n--) + Endpoint_Write_Byte (*c++); if (!Endpoint_ReadWriteAllowed ()) Endpoint_ClearCurrentBank (); Endpoint_SelectEndpoint (GPIO_RX_EPNUM); ctx.data_sent = 1; } +static void +gpio_bin_serial_out (void) +{ + uint8_t bits = ctx.args[2]; + uint8_t *p = &ctx.args[3]; + uint8_t b; + uint8_t i; + for (i = 0; i < bits; i++) + { + /* Read more data. */ + if (i % 8 == 0) + b = *p++; + /* Set data. */ + if (b & 1) + PORTD |= ctx.args[0]; + else + PORTD &= ~ctx.args[0]; + /* Clock cycle. */ + PORTD ^= ctx.args[1]; + PORTD ^= ctx.args[1]; + /* Next. */ + b >>= 1; + } +} + +static void +gpio_bin_serial_in (void) +{ + uint8_t bits = ctx.args[2]; + uint8_t *p = &ctx.args[3]; + uint8_t b = 0; + uint8_t bp = 1; + uint8_t i; + for (i = 0; i < bits; i++) + { + /* Read data. */ + if (PIND & ctx.args[0]) + b |= bp; + /* Clock cycle. */ + PORTD ^= ctx.args[1]; + PORTD ^= ctx.args[1]; + /* Next. */ + bp <<= 1; + /* Store data. */ + if (bp == 0) + { + *p++ = b; + b = 0; + bp = 1; + } + } + /* Store last data. */ + if (bp != 1) + *p++ = b; + gpio_bin_send (&ctx.args[3], (bits + 7) / 8); +} + static void gpio_bin_accept (uint8_t c) { @@ -95,6 +153,8 @@ gpio_bin_accept (uint8_t c) { GPIO_OP_OUT_TOGGLE, 1 }, { GPIO_OP_OUT_CHANGE, 2 }, { GPIO_OP_IN, 0 }, + { GPIO_OP_SERIAL_OUT, 3 }, + { GPIO_OP_SERIAL_IN, 3 }, }; uint8_t i; ctx.op = 0; @@ -116,6 +176,7 @@ gpio_bin_accept (uint8_t c) } if (ctx.op && ctx.args_index == ctx.args_nb) { + uint8_t done = 1; switch (ctx.op) { case GPIO_OP_RESET_SYNC: @@ -154,10 +215,29 @@ gpio_bin_accept (uint8_t c) PORTD = (PORTD & ~ctx.args[0]) | ctx.args[1]; break; case GPIO_OP_IN: - gpio_bin_send (PIND); + { + uint8_t in = PIND; + gpio_bin_send (&in, 1); + } + break; + case GPIO_OP_SERIAL_OUT: + if (ctx.args_nb == 3) + { + if (ctx.args[2] <= 64) + { + ctx.args_nb += (ctx.args[2] + 7) / 8; + done = 0; + } + } + else + gpio_bin_serial_out (); + break; + case GPIO_OP_SERIAL_IN: + gpio_bin_serial_in (); break; } - ctx.op = 0; + if (done) + ctx.op = 0; } } diff --git a/digital/dev2/src/common/gpio_proto.h b/digital/dev2/src/common/gpio_proto.h index 5252480e..0837acf4 100644 --- a/digital/dev2/src/common/gpio_proto.h +++ b/digital/dev2/src/common/gpio_proto.h @@ -25,7 +25,7 @@ * * }}} */ -/* All communications are big endian. */ +/* All communications are little endian. */ /* Reset communication and set all pins as input. */ #define GPIO_OP_RESET_SYNC 0xa5 @@ -54,4 +54,14 @@ /* Request port input. */ #define GPIO_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 GPIO_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 GPIO_OP_SERIAL_IN 0xc1 + + #endif /* gpio_proto_h */ diff --git a/digital/dev2/tools/blackmagic b/digital/dev2/tools/blackmagic index 7b230c04..dc61826e 160000 --- a/digital/dev2/tools/blackmagic +++ b/digital/dev2/tools/blackmagic @@ -1 +1 @@ -Subproject commit 7b230c04b3d4be2ac4d78414efe201dc11415c7c +Subproject commit dc61826ef72d56249f1eaf61b8ac0e1741627e27 -- cgit v1.2.3