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