b8d9e3dbe7940936065d98a0c4bb9b4ccbe5c7ff
[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
116   case I2CAPP:
117     i2chandle(app,verb,len);
118     break;
119   case CHIPCON:
120     cchandle(app,verb,len);
121     break;
122   case JTAG:
123     jtaghandle(app,verb,len);
124     break;
125   case EJTAG:
126     ejtaghandle(app,verb,len);
127     break;
128   case JTAG430: //Also JTAG430X, JTAG430X2
129     //Revert this when X2 support returns.
130     jtag430x2handle(app,verb,len);
131     //jtag430handle(app,verb,len);
132     break;
133   case SMARTCARD:
134     smartcardhandle(app,verb,len);
135     break;
136   case JTAGARM7TDMI:
137     jtagarm7tdmihandle(app,verb,len);
138     break;
139   default:
140     if(pluginhandle){
141       pluginhandle(app,verb,len);
142     }else{
143       debugstr("Plugin missing.");
144       debughex(app);
145       txdata(app,NOK,0);
146     }
147     break;
148   }
149 }
150
151 //! Main loop.
152 int main(void)
153 {
154   volatile unsigned int i;
155   unsigned char app, verb;
156   unsigned long len;
157   // MSP reboot count for reset input & reboot function located at 0xFFFE
158   volatile unsigned int reset_count = 0;
159   void (*reboot_function)(void) = (void *) 0xFFFE;
160   
161   init();
162   
163   txstring(MONITOR,OK,"http://goodfet.sf.net/");
164   
165   
166   //Command loop.  There's no end!
167   while(1){
168     //Magic 3
169     app=serial_rx();
170     
171     // If the app is the reset byte (0x80) increment and loop
172     if (app == RESET) {
173       reset_count++;
174
175       if (reset_count > 4) {
176         // We could trigger the WDT with either:
177         // WDTCTL = 0;
178         // or
179         // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00;
180         // but instead we'll jump to our reboot function pointer
181         (*reboot_function)();
182       }
183       
184       continue;
185     } else {
186       reset_count = 0;
187     }
188     
189     verb=serial_rx();
190     //len=serial_rx();
191     len=rxword();
192     
193     //Read data, looking for buffer overflow.y
194     if(len<=CMDDATALEN){
195       for(i=0;i<len;i++){
196         cmddata[i]=serial_rx();
197       }
198       handle(app,verb,len);
199     }else{
200       //Listen to the blaberring.
201       for(i=0;i<len;i++)
202         serial_rx();
203       //Reply with an error.
204       debugstr("Buffer length exceeded.");
205       txdata(MONITOR,NOK,0);
206     }
207   }
208 }
209