OpenOCD
protocol.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2011 by Martin Schmoelzer *
5  * <martin.schmoelzer@student.tuwien.ac.at> *
6  ***************************************************************************/
7 
8 #include "protocol.h"
9 #include "jtag.h"
10 #include "delay.h"
11 #include "usb.h"
12 #include "io.h"
13 #include "msgtypes.h"
14 
15 #include "reg_ezusb.h"
16 
38 volatile uint8_t cmd_id_index;
39 
41 volatile uint8_t payload_index_in;
42 
47 {
48  uint8_t led_state = OUT2BUF[cmd_id_index + 1];
49 
50  if (led_state & RUN_LED_ON)
51  SET_RUN_LED();
52 
53  if (led_state & COM_LED_ON)
54  SET_COM_LED();
55 
56  if (led_state & RUN_LED_OFF)
57  CLEAR_RUN_LED();
58 
59  if (led_state & COM_LED_OFF)
60  CLEAR_COM_LED();
61 }
62 
70 bool execute_command(void)
71 {
72  uint8_t usb_out_bytecount, usb_in_bytecount;
73  uint16_t signal_state;
74  uint16_t count;
75 
76  /* Most commands do not transfer IN data. To save code space, we write 0 to
77  * usb_in_bytecount here, then modify it in the switch statement below where
78  * necessary */
79  usb_in_bytecount = 0;
80 
81  switch (OUT2BUF[cmd_id_index] /* Command ID */) {
82  case CMD_SCAN_IN:
83  usb_out_bytecount = 5;
84  usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
86  break;
87  case CMD_SCAN_OUT:
88  usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5;
90  break;
91  case CMD_SCAN_IO:
92  usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
93  usb_out_bytecount = usb_in_bytecount + 5;
95  break;
96  case CMD_CLOCK_TMS:
97  usb_out_bytecount = 2;
98  jtag_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);
99  break;
100  case CMD_CLOCK_TCK:
101  usb_out_bytecount = 2;
102  count = (uint16_t)OUT2BUF[cmd_id_index + 1];
103  count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;
105  break;
106  case CMD_SLOW_SCAN_IN:
107  usb_out_bytecount = 5;
108  usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
110  break;
111  case CMD_SLOW_SCAN_OUT:
112  usb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5;
114  break;
115  case CMD_SLOW_SCAN_IO:
116  usb_in_bytecount = OUT2BUF[cmd_id_index + 1];
117  usb_out_bytecount = usb_in_bytecount + 5;
119  break;
120  case CMD_SLOW_CLOCK_TMS:
121  usb_out_bytecount = 2;
122  jtag_slow_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);
123  break;
124  case CMD_SLOW_CLOCK_TCK:
125  usb_out_bytecount = 2;
126  count = (uint16_t)OUT2BUF[cmd_id_index + 1];
127  count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;
129  break;
130  case CMD_SLEEP_US:
131  usb_out_bytecount = 2;
132  count = (uint16_t)OUT2BUF[cmd_id_index + 1];
133  count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;
134  delay_us(count);
135  break;
136  case CMD_SLEEP_MS:
137  usb_out_bytecount = 2;
138  count = (uint16_t)OUT2BUF[cmd_id_index + 1];
139  count |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;
140  delay_ms(count);
141  break;
142  case CMD_GET_SIGNALS:
143  usb_out_bytecount = 0;
144  usb_in_bytecount = 2;
145  signal_state = jtag_get_signals();
146  IN2BUF[payload_index_in] = (signal_state >> 8) & 0x00FF;
147  IN2BUF[payload_index_in + 1] = signal_state & 0x00FF;
148  break;
149  case CMD_SET_SIGNALS:
150  usb_out_bytecount = 2;
151  jtag_set_signals(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);
152  break;
154  usb_out_bytecount = 5;
156  OUT2BUF[cmd_id_index + 1], /* scan_in */
157  OUT2BUF[cmd_id_index + 2], /* scan_out */
158  OUT2BUF[cmd_id_index + 3], /* scan_io */
159  OUT2BUF[cmd_id_index + 4], /* clock_tck */
160  OUT2BUF[cmd_id_index + 5]); /* clock_tms */
161  break;
162  case CMD_SET_LEDS:
163  usb_out_bytecount = 1;
165  break;
166  case CMD_TEST:
167  usb_out_bytecount = 1;
168  /* Do nothing... This command is only used to test if the device is ready
169  * to accept new commands */
170  break;
171  default:
172  /* Should never be reached */
173  usb_out_bytecount = 0;
174  break;
175  }
176 
177  /* Update EP2 Bulk-IN data byte count */
178  payload_index_in += usb_in_bytecount;
179 
180  /* Determine if this was the last command */
181  if ((cmd_id_index + usb_out_bytecount + 1) >= OUT2BC)
182  return true;
183  else {
184  /* Not the last command, update cmd_id_index */
185  cmd_id_index += (usb_out_bytecount + 1);
186  return false;
187  }
188 }
189 
193 void command_loop(void)
194 {
195  bool last_command;
196 
197  while (1) {
198  cmd_id_index = 0;
199  payload_index_in = 0;
200 
201  /* Wait until host sends EP2 Bulk-OUT packet */
202  while (!EP2_out)
203  ;
204  EP2_out = 0;
205 
206  /* Turn on COM LED to indicate command execution */
207  SET_COM_LED();
208 
209  /* Execute the commands */
210  last_command = false;
211  while (last_command == false)
212  last_command = execute_command();
213 
214  CLEAR_COM_LED();
215 
216  /* Send back EP2 Bulk-IN packet if required */
217  if (payload_index_in > 0) {
218  IN2BC = payload_index_in;
219  while (!EP2_in)
220  ;
221  EP2_in = 0;
222  }
223 
224  /* Re-arm EP2-OUT after command execution */
225  OUT2BC = 0;
226  }
227 }
void delay_us(uint16_t delay)
Definition: delay.c:23
void delay_ms(uint16_t delay)
Definition: delay.c:32
#define CLEAR_COM_LED()
Definition: io.h:77
#define SET_COM_LED()
Definition: io.h:76
#define CLEAR_RUN_LED()
Definition: io.h:74
#define SET_RUN_LED()
Definition: io.h:73
Definition of the commands supported by the OpenULINK firmware.
#define CMD_CONFIGURE_TCK_FREQ
Definition: msgtypes.h:153
#define RUN_LED_ON
Definition: msgtypes.h:174
#define COM_LED_OFF
Definition: msgtypes.h:175
#define CMD_SLOW_CLOCK_TCK
Definition: msgtypes.h:148
#define CMD_SET_LEDS
Definition: msgtypes.h:154
#define CMD_SLOW_SCAN_IN
Definition: msgtypes.h:138
#define CMD_SLOW_SCAN_OUT
Definition: msgtypes.h:140
#define RUN_LED_OFF
Definition: msgtypes.h:176
#define CMD_SLOW_SCAN_IO
Definition: msgtypes.h:142
#define CMD_SCAN_OUT
Definition: msgtypes.h:139
#define CMD_GET_SIGNALS
Definition: msgtypes.h:151
#define CMD_SLEEP_MS
Definition: msgtypes.h:150
#define COM_LED_ON
Definition: msgtypes.h:173
#define CMD_SCAN_IN
Definition: msgtypes.h:137
#define CMD_TEST
Definition: msgtypes.h:155
#define CMD_CLOCK_TCK
Definition: msgtypes.h:147
#define CMD_CLOCK_TMS
Definition: msgtypes.h:145
#define CMD_SCAN_IO
Definition: msgtypes.h:141
#define CMD_SLOW_CLOCK_TMS
Definition: msgtypes.h:146
#define CMD_SET_SIGNALS
Definition: msgtypes.h:152
#define CMD_SLEEP_US
Definition: msgtypes.h:149
volatile uint8_t payload_index_in
Number of data bytes already in EP2 Bulk-IN buffer.
Definition: protocol.c:41
bool execute_command(void)
Executes one command and updates global command indexes.
Definition: protocol.c:70
void command_loop(void)
Forever wait for commands and execute them as they arrive.
Definition: protocol.c:193
void execute_set_led_command(void)
Execute a SET_LEDS command.
Definition: protocol.c:46
volatile uint8_t cmd_id_index
Index in EP2 Bulk-OUT data buffer that contains the current command ID.
Definition: protocol.c:38
All information in this file was taken from the EZ-USB Technical Reference Manual,...
volatile bool EP2_out
Definition: usb.c:24
volatile bool EP2_in
Definition: usb.c:25
uint8_t count[4]
Definition: vdebug.c:22