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