myriad of arm/adi additions. working on moving past arm7 into adiv5
[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   
44   
45   //P5REN &= ~BIT0; //DO NOT UNCOMMENT.  Breaks GF1x support.
46   
47   //This will have to be cut soon.  Use pulling resistors instead.
48   /*
49   P5DIR |= BIT0;
50   P5OUT &= ~BIT0;
51   */
52   
53   //Setup clocks, unique to each '430.
54   msp430_init_dco();
55   msp430_init_uart();
56
57   //DAC should be at full voltage if it exists.
58 #ifdef DAC12IR
59   //glitchvoltages(0xfff,0xfff);
60   ADC12CTL0 = REF2_5V + REFON;                  // Internal 2.5V ref on
61   for(i=0;i!=0xFFFF;i++) asm("nop");
62   DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
63   DAC12_0DAT = 0xFFF; //Max voltage 0xfff
64   DAC12_1CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
65   DAC12_1DAT = 0x000; //Min voltage 0x000
66 #endif
67   
68   /** FIXME
69       
70       This part is really ugly.  GSEL (P5.7) must be high to select
71       normal voltage, but a lot of applications light to swing it low
72       to be a nuissance.  To get around this, we assume that anyone
73       with a glitching FET will also have a DAC, then we set that DAC
74       to a high voltage.
75       
76       At some point, each target must be sanitized to show that it
77       doesn't clear P5OUT or P5DIR.
78   */
79   P5DIR|=BIT7; P5OUT=BIT7; //Normal Supply
80   //P5DIR&=~BIT7; //Glitch Supply
81   
82   //Enable Interrupts.
83   //eint();
84 }
85
86
87 //! Handle a command.
88 void handle(unsigned char app,
89             unsigned char verb,
90             unsigned long len){
91   //debugstr("GoodFET");
92   PLEDOUT&=~PLEDPIN;
93   switch(app){
94   case GLITCH:
95     glitchhandle(app,verb,len);
96     break;
97   case MONITOR:
98     monitorhandle(app,verb,len);
99     break;
100   case SPI:
101     spihandle(app,verb,len);
102     break;
103   case NRF:
104     nrfhandle(app,verb,len);
105     break;
106   case CCSPI:
107     ccspihandle(app,verb,len);
108     break;
109   case AVR:
110     avrhandle(app,verb,len);
111     break;
112   case PIC:
113     pichandle(app,verb,len);
114     break;
115         case ADC10:
116                 adchandle(app,verb,len);
117                 break;
118   case I2CAPP:
119     i2chandle(app,verb,len);
120     break;
121   case CHIPCON:
122     cchandle(app,verb,len);
123     break;
124   case JTAG:
125     jtaghandle(app,verb,len);
126     break;
127   case EJTAG:
128     ejtaghandle(app,verb,len);
129     break;
130   case JTAG430: //Also JTAG430X, JTAG430X2
131     //Revert this when X2 support returns.
132     jtag430x2handle(app,verb,len);
133     //jtag430handle(app,verb,len);
134     break;
135   case SMARTCARD:
136     smartcardhandle(app,verb,len);
137     break;
138   case JTAGARM7TDMI:
139     jtagarm7tdmihandle(app,verb,len);
140     break;
141   default:
142     if(pluginhandle){
143       pluginhandle(app,verb,len);
144     }else{
145       debugstr("Plugin missing.");
146       debughex(app);
147       txdata(app,NOK,0);
148     }
149     break;
150   }
151 }
152
153 //! Main loop.
154 int main(void)
155 {
156   volatile unsigned int i;
157   unsigned char app, verb;
158   unsigned long len;
159   // MSP reboot count for reset input & reboot function located at 0xFFFE
160   volatile unsigned int reset_count = 0;
161   void (*reboot_function)(void) = (void *) 0xFFFE;
162   
163   init();
164   
165   txstring(MONITOR,OK,"http://goodfet.sf.net/");
166   
167   
168   //Command loop.  There's no end!
169   while(1){
170     //Magic 3
171     app=serial_rx();
172     
173     // If the app is the reset byte (0x80) increment and loop
174     if (app == RESET) {
175       reset_count++;
176
177       if (reset_count > 4) {
178         // We could trigger the WDT with either:
179         // WDTCTL = 0;
180         // or
181         // WDTCTL = WDTPW + WDTCNTCL + WDTSSEL + 0x00;
182         // but instead we'll jump to our reboot function pointer
183         (*reboot_function)();
184       }
185       
186       continue;
187     } else {
188       reset_count = 0;
189     }
190     
191     verb=serial_rx();
192     //len=serial_rx();
193     len=rxword();
194     
195     //Read data, looking for buffer overflow.y
196     if(len<=CMDDATALEN){
197       for(i=0;i<len;i++){
198         cmddata[i]=serial_rx();
199       }
200       handle(app,verb,len);
201     }else{
202       //Listen to the blaberring.
203       for(i=0;i<len;i++)
204         serial_rx();
205       //Reply with an error.
206       debugstr("Buffer length exceeded.");
207       txdata(MONITOR,NOK,0);
208     }
209   }
210 }
211