common/swdptap.c: Speed up by "unrolling" swd.._seq_...() for GPIO.
Try to have sensible setup/hold times by evenntually duplicated or logically useless port commands. Loading code to RAM on a STM32L476 got up from 46 to 83 kB/sec.
This commit is contained in:
parent
d4d24c256c
commit
e54a826745
|
@ -18,7 +18,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This file implements the low-level SW-DP interface. */
|
/* This file implements the SW-DP interface. */
|
||||||
|
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include "swdptap.h"
|
#include "swdptap.h"
|
||||||
|
@ -43,6 +43,7 @@ static void swdptap_turnaround(uint8_t dir)
|
||||||
if(dir)
|
if(dir)
|
||||||
SWDIO_MODE_FLOAT();
|
SWDIO_MODE_FLOAT();
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
if(!dir)
|
if(!dir)
|
||||||
SWDIO_MODE_DRIVE();
|
SWDIO_MODE_DRIVE();
|
||||||
|
@ -56,6 +57,7 @@ bool swdptap_bit_in(void)
|
||||||
|
|
||||||
ret = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
ret = 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_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
|
||||||
#ifdef DEBUG_SWD_BITS
|
#ifdef DEBUG_SWD_BITS
|
||||||
|
@ -65,6 +67,64 @@ bool swdptap_bit_in(void)
|
||||||
return ret != 0;
|
return ret != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
swdptap_seq_in(int ticks)
|
||||||
|
{
|
||||||
|
uint32_t index = 1;
|
||||||
|
uint32_t ret = 0;
|
||||||
|
int len = ticks;
|
||||||
|
|
||||||
|
swdptap_turnaround(1);
|
||||||
|
while (len--) {
|
||||||
|
int res;
|
||||||
|
res = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
if (res)
|
||||||
|
ret |= index;
|
||||||
|
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);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
swdptap_seq_in_parity(uint32_t *ret, int ticks)
|
||||||
|
{
|
||||||
|
uint32_t index = 1;
|
||||||
|
uint8_t parity = 0;
|
||||||
|
uint32_t res = 0;
|
||||||
|
bool bit;
|
||||||
|
int len = ticks;
|
||||||
|
|
||||||
|
swdptap_turnaround(1);
|
||||||
|
while (len--) {
|
||||||
|
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
if (bit) {
|
||||||
|
res |= index;
|
||||||
|
parity ^= 1;
|
||||||
|
}
|
||||||
|
index <<= 1;
|
||||||
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
}
|
||||||
|
bit = gpio_get(SWDIO_PORT, SWDIO_PIN);
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
if (bit)
|
||||||
|
parity ^= 1;
|
||||||
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
#ifdef DEBUG_SWD_BITS
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
DEBUG("%d", (res & (1 << i)) ? 1 : 0);
|
||||||
|
#endif
|
||||||
|
*ret = res;
|
||||||
|
return parity;
|
||||||
|
}
|
||||||
|
|
||||||
void swdptap_bit_out(bool val)
|
void swdptap_bit_out(bool val)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_SWD_BITS
|
#ifdef DEBUG_SWD_BITS
|
||||||
|
@ -75,6 +135,48 @@ void swdptap_bit_out(bool val)
|
||||||
|
|
||||||
gpio_set_val(SWDIO_PORT, SWDIO_PIN, val);
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, val);
|
||||||
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
}
|
}
|
||||||
|
void
|
||||||
|
swdptap_seq_out(uint32_t MS, int ticks)
|
||||||
|
{
|
||||||
|
int data = MS & 1;
|
||||||
|
#ifdef DEBUG_SWD_BITS
|
||||||
|
for (int i = 0; i < ticks; i++)
|
||||||
|
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
|
||||||
|
#endif
|
||||||
|
swdptap_turnaround(0);
|
||||||
|
while (ticks--) {
|
||||||
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, data);
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
MS >>= 1;
|
||||||
|
data = MS & 1;
|
||||||
|
gpio_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
swdptap_seq_out_parity(uint32_t MS, int ticks)
|
||||||
|
{
|
||||||
|
uint8_t parity = 0;
|
||||||
|
int data = MS & 1;
|
||||||
|
#ifdef DEBUG_SWD_BITS
|
||||||
|
for (int i = 0; i < ticks; i++)
|
||||||
|
DEBUG("%d", (MS & (1 << i)) ? 1 : 0);
|
||||||
|
#endif
|
||||||
|
swdptap_turnaround(0);
|
||||||
|
|
||||||
|
while (ticks--) {
|
||||||
|
gpio_set_val(SWDIO_PORT, SWDIO_PIN, data);
|
||||||
|
gpio_set(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
parity ^= MS;
|
||||||
|
MS >>= 1;
|
||||||
|
data = 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_clear(SWCLK_PORT, SWCLK_PIN);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue