Version 0.04.
[bbg-swd.git] / pru-swd.p
1 //                                                      -*- mode: asm -*-
2 // pru-swd.p - PRU program to handle SWD protocol
3 //
4 // Copyright (C) 2016, 2018  Flying Stone Technology
5 // Author: NIIBE Yutaka <gniibe@fsij.org>
6 //
7 // This file is a part of BBG-SWD, a SWD tool for BeagleBoneGreen.
8 //
9 // BBG-SWD is free software: you can redistribute it and/or modify it
10 // under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
13 //
14 // BBG-SWD is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 // General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 //
22
23 .origin 0
24 .entrypoint START
25
26 #define CONST_DELAY             10 // 100ns
27
28 //
29 //      DELAY - Macro for do nothing but wait
30 //
31 .macro  DELAY
32         JAL     r29.w0, DELAY_10NS
33 .endm
34
35
36 #define PRU0_ARM_INTERRUPT      19
37 #define ARM_PRU0_INTERRUPT      21
38
39 // Constant Table
40 #define CT_PRUCFG       C4
41 #define CT_PRUDRAM      C24
42
43 //  PRU Control register
44 #define PRU0_CTRL 0x00022000    // address
45 #define WAKEUP_EN 8             // offset
46
47 // PRU CFG registers
48 #define SYSCFG          4 // offset
49 #define STANDBY_INIT    4 // bit
50
51 // PRU INTC registers
52 #define INTC      0x00020000    // address
53 #define INTC_SICR       0x24    // offset
54
55 // P8_11 GPIO1_13 GPIO_45 SWD_DIO
56 // P8_12 GPIO1_12 GPIO_44 SWD_CLK
57 // P8_15 GPIO1_15 GPIO_47 nRST
58 #define SWD_NRST_BIT 15
59 #define SWD_DIO_BIT 13
60 #define SWD_CLK_BIT 12
61 #define SWD_DIO (1<<SWD_DIO_BIT)
62 #define SWD_CLK (1<<SWD_CLK_BIT)
63
64 #define GPIO1_BASE_0100   0x4804c100
65 // offsets
66 #define GPIO_OE                 0x34
67 #define GPIO_DATAIN             0x38
68 #define GPIO_CLEARDATAOUT       0x90
69 #define GPIO_SETDATAOUT         0x94
70
71 // LED
72 // bit 21: USR0, 22: USR1, 23: USR2, 24: USR3
73
74 // No operation but delay
75 #define NOP     OR      r0, r0, r0
76
77 #define CTBIR_0         0x22020
78
79 //
80 //      DRIVE_CLK_HIGH - Macro to drive SWD_CLK "High"
81 //
82 .macro  DRIVE_CLK_HIGH
83         SBBO    r7, r5, GPIO_SETDATAOUT, 4
84 .endm
85
86 //
87 //      DRIVE_CLK_LOW - Macro to drive SWD_CLK "Low"
88 //
89 .macro  DRIVE_CLK_LOW
90         SBBO    r7, r5, GPIO_CLEARDATAOUT, 4
91 .endm
92
93 //
94 //      DRIVE_DIO_HIGH - Macro to drive SWD_DIO "High"
95 //
96 .macro  DRIVE_DIO_HIGH
97         SBBO    r6, r5, GPIO_SETDATAOUT, 4
98 .endm
99
100 //
101 //      DRIVE_DIO_LOW - Macro to drive SWD_DIO "Low"
102 //
103 .macro  DRIVE_DIO_LOW
104         SBBO    r6, r5, GPIO_CLEARDATAOUT, 4
105 .endm
106
107 //
108 //      TRN_INPUT - Macro to do TRN-bit for preparing input
109 //
110 .macro  TRN_INPUT
111         DRIVE_CLK_LOW
112         SET_DIO_INPUT r2
113         DELAY
114         NOP
115         DRIVE_CLK_HIGH
116         DELAY
117         NOP
118         NOP
119 .endm
120
121 START:
122         // Enable OCP master port to access GPIO
123         LBCO    r0, CT_PRUCFG, SYSCFG, 4
124         CLR     r0, r0, STANDBY_INIT
125         SBCO    r0, CT_PRUCFG, SYSCFG, 4
126
127         // Configure C24 to 0x00000000 (PRU0 DRAM)
128         LDI     r0, #0
129         MOV     r1, CTBIR_0
130         SBBO    r0, r1, 0, 4
131
132         // Registers for constant values
133         MOV     r5, #GPIO1_BASE_0100
134         LDI     r6, #SWD_DIO
135         LDI     r7, #SWD_CLK
136
137         // Initialize NRST, SWD_DIO and SWD_CLK pins
138         DRIVE_DIO_HIGH
139         DRIVE_CLK_HIGH
140         // NRST_oe <= Output
141         // SWD_DIO_oe <= Output
142         // SWD_CLK_oe <= Output
143         LBBO    r0, r5, GPIO_OE, 4
144         CLR     r0, SWD_NRST_BIT
145         CLR     r0, SWD_DIO_BIT
146         CLR     r0, SWD_CLK_BIT
147         SBBO    r0, r5, GPIO_OE, 4
148
149         // Wakeup control configuration
150         MOV     r0, #PRU0_CTRL
151         MOV     r1, #0xffffffff
152         SBBO    r1, r0, WAKEUP_EN, 4
153
154         // Clear the counter
155         LDI     r0, #0
156         SBCO    r0, CT_PRUDRAM, 72, 4
157
158         QBA     COMMAND_LOOP
159
160 //
161 //      BLINK - Blink LED
162 //
163 BLINK:
164         LBCO    r0, CT_PRUDRAM, 4, 12
165         //
166         // R0 = delay
167         // R1 = number of loops
168         // R2 = LED bit value
169         //
170 LOOP0:
171         SBBO    r2, r5, GPIO_SETDATAOUT, 4
172         MOV     r3, r0
173 LOOP1:
174         SUB     r3, r3, 1
175         QBNE    LOOP1, r3, 0
176
177         SBBO    r2, r5, GPIO_CLEARDATAOUT, 4
178         MOV     r3, r0
179 LOOP2:
180         SUB     r3, r3, 1
181         QBNE    LOOP2, r3, 0
182
183         SUB     r1, r1, 1
184         QBNE    LOOP0, r1, 0
185
186         LDI     r0, #0
187         SBCO    r0, CT_PRUDRAM, 64, 4
188         QBA     COMMAND_DONE
189
190
191 //
192 //      GPIO_OUT - Output to GPIO pin
193 //
194 GPIO_OUT:
195         //
196         // R0 = bit-value
197         // R1 = value
198         //
199         LBCO    r0, CT_PRUDRAM, 4, 8
200         //
201         QBBS    L_GPIO_OUT_1, r1.t0
202         SBBO    r0, r5, GPIO_CLEARDATAOUT, 4
203         QBA     L_GPIO_OUT_DONE
204 L_GPIO_OUT_1:
205         SBBO    r0, r5, GPIO_SETDATAOUT, 4
206         NOP
207 L_GPIO_OUT_DONE:
208         //
209         LDI     r0, #0
210         SBCO    r0, CT_PRUDRAM, 64, 4
211         QBA     COMMAND_DONE
212
213
214 //
215 //      GPIO_IN - Input from GPIO pin
216 //
217 GPIO_IN:
218         LBBO    r0, r5, GPIO_DATAIN, 4
219         //
220         // RETURN: Value
221         SBCO    r0, CT_PRUDRAM, 64, 4
222         QBA     COMMAND_DONE
223
224
225 //
226 //      SET_DIO_OUTPUT - Macro to set mode of SWD_DIO to output
227 //
228 .macro  SET_DIO_OUTPUT
229 .mparam rx
230         // SWD_DIO_oe <= Output
231         LBBO    rx, r5, GPIO_OE, 4
232         CLR     rx, SWD_DIO_BIT
233         SBBO    rx, r5, GPIO_OE, 4
234 .endm
235         
236 //
237 //      SET_DIO_INPUT - Macro to set mode of SWD_DIO to input
238 //
239 .macro  SET_DIO_INPUT
240 .mparam rx
241         // SWD_DIO_oe <= Input
242         LBBO    rx, r5, GPIO_OE, 4
243         SET     rx, SWD_DIO_BIT
244         SBBO    rx, r5, GPIO_OE, 4
245 .endm
246
247 DO_SIG_IDLE:
248 L_SIG_IDLE:
249         DRIVE_CLK_LOW
250         DELAY
251         NOP
252         NOP
253         DRIVE_CLK_HIGH
254         DELAY
255         SUB     r0, r0, 1
256         QBNE    L_SIG_IDLE, r0, 0
257         RET
258
259 //
260 //      SIG_IDLE - Park SWD_DIO = Low and strobe SWD_CLK
261 //
262 SIG_IDLE:
263         //
264         // R0 = count
265         //
266         LBCO    r0, CT_PRUDRAM, 4, 4
267         //
268         DRIVE_DIO_LOW
269         //
270         JAL     r30.w0, DO_SIG_IDLE
271         //
272         DRIVE_DIO_HIGH
273         //
274         LDI     r0, #0
275         SBCO    r0, CT_PRUDRAM, 64, 4
276         QBA     COMMAND_DONE
277
278 //
279 //      SIG_GEN - Generate signal pattern on SWD_DIO with SWD_CLK strobe
280 //
281 SIG_GEN:
282         //
283         // R0 = bit-count
284         //
285         LDI     r0, #0
286         LBCO    r0.b0, CT_PRUDRAM, 1, 1
287         //
288         // R16..R23: Bit pattern (256-bit maximum)
289         //
290         LBCO    r16, CT_PRUDRAM, 4, 32
291         //
292         // Start with r16, from LSB
293         MOV     r1.b0, &r16
294         LDI     r2, #1
295         MVID    r3, *r1.b0++
296 L_GEN_LOOP:
297         SUB     r0, r0, 1
298         LSL     r2, r2, 1
299         QBBS    L_GEN_BIT1, r3.t0
300         LSR     r3, r3, 1
301         DRIVE_CLK_LOW
302         DRIVE_DIO_LOW
303         QBA     L_GEN_BIT_DONE
304         //
305 L_NO_LOAD:
306         NOP
307         QBA     L_NEXT_BIT
308         //
309 L_GEN_BIT1:
310         LSR     r3, r3, 1
311         DRIVE_CLK_LOW
312         DRIVE_DIO_HIGH
313         NOP
314 L_GEN_BIT_DONE:
315         //
316         DELAY
317         QBNE    L_NO_LOAD, r2, 0
318         MVID    r3, *r1.b0++
319         LDI     r2, #1
320 L_NEXT_BIT:
321         DRIVE_CLK_HIGH
322         DELAY
323         QBNE    L_GEN_LOOP, r0, 0
324         //
325 L_SIG_GEN_DONE:
326         LDI     r0, #0
327         SBCO    r0, CT_PRUDRAM, 64, 4
328         //
329         DRIVE_DIO_HIGH
330         QBA     COMMAND_DONE
331
332 ///////////////////////////////////////////////////////////////////////////
333 COMMAND_DONE:
334         // Increment the counter
335         LBCO    r0, CT_PRUDRAM, 72, 4
336         ADD     r0, r0, #1
337         SBCO    r0, CT_PRUDRAM, 72, 4
338
339         // Clear the event
340         MOV     r1, #INTC
341         LDI     r2, #ARM_PRU0_INTERRUPT
342         SBBO    r2, r1, INTC_SICR, 4
343
344         // Notify Host
345         MOV     r31.b0, PRU0_ARM_INTERRUPT+16
346
347 COMMAND_LOOP:
348         // Wait until host wakes up PRU0
349         SLP     1
350
351         // Load values from data RAM into register R0
352         LBCO    r0, CT_PRUDRAM, 0, 1
353
354         QBBS    L_1xx, r0.t2
355         QBBS    L_01x, r0.t1
356         QBBS    L_001, r0.t0
357 L_000:  // Command HALT
358         MOV     r0, #0
359         SBCO    r0, CT_PRUDRAM, 64, 4
360         MOV     r31.b0, PRU0_ARM_INTERRUPT+16
361         HALT
362 L_001:  // Command BLINK
363         QBA     BLINK
364 L_01x:
365         QBBS    L_011, r0.t0
366 L_010:  // Command GPIO_OUT
367         QBA     GPIO_OUT
368 L_011:  // Command GPIO_IN
369         QBA     GPIO_IN
370 L_1xx:
371         QBBS    L_11x, r0.t1
372         QBBS    L_101, r0.t0
373 L_100:  // Command SIG_IDLE
374         QBA     SIG_IDLE
375 L_101:  // Command SIG_GEN
376         QBA     SIG_GEN
377 L_11x:
378         QBBS    L_111, r0.t0
379 L_110:  // Command READ_REG
380         QBA     READ_REG
381 L_111:  // Command WRITE_REG
382         QBA     WRITE_REG
383 ///////////////////////////////////////////////////////////////////////////
384
385 DELAY_10NS: // delay_clocks = CONST_DELAY * 2 + 2
386         LDI     r8, #CONST_DELAY
387 L_DELAY:
388         SUB     r8, r8, 1
389         QBNE    L_DELAY, r8, 1
390         JMP     r29.w0
391
392 //
393 // WRITE_SWD_DIO_BIT_NO_LAST_NOP - Macro writing SWD_DIO bit, but NOP
394 //
395 .macro  WRITE_SWD_DIO_BIT_NO_LAST_NOP
396 .mparam src_bit, label_bit1, label_done
397         QBBS    label_bit1, src_bit
398         DRIVE_CLK_LOW
399         DRIVE_DIO_LOW
400         QBA     label_done
401 label_bit1:
402         DRIVE_CLK_LOW
403         DRIVE_DIO_HIGH
404         NOP
405 label_done:
406         DELAY
407         DRIVE_CLK_HIGH // <---- Target read
408         DELAY
409 .endm
410 //
411 // WRITE_SWD_DIO_BIT_NO_LAST_NOP - Macro writing SWD_DIO bit, with NOP
412 //
413 .macro  WRITE_SWD_DIO_BIT
414 .mparam src_bit, label_bit1, label_done
415         WRITE_SWD_DIO_BIT_NO_LAST_NOP src_bit, label_bit1, label_done
416         NOP
417 .endm
418 //
419 // READ_SWD_DIO_BIT - Macro reading SWD_DIO bit onto register Rx
420 //
421 .macro  READ_SWD_DIO_BIT
422 .mparam rx, ry, label_1, label_done, shift=1
423         DRIVE_CLK_LOW
424         DELAY
425         LBBO    ry, r5, GPIO_DATAIN, 4
426         LSR     rx, rx, shift
427         DRIVE_CLK_HIGH
428         QBBS    label_1, ry, SWD_DIO_BIT
429         QBA     label_done
430 label_1:
431         SET     rx, 31
432 label_done:
433         DELAY
434 .endm
435 //
436 //      READ_REG - execute READ_REG transaction
437 //
438 READ_REG:
439         //
440         // R0 = command
441         //
442         LDI     r0, #0
443         LBCO    r0.b0, CT_PRUDRAM, 1, 1
444         LBCO    r0.b2, CT_PRUDRAM, 3, 1
445         //
446         //
447         //
448         WRITE_SWD_DIO_BIT r0.t0, L_RRC0_BIT1, L_RRC0_DONE
449         WRITE_SWD_DIO_BIT r0.t1, L_RRC1_BIT1, L_RRC1_DONE
450         WRITE_SWD_DIO_BIT r0.t2, L_RRC2_BIT1, L_RRC2_DONE
451         WRITE_SWD_DIO_BIT r0.t3, L_RRC3_BIT1, L_RRC3_DONE
452         WRITE_SWD_DIO_BIT r0.t4, L_RRC4_BIT1, L_RRC4_DONE
453         WRITE_SWD_DIO_BIT r0.t5, L_RRC5_BIT1, L_RRC5_DONE
454         WRITE_SWD_DIO_BIT r0.t6, L_RRC6_BIT1, L_RRC6_DONE
455         WRITE_SWD_DIO_BIT r0.t7, L_RRC7_BIT1, L_RRC7_DONE
456         NOP
457         //
458         TRN_INPUT
459         // Read ACK bits onto R3
460         READ_SWD_DIO_BIT r3, r2, L_RRD0_1, L_RRD0_F
461         READ_SWD_DIO_BIT r3, r2, L_RRD1_1, L_RRD1_F
462         READ_SWD_DIO_BIT r3, r2, L_RRD2_1, L_RRD2_F
463         // Read RDATA bits onto R4
464         READ_SWD_DIO_BIT r4, r2, L_RRD3_1, L_RRD3_F
465         READ_SWD_DIO_BIT r4, r2, L_RRD4_1, L_RRD4_F
466         READ_SWD_DIO_BIT r4, r2, L_RRD5_1, L_RRD5_F
467         READ_SWD_DIO_BIT r4, r2, L_RRD6_1, L_RRD6_F
468         READ_SWD_DIO_BIT r4, r2, L_RRD7_1, L_RRD7_F
469         READ_SWD_DIO_BIT r4, r2, L_RRD8_1, L_RRD8_F
470         READ_SWD_DIO_BIT r4, r2, L_RRD9_1, L_RRD9_F
471         READ_SWD_DIO_BIT r4, r2, L_RRDa_1, L_RRDa_F
472         //
473         READ_SWD_DIO_BIT r4, r2, L_RRDb_1, L_RRDb_F
474         READ_SWD_DIO_BIT r4, r2, L_RRDc_1, L_RRDc_F
475         READ_SWD_DIO_BIT r4, r2, L_RRDd_1, L_RRDd_F
476         READ_SWD_DIO_BIT r4, r2, L_RRDe_1, L_RRDe_F
477         READ_SWD_DIO_BIT r4, r2, L_RRDf_1, L_RRDf_F
478         READ_SWD_DIO_BIT r4, r2, L_RRDg_1, L_RRDg_F
479         READ_SWD_DIO_BIT r4, r2, L_RRDh_1, L_RRDh_F
480         READ_SWD_DIO_BIT r4, r2, L_RRDi_1, L_RRDi_F
481         //
482         READ_SWD_DIO_BIT r4, r2, L_RRDj_1, L_RRDj_F
483         READ_SWD_DIO_BIT r4, r2, L_RRDk_1, L_RRDk_F
484         READ_SWD_DIO_BIT r4, r2, L_RRDl_1, L_RRDl_F
485         READ_SWD_DIO_BIT r4, r2, L_RRDm_1, L_RRDm_F
486         READ_SWD_DIO_BIT r4, r2, L_RRDn_1, L_RRDn_F
487         READ_SWD_DIO_BIT r4, r2, L_RRDo_1, L_RRDo_F
488         READ_SWD_DIO_BIT r4, r2, L_RRDp_1, L_RRDp_F
489         READ_SWD_DIO_BIT r4, r2, L_RRDq_1, L_RRDq_F
490         //
491         READ_SWD_DIO_BIT r4, r2, L_RRDr_1, L_RRDr_F
492         READ_SWD_DIO_BIT r4, r2, L_RRDs_1, L_RRDs_F
493         READ_SWD_DIO_BIT r4, r2, L_RRDt_1, L_RRDt_F
494         READ_SWD_DIO_BIT r4, r2, L_RRDu_1, L_RRDu_F
495         READ_SWD_DIO_BIT r4, r2, L_RRDv_1, L_RRDv_F
496         READ_SWD_DIO_BIT r4, r2, L_RRDw_1, L_RRDw_F
497         READ_SWD_DIO_BIT r4, r2, L_RRDx_1, L_RRDx_F
498         READ_SWD_DIO_BIT r4, r2, L_RRDy_1, L_RRDy_F
499         // Parity bit
500         READ_SWD_DIO_BIT r3, r2, L_RRDz_1, L_RRDz_F, 29
501         // TRN
502         DRIVE_CLK_LOW
503         DELAY
504         NOP
505         NOP
506         DRIVE_CLK_HIGH
507         //
508         DELAY
509         LSR     r0, r0, 16
510         QBEQ    L_SKIP_IDLE_R, r0, 0
511         DRIVE_DIO_LOW
512         SET_DIO_OUTPUT r2
513         JAL     r30.w0, DO_SIG_IDLE
514         //
515 L_SKIP_IDLE_R:
516         DRIVE_DIO_HIGH
517         SET_DIO_OUTPUT r2
518         // RETURN: Parity|Ack, Value
519         SBCO    r3, CT_PRUDRAM, 64, 8
520         QBA     COMMAND_DONE
521
522 //
523 //      WRITE_REG - execute WRITE_REG transaction
524 //
525 WRITE_REG:
526         //
527         // R0 = command + parity_as_t8
528         // R1 = value
529         //
530         LDI     r0, #0
531         LBCO    r0.b0, CT_PRUDRAM, 1, 1
532         LBCO    r0.b1, CT_PRUDRAM, 2, 1
533         LBCO    r0.b2, CT_PRUDRAM, 3, 1
534         LBCO    r1, CT_PRUDRAM, 4, 8
535         //
536         //
537         WRITE_SWD_DIO_BIT r0.t0, L_WRC0_BIT1, L_WRC0_DONE
538         WRITE_SWD_DIO_BIT r0.t1, L_WRC1_BIT1, L_WRC1_DONE
539         WRITE_SWD_DIO_BIT r0.t2, L_WRC2_BIT1, L_WRC2_DONE
540         WRITE_SWD_DIO_BIT r0.t3, L_WRC3_BIT1, L_WRC3_DONE
541         WRITE_SWD_DIO_BIT r0.t4, L_WRC4_BIT1, L_WRC4_DONE
542         WRITE_SWD_DIO_BIT r0.t5, L_WRC5_BIT1, L_WRC5_DONE
543         WRITE_SWD_DIO_BIT r0.t6, L_WRC6_BIT1, L_WRC6_DONE
544         WRITE_SWD_DIO_BIT r0.t7, L_WRC7_BIT1, L_WRC7_DONE
545         NOP
546         //
547         TRN_INPUT
548         // Read ACK bits onto R3
549         READ_SWD_DIO_BIT r3, r2, L_WRA0_1, L_WRA0_F
550         READ_SWD_DIO_BIT r3, r2, L_WRA1_1, L_WRA1_F
551         READ_SWD_DIO_BIT r3, r2, L_WRA2_1, L_WRA2_F
552         //
553         // TRN and WRITE the first bit
554         DRIVE_CLK_LOW
555         DELAY
556         NOP
557         QBBS    L_WRD0_BIT1, r1.t0
558         DRIVE_CLK_HIGH
559         DRIVE_DIO_LOW
560         QBA     L_WRD0_DONE
561 L_WRD0_BIT1:
562         DRIVE_CLK_HIGH
563         DRIVE_DIO_HIGH
564         NOP
565 L_WRD0_DONE:
566         DELAY
567         DRIVE_CLK_LOW
568         SET_DIO_OUTPUT r2
569         DELAY
570         NOP
571         DRIVE_CLK_HIGH
572         DELAY
573         NOP
574         //
575         WRITE_SWD_DIO_BIT r1.t1, L_WRD1_BIT1, L_WRD1_DONE
576         WRITE_SWD_DIO_BIT r1.t2, L_WRD2_BIT1, L_WRD2_DONE
577         WRITE_SWD_DIO_BIT r1.t3, L_WRD3_BIT1, L_WRD3_DONE
578         WRITE_SWD_DIO_BIT r1.t4, L_WRD4_BIT1, L_WRD4_DONE
579         WRITE_SWD_DIO_BIT r1.t5, L_WRD5_BIT1, L_WRD5_DONE
580         WRITE_SWD_DIO_BIT r1.t6, L_WRD6_BIT1, L_WRD6_DONE
581         WRITE_SWD_DIO_BIT r1.t7, L_WRD7_BIT1, L_WRD7_DONE
582         WRITE_SWD_DIO_BIT r1.t8, L_WRD8_BIT1, L_WRD8_DONE
583         WRITE_SWD_DIO_BIT r1.t9, L_WRD9_BIT1, L_WRD9_DONE
584         WRITE_SWD_DIO_BIT r1.t10, L_WRDa_BIT1, L_WRDa_DONE
585         WRITE_SWD_DIO_BIT r1.t11, L_WRDb_BIT1, L_WRDb_DONE
586         WRITE_SWD_DIO_BIT r1.t12, L_WRDc_BIT1, L_WRDc_DONE
587         WRITE_SWD_DIO_BIT r1.t13, L_WRDd_BIT1, L_WRDd_DONE
588         WRITE_SWD_DIO_BIT r1.t14, L_WRDe_BIT1, L_WRDe_DONE
589         WRITE_SWD_DIO_BIT r1.t15, L_WRDf_BIT1, L_WRDf_DONE
590         WRITE_SWD_DIO_BIT r1.t16, L_WRDg_BIT1, L_WRDg_DONE
591         WRITE_SWD_DIO_BIT r1.t17, L_WRDh_BIT1, L_WRDh_DONE
592         WRITE_SWD_DIO_BIT r1.t18, L_WRDi_BIT1, L_WRDi_DONE
593         WRITE_SWD_DIO_BIT r1.t19, L_WRDj_BIT1, L_WRDj_DONE
594         WRITE_SWD_DIO_BIT r1.t20, L_WRDk_BIT1, L_WRDk_DONE
595         WRITE_SWD_DIO_BIT r1.t21, L_WRDl_BIT1, L_WRDl_DONE
596         WRITE_SWD_DIO_BIT r1.t22, L_WRDm_BIT1, L_WRDm_DONE
597         WRITE_SWD_DIO_BIT r1.t23, L_WRDn_BIT1, L_WRDn_DONE
598         WRITE_SWD_DIO_BIT r1.t24, L_WRDo_BIT1, L_WRDo_DONE
599         WRITE_SWD_DIO_BIT r1.t25, L_WRDp_BIT1, L_WRDp_DONE
600         WRITE_SWD_DIO_BIT r1.t26, L_WRDq_BIT1, L_WRDq_DONE
601         WRITE_SWD_DIO_BIT r1.t27, L_WRDr_BIT1, L_WRDr_DONE
602         WRITE_SWD_DIO_BIT r1.t28, L_WRDs_BIT1, L_WRDs_DONE
603         WRITE_SWD_DIO_BIT r1.t29, L_WRDt_BIT1, L_WRDt_DONE
604         WRITE_SWD_DIO_BIT r1.t30, L_WRDu_BIT1, L_WRDu_DONE
605         WRITE_SWD_DIO_BIT r1.t31, L_WRDv_BIT1, L_WRDv_DONE
606         WRITE_SWD_DIO_BIT_NO_LAST_NOP r0.t8, L_WRDw_BIT1, L_WRDw_DONE
607         //
608         LSR     r0, r0, 16
609         QBEQ    L_SKIP_IDLE_W, r0, 0
610         DRIVE_DIO_LOW
611         JAL     r30.w0, DO_SIG_IDLE
612         //
613 L_SKIP_IDLE_W:
614         DRIVE_DIO_HIGH
615         // RETURN: Ack
616         LSR     r3, r3, 29
617         SBCO    r3, CT_PRUDRAM, 64, 4
618         JMP     COMMAND_DONE
619 //
620 // Local Variables:
621 // compile-command: "pasm -V3 -l -b pru-swd.p"
622 // End:
623 //