forked from phdussud/pico-dirtyJtag
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dirtyJtag.c
171 lines (152 loc) · 4.24 KB
/
dirtyJtag.c
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/pio.h"
#include "pico/multicore.h"
#include "pio_jtag.h"
#include "cdc_uart.h"
#include "led.h"
#include "bsp/board.h"
#include "tusb.h"
#include "cmd.h"
#include "get_serial.h"
#include "dirtyJtagConfig.h"
#define MULTICORE
void init_pins()
{
bi_decl(bi_4pins_with_names(PIN_TCK, "TCK", PIN_TDI, "TDI", PIN_TDO, "TDO", PIN_TMS, "TMS"));
#if !( BOARD_TYPE == BOARD_QMTECH_RP2040_DAUGHTERBOARD )
bi_decl(bi_2pins_with_names(PIN_RST, "RST", PIN_TRST, "TRST"));
#endif
}
pio_jtag_inst_t jtag = {
.pio = pio0,
.sm = 0
};
void djtag_init()
{
init_pins();
#if !( BOARD_TYPE == BOARD_QMTECH_RP2040_DAUGHTERBOARD )
init_jtag(&jtag, 1000, PIN_TCK, PIN_TDI, PIN_TDO, PIN_TMS, PIN_RST, PIN_TRST);
#else
init_jtag(&jtag, 1000, PIN_TCK, PIN_TDI, PIN_TDO, PIN_TMS, 255, 255);
#endif
}
typedef uint8_t cmd_buffer[64];
static uint wr_buffer_number = 0;
static uint rd_buffer_number = 0;
typedef struct buffer_info
{
volatile uint8_t count;
volatile uint8_t busy;
cmd_buffer buffer;
} buffer_info;
#define n_buffers (4)
buffer_info buffer_infos[n_buffers];
static cmd_buffer tx_buf;
void jtag_main_task()
{
#ifdef MULTICORE
if (multicore_fifo_rvalid())
{
//some command processing has been done
uint rx_num = multicore_fifo_pop_blocking();
buffer_info* bi = &buffer_infos[rx_num];
bi->busy = false;
}
#endif
if ((buffer_infos[wr_buffer_number].busy == false))
{
//If tud_task() is called and tud_vendor_read isn't called immediately (i.e before calling tud_task again)
//after there is data available, there is a risk that data from 2 BULK OUT transaction will be (partially) combined into one
//The DJTAG protocol does not tolerate this.
tud_task();// tinyusb device task
if (tud_vendor_available())
{
led_rx( 1 );
uint bnum = wr_buffer_number;
uint count = tud_vendor_read(buffer_infos[wr_buffer_number].buffer, 64);
if (count != 0)
{
buffer_infos[bnum].count = count;
buffer_infos[bnum].busy = true;
wr_buffer_number = wr_buffer_number + 1; //switch buffer
if (wr_buffer_number == n_buffers)
{
wr_buffer_number = 0;
}
#ifdef MULTICORE
multicore_fifo_push_blocking(bnum);
#endif
}
led_rx( 0 );
} else {
#if ( USB_CDC_UART_BRIDGE )
cdc_uart_task();
#endif
}
}
}
void jtag_task()
{
#ifndef MULTICORE
jtag_main_task();
#endif
}
#ifdef MULTICORE
void core1_entry() {
djtag_init();
while (1)
{
uint rx_num = multicore_fifo_pop_blocking();
buffer_info* bi = &buffer_infos[rx_num];
assert (bi->busy);
cmd_handle(&jtag, bi->buffer, bi->count, tx_buf);
multicore_fifo_push_blocking(rx_num);
}
}
#endif
void fetch_command()
{
#ifndef MULTICORE
if (buffer_infos[rd_buffer_number].busy)
{
cmd_handle(&jtag, buffer_infos[rd_buffer_number].buffer, buffer_infos[rd_buffer_number].count, tx_buf);
buffer_infos[rd_buffer_number].busy = false;
rd_buffer_number++; //switch buffer
if (rd_buffer_number == n_buffers)
{
rd_buffer_number = 0;
}
}
#endif
}
//this is to work around the fact that tinyUSB does not handle setup request automatically
//Hence this boiler plate code
bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request)
{
if (stage != CONTROL_STAGE_SETUP) return true;
return false;
}
int main()
{
board_init();
usb_serial_init();
tusb_init();
led_init( LED_INVERTED, PIN_LED_TX, PIN_LED_RX, PIN_LED_ERROR );
#if ( USB_CDC_UART_BRIDGE )
cdc_uart_init( PIN_UART0, PIN_UART0_RX, PIN_UART0_TX );
#if (PIN_UART_INTF_COUNT == 2)
cdc_uart_init( PIN_UART1, PIN_UART1_RX, PIN_UART1_TX );
#endif
#endif
#ifdef MULTICORE
multicore_launch_core1(core1_entry);
#else
djtag_init();
#endif
while (1) {
jtag_main_task();
fetch_command();//for unicore implementation
}
}