Reverted Chipcon client to C implementation.
[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 #ifdef INSTALL_PIC_APP
79   case PIC:
80     pichandle(app,verb,len);
81     break;
82 #endif
83   case I2CAPP:
84     i2chandle(app,verb,len);
85     break;
86   case CHIPCON:
87     cchandle(app,verb,len);
88     break;
89   case JTAG:
90     jtaghandle(app,verb,len);
91     break;
92   case EJTAG:
93     ejtaghandle(app,verb,len);
94     break;
95   case JTAG430: //Also JTAG430X, JTAG430X2
96     jtag430x2handle(app,verb,len);
97     break;
98   case SMARTCARD:
99     smartcardhandle(app,verb,len);
100     break;
101   case JTAGARM7TDMI:
102     jtagarm7tdmihandle(app,verb,len);
103     break;
104   default:
105     if(pluginhandle){
106       pluginhandle(app,verb,len);
107     }else{
108       debugstr("Plugin missing.");
109       debughex(app);
110       txdata(app,NOK,0);
111     }
112     break;
113   }
114 }
115
116 //! Main loop.
117 int main(void)
118 {
119   volatile unsigned int i;
120   unsigned char app, verb;
121   unsigned long len;
122   // MSP reboot count for reset input & reboot function located at 0xFFFE
123   volatile unsigned int reset_count = 0;
124   void (*reboot_function)(void) = (void *) 0xFFFE;
125   
126   init();
127
128   txstring(MONITOR,OK,"http://goodfet.sf.net/");
129   
130   
131   //Command loop.  There's no end!
132   while(1){
133     //Magic 3
134     app=serial_rx();
135
136         // If the app is the reset byte (0x80) increment and loop
137         if (app == RESET) {
138                 reset_count++;
139
140                 if (reset_count > 4) {
141                         // We could trigger the WDT with either:
142                         // WDTCTL = 0;
143                         // or
144                         // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00;
145                         // but instead we'll jump to our reboot function pointer
146                         (*reboot_function)();
147                 }
148
149                 continue;
150         } else {
151                 reset_count = 0;
152         }
153
154     verb=serial_rx();
155     //len=serial_rx();
156     len=rxword();
157     
158     //Read data, looking for buffer overflow.y
159     if(len<=CMDDATALEN){
160       for(i=0;i<len;i++){
161         cmddata[i]=serial_rx();
162       }
163       handle(app,verb,len);
164     }else{
165       //Listen to the blaberring.
166       for(i=0;i<len;i++)
167         serial_rx();
168       //Reply with an error.
169       debugstr("Buffer length exceeded.");
170       txdata(MONITOR,NOK,0);
171     }
172   }
173 }
174