Fixed force of msp430x2618 in Makefile.
[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 #define RESET 0x80      // not a real app -- causes firmware to reset
16 #define DEBUGAPP 0xFF
17
18 //! Initialize registers and all that jazz.
19 void init()
20 {
21         WDTCTL = WDTPW + WDTHOLD;                                       // Stop watchdog timer
22
23         //LED out and on.
24         PLEDDIR |= PLEDPIN;
25         PLEDOUT &= ~PLEDPIN;
26
27
28         /* P5.0 out and low; this is chosen for the PIC app (in which P5.0
29          is !MCLR) to ensure that an attached PIC chip, if present, is
30          immediately driven to reset state. A brief explanation of why this
31          is important follows.
32
33         At least dsPIC33F and PIC24H --and very likely other 16-bit PIC
34         families-- draw a large amount of current when running, especially
35         when using a fast clock: from 60 mA up to approx. 90 mA.  If the
36         PIC target begins to run before the client can request a new ICSP
37         session, which requires much less current (e.g., less than 2 mA),
38         then the MSP430 chip on the GoodFET will fail to start and the FTDI
39         may have trouble communicating with the client. The latter likely
40         relates to the FTDI on-chip 3V3 regulator being specified up to
41         only 50 mA. */
42
43
44         //P5REN &= ~BIT0; //DO NOT UNCOMMENT.  Breaks GF1x support.
45
46         //This will have to be cut soon.        Use pulling resistors instead.
47         /*
48         P5DIR |= BIT0;
49         P5OUT &= ~BIT0;
50         */
51
52         //Setup clocks, unique to each '430.
53         msp430_init_dco();
54         msp430_init_uart();
55
56         //DAC should be at full voltage if it exists.
57 #ifdef DAC12IR
58         //glitchvoltages(0xfff,0xfff);
59         ADC12CTL0 = REF2_5V + REFON;                                    // Internal 2.5V ref on
60         //for(i=0;i!=0xFFFF;i++) asm("nop"); //DO NOT UNCOMMENT, breaks GCC4
61         DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
62         DAC12_0DAT = 0xFFF; //Max voltage 0xfff
63         DAC12_1CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
64         DAC12_1DAT = 0x000; //Min voltage 0x000
65 #endif
66
67         /** FIXME
68           
69           This part is really ugly.  GSEL (P5.7) must be high to select
70           normal voltage, but a lot of applications light to swing it low
71           to be a nuissance.  To get around this, we assume that anyone
72           with a glitching FET will also have a DAC, then we set that DAC
73           to a high voltage.
74           
75           At some point, each target must be sanitized to show that it
76           doesn't clear P5OUT or P5DIR.
77         */
78         P5DIR|=BIT7; P5OUT=BIT7; //Normal Supply
79         //P5DIR&=~BIT7; //Glitch Supply
80
81         //Enable Interrupts.
82         //eint();
83 }
84
85
86 //! Handle a command.
87 void handle(uint8_t const app,
88                         uint8_t const verb,
89                         uint32_t const len)
90 {
91         int i;
92
93         //debugstr("GoodFET");
94         PLEDOUT&=~PLEDPIN;
95
96         // find the app and call the handle fn
97         for(i = 0; i < num_apps; i++)
98         {
99                 if(apps[i]->app == app)
100                 {
101                         // call the app's handle fn
102                         (*(apps[i]->handle))(app, verb, len);
103
104                         // exit early
105                         return;
106                 }
107         }
108
109         // if we get here, then the desired app is not copiled in 
110         // this firmware
111         debugstr("App missing.");
112         debughex(app);
113         txdata(app, NOK, 0);
114 }
115
116
117 //! Main loop.
118 int main(void)
119 {
120         volatile unsigned int i;
121         unsigned char app, verb;
122         unsigned long len;
123         // MSP reboot count for reset input & reboot function located at 0xFFFE
124         volatile unsigned int reset_count = 0;
125         void (*reboot_function)(void) = (void *) 0xFFFE;
126
127         init();
128   
129         txstring(MONITOR,OK,"http://goodfet.sf.net/");
130   
131         //Command loop.  There's no end!
132         while(1)
133         {
134                 //Magic 3
135                 app = serial_rx();
136
137                 // If the app is the reset byte (0x80) increment and loop
138                 if (app == RESET)
139                 {
140                         reset_count++;
141
142                         if (reset_count > 4) 
143                         {
144                                 // We could trigger the WDT with either:
145                                 // WDTCTL = 0;
146                                 // or
147                                 // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00;
148                                 // but instead we'll jump to our reboot function pointer
149                                 (*reboot_function)();
150                         }
151
152                         continue;
153                 } 
154                 else 
155                 {
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                 {
166                         for(i = 0; i < len; i++)
167                         {
168                                 cmddata[i] = serial_rx();
169                         }
170
171                         handle(app,verb,len);
172                 }
173                 else
174                 {
175                         //Listen to the blaberring.
176                         for(i = 0; i < len; i++)
177                                 serial_rx();
178
179                         //Reply with an error.
180                         debugstr("Buffer length exceeded.");
181                         txdata(MONITOR,NOK,0);
182                 }
183         }
184 }
185