Clocking changes.
[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   default:
97     if(pluginhandle){
98       pluginhandle(app,verb,len);
99     }else{
100       debugstr("Plugin missing.");
101       debughex(app);
102       txdata(app,NOK,0);
103     }
104     break;
105   }
106 }
107
108 //! Main loop.
109 int main(void)
110 {
111   volatile unsigned int i;
112   unsigned char app, verb;
113   unsigned long len;
114   // MSP reboot count for reset input & reboot function located at 0xFFFE
115   volatile unsigned int reset_count = 0;
116   void (*reboot_function)(void) = (void *) 0xFFFE;
117   
118   init();
119
120   txstring(MONITOR,OK,"http://goodfet.sf.net/");
121   
122   
123   //Command loop.  There's no end!
124   while(1){
125     //Magic 3
126     app=serial_rx();
127
128         // If the app is the reset byte (0x80) increment and loop
129         if (app == 0x80) {
130                 reset_count++;
131
132                 if (reset_count > 4) {
133                         // We could trigger the WDT with either:
134                         // WDTCTL = 0;
135                         // or
136                         // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00;
137                         // but instead we'll jump to our reboot function pointer
138                         (*reboot_function)();
139                 }
140
141                 continue;
142         } else {
143                 reset_count = 0;
144         }
145
146     verb=serial_rx();
147     //len=serial_rx();
148     len=rxword();
149     
150     //Read data, looking for buffer overflow.y
151     if(len<=CMDDATALEN){
152       for(i=0;i<len;i++){
153         cmddata[i]=serial_rx();
154       }
155       handle(app,verb,len);
156     }else{
157       //Listen to the blaberring.
158       for(i-0;i<len;i++)
159         serial_rx();
160       //Reply with an error.
161       debugstr("Buffer length exceeded.");
162       txdata(MONITOR,NOK,0);
163     }
164   }
165 }
166