43007cb932c0db00f0c510a9d84f71c86b40cc55
[i3-mote/i3-mote.git] / Basic-Test-Package / BSL / MSP430 / Boot_MSP430_Dual / main.c
1 /*---------------------------------------------------------------------------*/
3 #include <msp430.h>
4 #include <stdint.h>
5 #include <stdbool.h>
6 #include <stdio.h>
8 #define CC2650
9 #define MSP432
11 /*---------------------------------------------------------------------------*/
12 #define RESET_IN1            (BIT0)  // RTS - RESET
13 #define BOOT_IN1             (BIT1)  // DTR - BOOT
14 #define RESET_OUT1           (BIT2)  // RTS - RESET
15 #define BOOT_OUT1            (BIT3)  // DTR - BOOT
16 /*---------------------------------------------------------------------------*/
17 #define RESET_IN2            (BIT4)  // RTS - RESET
18 #define BOOT_IN2             (BIT5)  // DTR - BOOT
19 #define RESET_OUT2           (BIT6)  // RTS - RESET
20 #define BOOT_OUT2            (BIT7)  // DTR - BOOT
22 /*---------------------------------------------------------------------------*/
23 /* Timer Delays*/
24 #define STARTUP_DELAY     (5*1500)  // ~5s @ 1.5 Khz
25 #define BOOTLOADER_TIMEOUT    (50)  // ~100 ms @ 1.5 kHz
27 /*---------------------------------------------------------------------------*/
28 /* Procesor Delays */
29 #define MSEC_DELAY          (4250)  // ~1 ms @ 4.25 MHz
30 #define CC2650_BSL_DELAY    (8500)  //  2 ms @ 4.25 MHz
31 #define MSP432_BSL_DELAY    (42500) // 10 ms @ 4.25 MHz
34 /*---------------------------------------------------------------------------*/
35 static volatile bool bootloader_active = false;
36 static volatile bool bootload_enable   = false;
39 /*---------------------------------------------------------------------------*/
40 int main(void) {
42   int i;
44   // Disable Watchdog
45   WDTCTL = WDTPW + WDTHOLD;
47   // Set DCO operation to 4.25 MHz
48   BCSCTL1 &= ~(BIT2 + BIT1 + BIT0);
49   BCSCTL1 |= (BIT3 + BIT1 + BIT0);
51   /*
52      MCLK  = DCO / 1 = 4.25 MHz
53      SMCLK = DCO / 1 = 4.25 MHz
54      ACLK  = VLOCLK / 8 = 12 kHz / 8 = 1.5 kHz
55   */
56   BCSCTL1 |= (XT2OFF + DIVA_3);
57   BCSCTL3 |= (LFXT1S_2);
59   /* Wait Oscillator stable */
60   while (IFG1 & OFIFG)            // OSCFault flag still set?
61   {
62     IFG1 &= ~OFIFG;               // Clear OSCFault flag
63     for (i = 0xFFF; i > 0; i--);  // Time for flag to set
64   }
66   // Startup Delay: avoid DTR/RTS glitches on FDTI initialization
67   TACCTL1 = CCIE;
68   TACCR1  = STARTUP_DELAY;
69   TACTL = (TASSEL_1 + MC_2 + TAIE + TACLR);
70   _BIS_SR(LPM3_bits + GIE);
72 // Configure P1 input and ouput
73 #ifdef MSP432
74   P1DIR &= ~(RESET_IN1 + BOOT_IN1);
75   P1DIR &= ~(RESET_OUT1);
76   P1DIR |= (BOOT_OUT1);
77   P1OUT |= (BOOT_OUT1);
78 #endif
80 #ifdef CC2650
81   P1DIR &= ~(RESET_IN2 + BOOT_IN2);
82   P1DIR &= ~(RESET_OUT2);
83   P1DIR |= (BOOT_OUT2);
84   P1OUT |= (BOOT_OUT2);
85 #endif
87 // Configure P1 ints
88 #ifdef MSP432
89   // Configure BOOT_IN1 interrupt high to low
90   P1IFG &=~ (BOOT_IN1);
91   P1IES |=  (BOOT_IN1);
92   P1IE  |=  (BOOT_IN1);
93 #endif
95 #ifdef CC2650
96   // Configure BOOT_IN2 interrupt high to low
97   P1IFG &=~ (BOOT_IN2);
98   P1IES |=  (BOOT_IN2);
99   P1IE  |=  (BOOT_IN2);
100 #endif
102   // Forever: Go to the lowest LPM
103   while (1) {
104     if (bootloader_active == true) {
105       _BIS_SR(LPM3_bits + GIE);
106     } else {
107       _BIS_SR(LPM4_bits + GIE);
108     }
109   }
111   return 0;
114 /*---------------------------------------------------------------------------*/
115 #pragma vector=PORT1_VECTOR
116 __interrupt void port1_isr (void) {
118         int flag=0;
120 #ifdef MSP432
122         // BOOT_IN2 high to low
123         if (((P1IFG & BOOT_IN1) == BOOT_IN1) &&
124           ((P1IN  & BOOT_IN1) == 0) &&
125           ((P1IES & BOOT_IN1) == BOOT_IN1)) {
127                 // BOOT_IN2 interrupt clear and disable
128                 P1IFG &=~ (BOOT_IN1);
129                 P1IE &=~ (BOOT_IN1);
131                 flag=1;
133                 /* Disable CC2650 BSL */
134                 P1IFG &=~(RESET_IN2|BOOT_IN2);
135                 P1IE  &=~(RESET_IN2|BOOT_IN2);
137                 /* Enable Reset High to Low */
138                 P1IES |= (RESET_IN1);
139                 P1IFG &=~ (RESET_IN1);
140                 P1IE |= (RESET_IN1);
142                 // RESET_IN1 should be low
143                 if ((P1IN & RESET_IN1) == 0) {
144                         bootloader_active = true;
145                 }
146         }
149         // RESET_IN1 high to low
150         if (((P1IFG & RESET_IN1) == RESET_IN1) &&
151       ((P1IN  & RESET_IN1) == 0) &&
152           ((P1IES & RESET_IN1) == RESET_IN1)) {
154                 // RESET_IN1 interrupt clear and disable
155                 P1IFG &=~(RESET_IN1);
156                 P1IE &=~(RESET_IN1);
158                 flag=1;
160                 /* Enable Reset_IN Low to High */
161                 P1IES &=~ (RESET_IN1);
162                 P1IFG &=~ (RESET_IN1);
163                 P1IE |= (RESET_IN1);
165                 // Enable Bootload
166                 bootload_enable = true;
167         }
171         // RESET_IN1 low to high
172         if (((P1IFG & RESET_IN1) == RESET_IN1) &&
173           ((P1IN  & RESET_IN1) == RESET_IN1) &&
174            ((P1IES & RESET_IN1) == 0)) {
176                 // RESET_IN1 interrupt clear and dsiable
177                 P1IFG &=~(RESET_IN1);
178                 P1IE &= ~(RESET_IN1);
180                 flag=1;
182                 // If bootload_enable is set
183                 if (bootload_enable == true) {
185                         // RESET_OUT1 ouput
186                         P1DIR |=  (RESET_OUT1);
187                         P1OUT &= ~(BOOT_OUT1);
189                         // Reset Pulse
190                         __delay_cycles(MSEC_DELAY);
191                         P1OUT &=~(RESET_OUT1);
192                         __delay_cycles(MSEC_DELAY);
193                         P1OUT |= (RESET_OUT1);
195                         __delay_cycles(MSP432_BSL_DELAY);
196                         // Release Boot Pin
197                         P1OUT |= (BOOT_OUT1);
198                         P1DIR &= ~(RESET_OUT1);
200                 }
201   }
202 #endif
204 #ifdef CC2650
206     // BOOT_IN2 high to low
207     if (((P1IFG & BOOT_IN2) == BOOT_IN2) &&
208         ((P1IN  & BOOT_IN2) == 0) &&
209         ((P1IES & BOOT_IN2) == BOOT_IN2)) {
211                 // BOOT_IN2 interrupt clear and disable
212                 P1IFG &=~ (BOOT_IN2);
213                 P1IE &=~ (BOOT_IN2);
215                 flag=1;
217                 /* Disable MCP432 Boot */
218                 P1IFG &=~(RESET_IN1|BOOT_IN1);
219                 P1IE  &=~(RESET_IN1|BOOT_IN1);
221                 /* Enable Reset High to Low */
222                 P1IES |= (RESET_IN2);
223                 P1IFG &=~ (RESET_IN2);
224                 P1IE |= (RESET_IN2);
226                 // RESET_IN2 should be low
227                 if ((P1IN & RESET_IN2) == 0) {
228                         bootloader_active = true;
229                 }
230     }
233         // RESET_IN1 high to low
234         if (((P1IFG & RESET_IN2) == RESET_IN2) &&
235           ((P1IN  & RESET_IN2) == 0) &&
236           ((P1IES & RESET_IN2) == RESET_IN2)) {
238                 // RESET_IN2 interrupt clear
239                 P1IFG &=~(RESET_IN2);
240                 P1IE &=~(RESET_IN2);
242                 flag=1;
244                 /* Low to High */
245                 P1IES &=~ (RESET_IN2);
246                 P1IFG &=~ (RESET_IN2);
247                 P1IE |= (RESET_IN2);
249                 // Set bootloader_active
250                 bootload_enable = true;
251         }
255         // RESET_IN1 low to high
256         if (((P1IFG & RESET_IN2) == RESET_IN2) &&
257           ((P1IN  & RESET_IN2) == RESET_IN2) &&
258           ((P1IES & RESET_IN2) == 0)) {
260                 // RESET_IN1 interrupt clear
261                 P1IFG &=~(RESET_IN2);
262                 P1IE &= ~(RESET_IN2);
264                 flag=1;
266                 // If bootload_enable is set
267                 if (bootload_enable == true) {
269                         // RESET_OUT1 is now ouput
270                         P1DIR |=  (RESET_OUT2);
271                         //__delay_cycles(STARTUP_DELAY);
272                         P1OUT &= ~(BOOT_OUT2);
274                         /* Reset Pulse */
275                         __delay_cycles(425);
276                         P1OUT &=~(RESET_OUT2);
277                         __delay_cycles(MSEC_DELAY);
278                         P1OUT |= (RESET_OUT2);
279                         __delay_cycles(CC2650_BSL_DELAY);
281                         /* Release Boot Pin*/
282                         P1OUT |= (BOOT_OUT2);
283                         // RESET_OUT2 is now input
284                         P1DIR &= ~(RESET_OUT2);
285                 }
286         }
287 #endif
289   // Set TIMER_A-CCR0 Timout
290   TACCR0  = BOOTLOADER_TIMEOUT;
291   TACCTL0 = (CCIE);
292   TACTL = (TASSEL_1 + MC_1 + TAIE + TACLR);
294   if(flag==0){
295           P1IFG = 0;
296   }
298   _BIC_SR_IRQ(LPM4_bits + GIE);
301 /*---------------------------------------------------------------------------*/
302 #pragma vector=TIMERA0_VECTOR
303 __interrupt void timera0_isr (void) {
305   // TIMERA0 reset
306   TACTL = 0;
307   TACCTL0 &=~(CCIE);
309   // Clear variables
310   bootloader_active = false;
311   bootload_enable   = false;
313 #ifdef MSP432
315   // Ensure RESET_OUT1 and BOOT_OUT1 are high
316   P1OUT |=  (RESET_OUT1 + BOOT_OUT1);
317   P1DIR &=~(RESET_OUT1);
319   // (Re)Enable BOOT_IN1 high to low Int
320   P1IES |= (BOOT_IN1);
321   P1IFG &= ~(RESET_IN1+BOOT_IN1);
322   P1IE  &=~ (RESET_IN1);
323   P1IE  |= (BOOT_IN1);
324 #endif
327 #ifdef CC2650
328   // Ensure RESET_OUT2 and BOOT_OUT2 are high
329   P1OUT |=  (RESET_OUT2 + BOOT_OUT2);
330   P1DIR &=~(RESET_OUT2);
332   // (Re)Enable RESET_IN2 high to low Int
333   P1IES |= (BOOT_IN2);
334   P1IFG &= ~(RESET_IN2+BOOT_IN2);
335   P1IE  &=~ (RESET_IN2);
336   P1IE  |= (BOOT_IN2);
337 #endif
340   _BIC_SR_IRQ(LPM3_bits + GIE);
344 #pragma vector=TIMERA1_VECTOR
345 __interrupt void timera1_isr (void) {
348   switch(TAIV)
349   {
350     case TAIV_TACCR1: // CCR1
351         {
352           TACTL = 0;
353           TACCTL1 &=~(CCIE);
354         }
355         break;
357     case TAIV_TAIFG: // overflow not used
358     break;
360  }
362  _BIC_SR_IRQ(LPM3_bits + GIE);
367 /*
368 #pragma vector=NMI_VECTOR
369 __interrupt void nmi_isr (void) {
370     _BIC_SR_IRQ(LPM3_bits + GIE);
372 */
376 /*---------------------------------------------------------------------------*/