8be9a74f403228e9ca672873fc16b28e9844efcb
[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   
44   
45   //P5REN &= ~BIT0; //DO NOT UNCOMMENT.  Breaks GF1x support.
46   
47   //This will have to be cut soon.  Use pulling resistors instead.
48   /*
49   P5DIR |= BIT0;
50   P5OUT &= ~BIT0;
51   */
52   
53   //Setup clocks, unique to each '430.
54   msp430_init_dco();
55   msp430_init_uart();
56
57   //DAC should be at full voltage if it exists.
58 #ifdef DAC12IR
59   //glitchvoltages(0xfff,0xfff);
60   ADC12CTL0 = REF2_5V + REFON;                  // Internal 2.5V ref on
61   for(i=0;i!=0xFFFF;i++) asm("nop");
62   DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
63   DAC12_0DAT = 0xFFF; //Max voltage 0xfff
64   DAC12_1CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
65   DAC12_1DAT = 0x000; //Min voltage 0x000
66 #endif
67   
68   /** FIXME
69       
70       This part is really ugly.  GSEL (P5.7) must be high to select
71       normal voltage, but a lot of applications light to swing it low
72       to be a nuissance.  To get around this, we assume that anyone
73       with a glitching FET will also have a DAC, then we set that DAC
74       to a high voltage.
75       
76       At some point, each target must be sanitized to show that it
77       doesn't clear P5OUT or P5DIR.
78   */
79   P5DIR|=BIT7; P5OUT=BIT7; //Normal Supply
80   //P5DIR&=~BIT7; //Glitch Supply
81   
82   //Enable Interrupts.
83   //eint();
84 }
85
86
87 //! Handle a command.
88 void handle(unsigned char app,
89             unsigned char verb,
90             unsigned long len){
91   //debugstr("GoodFET");
92   PLEDOUT&=~PLEDPIN;
93   switch(app){
94   case GLITCH:
95     glitchhandle(app,verb,len);
96     break;
97   case MONITOR:
98     monitorhandle(app,verb,len);
99     break;
100   case SPI:
101     spihandle(app,verb,len);
102     break;
103   case NRF:
104     nrfhandle(app,verb,len);
105     break;
106   case CCSPI:
107     ccspihandle(app,verb,len);
108     break;
109   case AVR:
110     avrhandle(app,verb,len);
111     break;
112   case PIC:
113     pichandle(app,verb,len);
114     break;
115   case ADC10:
116     adchandle(app,verb,len);
117     break;
118   case I2CAPP:
119     i2chandle(app,verb,len);
120     break;
121   case CHIPCON:
122     cchandle(app,verb,len);
123     break;
124   case JTAG:
125     jtaghandle(app,verb,len);
126     break;
127   case EJTAG:
128     ejtaghandle(app,verb,len);
129     break;
130   case JTAGXSCALE:
131     xscalehandle(app,verb,len);
132     break;
133   case JTAG430: //Also JTAG430X, JTAG430X2
134     //Revert this when X2 support returns.
135     jtag430x2handle(app,verb,len);
136     //jtag430handle(app,verb,len);
137     break;
138   case SMARTCARD:
139     smartcardhandle(app,verb,len);
140     break;
141   case JTAGARM7TDMI:
142     jtagarm7tdmihandle(app,verb,len);
143     break;
144   default:
145     if(pluginhandle){
146       pluginhandle(app,verb,len);
147     }else{
148       debugstr("Plugin missing.");
149       debughex(app);
150       txdata(app,NOK,0);
151     }
152     break;
153   }
154 }
155
156 //! Main loop.
157 int main(void)
158 {
159   volatile unsigned int i;
160   unsigned char app, verb;
161   unsigned long len;
162   // MSP reboot count for reset input & reboot function located at 0xFFFE
163   volatile unsigned int reset_count = 0;
164   void (*reboot_function)(void) = (void *) 0xFFFE;
165   
166   init();
167   
168   txstring(MONITOR,OK,"http://goodfet.sf.net/");
169   
170   
171   //Command loop.  There's no end!
172   while(1){
173     //Magic 3
174     app=serial_rx();
175     
176     // If the app is the reset byte (0x80) increment and loop
177     if (app == RESET) {
178       reset_count++;
179
180       if (reset_count > 4) {
181         // We could trigger the WDT with either:
182         // WDTCTL = 0;
183         // or
184         // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00;
185         // but instead we'll jump to our reboot function pointer
186         (*reboot_function)();
187       }
188       
189       continue;
190     } else {
191       reset_count = 0;
192     }
193     
194     verb=serial_rx();
195     //len=serial_rx();
196     len=rxword();
197     
198     //Read data, looking for buffer overflow.y
199     if(len<=CMDDATALEN){
200       for(i=0;i<len;i++){
201         cmddata[i]=serial_rx();
202       }
203       handle(app,verb,len);
204     }else{
205       //Listen to the blaberring.
206       for(i=0;i<len;i++)
207         serial_rx();
208       //Reply with an error.
209       debugstr("Buffer length exceeded.");
210       txdata(MONITOR,NOK,0);
211     }
212   }
213 }
214