turn ftdi driver into echo server
[goodfet] / firmware / apps / jtag / openocd.c
1 /*! \file openocd.c
2   \author Dave Huseby <dave at linuxprogrammer.org>
3   \brief OpenOCD firmware
4 */
5
6
7 #include "platform.h"
8 #include "command.h"
9 #include "openocd.h"
10 #include "jtag.h"
11
12 #define OPENOCD_APP
13
14 //! Handles a monitor command.
15 void openocd_handle_fn(uint8_t const app,
16                                            uint8_t const verb,
17                                            uint32_t const len);
18
19 // define the openocd app's app_t
20 app_t const openocd_app = {
21
22         /* app number */
23         OPENOCD,
24
25         /* handle fn */
26         openocd_handle_fn,
27
28         /* name */
29         "OpenOCD",
30
31         /* desc */
32         "\tThe OpenOCD app handles the OpenOCD bitbang protocol.\n"
33 };
34
35 //! Clock the JTAG clock line
36 static void openocd_tcktock() 
37 {
38         CLRTCK; 
39         SETTCK; 
40 }
41
42 //! reset the cpu
43 static void openocd_reset_cpu(void)
44 {
45         SETRST;
46         msdelay(100);
47         CLRRST;
48         msdelay(100);
49         SETRST;
50         msdelay(100);
51 }
52
53 //! reset the tap logic
54 static void openocd_reset_test_logic(void)
55 {
56         CLRMOSI;
57         SETTMS;
58         openocd_tcktock();
59         openocd_tcktock();
60         openocd_tcktock();
61         openocd_tcktock();
62         openocd_tcktock(); // now in reset-test-logic
63         CLRTMS;
64         openocd_tcktock();  // now in run-test-idle state
65 }
66
67 //! sets the LED value
68 void openocd_led(int led)
69 {
70         if (led)
71                 /* turn the LED on */
72                 led_on();
73         else
74                 /* turn the LED off */
75                 led_off();
76 }
77
78 //! resets the device/JTAG logic
79 void openocd_reset(int trst, int srst)
80 {
81         if(srst && trst)
82         {
83                 // we need to drive TST from low to high at
84                 // the same time as the RST
85                 SETTST;
86                 SETRST;
87                 msdelay(100);
88                 CLRTST;
89                 CLRRST;
90                 msdelay(100);
91                 SETTST;
92                 SETRST;
93                 msdelay(100);
94         }
95         else if (!srst && trst)
96         {
97                 openocd_reset_test_logic();
98         }
99         else if(srst && !trst)
100         {
101                 openocd_reset_cpu();
102         }
103 }
104
105 //! updates the tck, tms, and tdi values
106 void openocd_write(int tck, int tms, int tdi)
107 {
108         if(tms)
109                 SETTMS;
110         else
111                 CLRTMS;
112
113         if(tdi)
114                 SETMOSI;
115         else
116                 CLRMOSI;
117
118         if(tck)
119                 SETTCK;
120         else
121                 CLRTCK;
122 }
123
124 //! Stop JTAG, release pins
125 void openocd_stop()
126 {
127         P5OUT=0;
128         P4OUT=0;
129 }
130
131 //! Set up the pins for JTAG mode.
132 void openocd_setup()
133 {
134         P5DIR|=MOSI+SCK+TMS;
135         P5DIR&=~MISO;
136         P4DIR|=TST;
137         P2DIR|=RST;
138         msdelay(100);
139 }
140
141 //! handles OpenOCD commands
142 void openocd_handle_fn(uint8_t const app,
143                                            uint8_t const verb,
144                                            uint32_t const len)
145 {
146         switch(verb)
147         {
148                 case START:
149                         /* do nothing...*/
150                         txdata(app,OK,0);
151                         break;
152
153                 case STOP:
154                         openocd_stop();
155                         txdata(app,OK,0);
156                         break;
157
158                 case SETUP:
159                         openocd_setup();
160                         txdata(app,OK,0);
161                         break;
162
163                 case OPENOCD_RESET:
164                         openocd_reset(cmddata[0], cmddata[1]);
165                         txdata(app,OK,0);
166                         break;
167
168                 case OPENOCD_READ:
169                         cmddata[0] = READMISO;
170                         txdata(app,OK,1);
171                         break;
172
173                 case OPENOCD_WRITE:
174                         openocd_write(cmddata[0], cmddata[1], cmddata[2]);
175                         txdata(app,OK,0);
176                         break;
177
178                 case OPENOCD_LED:
179                         openocd_led(cmddata[0]);
180                         txdata(app,OK,0);
181                         break;
182
183                 default:
184                         txdata(app,NOK,0);
185         }
186 }
187
188