fe0983ef003ac3e5ead53e2975f3b7afec383b3a
1 /*---------------------------------------------------------------------------*/
3 #include <msp430.h>
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <stdio.h>
8 #define CC2650
9 #define MSP432
12 /*---------------------------------------------------------------------------*/
13 #define BOOTLOADER_INVERT_LINES
15 #ifndef BOOTLOADER_INVERT_LINES
16 /* MPS432 */
17 #define RESET_IN1 (BIT0) // RTS - RESET
18 #define BOOT_IN1 (BIT1) // DTR - BOOT
19 #define RESET_OUT1 (BIT2) // RTS - RESET
20 #define BOOT_OUT1 (BIT3) // DTR - BOOT
21 /* CC2650 */
22 #define RESET_IN2 (BIT4) // RTS - RESET
23 #define BOOT_IN2 (BIT5) // DTR - BOOT
24 #define RESET_OUT2 (BIT6) // RTS - RESET
25 #define BOOT_OUT2 (BIT7) // DTR - BOOT
26 #else
27 /* MPS432 */
28 #define BOOT_IN1 (BIT0) // RTS - BOOT
29 #define RESET_IN1 (BIT1) // DTR - RESET
30 #define RESET_OUT1 (BIT2) // RTS - RESET
31 #define BOOT_OUT1 (BIT3) // DTR - BOOT
32 /* CC2650 */
33 #define BOOT_IN2 (BIT4) // RTS - BOOT
34 #define RESET_IN2 (BIT5) // DTR - RESET
35 #define RESET_OUT2 (BIT6) // RTS - RESET
36 #define BOOT_OUT2 (BIT7) // DTR - BOOT
37 #endif
40 /*---------------------------------------------------------------------------*/
41 /* Timer Delays*/
42 #define STARTUP_DELAY (750) // ~0.5s @ 1.5 Khz
43 #define BOOTLOADER_TIMEOUT (75) // ~50 ms @ 1.5 kHz
45 /*---------------------------------------------------------------------------*/
46 /* Procesor Delays */
47 #define MSEC_DELAY (4250) // ~1 ms @ 4.25 MHz
48 #define CC2650_BSL_DELAY (8500) // 2 ms @ 4.25 MHz
49 #define MSP432_BSL_DELAY (42500) // 10 ms @ 4.25 MHz
52 /*---------------------------------------------------------------------------*/
53 static volatile bool bootloader_active = false;
54 static volatile bool bootload_enable = false;
57 /*---------------------------------------------------------------------------*/
58 int main(void) {
60 int i;
62 // Disable Watchdog
63 WDTCTL = WDTPW + WDTHOLD;
65 // Set DCO operation to 4.25 MHz
66 BCSCTL1 &= ~(BIT2 + BIT1 + BIT0);
67 BCSCTL1 |= (BIT3 + BIT1 + BIT0);
69 /*
70 MCLK = DCO / 1 = 4.25 MHz
71 SMCLK = DCO / 1 = 4.25 MHz
72 ACLK = VLOCLK / 8 = 12 kHz / 8 = 1.5 kHz
73 */
74 BCSCTL1 |= (XT2OFF + DIVA_3);
75 BCSCTL3 |= (LFXT1S_2);
77 /* Wait Oscillator stable */
78 while (IFG1 & OFIFG) // OSCFault flag still set?
79 {
80 IFG1 &= ~OFIFG; // Clear OSCFault flag
81 for (i = 0xFFF; i > 0; i--); // Time for flag to set
82 }
84 // Startup Delay: avoid DTR/RTS glitches on FDTI initialization
85 TACCTL1 = CCIE;
86 TACCR1 = STARTUP_DELAY;
87 TACTL = (TASSEL_1 + MC_2 + TAIE + TACLR);
88 _BIS_SR(LPM3_bits + GIE);
90 // Configure P1 input and ouput
91 #ifdef MSP432
92 P1DIR &= ~(RESET_IN1 + BOOT_IN1);
93 P1DIR &= ~(RESET_OUT1);
94 P1DIR |= (BOOT_OUT1);
95 P1OUT |= (BOOT_OUT1);
96 #endif
98 #ifdef CC2650
99 P1DIR &= ~(RESET_IN2 + BOOT_IN2);
100 P1DIR &= ~(RESET_OUT2);
101 P1DIR |= (BOOT_OUT2);
102 P1OUT |= (BOOT_OUT2);
103 #endif
105 // Configure P1 ints
106 #ifdef MSP432
107 // Configure BOOT_IN1 interrupt high to low
108 P1IFG &=~ (BOOT_IN1);
109 P1IES |= (BOOT_IN1);
110 P1IE |= (BOOT_IN1);
111 #endif
113 #ifdef CC2650
114 // Configure BOOT_IN2 interrupt high to low
115 P1IFG &=~ (BOOT_IN2);
116 P1IES |= (BOOT_IN2);
117 P1IE |= (BOOT_IN2);
118 #endif
120 // Forever: Go to the lowest LPM
121 while (1) {
122 if (bootloader_active == true) {
123 _BIS_SR(LPM3_bits + GIE);
124 } else {
125 _BIS_SR(LPM4_bits + GIE);
126 }
127 }
129 return 0;
131 }
132 /*---------------------------------------------------------------------------*/
133 #pragma vector=PORT1_VECTOR
134 __interrupt void port1_isr (void) {
136 int flag=0;
138 #ifdef MSP432
140 // BOOT_IN2 high to low
141 if (((P1IFG & BOOT_IN1) == BOOT_IN1) &&
142 ((P1IN & BOOT_IN1) == 0) &&
143 ((P1IES & BOOT_IN1) == BOOT_IN1)) {
145 // BOOT_IN2 interrupt clear and disable
146 P1IFG &=~ (BOOT_IN1);
147 P1IE &=~ (BOOT_IN1);
149 flag=1;
151 /* Disable CC2650 BSL */
152 P1IFG &=~(RESET_IN2|BOOT_IN2);
153 P1IE &=~(RESET_IN2|BOOT_IN2);
155 /* Enable Reset High to Low */
156 P1IES |= (RESET_IN1);
157 P1IFG &=~ (RESET_IN1);
158 P1IE |= (RESET_IN1);
160 // RESET_IN1 should be low
161 if ((P1IN & RESET_IN1) == 0) {
162 bootloader_active = true;
163 }
164 }
167 // RESET_IN1 high to low
168 if (((P1IFG & RESET_IN1) == RESET_IN1) &&
169 ((P1IN & RESET_IN1) == 0) &&
170 ((P1IES & RESET_IN1) == RESET_IN1)) {
172 // RESET_IN1 interrupt clear and disable
173 P1IFG &=~(RESET_IN1);
174 P1IE &=~(RESET_IN1);
176 flag=1;
178 /* Enable Reset_IN Low to High */
179 P1IES &=~ (RESET_IN1);
180 P1IFG &=~ (RESET_IN1);
181 P1IE |= (RESET_IN1);
183 // Enable Bootload
184 bootload_enable = true;
185 }
189 // RESET_IN1 low to high
190 if (((P1IFG & RESET_IN1) == RESET_IN1) &&
191 ((P1IN & RESET_IN1) == RESET_IN1) &&
192 ((P1IES & RESET_IN1) == 0)) {
194 // RESET_IN1 interrupt clear and dsiable
195 P1IFG &=~(RESET_IN1);
196 P1IE &= ~(RESET_IN1);
198 flag=1;
200 // If bootload_enable is set
201 if (bootload_enable == true) {
203 // RESET_OUT1 ouput
204 P1DIR |= (RESET_OUT1);
205 P1OUT &= ~(BOOT_OUT1);
207 // Reset Pulse
208 __delay_cycles(MSEC_DELAY);
209 P1OUT &=~(RESET_OUT1);
210 __delay_cycles(MSEC_DELAY);
211 P1OUT |= (RESET_OUT1);
213 __delay_cycles(MSP432_BSL_DELAY);
214 // Release Boot Pin
215 P1OUT |= (BOOT_OUT1);
216 P1DIR &= ~(RESET_OUT1);
218 }
219 }
220 #endif
222 #ifdef CC2650
224 // BOOT_IN2 high to low
225 if (((P1IFG & BOOT_IN2) == BOOT_IN2) &&
226 ((P1IN & BOOT_IN2) == 0) &&
227 ((P1IES & BOOT_IN2) == BOOT_IN2)) {
229 // BOOT_IN2 interrupt clear and disable
230 P1IFG &=~ (BOOT_IN2);
231 P1IE &=~ (BOOT_IN2);
233 flag=1;
235 /* Disable MCP432 Boot */
236 P1IFG &=~(RESET_IN1|BOOT_IN1);
237 P1IE &=~(RESET_IN1|BOOT_IN1);
239 /* Enable Reset High to Low */
240 P1IES |= (RESET_IN2);
241 P1IFG &=~ (RESET_IN2);
242 P1IE |= (RESET_IN2);
244 // RESET_IN2 should be low
245 if ((P1IN & RESET_IN2) == 0) {
246 bootloader_active = true;
247 }
248 }
251 // RESET_IN1 high to low
252 if (((P1IFG & RESET_IN2) == RESET_IN2) &&
253 ((P1IN & RESET_IN2) == 0) &&
254 ((P1IES & RESET_IN2) == RESET_IN2)) {
256 // RESET_IN2 interrupt clear
257 P1IFG &=~(RESET_IN2);
258 P1IE &=~(RESET_IN2);
260 flag=1;
262 /* Low to High */
263 P1IES &=~ (RESET_IN2);
264 P1IFG &=~ (RESET_IN2);
265 P1IE |= (RESET_IN2);
267 // Set bootloader_active
268 bootload_enable = true;
269 }
273 // RESET_IN1 low to high
274 if (((P1IFG & RESET_IN2) == RESET_IN2) &&
275 ((P1IN & RESET_IN2) == RESET_IN2) &&
276 ((P1IES & RESET_IN2) == 0)) {
278 // RESET_IN1 interrupt clear
279 P1IFG &=~(RESET_IN2);
280 P1IE &= ~(RESET_IN2);
282 flag=1;
284 // If bootload_enable is set
285 if (bootload_enable == true) {
287 // RESET_OUT1 is now ouput
288 P1DIR |= (RESET_OUT2);
289 //__delay_cycles(STARTUP_DELAY);
290 P1OUT &= ~(BOOT_OUT2);
292 /* Reset Pulse */
293 __delay_cycles(425);
294 P1OUT &=~(RESET_OUT2);
295 __delay_cycles(MSEC_DELAY);
296 P1OUT |= (RESET_OUT2);
297 __delay_cycles(CC2650_BSL_DELAY);
299 /* Release Boot Pin*/
300 P1OUT |= (BOOT_OUT2);
301 // RESET_OUT2 is now input
302 P1DIR &= ~(RESET_OUT2);
303 }
304 }
305 #endif
307 /* Unknown Sequence: Disable PIOs, Wait Timout */
308 if(flag==0){
309 P1IE &=~ (RESET_IN1|RESET_IN2|BOOT_IN1|BOOT_IN2);
310 P1IFG = 0;
311 }
313 // Set TIMER_A-CCR0 Timout
314 TACCR0 = BOOTLOADER_TIMEOUT;
315 TACCTL0 = (CCIE);
316 TACTL = (TASSEL_1 + MC_1 + TAIE + TACLR);
318 _BIC_SR_IRQ(LPM4_bits + GIE);
320 }
321 /*---------------------------------------------------------------------------*/
322 #pragma vector=TIMERA0_VECTOR
323 __interrupt void timera0_isr (void) {
325 // TIMERA0 reset
326 TACTL = 0;
327 TACCTL0 &=~(CCIE);
329 // Clear variables
330 bootloader_active = false;
331 bootload_enable = false;
333 #ifdef MSP432
335 // Ensure RESET_OUT1 and BOOT_OUT1 are high
336 P1OUT |= (RESET_OUT1 + BOOT_OUT1);
337 P1DIR &=~(RESET_OUT1);
339 // (Re)Enable BOOT_IN1 high to low Int
340 P1IES |= (BOOT_IN1);
341 P1IFG &= ~(RESET_IN1+BOOT_IN1);
342 P1IE &=~ (RESET_IN1);
343 P1IE |= (BOOT_IN1);
344 #endif
347 #ifdef CC2650
348 // Ensure RESET_OUT2 and BOOT_OUT2 are high
349 P1OUT |= (RESET_OUT2 + BOOT_OUT2);
350 P1DIR &=~(RESET_OUT2);
352 // (Re)Enable RESET_IN2 high to low Int
353 P1IES |= (BOOT_IN2);
354 P1IFG &= ~(RESET_IN2+BOOT_IN2);
355 P1IE &=~ (RESET_IN2);
356 P1IE |= (BOOT_IN2);
357 #endif
360 _BIC_SR_IRQ(LPM3_bits + GIE);
362 }
364 #pragma vector=TIMERA1_VECTOR
365 __interrupt void timera1_isr (void) {
368 switch(TAIV)
369 {
370 case TAIV_TACCR1: // CCR1
371 {
372 TACTL = 0;
373 TACCTL1 &=~(CCIE);
374 }
375 break;
377 case TAIV_TAIFG: // overflow not used
378 break;
380 }
382 _BIC_SR_IRQ(LPM3_bits + GIE);
384 }
387 /*
388 #pragma vector=NMI_VECTOR
389 __interrupt void nmi_isr (void) {
390 _BIC_SR_IRQ(LPM3_bits + GIE);
391 }
392 */
396 /*---------------------------------------------------------------------------*/