turn ftdi driver into echo server
[goodfet] / firmware / apps / glitch / glitch.c
1 /*! \file glitch.c
2   \author Travis Goodspeed
3   \brief Glitching Support for GoodFET20
4   
5   See the TI example MSP430x261x_dac12_01.c for usage of the DAC.
6   This module sends odd and insufficient voltages on P6.6/DAC0
7   in order to bypass security restrictions of target devices.
8 */
9
10 #include "platform.h"
11 #include "command.h"
12 #include "glitch.h"
13
14 #include <msp430.h>
15
16 //! Handles a monitor command.
17 void glitch_handle_fn( uint8_t const app,
18                                            uint8_t const verb,
19                                            uint32_t const len);
20
21 // define the glitch app's app_t
22 app_t const glitch_app = {
23
24         /* app number */
25         GLITCH,
26
27         /* handle fn */
28         glitch_handle_fn,
29
30         /* name */
31         "GLITCH",
32
33         /* desc */
34         "\tThe GLITCH app adds support for doing glitch research.\n"
35         "\tSee the TI example MSP430x261x_dac12_01.c for usage of the DAC.\n"
36         "\tThis module sends odd and insufficient voltages on P6.6/DAC0\n"
37         "\tin order to bypass security restrictions of target devices.\n"
38 };
39
40 //! Call this before the function to be glitched.
41 void glitchprime(){
42 #ifdef DAC12IR
43   WDTCTL = WDTPW + WDTHOLD;             // Stop WDT
44   
45   glitchsetup();
46   //_EINT();
47   __eint();
48   return;
49 #endif
50 }
51
52 //! Setup glitching.
53 void glitchsetup(){
54 #ifdef DAC12IR
55   //Set GSEL high to disable glitching.
56   
57   //Normal voltage, use resistors instead of output.
58   //P5DIR=0x80;   //ONLY glitch pin is output.
59   P5DIR|=0x80;   //glitch pin is output.
60   P5OUT|=0x80;  //It MUST begin high.
61   //P5REN|=0x7F;  //Resistors pull high and low weakly.
62   
63   P6DIR|=BIT6+BIT5;
64   P6OUT|=BIT6+BIT5;
65   
66   WDTCTL = WDTPW + WDTHOLD;             // Stop WDT
67   TACTL = TASSEL1 + TACLR;              // SMCLK, clear TAR
68   CCTL0 = CCIE;                         // CCR0 interrupt enabled
69   CCR0 = glitchcount+0x10;              // Compare Value
70   TACTL |= MC_2;                        // continuous mode.
71 #endif
72 }
73
74 // Timer A0 interrupt service routine
75 void __attribute__((interrupt(TIMERA0_VECTOR))) Timer_A (void){
76   //This oughtn't be necessary, but glitches repeat without it.
77   TACTL=0; //disable counter.
78   
79   
80   P5OUT^=BIT7;//Glitch
81   //asm("nop"); //delay deepens glitch.
82   P5OUT^=BIT7;//Normal
83   
84   //This oughtn't be necessary, but glitches repeat without it.
85   TACTL=0; //disable counter.
86   
87   //P5OUT^=BIT7;//Normal
88   return;
89 }
90
91
92 u16 glitchcount=0;
93
94 //! Glitch an application.
95 void glitchapp(u8 app){
96   debugstr("That app is not yet supported.");
97 }
98
99
100 //! Set glitching voltages.
101 void glitchvoltages(u16 gnd, u16 vcc){
102   
103   //debugstr("Set glitching voltages: GND and VCC");
104   //debughex(gnd);
105   //debughex(vcc);
106   
107   /** N.B., because this is confusing as hell.  As per Page 86 of
108       SLAS541F, P6SEL is not what controls the use of the DAC0/DAC1
109       functions on P6.6 and P6.5.  Instead, CAPD or DAC12AMP>0 sets
110       the state.
111   */
112   
113   #ifdef DAC12IR
114   int i;
115   ADC12CTL0 = REF2_5V + REFON;                  // Internal 2.5V ref on
116   // Delay here for reference to settle.
117   for(i=0;i!=0xFFFF;i++) asm("nop");
118   DAC12_0CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
119   DAC12_1CTL = DAC12IR + DAC12AMP_5 + DAC12ENC; // Int ref gain 1
120   // 1.0V 0x0666, 2.5V 0x0FFF
121   DAC12_0DAT = vcc; //high;
122   DAC12_1DAT = gnd; //low;
123   #endif 
124 }
125 //! Set glitching rate.
126 void glitchrate(u16 rate){
127   glitchcount=rate;
128 }
129
130 //! Handles a monitor command.
131 void glitch_handle_fn( uint8_t const app,
132                                            uint8_t const verb,
133                                            uint32_t const len)
134 {
135   switch(verb){
136   case GLITCHVOLTAGES:
137     glitchvoltages(cmddataword[0],
138                    cmddataword[1]);
139     txdata(app,verb,0);
140     break;
141   case GLITCHRATE:
142     glitchrate(cmddataword[0]);
143     txdata(app,verb,0);
144     break;
145   case GLITCHVERB:
146     //FIXME parameters don't work yet.
147     glitchprime();
148     TAR=0; //Reset clock.
149     handle(cmddata[0],cmddata[1],0);
150     TACTL |= MC0;// Stop Timer_A;
151     break;
152   case GLITCHTIME:
153     debugstr("Measuring start time.");
154     __dint();//disable interrupts
155     TACTL=0; //clear dividers
156     TACTL|=TACLR; //clear config
157     TACTL|=
158       TASSEL_2 //smclk source
159       | MC_2; //continuous mode.
160     
161     //perform the function
162     silent++;//Don't want the function to return anything.
163     TAR=0;
164     handle(cmddata[0],cmddata[1],0);
165     cmddataword[0]=TAR; //Return counter.
166     silent--;
167     debugstr("Measured start time.");
168     debughex(cmddataword[0]);
169     txdata(app,verb,2);
170     break;
171   case START:
172     //Testing mode, for looking at the glitch waveform.
173     glitchvoltages(0,0xFFF);//Minimum glitch, for noise test.
174     //glitchvoltages(0,0);//Drop VCC
175     //glitchvoltages(0xFFF,0xFFF);//Raise Ground
176     P5OUT|=BIT7;//Normal
177     P5DIR|=BIT7;
178     while(1){
179       P5OUT&=~BIT7;//Glitch
180       //asm("nop"); //Not Necessary
181       P5OUT|=BIT7;//Normal
182       asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
183       asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");
184     }
185     txdata(app,verb,0);
186     break;
187   case STOP:
188   case GLITCHAPP:
189   default:
190     debugstr("Unknown glitching verb.");
191     txdata(app,NOK,0);
192   }
193 }