MSP430 BSL shared RST (JTAG chain)
[i3-mote/i3-mote.git] / Basic-Test-Package / BSL / MSP430 / Boot_MSP430_Chain / 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
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 BOOT_OUT1            (BIT3)  // BSL
21     #define RESET_IN2            (BIT4)  // RTS - RESET
22         #define BOOT_IN2             (BIT5)  // DTR - BOOT
23         #define BOOT_OUT2            (BIT7)  // BSL
25         #define RESET_OUT            (BIT2)  // RESET
26 #else
27     /* MPS432 */
28         #define BOOT_IN1             (BIT0)  // RTS - BOOT
29         #define RESET_IN1            (BIT1)  // DTR - RESET
30         #define BOOT_OUT1            (BIT3)  // BSL
31         /* CC2650 */
32     #define BOOT_IN2             (BIT4)  // RTS - BOOT
33         #define RESET_IN2            (BIT5)  // DTR - RESET
34         #define BOOT_OUT2            (BIT7)  // BSL
36     #define RESET_OUT           (BIT2)  // RESET
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   P1DIR &= ~(RESET_OUT);
93   #ifdef MSP432
94   P1DIR &= ~(RESET_IN1 + BOOT_IN1);
95   P1DIR |= (BOOT_OUT1);
96   P1OUT |= (BOOT_OUT1);
97 #endif
99 #ifdef CC2650
100   P1DIR &= ~(RESET_IN2 + BOOT_IN2);
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;
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_OUT ouput
204                         P1DIR |=  (RESET_OUT);
205                         P1OUT &= ~(BOOT_OUT1);
207                         // Reset Pulse
208                         __delay_cycles(MSEC_DELAY);
209                         P1OUT &=~(RESET_OUT);
210                         __delay_cycles(MSEC_DELAY);
211                         P1OUT |= (RESET_OUT);
213                         __delay_cycles(MSP432_BSL_DELAY);
214                         // Release Boot Pin
215                         P1OUT |= (BOOT_OUT1);
216                         P1DIR &= ~(RESET_OUT);
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_OUT);
289                         //__delay_cycles(STARTUP_DELAY);
290                         P1OUT &= ~(BOOT_OUT2);
292                         /* Reset Pulse */
293                         __delay_cycles(425);
294                         P1OUT &=~(RESET_OUT);
295                         __delay_cycles(MSEC_DELAY);
296                         P1OUT |= (RESET_OUT);
297                         __delay_cycles(CC2650_BSL_DELAY);
299                         /* Release Boot Pin*/
300                         P1OUT |= (BOOT_OUT2);
301                         // RESET_OUT2 is now input
302                         P1DIR &= ~(RESET_OUT);
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);
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   // Ensure RESET_OUT1 and BOOT_OUT1 are high
334   P1OUT |=  (RESET_OUT + BOOT_OUT1);
335   P1DIR &=~(RESET_OUT);
337 #ifdef MSP432
338   // (Re)Enable BOOT_IN1 high to low Int
339   P1IES |= (BOOT_IN1);
340   P1IFG &= ~(RESET_IN1+BOOT_IN1);
341   P1IE  &=~ (RESET_IN1);
342   P1IE  |= (BOOT_IN1);
343 #endif
346 #ifdef CC2650
347   // (Re)Enable RESET_IN2 high to low Int
348   P1IES |= (BOOT_IN2);
349   P1IFG &= ~(RESET_IN2+BOOT_IN2);
350   P1IE  &=~ (RESET_IN2);
351   P1IE  |= (BOOT_IN2);
352 #endif
355   _BIC_SR_IRQ(LPM3_bits + GIE);
359 #pragma vector=TIMERA1_VECTOR
360 __interrupt void timera1_isr (void) {
363   switch(TAIV)
364   {
365     case TAIV_TACCR1: // CCR1
366         {
367           TACTL = 0;
368           TACCTL1 &=~(CCIE);
369         }
370         break;
372     case TAIV_TAIFG: // overflow not used
373     break;
375  }
377  _BIC_SR_IRQ(LPM3_bits + GIE);
382 /*
383 #pragma vector=NMI_VECTOR
384 __interrupt void nmi_isr (void) {
385     _BIC_SR_IRQ(LPM3_bits + GIE);
387 */
391 /*---------------------------------------------------------------------------*/