Self test code.
[goodfet] / firmware / goodfet.c
1 /*! \file goodfet.c
2   \author Travis Goodspeed
3   \brief Main module.
4   
5   This is the main module of the GoodFET, which calls the initialization
6   routines and delegates commands to the various applications.
7 */
8
9
10 #include "platform.h"
11 #include "command.h"
12 #include "apps.h"
13 #include "glitch.h"
14
15
16 //! Initialize registers and all that jazz.
17 void init(){
18   #ifdef DAC12IR
19   int i;
20   #endif
21   
22   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
23   
24   //LED out and on.
25   PLEDDIR |= PLEDPIN;
26   PLEDOUT &= ~PLEDPIN;
27
28
29   /* P5.0 out and low; this is chosen for the PIC app (in which P5.0
30          is !MCLR) to ensure that an attached PIC chip, if present, is
31          immediately driven to reset state. A brief explanation of why this
32          is important follows.
33
34    At least dsPIC33F and PIC24H --and very likely other 16-bit PIC
35    families-- draw a large amount of current when running, especially
36    when using a fast clock: from 60 mA up to approx. 90 mA.  If the
37    PIC target begins to run before the client can request a new ICSP
38    session, which requires much less current (e.g., less than 2 mA),
39    then the MSP430 chip on the GoodFET will fail to start and the FTDI
40    may have trouble communicating with the client.  The latter likely
41    relates to the FTDI on-chip 3V3 regulator being specified up to
42    only 50 mA. */
43         P5DIR |= BIT0;
44         P5REN &= ~BIT0;
45         P5OUT &= ~BIT0;
46   
47   //Setup clocks, unique to each '430.
48   msp430_init_dco();
49   msp430_init_uart();
50   
51   //DAC should be at full voltage if it exists.
52 #ifdef DAC12IR
53   //glitchvoltages(0xfff,0xfff);
54   ADC12CTL0 = REF2_5V + REFON;                  // Internal 2.5V ref on
55   for(i=0;i!=0xFFFF;i++) asm("nop");
56   DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
57   DAC12_0DAT = 0xFFF; //Max voltage 0xfff
58   DAC12_1CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
59   DAC12_1DAT = 0x000; //Min voltage 0x000
60 #endif
61   
62   /** FIXME
63       
64       This part is really ugly.  GSEL (P5.7) must be high to select
65       normal voltage, but a lot of applications light to swing it low
66       to be a nuissance.  To get around this, we assume that anyone
67       with a glitching FET will also have a DAC, then we set that DAC
68       to a high voltage.
69       
70       At some point, each target must be sanitized to show that it
71       doesn't clear P5OUT or P5DIR.
72   */
73   P5DIR|=BIT7; P5OUT=BIT7; //Normal Supply
74   //P5DIR&=~BIT7; //Glitch Supply
75   
76   //Enable Interrupts.
77   //eint();
78 }
79
80
81 //! Handle a command.
82 void handle(unsigned char app,
83             unsigned char verb,
84             unsigned long len){
85   //debugstr("GoodFET");
86   P1OUT&=~1;
87   switch(app){
88   case GLITCH:
89     glitchhandle(app,verb,len);
90     break;
91   case MONITOR:
92     monitorhandle(app,verb,len);
93     break;
94   case SPI:
95     spihandle(app,verb,len);
96     break;
97   case NRF:
98     nrfhandle(app,verb,len);
99     break;
100   case AVR:
101     avrhandle(app,verb,len);
102     break;
103   case PIC:
104     pichandle(app,verb,len);
105     break;
106
107   case I2CAPP:
108     i2chandle(app,verb,len);
109     break;
110   case CHIPCON:
111     cchandle(app,verb,len);
112     break;
113   case JTAG:
114     jtaghandle(app,verb,len);
115     break;
116   case EJTAG:
117     ejtaghandle(app,verb,len);
118     break;
119   case JTAG430: //Also JTAG430X, JTAG430X2
120     //Revert this when X2 support returns.
121     jtag430x2handle(app,verb,len);
122     //jtag430handle(app,verb,len);
123     break;
124   case SMARTCARD:
125     smartcardhandle(app,verb,len);
126     break;
127   case JTAGARM7TDMI:
128     jtagarm7tdmihandle(app,verb,len);
129     break;
130   default:
131     if(pluginhandle){
132       pluginhandle(app,verb,len);
133     }else{
134       debugstr("Plugin missing.");
135       debughex(app);
136       txdata(app,NOK,0);
137     }
138     break;
139   }
140 }
141
142 //! Main loop.
143 int main(void)
144 {
145   volatile unsigned int i;
146   unsigned char app, verb;
147   unsigned long len;
148   // MSP reboot count for reset input & reboot function located at 0xFFFE
149   volatile unsigned int reset_count = 0;
150   void (*reboot_function)(void) = (void *) 0xFFFE;
151   
152   init();
153   
154   txstring(MONITOR,OK,"http://goodfet.sf.net/");
155   
156   
157   //Command loop.  There's no end!
158   while(1){
159     //Magic 3
160     app=serial_rx();
161     
162     // If the app is the reset byte (0x80) increment and loop
163     if (app == RESET) {
164       reset_count++;
165
166       if (reset_count > 4) {
167         // We could trigger the WDT with either:
168         // WDTCTL = 0;
169         // or
170         // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00;
171         // but instead we'll jump to our reboot function pointer
172         (*reboot_function)();
173       }
174       
175       continue;
176     } else {
177       reset_count = 0;
178     }
179     
180     verb=serial_rx();
181     //len=serial_rx();
182     len=rxword();
183     
184     //Read data, looking for buffer overflow.y
185     if(len<=CMDDATALEN){
186       for(i=0;i<len;i++){
187         cmddata[i]=serial_rx();
188       }
189       handle(app,verb,len);
190     }else{
191       //Listen to the blaberring.
192       for(i=0;i<len;i++)
193         serial_rx();
194       //Reply with an error.
195       debugstr("Buffer length exceeded.");
196       txdata(MONITOR,NOK,0);
197     }
198   }
199 }
200