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