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