2 // pru-swd.p - PRU program to handle SWD protocol
4 // Copyright (C) 2016 Flying Stone Technology
5 // Author: NIIBE Yutaka <gniibe@fsij.org>
7 // This file is a part of BBG-SWD, a SWD tool for BeagleBoneGreen.
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.
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.
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/>.
26 #define CONST_DELAY 47 // 470ns To be 1000 kHz
29 // DELAY - Macro for do nothing but wait
32 JAL r29.w0, DELAY_10NS
36 #define PRU0_ARM_INTERRUPT 19
37 #define ARM_PRU0_INTERRUPT 21
41 #define CT_PRUDRAM C24
43 // PRU Control register
44 #define PRU0_CTRL 0x00022000 // address
45 #define WAKEUP_EN 8 // offset
48 #define SYSCFG 4 // offset
49 #define STANDBY_INIT 4 // bit
52 #define INTC 0x00020000 // address
53 #define INTC_SICR 0x24 // offset
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)
64 #define GPIO1_BASE_0100 0x4804c100
67 #define GPIO_DATAIN 0x38
68 #define GPIO_CLEARDATAOUT 0x90
69 #define GPIO_SETDATAOUT 0x94
72 // bit 21: USR0, 22: USR1, 23: USR2, 24: USR3
74 // No operation but delay
75 #define NOP OR r0, r0, r0
77 #define CTBIR_0 0x22020
80 // DRIVE_CLK_HIGH - Macro to drive SWD_CLK "High"
83 SBBO r7, r5, GPIO_SETDATAOUT, 4
87 // DRIVE_CLK_LOW - Macro to drive SWD_CLK "Low"
90 SBBO r7, r5, GPIO_CLEARDATAOUT, 4
94 // DRIVE_DIO_HIGH - Macro to drive SWD_DIO "High"
97 SBBO r6, r5, GPIO_SETDATAOUT, 4
101 // DRIVE_DIO_LOW - Macro to drive SWD_DIO "Low"
104 SBBO r6, r5, GPIO_CLEARDATAOUT, 4
108 // TRN_INPUT - Macro to do TRN-bit for preparing input
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
127 // Configure C24 to 0x00000000 (PRU0 DRAM)
132 // Registers for constant values
133 MOV r5, #GPIO1_BASE_0100
137 // Initialize NRST, SWD_DIO and SWD_CLK pins
141 // SWD_DIO_oe <= Output
142 // SWD_CLK_oe <= Output
143 LBBO r0, r5, GPIO_OE, 4
147 SBBO r0, r5, GPIO_OE, 4
149 // Wakeup control configuration
152 SBBO r1, r0, WAKEUP_EN, 4
156 SBCO r0, CT_PRUDRAM, 72, 4
164 LBCO r0, CT_PRUDRAM, 4, 12
167 // R1 = number of loops
168 // R2 = LED bit value
171 SBBO r2, r5, GPIO_SETDATAOUT, 4
177 SBBO r2, r5, GPIO_CLEARDATAOUT, 4
187 SBCO r0, CT_PRUDRAM, 64, 4
192 // GPIO_OUT - Output to GPIO pin
199 LBCO r0, CT_PRUDRAM, 4, 8
201 QBBS L_GPIO_OUT_1, r1.t0
202 SBBO r0, r5, GPIO_CLEARDATAOUT, 4
205 SBBO r0, r5, GPIO_SETDATAOUT, 4
210 SBCO r0, CT_PRUDRAM, 64, 4
215 // GPIO_IN - Input from GPIO pin
218 LBBO r0, r5, GPIO_DATAIN, 4
221 SBCO r0, CT_PRUDRAM, 64, 4
226 // SET_DIO_OUTPUT - Macro to set mode of SWD_DIO to output
228 .macro SET_DIO_OUTPUT
230 // SWD_DIO_oe <= Output
231 LBBO rx, r5, GPIO_OE, 4
233 SBBO rx, r5, GPIO_OE, 4
237 // SET_DIO_INPUT - Macro to set mode of SWD_DIO to input
241 // SWD_DIO_oe <= Input
242 LBBO rx, r5, GPIO_OE, 4
244 SBBO rx, r5, GPIO_OE, 4
256 QBNE L_SIG_IDLE, r0, 0
260 // SIG_IDLE - Park SWD_DIO = Low and strobe SWD_CLK
266 LBCO r0, CT_PRUDRAM, 4, 4
270 JAL r30.w0, DO_SIG_IDLE
275 SBCO r0, CT_PRUDRAM, 64, 4
279 // SIG_GEN - Generate signal pattern on SWD_DIO with SWD_CLK strobe
286 LBCO r0.b0, CT_PRUDRAM, 1, 1
288 // R16..R23: Bit pattern (256-bit maximum)
290 LBCO r16, CT_PRUDRAM, 4, 32
292 // Start with r16, from LSB
299 QBBS L_GEN_BIT1, r3.t0
317 QBNE L_NO_LOAD, r2, 0
323 QBNE L_GEN_LOOP, r0, 0
327 SBCO r0, CT_PRUDRAM, 64, 4
332 ///////////////////////////////////////////////////////////////////////////
334 // Increment the counter
335 LBCO r0, CT_PRUDRAM, 72, 4
337 SBCO r0, CT_PRUDRAM, 72, 4
341 LDI r2, #ARM_PRU0_INTERRUPT
342 SBBO r2, r1, INTC_SICR, 4
345 MOV r31.b0, PRU0_ARM_INTERRUPT+16
348 // Wait until host wakes up PRU0
351 // Load values from data RAM into register R0
352 LBCO r0, CT_PRUDRAM, 0, 1
357 L_000: // Command HALT
359 SBCO r0, CT_PRUDRAM, 64, 4
360 MOV r31.b0, PRU0_ARM_INTERRUPT+16
362 L_001: // Command BLINK
366 L_010: // Command GPIO_OUT
368 L_011: // Command GPIO_IN
373 L_100: // Command SIG_IDLE
375 L_101: // Command SIG_GEN
379 L_110: // Command READ_REG
381 L_111: // Command WRITE_REG
383 ///////////////////////////////////////////////////////////////////////////
385 DELAY_10NS: // delay_clocks = CONST_DELAY * 2 + 2
393 // WRITE_SWD_DIO_BIT_NO_LAST_NOP - Macro writing SWD_DIO bit, but NOP
395 .macro WRITE_SWD_DIO_BIT_NO_LAST_NOP
396 .mparam src_bit, label_bit1, label_done
397 QBBS label_bit1, src_bit
407 DRIVE_CLK_HIGH // <---- Target read
411 // WRITE_SWD_DIO_BIT_NO_LAST_NOP - Macro writing SWD_DIO bit, with NOP
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
419 // READ_SWD_DIO_BIT - Macro reading SWD_DIO bit onto register Rx
421 .macro READ_SWD_DIO_BIT
422 .mparam rx, ry, label_1, label_done, shift=1
425 LBBO ry, r5, GPIO_DATAIN, 4
428 QBBS label_1, ry, SWD_DIO_BIT
436 // READ_REG - execute READ_REG transaction
443 LBCO r0.b0, CT_PRUDRAM, 1, 1
444 LBCO r0.b2, CT_PRUDRAM, 3, 1
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
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
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
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
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
500 READ_SWD_DIO_BIT r3, r2, L_RRDz_1, L_RRDz_F, 29
510 QBEQ L_SKIP_IDLE_R, r0, 0
513 JAL r30.w0, DO_SIG_IDLE
518 // RETURN: Parity|Ack, Value
519 SBCO r3, CT_PRUDRAM, 64, 8
523 // WRITE_REG - execute WRITE_REG transaction
527 // R0 = command + parity_as_t8
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
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
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
553 // TRN and WRITE the first bit
557 QBBS L_WRD0_BIT1, r1.t0
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
609 QBEQ L_SKIP_IDLE_W, r0, 0
611 JAL r30.w0, DO_SIG_IDLE
617 SBCO r3, CT_PRUDRAM, 64, 4
621 // compile-command: "pasm -V3 -l -b pru-swd.p"