Proper I/O ports with new firmware.
[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   #ifdef DAC12IR
19   int i;
20   #endif
21   
22   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
23   
24   //LED out and on.
25   PLEDDIR |= PLEDPIN;
26   PLEDOUT &= ~PLEDPIN;
27
28
29   /* P5.0 out and low; this is chosen for the PIC app (in which P5.0
30          is !MCLR) to ensure that an attached PIC chip, if present, is
31          immediately driven to reset state. A brief explanation of why this
32          is important follows.
33
34    At least dsPIC33F and PIC24H --and very likely other 16-bit PIC
35    families-- draw a large amount of current when running, especially
36    when using a fast clock: from 60 mA up to approx. 90 mA.  If the
37    PIC target begins to run before the client can request a new ICSP
38    session, which requires much less current (e.g., less than 2 mA),
39    then the MSP430 chip on the GoodFET will fail to start and the FTDI
40    may have trouble communicating with the client.  The latter likely
41    relates to the FTDI on-chip 3V3 regulator being specified up to
42    only 50 mA. */
43         P5DIR |= BIT0;
44         P5REN &= ~BIT0;
45         P5OUT &= ~BIT0;
46   
47   //Setup clocks, unique to each '430.
48   msp430_init_dco();
49   msp430_init_uart();
50   
51   //DAC should be at full voltage if it exists.
52 #ifdef DAC12IR
53   //glitchvoltages(0xfff,0xfff);
54   ADC12CTL0 = REF2_5V + REFON;                  // Internal 2.5V ref on
55   for(i=0;i!=0xFFFF;i++) asm("nop");
56   DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
57   DAC12_0DAT = 0xFFF; //Max voltage 0xfff
58   DAC12_1CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
59   DAC12_1DAT = 0x000; //Min voltage 0x000
60 #endif
61   
62   /** FIXME
63       
64       This part is really ugly.  GSEL (P5.7) must be high to select
65       normal voltage, but a lot of applications light to swing it low
66       to be a nuissance.  To get around this, we assume that anyone
67       with a glitching FET will also have a DAC, then we set that DAC
68       to a high voltage.
69       
70       At some point, each target must be sanitized to show that it
71       doesn't clear P5OUT or P5DIR.
72   */
73   P5DIR|=BIT7; P5OUT=BIT7; //Normal Supply
74   //P5DIR&=~BIT7; //Glitch Supply
75   
76   //Enable Interrupts.
77   //eint();
78 }
79
80
81 //! Handle a command.
82 void handle(unsigned char app,
83             unsigned char verb,
84             unsigned long len){
85   //debugstr("GoodFET");
86   PLEDOUT&=~PLEDPIN;
87   switch(app){
88   case GLITCH:
89     glitchhandle(app,verb,len);
90     break;
91   case MONITOR:
92     monitorhandle(app,verb,len);
93     break;
94   case SPI:
95     spihandle(app,verb,len);
96     break;
97   case NRF:
98     nrfhandle(app,verb,len);
99     break;
100   case CCSPI:
101     ccspihandle(app,verb,len);
102     break;
103   case AVR:
104     avrhandle(app,verb,len);
105     break;
106   case PIC:
107     pichandle(app,verb,len);
108     break;
109
110   case I2CAPP:
111     i2chandle(app,verb,len);
112     break;
113   case CHIPCON:
114     cchandle(app,verb,len);
115     break;
116   case JTAG:
117     jtaghandle(app,verb,len);
118     break;
119   case EJTAG:
120     ejtaghandle(app,verb,len);
121     break;
122   case JTAG430: //Also JTAG430X, JTAG430X2
123     //Revert this when X2 support returns.
124     jtag430x2handle(app,verb,len);
125     //jtag430handle(app,verb,len);
126     break;
127   case SMARTCARD:
128     smartcardhandle(app,verb,len);
129     break;
130   case JTAGARM7TDMI:
131     jtagarm7tdmihandle(app,verb,len);
132     break;
133   default:
134     if(pluginhandle){
135       pluginhandle(app,verb,len);
136     }else{
137       debugstr("Plugin missing.");
138       debughex(app);
139       txdata(app,NOK,0);
140     }
141     break;
142   }
143 }
144
145 //! Main loop.
146 int main(void)
147 {
148   volatile unsigned int i;
149   unsigned char app, verb;
150   unsigned long len;
151   // MSP reboot count for reset input & reboot function located at 0xFFFE
152   volatile unsigned int reset_count = 0;
153   void (*reboot_function)(void) = (void *) 0xFFFE;
154   
155   init();
156   
157   txstring(MONITOR,OK,"http://goodfet.sf.net/");
158   
159   
160   //Command loop.  There's no end!
161   while(1){
162     //Magic 3
163     app=serial_rx();
164     
165     // If the app is the reset byte (0x80) increment and loop
166     if (app == RESET) {
167       reset_count++;
168
169       if (reset_count > 4) {
170         // We could trigger the WDT with either:
171         // WDTCTL = 0;
172         // or
173         // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00;
174         // but instead we'll jump to our reboot function pointer
175         (*reboot_function)();
176       }
177       
178       continue;
179     } else {
180       reset_count = 0;
181     }
182     
183     verb=serial_rx();
184     //len=serial_rx();
185     len=rxword();
186     
187     //Read data, looking for buffer overflow.y
188     if(len<=CMDDATALEN){
189       for(i=0;i<len;i++){
190         cmddata[i]=serial_rx();
191       }
192       handle(app,verb,len);
193     }else{
194       //Listen to the blaberring.
195       for(i=0;i<len;i++)
196         serial_rx();
197       //Reply with an error.
198       debugstr("Buffer length exceeded.");
199       txdata(MONITOR,NOK,0);
200     }
201   }
202 }
203