aboutsummaryrefslogtreecommitdiff
path: root/src/platforms/tm4c/swdptap.c
blob: 058f6ba942e63e7efc843172855553841ab3aa97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "general.h"
#include "swdptap.h"

static void swdptap_turnaround(uint8_t dir)
{
	static uint8_t olddir = 0;

	DEBUG("%s", dir ? "\n-> ":"\n<- ");

	/* Don't turnaround if direction not changing */
	if(dir == olddir) return;
	olddir = dir;

	if(dir)
		SWDIO_MODE_FLOAT();
	gpio_set(SWCLK_PORT, SWCLK_PIN);
	gpio_clear(SWCLK_PORT, SWCLK_PIN);
	if(!dir)
		SWDIO_MODE_DRIVE();
}

static uint8_t swdptap_bit_in(void)
{
	uint16_t ret;

	ret = gpio_get(SWDIO_PORT, SWDIO_PIN);
	gpio_set(SWCLK_PORT, SWCLK_PIN);
	gpio_clear(SWCLK_PORT, SWCLK_PIN);

	DEBUG("%d", ret?1:0);

	return ret != 0;
}

static void swdptap_bit_out(uint8_t val)
{
	DEBUG("%d", val);

	gpio_set_val(SWDIO_PORT, SWDIO_PIN, val);
	gpio_set(SWCLK_PORT, SWCLK_PIN);
	gpio_clear(SWCLK_PORT, SWCLK_PIN);
}

int
swdptap_init(void)
{
	swdptap_reset();
	swdptap_seq_out(0xE79E, 16); /* 0b0111100111100111 */ 
	swdptap_reset();
	swdptap_seq_out(0, 16); 

	return 0;
}

void
swdptap_reset(void)
{
	swdptap_turnaround(0);
	/* 50 clocks with TMS high */
	for(int i = 0; i < 50; i++) swdptap_bit_out(1);
}

uint32_t
swdptap_seq_in(int ticks)
{
	uint32_t index = 1;
	uint32_t ret = 0;

	swdptap_turnaround(1);

	while(ticks--) {
		if(swdptap_bit_in()) ret |= index;
		index <<= 1;
	}

	return ret;
}

uint8_t
swdptap_seq_in_parity(uint32_t *ret, int ticks)
{
	uint32_t index = 1;
	uint8_t parity = 0;
	*ret = 0;

	swdptap_turnaround(1);

	while(ticks--) {
		if(swdptap_bit_in()) {
			*ret |= index;
			parity ^= 1;
		}
		index <<= 1;
	}
	if(swdptap_bit_in()) parity ^= 1;

	return parity;
}

void
swdptap_seq_out(uint32_t MS, int ticks)
{
	swdptap_turnaround(0);

	while(ticks--) {
		swdptap_bit_out(MS & 1);
		MS >>= 1; 
	}
}

void
swdptap_seq_out_parity(uint32_t MS, int ticks)
{
	uint8_t parity = 0;

	swdptap_turnaround(0);

	while(ticks--) {
		swdptap_bit_out(MS & 1);
		parity ^= MS;
		MS >>= 1; 
	}
	swdptap_bit_out(parity & 1);
}