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