1 /*
2 * Copyright (C) 2007 - 2014 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include "archFpga.h"
35 #include "arch.h"
36 #include "hilDelays.h"
37 #include "hilFpgaAccess.h"
38 #include "hw_compiler_specific.h"
39
40 // structs representing ports for FPGA communication
41 s_FPGA_PA FPGA_PORTA;
42 s_FPGA_PB FPGA_PORTB;
43
44 unsigned char lastTestState = 0;
45 unsigned char lastResetState= 0;
46
47 static struct jtag _Jtag = {0};
48
49 extern unsigned short gprotocol_id;
50 unsigned short static volatile TimeOut = FET_FALSE;
51
hil_fpga_init(void)52 void hil_fpga_init(void)
53 {
54 // Port1
55 // P1.0 -> DATA0[0]
56 // P1.1 -> DATA0[1]
57 // P1.2 -> DATA0[2]
58 // P1.3 -> DATA0[3]
59 // P1.4 -> DATA0[4]
60 // P1.5 -> DATA0[5]
61 // P1.6 -> DATA0[6]
62 // P1.7 -> DATA0[7]
63 P1DIR |= (BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7); // set pins to output direction
64 P1SEL &= ~(BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7);
65
66 // Port2
67 // P2.0 <- DCDC_PULSE
68 // P2.1 <- UART_RTS
69 // P2.2 -> CMD[0]
70 // P2.3 -> CMD[1]
71 // P2.4 -> CMD[2]
72 // P2.5 -> CMD[3]
73 // P2.6 -> WR_TRIG
74 // P2.7 -> SYS_CLK
75 P2DIR |= (BIT2+BIT3+BIT4+BIT5+BIT6+BIT7); // set pins to output direction
76 P2SEL &= ~(BIT2+BIT3+BIT4+BIT5+BIT6+BIT7);
77
78 // Port3
79 // P3.0 <-> DATA1[0]
80 // P3.1 <-> DATA1[1]
81 // P3.2 <-> DATA1[2]
82 // P3.3 <-> DATA1[3]
83 // P3.4 <-> DATA1[4]
84 // P3.5 <-> DATA1[5]
85 // P3.6 <-> DATA1[6]
86 // P3.7 <-> DATA1[7]
87 P3DIR |= (BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7); // set pins initially to output direction
88 P3SEL &= ~(BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7);
89
90 // Port4
91 // P4.0 <-> DATA1[8]
92 // P4.1 <-> DATA1[9]
93 // P4.2 <-> DATA1[10]
94 // P4.3 <-> DATA1[11]
95 // P4.4 <-> DATA1[12]
96 // P4.5 <-> DATA1[13]
97 // P4.6 <-> DATA1[14]
98 // P4.7 <-> DATA1[15]
99 P4DIR |= (BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7); // set pins initially to output direction
100 P4SEL &= ~(BIT0+BIT1+BIT2+BIT3+BIT4+BIT5+BIT6+BIT7);
101
102 // Port5
103 // P5.0 -> VREF+ (output of reference voltage to ADC)
104 // P5.1 -> FPGA_RESET
105 // P5.2 -> VF2TEST_CTRL
106 // P5.3 -> LED1
107 // P5.4 -> VF2TDI_CTRL
108 // P5.5 -> TDIOFF_CTRL (0 = turns off TDI, after that ok to select VF for fuse blowing)
109 // P5.6 <- MCU_DMAE0 / RD_TRIG (DMA trigger input)
110 // P5.7 -> DCDC_IO1
111 P5DIR |= (BIT1+BIT2+BIT4+BIT5); // set pins initially to output direction
112 P5DIR &= ~(BIT6);
113 P5OUT |= (BIT5);
114 P5OUT &= ~(BIT2+BIT4);
115
116 // Port8
117 // P8.0 -> VCC_DT2TRGT_CTRL (control signal to switches to provide debug signals to target via JTAG.x)
118 // P8.1 -> IO_DIR
119 // P8.2 -> UART_TXD
120 // P8.3 <- UART_RXD
121 // P8.4 <- DCDC_IO0
122 // P8.5 -> HOST_SDA
123 // P8.6 -> HOST_SCL
124 // P8.7 -> VCC_SUPPLY2TRGT_CTRL (DCDC VCC to target VCC)
125 P8OUT |= (BIT1); // set pins to '1'
126 P8DIR |= (BIT1); // set pins initially to output direction
127
128 // Port9
129 // P9.0 -> FPGA_TCK
130 // P9.1 -> FPGA_TDI
131 // P9.2 -> FPGA_TMS
132 // P9.3 <- FPGA_TDO
133 // P9.4 -> FPGA_TRST
134 // P9.5 -> UART_CTS
135 // P9.6 -> VCC_DT2SUPPLY_CTRL (DT voltage to target VCC)
136 // P9.7 -> PWM_SETVF (to fuse blow circuit)
137 P9OUT |= BIT0+BIT1+BIT2+BIT4;
138 P9OUT &= ~(BIT3);
139 P9DIR |= BIT0+BIT1+BIT2+BIT4+BIT7; // TDO is in, all others out
140 P9DIR &= ~(BIT3);
141 P9REN |= BIT3; // TDO with pulldown
142
143
144 // SYS_CLK: Output 20MHz MCLK on P2.7
145 _DINT_FET(); // Disable Interrupts before altering Port Mapping registers
146 PMAPPWD = 0x02D52; // Enable Write-access to modify port mapping registers
147 PMAPCTL = PMAPRECFG; // Allow reconfiguration during runtime
148 P2MAP7 = PM_MCLK;
149 PMAPPWD = 0; // Disable Write-Access to modify port mapping registers
150 _EINT_FET(); // Re-enable all interrupts
151
152 // Reset FPGA
153 FPGA_RESET_DEASSERT;
154 __delay_cycles(100);
155 FPGA_RESET_ASSERT;
156
157 // Reset the internal structure
158 FPGA_PORTA.all = 0;
159 FPGA_PORTA.bit.CMD = 0xF;
160 FPGA_CMD_DATA0_PORT_OUT = FPGA_PORTA.all;
161
162 // Enable SYS_CLK
163 __delay_cycles(100);
164 FPGA_SYS_CLK_START;
165
166 __delay_cycles(10000);
167 FPGA_RESET_DEASSERT;
168
169 lastTestState = 0;
170 lastResetState= 1;
171
172 TimeOut = FET_FALSE;
173 }
174
startWdtTimeOutCounter(unsigned long timeout)175 static void startWdtTimeOutCounter(unsigned long timeout)
176 {
177 TimeOut = FET_FALSE;
178 // Start WDT timer use SMCLK 20 MHz, timer mode, and clear timer, timout is 6.4 s
179 WDTCTL = WDTPW + WDTSSEL__SMCLK + WDTCNTCL + WDTTMSEL + timeout;
180 SFRIE1 |= WDTIE;
181 SFRIFG1 &= ~WDTIFG;
182 }
183
stopWdtTimeOutCounter()184 static void stopWdtTimeOutCounter()
185 {
186 // Stop watchdog timer
187 WDTCTL = WDTPW + WDTHOLD;
188 SFRIE1 &= ~WDTIE;
189 SFRIFG1 &= ~WDTIFG;
190 }
191
_hil_FpgaAccess_setTimeOut(unsigned short state)192 void _hil_FpgaAccess_setTimeOut(unsigned short state)
193 {
194 TimeOut = state;
195
196 // Reset FPGA
197 FPGA_RESET_DEASSERT;
198 __delay_cycles(100);
199 FPGA_RESET_ASSERT;
200
201 // Enable SYS_CLK
202 __delay_cycles(100);
203 FPGA_SYS_CLK_START;
204
205 __delay_cycles(10000);
206 FPGA_RESET_DEASSERT;
207
208 lastTestState = 0;
209 lastResetState= 1;
210 }
211
initJtagBypass(struct jtag tmp)212 void initJtagBypass(struct jtag tmp)
213 {
214 _Jtag = tmp;
215 }
216
217 //enable bypass
hil_fpga_enable_bypass()218 void hil_fpga_enable_bypass()
219 {
220 FPGA_BYPASS_DIR_CTRL_PORT_DIR = FPGA_BYPASS_DIR_CTRL_TEST_BIT + FPGA_BYPASS_DIR_CTRL_RST_BIT + FPGA_BYPASS_DIR_CTRL_TDO_BIT + FPGA_BYPASS_DIR_CTRL_TDI_BIT + FPGA_BYPASS_DIR_CTRL_TMS_BIT + FPGA_BYPASS_DIR_CTRL_TCK_BIT;
221
222 /*------------------------ test pin state handling ----------------------*/
223 if (lastTestState)
224 {
225 (*_Jtag.Out) |= _Jtag.TST;
226 }
227 else
228 {
229 (*_Jtag.Out) &= ~_Jtag.TST;
230 }
231
232 /*------------------------ RST pin state handling ----------------------*/
233 if(lastResetState)
234 {
235 (*_Jtag.Out) |= _Jtag.RST;
236 }
237 else
238 {
239 (*_Jtag.Out) &= ~_Jtag.RST;
240 }
241
242 if( gprotocol_id == SPYBIWIRE || gprotocol_id == SPYBIWIRE_MSP_FET)
243 {
244 (*_Jtag.DIRECTION) = _Jtag.TST + _Jtag.RST;
245 FPGA_BYPASS_DIR_CTRL_PORT_OUT = _Jtag.TST + _Jtag.RST;
246 }
247 if( gprotocol_id == SPYBIWIREJTAG || gprotocol_id == JTAG || gprotocol_id == JTAG_432 || gprotocol_id == SWD_432)
248 {
249 (*_Jtag.Out) |= (_Jtag.TCK + _Jtag.TDI);
250 (*_Jtag.DIRECTION) = _Jtag.TST + _Jtag.RST + _Jtag.TDI + _Jtag.TMS + _Jtag.TCK;
251 FPGA_BYPASS_DIR_CTRL_PORT_OUT = _Jtag.TST + _Jtag.RST + _Jtag.TDI + _Jtag.TMS + _Jtag.TCK;
252 }
253
254 // Enable bypass mode
255 hil_fpga_write_cmd_data0(FPGA_CMD_BYPASS, 1);
256
257 FPGA_IO_DIR_PORT_OUT &= ~FPGA_IO_DIR_BIT;
258
259 _hil_Delay_1ms(10);
260 }
261
262
263 // Leave bypass
hil_fpga_disable_bypass(void)264 void hil_fpga_disable_bypass(void)
265 {
266 if((*_Jtag.Out) & _Jtag.TST)
267 {
268 lastTestState = 1;
269 }
270 else
271 {
272 lastTestState = 0;
273 }
274 if((*_Jtag.Out) & _Jtag.RST)
275 {
276 lastResetState = 1;
277 }
278 else
279 {
280 lastResetState = 0;
281 }
282
283 FPGA_IO_DIR_PORT_OUT |= FPGA_IO_DIR_BIT;
284 // Disable bypass mode
285 hil_fpga_write_cmd_data0(FPGA_CMD_BYPASS, 0);
286 _hil_Delay_1us(10);
287 }
288
hil_fpga_write_cmd_data0(unsigned char cmd,unsigned char data0)289 void hil_fpga_write_cmd_data0(unsigned char cmd, unsigned char data0)
290 {
291 // Assemble PORTA data
292 FPGA_PORTA.bit.CMD = cmd;
293 FPGA_PORTA.bit.DATA0 = data0;
294 FPGA_PORTA.bit.WR_TRIG ^= 1;
295
296 startWdtTimeOutCounter(WDTIS__128M);
297 // Wait until RD_TRIG = 1 and FPGA is ready to accept data
298 while ((!FPGA_RD_TRIG_IS_ASSERTED))
299 {
300 if(TimeOut){break;}
301 }
302 stopWdtTimeOutCounter();
303
304 // Write to FPGA
305 FPGA_CMD_DATA0_PORT_OUT = FPGA_PORTA.all;
306 }
307
308
hil_fpga_write_cmd_data0_432(unsigned char cmd,unsigned char data0)309 void hil_fpga_write_cmd_data0_432(unsigned char cmd, unsigned char data0)
310 {
311 // Assemble PORTA data
312 FPGA_PORTA.bit.CMD = cmd;
313 FPGA_PORTA.bit.DATA0 = data0;
314 FPGA_PORTA.bit.WR_TRIG ^= 1;
315
316 // Wait until RD_TRIG = 1 and FPGA is ready to accept data
317 while ((!FPGA_RD_TRIG_IS_ASSERTED));
318
319 // Write to FPGA
320 FPGA_CMD_DATA0_PORT_OUT = FPGA_PORTA.all;
321 }
322
323 // Write CMD, DATA0 and DATA1 to FPGA
hil_fpga_write_cmd_data0_data1(unsigned char cmd,unsigned char data0,unsigned short data1)324 void hil_fpga_write_cmd_data0_data1(unsigned char cmd, unsigned char data0, unsigned short data1)
325 {
326 // Set DATA1 bus to output direction
327 FPGA_IO_DIR_PORT_OUT |= FPGA_IO_DIR_BIT;
328 FPGA_DATA1_PORT_DIR = 0xFFFF;
329
330 // Assemble PORTA data
331 FPGA_PORTA.bit.CMD = cmd;
332 FPGA_PORTA.bit.DATA0 = data0;
333 FPGA_PORTA.bit.WR_TRIG ^= 1;
334
335 startWdtTimeOutCounter(WDTIS__128M);
336 // Wait until RD_TRIG = 1 and FPGA is ready to accept data
337 while (!(FPGA_RD_TRIG_PORT_IN & FPGA_RD_TRIG_BIT))
338 {
339 if(TimeOut){break;}
340 }
341 stopWdtTimeOutCounter();
342
343 // Write to FPGA
344 FPGA_DATA1_PORT_OUT = data1;
345 FPGA_CMD_DATA0_PORT_OUT = FPGA_PORTA.all;
346 }
347
348 // Write CMD, DATA0 and DATA1 to FPGA
hil_fpga_write_cmd_data0_data1_count_432(unsigned char cmd,unsigned char data0,unsigned short data1Buf[],unsigned char count)349 void hil_fpga_write_cmd_data0_data1_count_432(unsigned char cmd, unsigned char data0, unsigned short data1Buf[], unsigned char count)
350 {
351 // Set DATA1 bus to output direction
352 FPGA_IO_DIR_PORT_OUT |= FPGA_IO_DIR_BIT;
353 FPGA_DATA1_PORT_DIR = 0xFFFF;
354
355 // Assemble PORTA data
356 FPGA_PORTA.bit.CMD = cmd;
357 FPGA_PORTA.bit.DATA0 = data0;
358
359 unsigned char i =0;
360 while(i < count)
361 {
362 // Write to FPGA
363 FPGA_DATA1_PORT_OUT = data1Buf[i++];
364 FPGA_PORTA.bit.WR_TRIG ^= 1;
365 FPGA_CMD_DATA0_PORT_OUT = FPGA_PORTA.all;
366 }
367 }
368
369 // Read data from FPGA
hil_fpga_read_data_432(unsigned char count,unsigned short * buf)370 void hil_fpga_read_data_432(unsigned char count, unsigned short *buf)
371 {
372 // Set DATA1 bus to input direction
373 FPGA_DATA1_PORT_DIR = 0x0000;
374 FPGA_IO_DIR_PORT_OUT &= ~FPGA_IO_DIR_BIT;
375
376 while (count)
377 {
378 // Wait for word on DATA1
379 while (!(FPGA_RD_TRIG_PORT_IN & FPGA_RD_TRIG_BIT));
380
381 // Store word
382 *(buf+(--count)) = FPGA_DATA1_PORT_IN;
383 // Request next word on DATA1
384 if (count)
385 {
386 FPGA_IO_DIR_PORT_OUT ^= FPGA_IO_DIR_BIT;
387 FPGA_IO_DIR_PORT_OUT ^= FPGA_IO_DIR_BIT;
388 }
389 }
390 // Set DATA1 to output
391 FPGA_IO_DIR_PORT_OUT |= FPGA_IO_DIR_BIT;
392 FPGA_DATA1_PORT_DIR = 0xFFFF;
393 }
394
395
396 // Write CMD, DATA0 and DATA1 to FPGA
hil_fpga_write_cmd_data0_data1_count(unsigned char cmd,unsigned char data0,unsigned short data1Buf[],unsigned char count)397 void hil_fpga_write_cmd_data0_data1_count(unsigned char cmd, unsigned char data0, unsigned short data1Buf[], unsigned char count)
398 {
399 //unsigned short i = 0;
400 // Set DATA1 bus to output direction
401 FPGA_IO_DIR_PORT_OUT |= FPGA_IO_DIR_BIT;
402 FPGA_DATA1_PORT_DIR = 0xFFFF;
403
404 // Assemble PORTA data
405 FPGA_PORTA.bit.CMD = cmd;
406 FPGA_PORTA.bit.DATA0 = data0;
407
408 // Wait until RD_TRIG = 1 and FPGA is ready to accept data
409 startWdtTimeOutCounter(WDTIS__128M);
410 while (!(FPGA_RD_TRIG_PORT_IN & FPGA_RD_TRIG_BIT))
411 {
412 if(TimeOut){break;}
413 }
414 stopWdtTimeOutCounter();
415
416 do
417 {
418 // Write to FPGA
419 FPGA_DATA1_PORT_OUT = data1Buf[count - 1];
420 FPGA_PORTA.bit.WR_TRIG ^= 1;
421 FPGA_CMD_DATA0_PORT_OUT = FPGA_PORTA.all;
422 count--;
423 } while(count);
424 }
425
426
427 // Read data from FPGA
hil_fpga_read_data1(unsigned char count,unsigned short * buf)428 void hil_fpga_read_data1(unsigned char count, unsigned short *buf)
429 {
430 // Set DATA1 bus to input direction
431 FPGA_DATA1_PORT_DIR = 0x0000;
432 FPGA_IO_DIR_PORT_OUT &= ~FPGA_IO_DIR_BIT;
433
434 while (count)
435 {
436 startWdtTimeOutCounter(WDTIS__128M);
437
438 // Wait for word on DATA1
439 while (!(FPGA_RD_TRIG_PORT_IN & FPGA_RD_TRIG_BIT))
440 {
441 if(TimeOut){break;}
442 }
443 stopWdtTimeOutCounter();
444
445 // Store word
446 *(buf+(count-1)) = FPGA_DATA1_PORT_IN;
447 count--;
448 // Request next word on DATA1
449 if (count)
450 {
451 FPGA_IO_DIR_PORT_OUT ^= FPGA_IO_DIR_BIT;
452 FPGA_IO_DIR_PORT_OUT ^= FPGA_IO_DIR_BIT;
453 }
454 }
455 // Set DATA1 to output
456 FPGA_IO_DIR_PORT_OUT |= FPGA_IO_DIR_BIT;
457 FPGA_DATA1_PORT_DIR = 0xFFFF;
458 }
459
460 // Hi-Z JTAG signals to target, except TEST and RST (actively drive 0)
hil_fpga_power_up_target(void)461 void hil_fpga_power_up_target(void)
462 {
463 // Enable VCC_SUPPLY and VCC_DT
464 P8DIR |= (BIT0 + BIT7);
465 P8OUT |= (BIT0 + BIT7);
466 _hil_Delay_1ms(1);
467 }
468
hil_fpga_get_version(void)469 unsigned short hil_fpga_get_version(void)
470 {
471 unsigned short version = 0;
472
473 // This is a bit complicated, due to the configuration register returning a value
474 hil_fpga_write_cmd_data0(FPGA_CMD_VERSION, 0);
475
476 // Set DATA1 bus to input direction
477 FPGA_DATA1_PORT_DIR = 0x0000;
478 FPGA_IO_DIR_PORT_OUT &= ~FPGA_IO_DIR_BIT;
479
480 // Wait for data valid
481 while (!FPGA_RD_TRIG_IS_ASSERTED);
482
483 // Store word
484 version = FPGA_DATA1_PORT_IN;
485
486 // Remove VERSION command
487 FPGA_PORTA.bit.CMD = 0;
488 FPGA_PORTA.bit.DATA0 = 0;
489 FPGA_CMD_DATA0_PORT_OUT = FPGA_PORTA.all;
490
491 // Set DATA1 to output
492 FPGA_IO_DIR_PORT_OUT |= FPGA_IO_DIR_BIT;
493 FPGA_DATA1_PORT_DIR = 0xFFFF;
494
495 return version;
496 }
497