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