/*---------------------------------------------------------------------------*/ #include #include #include #include #define CC2650 #define MSP432 /*---------------------------------------------------------------------------*/ #define RESET_IN1 (BIT0) // RTS - RESET #define BOOT_IN1 (BIT1) // DTR - BOOT #define RESET_OUT1 (BIT2) // RTS - RESET #define BOOT_OUT1 (BIT3) // DTR - BOOT /*---------------------------------------------------------------------------*/ #define RESET_IN2 (BIT4) // RTS - RESET #define BOOT_IN2 (BIT5) // DTR - BOOT #define RESET_OUT2 (BIT6) // RTS - RESET #define BOOT_OUT2 (BIT7) // DTR - BOOT /*---------------------------------------------------------------------------*/ /* Timer Delays*/ #define STARTUP_DELAY (5*1500) // ~5s @ 1.5 Khz #define BOOTLOADER_TIMEOUT (50) // ~100 ms @ 1.5 kHz /*---------------------------------------------------------------------------*/ /* Procesor Delays */ #define MSEC_DELAY (4250) // ~1 ms @ 4.25 MHz #define CC2650_BSL_DELAY (8500) // 2 ms @ 4.25 MHz #define MSP432_BSL_DELAY (42500) // 10 ms @ 4.25 MHz /*---------------------------------------------------------------------------*/ static volatile bool bootloader_active = false; static volatile bool bootload_enable = false; /*---------------------------------------------------------------------------*/ int main(void) { int i; // Disable Watchdog WDTCTL = WDTPW + WDTHOLD; // Set DCO operation to 4.25 MHz BCSCTL1 &= ~(BIT2 + BIT1 + BIT0); BCSCTL1 |= (BIT3 + BIT1 + BIT0); /* MCLK = DCO / 1 = 4.25 MHz SMCLK = DCO / 1 = 4.25 MHz ACLK = VLOCLK / 8 = 12 kHz / 8 = 1.5 kHz */ BCSCTL1 |= (XT2OFF + DIVA_3); BCSCTL3 |= (LFXT1S_2); /* Wait Oscillator stable */ while (IFG1 & OFIFG) // OSCFault flag still set? { IFG1 &= ~OFIFG; // Clear OSCFault flag for (i = 0xFFF; i > 0; i--); // Time for flag to set } // Startup Delay: avoid DTR/RTS glitches on FDTI initialization TACCTL1 = CCIE; TACCR1 = STARTUP_DELAY; TACTL = (TASSEL_1 + MC_2 + TAIE + TACLR); _BIS_SR(LPM3_bits + GIE); // Configure P1 input and ouput #ifdef MSP432 P1DIR &= ~(RESET_IN1 + BOOT_IN1); P1DIR &= ~(RESET_OUT1); P1DIR |= (BOOT_OUT1); P1OUT |= (BOOT_OUT1); #endif #ifdef CC2650 P1DIR &= ~(RESET_IN2 + BOOT_IN2); P1DIR &= ~(RESET_OUT2); P1DIR |= (BOOT_OUT2); P1OUT |= (BOOT_OUT2); #endif // Configure P1 ints #ifdef MSP432 // Configure BOOT_IN1 interrupt high to low P1IFG &=~ (BOOT_IN1); P1IES |= (BOOT_IN1); P1IE |= (BOOT_IN1); #endif #ifdef CC2650 // Configure BOOT_IN2 interrupt high to low P1IFG &=~ (BOOT_IN2); P1IES |= (BOOT_IN2); P1IE |= (BOOT_IN2); #endif // Forever: Go to the lowest LPM while (1) { if (bootloader_active == true) { _BIS_SR(LPM3_bits + GIE); } else { _BIS_SR(LPM4_bits + GIE); } } return 0; } /*---------------------------------------------------------------------------*/ #pragma vector=PORT1_VECTOR __interrupt void port1_isr (void) { int flag=0; #ifdef MSP432 // BOOT_IN2 high to low if (((P1IFG & BOOT_IN1) == BOOT_IN1) && ((P1IN & BOOT_IN1) == 0) && ((P1IES & BOOT_IN1) == BOOT_IN1)) { // BOOT_IN2 interrupt clear and disable P1IFG &=~ (BOOT_IN1); P1IE &=~ (BOOT_IN1); flag=1; /* Disable CC2650 BSL */ P1IFG &=~(RESET_IN2|BOOT_IN2); P1IE &=~(RESET_IN2|BOOT_IN2); /* Enable Reset High to Low */ P1IES |= (RESET_IN1); P1IFG &=~ (RESET_IN1); P1IE |= (RESET_IN1); // RESET_IN1 should be low if ((P1IN & RESET_IN1) == 0) { bootloader_active = true; } } // RESET_IN1 high to low if (((P1IFG & RESET_IN1) == RESET_IN1) && ((P1IN & RESET_IN1) == 0) && ((P1IES & RESET_IN1) == RESET_IN1)) { // RESET_IN1 interrupt clear and disable P1IFG &=~(RESET_IN1); P1IE &=~(RESET_IN1); flag=1; /* Enable Reset_IN Low to High */ P1IES &=~ (RESET_IN1); P1IFG &=~ (RESET_IN1); P1IE |= (RESET_IN1); // Enable Bootload bootload_enable = true; } // RESET_IN1 low to high if (((P1IFG & RESET_IN1) == RESET_IN1) && ((P1IN & RESET_IN1) == RESET_IN1) && ((P1IES & RESET_IN1) == 0)) { // RESET_IN1 interrupt clear and dsiable P1IFG &=~(RESET_IN1); P1IE &= ~(RESET_IN1); flag=1; // If bootload_enable is set if (bootload_enable == true) { // RESET_OUT1 ouput P1DIR |= (RESET_OUT1); P1OUT &= ~(BOOT_OUT1); // Reset Pulse __delay_cycles(MSEC_DELAY); P1OUT &=~(RESET_OUT1); __delay_cycles(MSEC_DELAY); P1OUT |= (RESET_OUT1); __delay_cycles(MSP432_BSL_DELAY); // Release Boot Pin P1OUT |= (BOOT_OUT1); P1DIR &= ~(RESET_OUT1); } } #endif #ifdef CC2650 // BOOT_IN2 high to low if (((P1IFG & BOOT_IN2) == BOOT_IN2) && ((P1IN & BOOT_IN2) == 0) && ((P1IES & BOOT_IN2) == BOOT_IN2)) { // BOOT_IN2 interrupt clear and disable P1IFG &=~ (BOOT_IN2); P1IE &=~ (BOOT_IN2); flag=1; /* Disable MCP432 Boot */ P1IFG &=~(RESET_IN1|BOOT_IN1); P1IE &=~(RESET_IN1|BOOT_IN1); /* Enable Reset High to Low */ P1IES |= (RESET_IN2); P1IFG &=~ (RESET_IN2); P1IE |= (RESET_IN2); // RESET_IN2 should be low if ((P1IN & RESET_IN2) == 0) { bootloader_active = true; } } // RESET_IN1 high to low if (((P1IFG & RESET_IN2) == RESET_IN2) && ((P1IN & RESET_IN2) == 0) && ((P1IES & RESET_IN2) == RESET_IN2)) { // RESET_IN2 interrupt clear P1IFG &=~(RESET_IN2); P1IE &=~(RESET_IN2); flag=1; /* Low to High */ P1IES &=~ (RESET_IN2); P1IFG &=~ (RESET_IN2); P1IE |= (RESET_IN2); // Set bootloader_active bootload_enable = true; } // RESET_IN1 low to high if (((P1IFG & RESET_IN2) == RESET_IN2) && ((P1IN & RESET_IN2) == RESET_IN2) && ((P1IES & RESET_IN2) == 0)) { // RESET_IN1 interrupt clear P1IFG &=~(RESET_IN2); P1IE &= ~(RESET_IN2); flag=1; // If bootload_enable is set if (bootload_enable == true) { // RESET_OUT1 is now ouput P1DIR |= (RESET_OUT2); //__delay_cycles(STARTUP_DELAY); P1OUT &= ~(BOOT_OUT2); /* Reset Pulse */ __delay_cycles(425); P1OUT &=~(RESET_OUT2); __delay_cycles(MSEC_DELAY); P1OUT |= (RESET_OUT2); __delay_cycles(CC2650_BSL_DELAY); /* Release Boot Pin*/ P1OUT |= (BOOT_OUT2); // RESET_OUT2 is now input P1DIR &= ~(RESET_OUT2); } } #endif // Set TIMER_A-CCR0 Timout TACCR0 = BOOTLOADER_TIMEOUT; TACCTL0 = (CCIE); TACTL = (TASSEL_1 + MC_1 + TAIE + TACLR); if(flag==0){ P1IFG = 0; } _BIC_SR_IRQ(LPM4_bits + GIE); } /*---------------------------------------------------------------------------*/ #pragma vector=TIMERA0_VECTOR __interrupt void timera0_isr (void) { // TIMERA0 reset TACTL = 0; TACCTL0 &=~(CCIE); // Clear variables bootloader_active = false; bootload_enable = false; #ifdef MSP432 // Ensure RESET_OUT1 and BOOT_OUT1 are high P1OUT |= (RESET_OUT1 + BOOT_OUT1); P1DIR &=~(RESET_OUT1); // (Re)Enable BOOT_IN1 high to low Int P1IES |= (BOOT_IN1); P1IFG &= ~(RESET_IN1+BOOT_IN1); P1IE &=~ (RESET_IN1); P1IE |= (BOOT_IN1); #endif #ifdef CC2650 // Ensure RESET_OUT2 and BOOT_OUT2 are high P1OUT |= (RESET_OUT2 + BOOT_OUT2); P1DIR &=~(RESET_OUT2); // (Re)Enable RESET_IN2 high to low Int P1IES |= (BOOT_IN2); P1IFG &= ~(RESET_IN2+BOOT_IN2); P1IE &=~ (RESET_IN2); P1IE |= (BOOT_IN2); #endif _BIC_SR_IRQ(LPM3_bits + GIE); } #pragma vector=TIMERA1_VECTOR __interrupt void timera1_isr (void) { switch(TAIV) { case TAIV_TACCR1: // CCR1 { TACTL = 0; TACCTL1 &=~(CCIE); } break; case TAIV_TAIFG: // overflow not used break; } _BIC_SR_IRQ(LPM3_bits + GIE); } /* #pragma vector=NMI_VECTOR __interrupt void nmi_isr (void) { _BIC_SR_IRQ(LPM3_bits + GIE); } */ /*---------------------------------------------------------------------------*/