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