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