initial commit
[armstart-ibdap] / src / JTAG_DP.c
1 /******************************************************************************\r
2  * @file     JTAG_DP.c\r
3  * @brief    CMSIS-DAP JTAG DP I/O\r
4  * @version  V1.00\r
5  * @date     31. May 2012\r
6  *\r
7  * @note\r
8  * Copyright (C) 2012 ARM Limited. All rights reserved.\r
9  *\r
10  * @par\r
11  * ARM Limited (ARM) is supplying this software for use with Cortex-M\r
12  * processor based microcontrollers.\r
13  *\r
14  * @par\r
15  * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED\r
16  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF\r
17  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.\r
18  * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR\r
19  * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.\r
20  *\r
21  ******************************************************************************/\r
22 \r
23 #include "DAP_config.h"\r
24 #include "DAP.h"\r
25 \r
26 \r
27 // JTAG Macros\r
28 \r
29 #define PIN_TCK_SET PIN_SWCLK_TCK_SET\r
30 #define PIN_TCK_CLR PIN_SWCLK_TCK_CLR\r
31 #define PIN_TMS_SET PIN_SWDIO_TMS_SET\r
32 #define PIN_TMS_CLR PIN_SWDIO_TMS_CLR\r
33 \r
34 #define JTAG_CYCLE_TCK()                \\r
35   PIN_TCK_CLR();                        \\r
36   PIN_DELAY();                          \\r
37   PIN_TCK_SET();                        \\r
38   PIN_DELAY()\r
39 \r
40 #define JTAG_CYCLE_TDI(tdi)             \\r
41   PIN_TDI_OUT(tdi);                     \\r
42   PIN_TCK_CLR();                        \\r
43   PIN_DELAY();                          \\r
44   PIN_TCK_SET();                        \\r
45   PIN_DELAY()\r
46 \r
47 #define JTAG_CYCLE_TDO(tdo)             \\r
48   PIN_TCK_CLR();                        \\r
49   PIN_DELAY();                          \\r
50   tdo = PIN_TDO_IN();                   \\r
51   PIN_TCK_SET();                        \\r
52   PIN_DELAY()\r
53 \r
54 #define JTAG_CYCLE_TDIO(tdi,tdo)        \\r
55   PIN_TDI_OUT(tdi);                     \\r
56   PIN_TCK_CLR();                        \\r
57   PIN_DELAY();                          \\r
58   tdo = PIN_TDO_IN();                   \\r
59   PIN_TCK_SET();                        \\r
60   PIN_DELAY()\r
61 \r
62 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)\r
63 \r
64 \r
65 #if (DAP_JTAG != 0)\r
66 \r
67 \r
68 // Generate JTAG Sequence\r
69 //   info:   sequence information\r
70 //   tdi:    pointer to TDI generated data\r
71 //   tdo:    pointer to TDO captured data\r
72 //   return: none\r
73 void JTAG_Sequence (uint32_t info, uint8_t *tdi, uint8_t *tdo) {\r
74   uint32_t i_val;\r
75   uint32_t o_val;\r
76   uint32_t bit;\r
77   uint32_t n, k;\r
78 \r
79   n = info & JTAG_SEQUENCE_TCK;\r
80   if (n == 0) n = 64;\r
81 \r
82   if (info & JTAG_SEQUENCE_TMS) {\r
83     PIN_TMS_SET();\r
84   } else {\r
85     PIN_TMS_CLR();\r
86   }\r
87 \r
88   while (n) {\r
89     i_val = *tdi++;\r
90     o_val = 0;\r
91     for (k = 8; k && n; k--, n--) {\r
92       JTAG_CYCLE_TDIO(i_val, bit);\r
93       i_val >>= 1;\r
94       o_val >>= 1;\r
95       o_val  |= bit << 7;\r
96     }\r
97     o_val >>= k;\r
98     if (info & JTAG_SEQUENCE_TDO) {\r
99       *tdo++ = o_val;\r
100     }\r
101   }\r
102 }\r
103 \r
104 \r
105 // JTAG Set IR\r
106 //   ir:     IR value\r
107 //   return: none\r
108 #define JTAG_IR_Function(speed) /**/                                            \\r
109 void JTAG_IR_##speed (uint32_t ir) {                                            \\r
110   uint32_t n;                                                                   \\r
111                                                                                 \\r
112   PIN_TMS_SET();                                                                \\r
113   JTAG_CYCLE_TCK();                         /* Select-DR-Scan */                \\r
114   JTAG_CYCLE_TCK();                         /* Select-IR-Scan */                \\r
115   PIN_TMS_CLR();                                                                \\r
116   JTAG_CYCLE_TCK();                         /* Capture-IR */                    \\r
117   JTAG_CYCLE_TCK();                         /* Shift-IR */                      \\r
118                                                                                 \\r
119   PIN_TDI_OUT(1);                                                               \\r
120   for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) {      \\r
121     JTAG_CYCLE_TCK();                       /* Bypass before data */            \\r
122   }                                                                             \\r
123   for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1; n; n--) {  \\r
124     JTAG_CYCLE_TDI(ir);                     /* Set IR bits (except last) */     \\r
125     ir >>= 1;                                                                   \\r
126   }                                                                             \\r
127   n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index];                      \\r
128   if (n) {                                                                      \\r
129     JTAG_CYCLE_TDI(ir);                     /* Set last IR bit */               \\r
130     PIN_TDI_OUT(1);                                                             \\r
131     for (--n; n; n--) {                                                         \\r
132       JTAG_CYCLE_TCK();                     /* Bypass after data */             \\r
133     }                                                                           \\r
134     PIN_TMS_SET();                                                              \\r
135     JTAG_CYCLE_TCK();                       /* Bypass & Exit1-IR */             \\r
136   } else {                                                                      \\r
137     PIN_TMS_SET();                                                              \\r
138     JTAG_CYCLE_TDI(ir);                     /* Set last IR bit & Exit1-IR */    \\r
139   }                                                                             \\r
140                                                                                 \\r
141   JTAG_CYCLE_TCK();                         /* Update-IR */                     \\r
142   PIN_TMS_CLR();                                                                \\r
143   JTAG_CYCLE_TCK();                         /* Idle */                          \\r
144   PIN_TDI_OUT(1);                                                               \\r
145 }\r
146 \r
147 \r
148 // JTAG Transfer I/O\r
149 //   request: A[3:2] RnW APnDP\r
150 //   data:    DATA[31:0]\r
151 //   return:  ACK[2:0]\r
152 #define JTAG_TransferFunction(speed)        /**/                                \\r
153 uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) {               \\r
154   uint32_t ack;                                                                 \\r
155   uint32_t bit;                                                                 \\r
156   uint32_t val;                                                                 \\r
157   uint32_t n;                                                                   \\r
158                                                                                 \\r
159   PIN_TMS_SET();                                                                \\r
160   JTAG_CYCLE_TCK();                         /* Select-DR-Scan */                \\r
161   PIN_TMS_CLR();                                                                \\r
162   JTAG_CYCLE_TCK();                         /* Capture-DR */                    \\r
163   JTAG_CYCLE_TCK();                         /* Shift-DR */                      \\r
164                                                                                 \\r
165   for (n = DAP_Data.jtag_dev.index; n; n--) {                                   \\r
166     JTAG_CYCLE_TCK();                       /* Bypass before data */            \\r
167   }                                                                             \\r
168                                                                                 \\r
169   JTAG_CYCLE_TDIO(request >> 1, bit);       /* Set RnW, Get ACK.0 */            \\r
170   ack  = bit << 1;                                                              \\r
171   JTAG_CYCLE_TDIO(request >> 2, bit);       /* Set A2,  Get ACK.1 */            \\r
172   ack |= bit << 0;                                                              \\r
173   JTAG_CYCLE_TDIO(request >> 3, bit);       /* Set A3,  Get ACK.2 */            \\r
174   ack |= bit << 2;                                                              \\r
175                                                                                 \\r
176   if (ack != DAP_TRANSFER_OK) {                                                 \\r
177     /* Exit on error */                                                         \\r
178     PIN_TMS_SET();                                                              \\r
179     JTAG_CYCLE_TCK();                       /* Exit1-DR */                      \\r
180     goto exit;                                                                  \\r
181   }                                                                             \\r
182                                                                                 \\r
183   if (request & DAP_TRANSFER_RnW) {                                             \\r
184     /* Read Transfer */                                                         \\r
185     val = 0;                                                                    \\r
186     for (n = 31; n; n--) {                                                      \\r
187       JTAG_CYCLE_TDO(bit);                  /* Get D0..D30 */                   \\r
188       val  |= bit << 31;                                                        \\r
189       val >>= 1;                                                                \\r
190     }                                                                           \\r
191     n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1;                  \\r
192     if (n) {                                                                    \\r
193       JTAG_CYCLE_TDO(bit);                  /* Get D31 */                       \\r
194       for (--n; n; n--) {                                                       \\r
195         JTAG_CYCLE_TCK();                   /* Bypass after data */             \\r
196       }                                                                         \\r
197       PIN_TMS_SET();                                                            \\r
198       JTAG_CYCLE_TCK();                     /* Bypass & Exit1-DR */             \\r
199     } else {                                                                    \\r
200       PIN_TMS_SET();                                                            \\r
201       JTAG_CYCLE_TDO(bit);                  /* Get D31 & Exit1-DR */            \\r
202     }                                                                           \\r
203     val |= bit << 31;                                                           \\r
204     if (data) *data = val;                                                      \\r
205   } else {                                                                      \\r
206     /* Write Transfer */                                                        \\r
207     val = *data;                                                                \\r
208     for (n = 31; n; n--) {                                                      \\r
209       JTAG_CYCLE_TDI(val);                  /* Set D0..D30 */                   \\r
210       val >>= 1;                                                                \\r
211     }                                                                           \\r
212     n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1;                  \\r
213     if (n) {                                                                    \\r
214       JTAG_CYCLE_TDI(val);                  /* Set D31 */                       \\r
215       for (--n; n; n--) {                                                       \\r
216         JTAG_CYCLE_TCK();                   /* Bypass after data */             \\r
217       }                                                                         \\r
218       PIN_TMS_SET();                                                            \\r
219       JTAG_CYCLE_TCK();                     /* Bypass & Exit1-DR */             \\r
220     } else {                                                                    \\r
221       PIN_TMS_SET();                                                            \\r
222       JTAG_CYCLE_TDI(val);                  /* Set D31 & Exit1-DR */            \\r
223     }                                                                           \\r
224   }                                                                             \\r
225                                                                                 \\r
226 exit:                                                                           \\r
227   JTAG_CYCLE_TCK();                         /* Update-DR */                     \\r
228   PIN_TMS_CLR();                                                                \\r
229   JTAG_CYCLE_TCK();                         /* Idle */                          \\r
230   PIN_TDI_OUT(1);                                                               \\r
231                                                                                 \\r
232   /* Idle cycles */                                                             \\r
233   n = DAP_Data.transfer.idle_cycles;                                            \\r
234   while (n--) {                                                                 \\r
235     JTAG_CYCLE_TCK();                       /* Idle */                          \\r
236   }                                                                             \\r
237                                                                                 \\r
238   return (ack);                                                                 \\r
239 }\r
240 \r
241 \r
242 #undef  PIN_DELAY\r
243 #define PIN_DELAY() PIN_DELAY_FAST()\r
244 JTAG_IR_Function(Fast);\r
245 JTAG_TransferFunction(Fast);\r
246 \r
247 #undef  PIN_DELAY\r
248 #define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)\r
249 JTAG_IR_Function(Slow);\r
250 JTAG_TransferFunction(Slow);\r
251 \r
252 \r
253 // JTAG Read IDCODE register\r
254 //   return: value read\r
255 uint32_t JTAG_ReadIDCode (void) {\r
256   uint32_t bit;\r
257   uint32_t val;\r
258   uint32_t n;\r
259 \r
260   PIN_TMS_SET();\r
261   JTAG_CYCLE_TCK();                         /* Select-DR-Scan */\r
262   PIN_TMS_CLR();\r
263   JTAG_CYCLE_TCK();                         /* Capture-DR */\r
264   JTAG_CYCLE_TCK();                         /* Shift-DR */\r
265 \r
266   for (n = DAP_Data.jtag_dev.index; n; n--) {\r
267     JTAG_CYCLE_TCK();                       /* Bypass before data */\r
268   }\r
269 \r
270   val = 0;\r
271   for (n = 31; n; n--) {\r
272     JTAG_CYCLE_TDO(bit);                    /* Get D0..D30 */\r
273     val  |= bit << 31;\r
274     val >>= 1;\r
275   }\r
276   PIN_TMS_SET();\r
277   JTAG_CYCLE_TDO(bit);                      /* Get D31 & Exit1-DR */\r
278   val |= bit << 31;\r
279 \r
280   JTAG_CYCLE_TCK();                         /* Update-DR */\r
281   PIN_TMS_CLR();\r
282   JTAG_CYCLE_TCK();                         /* Idle */\r
283 \r
284   return (val);\r
285 }\r
286 \r
287 \r
288 // JTAG Write ABORT register\r
289 //   data:   value to write\r
290 //   return: none\r
291 void JTAG_WriteAbort (uint32_t data) {\r
292   uint32_t n;\r
293 \r
294   PIN_TMS_SET();\r
295   JTAG_CYCLE_TCK();                         /* Select-DR-Scan */\r
296   PIN_TMS_CLR();\r
297   JTAG_CYCLE_TCK();                         /* Capture-DR */\r
298   JTAG_CYCLE_TCK();                         /* Shift-DR */\r
299 \r
300   for (n = DAP_Data.jtag_dev.index; n; n--) {\r
301     JTAG_CYCLE_TCK();                       /* Bypass before data */\r
302   }\r
303 \r
304   PIN_TDI_OUT(0);\r
305   JTAG_CYCLE_TCK();                         /* Set RnW=0 (Write) */\r
306   JTAG_CYCLE_TCK();                         /* Set A2=0 */\r
307   JTAG_CYCLE_TCK();                         /* Set A3=0 */\r
308 \r
309   for (n = 31; n; n--) {\r
310     JTAG_CYCLE_TDI(data);                   /* Set D0..D30 */\r
311     data >>= 1;\r
312   }\r
313   n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1;\r
314   if (n) {\r
315     JTAG_CYCLE_TDI(data);                   /* Set D31 */\r
316     for (--n; n; n--) {\r
317       JTAG_CYCLE_TCK();                     /* Bypass after data */\r
318     }\r
319     PIN_TMS_SET();\r
320     JTAG_CYCLE_TCK();                       /* Bypass & Exit1-DR */\r
321   } else {\r
322     PIN_TMS_SET();\r
323     JTAG_CYCLE_TDI(data);                   /* Set D31 & Exit1-DR */\r
324   }\r
325 \r
326   JTAG_CYCLE_TCK();                         /* Update-DR */\r
327   PIN_TMS_CLR();\r
328   JTAG_CYCLE_TCK();                         /* Idle */\r
329   PIN_TDI_OUT(1);\r
330 }\r
331 \r
332 \r
333 // JTAG Set IR\r
334 //   ir:     IR value\r
335 //   return: none\r
336 void JTAG_IR (uint32_t ir) {\r
337   if (DAP_Data.fast_clock) {\r
338     JTAG_IR_Fast(ir);\r
339   } else {\r
340     JTAG_IR_Slow(ir);\r
341   }\r
342 }\r
343 \r
344 \r
345 // JTAG Transfer I/O\r
346 //   request: A[3:2] RnW APnDP\r
347 //   data:    DATA[31:0]\r
348 //   return:  ACK[2:0]\r
349 uint8_t  JTAG_Transfer(uint32_t request, uint32_t *data) {\r
350   if (DAP_Data.fast_clock) {\r
351     return JTAG_TransferFast(request, data);\r
352   } else {\r
353     return JTAG_TransferSlow(request, data);\r
354   }\r
355 }\r
356 \r
357 \r
358 #endif  /* (DAP_JTAG != 0) */\r