Example #1
0
void InitOsc(void)
{
  WDTCTL = WDTPW | WDTHOLD;                      // stop watchdog timer

  BCSCTL1 |= XTS;                                // XT1 as high-frequency
  _BIC_SR(OSCOFF);                               // turn on XT1 oscillator

  do                                             // wait in loop until crystal is stable
    IFG1 &= ~OFIFG;
  while (IFG1 & OFIFG);

  BCSCTL1 |= DIVA0;                              // ACLK = XT1 / 2
  BCSCTL1 &= ~DIVA1;

  IE1 &= ~WDTIE;                                 // disable WDT int.
  IFG1 &= ~WDTIFG;                               // clear WDT int. flag

  WDTCTL = WDTPW | WDTTMSEL | WDTCNTCL | WDTSSEL | WDTIS1; // use WDT as timer, flag each
                                                           // 512 pulses from ACLK

  while (!(IFG1 & WDTIFG));                      // count 1024 pulses from XT1 (until XT1's
                                                 // amplitude is OK)

  IFG1 &= ~OFIFG;                                // clear osc. fault int. flag
  BCSCTL2 |= SELM0 | SELM1;                      // set XT1 as MCLK
}
inline void initialize_cpu_12mhz()
{
	/* Disable the FLL control loop */
	_BIS_SR(SCG0);

	/* Set lowest possible DCOx, MODx */
	UCSCTL0 = 0x0000;

	/* Select suitable range */
	UCSCTL1 = DCORSEL_5;

	/* Set DCO Multiplier */
	UCSCTL2 = FLLD_1 + 0x16E;
	_BIC_SR(SCG0);

	/* Worst-case settling time for the DCO when the DCO range bits have been
	changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
	UG for optimization.
	32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle */
	__delay_cycles(250000);

	/* Loop until XT1 & DCO stabilizes, use do-while to insure that
	body is executed at least once */
	do {
		UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);

		/* Clear fault flags */
		SFRIFG1 &= ~OFIFG;
	} while ((SFRIFG1 & OFIFG));
}
Example #3
0
File: mctl.c Project: etorri/mctl
int main(void) {
  WDTCTL = WDTPW + WDTHOLD;   // Stop WDT
  // configure the CPU clock (MCLK)
  // to run from SMCLK: DCO @ 16MHz and SMCLK = DCO
  // If no DCO calibration => stop here by loop
  if(CALBC1_16MHZ==0xff)
    while(1)
      _NOP();
  _BIC_SR(GIE);
  DCOCTL = 0;
  BCSCTL1= CALBC1_16MHZ;
  DCOCTL = CALDCO_16MHZ;
  
  clock_init();
  uart_init();
  motor_init();
  protocols_init();
  pwm_init();

  // ----------
  // **action**
  // ----------
  _BIS_SR(GIE);
  
  FOREVER {
    // read input
    input_scanner();
    // handle any pending state changes in motor
    motor_step();
    // send status reports to pi
    reporter();
  }
}
Example #4
0
void RTC_Clock_init(void)
{
  P5OUT = 0x00;
  //P5DIR = 0x02;  // If this is uncommented RTC doesn't work!!!!!!!!!!!!!!!!!! P5DIR register must be set to 0x00!!!!!!
  P5SEL = 0x03; // Enabled alternative functions 
  
  _BIC_SR(OSCOFF);          // Enable the LFXT1 crystal oscillator
  UCSCTL6 &= (~XTS);        // Select Low-frequency mode. XCAP bits define the capacitance at the XIN and XOUT pins.
  UCSCTL6 |= (XCAP0);       // Set XCAP0
  UCSCTL6 |= (XCAP1);       // Set XCAP1
  // Then Qrystal Load Capacitance is:  
  //  (XCAP1=0),(XCAP0=0) -> 2pF     (XCAP1=0),(XCAP0=1) -> 5.5pF
  //  (XCAP1=1),(XCAP0=0) -> 8.5pF   (XCAP1=1),(XCAP0=1) -> 12pF
  UCSCTL6 &= (~XT1OFF);     // Turns on the XT1.
  
  // Loop until XT1,XT2 & DCO stabilizes
  do
  {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
  
  UCSCTL4 = ((SELA__XT1CLK | SELS__DCOCLKDIV) | SELM__DCOCLKDIV);   // ACLK source: XT1CLK, SMCLK: DCOCLKDIV, MCLK: DCOCLKDIV
  SFRIFG1 &= (~OFIFG);      // Oscillator fault interrupt flag
  SFRIE1 |= (OFIE);         // Oscillator fault interrupt enable
  
}
Example #5
0
__interrupt void
Port_1(void) {
    wdtCounter = 0;
    P1OUT |= 0x01;
    P1IFG &= ~0x08;
    _BIC_SR(LPM0_EXIT);
}
Example #6
0
/*******************************************************************************
 * @fn     void setup_oscillator( void )
 * @brief  configures oscillator for 12MHz operation derived from 32.768kHz
 *       low-frequency crystal driving ACLK.
 * ****************************************************************************/
void setup_oscillator( void )
{
  // ---------------------------------------------------------------------
  // Enable 32kHz ACLK
  P5SEL |= 0x03;                            // Select XIN, XOUT on P5.0 and P5.1
  UCSCTL6 &= ~(XT1OFF + XT1DRIVE_3);        // XT1 On, Lowest drive strength
  UCSCTL6 |= XCAP_3;                        // Internal load cap

  UCSCTL3 = SELA__XT1CLK;                   // Select XT1 as FLL reference
  UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV; // SMCLK == MCLK

  // ---------------------------------------------------------------------
  // Configure CPU clock for 12MHz
  _BIS_SR(SCG0);                  // Disable the FLL control loop
  UCSCTL0 = 0x0000;          // Set lowest possible DCOx, MODx
  UCSCTL1 = DCORSEL_5;       // Select suitable range
  UCSCTL2 = FLLD_1 + 0x16E;  // Set DCO Multiplier
  _BIC_SR(SCG0);                  // Enable the FLL control loop

  // Worst-case settling time for the DCO when the DCO range bits have been
  // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
  // UG for optimization.
  // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
  __delay_cycles(250000); // CHANGE

  // Loop until XT1 & DCO stabilizes, use do-while to insure that
  // body is executed at least once
  do
  {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
    SFRIFG1 &= ~OFIFG;                      // Clear fault flags
  } while ((SFRIFG1 & OFIFG));
}
Example #7
0
//______________________________________________________________________
int main() {
	WDTCTL = WDTPW + WDTHOLD;
	__use_cal_clk(MHZ);

	P1SEL = 0;
	P1DIR = 0;
	P1OUT = 0;
	P2SEL = 0;
	P2DIR = 0;
	P2OUT = 0;

	_BIC_SR(GIE);

	led_init();
	led_off();

	uart_init();

	_BIS_SR(GIE);

	char buf[64], *at=buf;
	uint8_t c = 0;

	while (1) {
		if (c || uart_getc(&c)) {
			switch (c) {
				case '.': led_flip(); break;
				case '1': uart_puts(quick); uart_putc('\n'); say(quick); break;
				case '2': uart_puts(dave); uart_putc('\n'); say(dave); break;
				case '3': uart_puts(luke); uart_putc('\n'); say(luke); break;
				case '4': uart_puts(time); uart_putc('\n'); say(time); break;
				case '5': uart_puts(temp); uart_putc('\n'); say(temp); break;
				case '\r':	// end of command
					uart_putc('\n');
					*at = '\0';
					at = buf;
					if (*at == '*') {
						speak(at+1);
					}//if
					else {
						if (*at == '!')
							setPitch(*(at+1)-'A');
						else
							say(at);
					}//else
					uart_puts("\ndone\n");
					break;
				default:
					*at++ = c;
					uart_putc(c);
					break;
			}//switch
		}//if
		c = 0;
	}//while

}
Example #8
0
__interrupt void PORT1_ISR(void)
#endif
{
	_BIC_SR(GIE);
	led_on();
	uart_port1_isr();
	P1IFG = 0x00;
	led_off();
	_BIS_SR(GIE);
}
Example #9
0
File: board.c Project: RELJEF/dapp
void board_init( void )
{
    _BIC_SR( GIE ); /* Disable interrupts during initialization. */

    WDTCTL = WDTPW | WDTHOLD; /* Stop WDT */

    init_ports( );
    init_button_led( );
    init_rf( );

    _BIS_SR( GIE ); /* Enable interrupts after initialization. */
}
Example #10
0
__interrupt void Port6_isr(void)
{
	uint8_t i;
	uint8_t pin;
		P6IFG &= P6IE;
		for(i = 0, pin = P6IFG; pin > 0; i++) {
			if(gpio6_isrs[i] != 0 && (pin & 0x01)) {
				gpio6_isrs[i](i);
			}
			pin >>= 1;
		}
		P6IFG = 0;
	_BIC_SR(LPM3_EXIT);
}
Example #11
0
File: main.c Project: advocd/MSP430
/*
 * main.c
 */
int main(void) {
    WDTCTL = WDTPW + WDTHOLD;	// Stop watchdog timer

    P1DIR|=BIT6+BIT0;
    P1SEL|=BIT6+BIT0;

    TA0CCR0=12000;
    TA0CCR1=6000;

    TA0CCTL1|=OUTMOD_7;

    TA0CTL|=TASSEL_1+MC_1;

    _BIC_SR(LPM0_bits);

}
Example #12
0
/*===============================================================
 * Timer_Kill : The purpose of this service is to kill the timer
 *
 * This is done by putting the timer counter to 0
 *
 * This function return information about the timer status at the
 * moment it was called.
 *
 * if the timer was running it returns 0
 * if the timer has already expired (event was already dispatched)
 * it returns 1. This info is useful for timed events in FSM
 * When event was already dispatched (we got too late) FSM has
 * can block the event.
*/
UINT Timer_Kill(void)
{

	_BIC_SR(GIE); 		// Disable General interrupts ( do atomic !!!!!!!!!!!!!!!!!!!)

	if (timer){			//If timer <> 0 => timer is running
		timer=0;		// Therefore  Kill timer
		_BIS_SR(GIE); 	// Re Enable General interrupts
		return (0); 	//Timer was running
	}

	else
		_BIS_SR(GIE); 	// Re Enable General interrupts
		return(1);     //Timer has already expired i.e. timer event has been dispatched

}
void clock_init(void)
{
//	UCSCTL1 = DCORSEL_5; // 0x0050
	//UCSCTL1 = DCORSEL_1;
//	UCSCTL2 = 0x01F9;
//	UCSCTL3 = 0x0020;
//	UCSCTL4 = 0x0233;
//	UCSCTL5 = 0x0040;
//	UCSCTL6 = 0x0100;

	//Set DCO FLL reference = REFO
	UCS_clockSignalInit(
			__MSP430_BASEADDRESS_UCS_RF__,
		UCS_FLLREF,
		UCS_REFOCLK_SELECT,
		UCS_CLOCK_DIVIDER_1
		);
	//Set ACLK = REFO
	UCS_clockSignalInit(
			__MSP430_BASEADDRESS_UCS_RF__,
		UCS_ACLK,
		UCS_REFOCLK_SELECT,
		UCS_CLOCK_DIVIDER_1
		);

	//Set Ratio and Desired MCLK Frequency  and initialize DCO
//	UCS_initFLLSettle(
//			__MSP430_BASEADDRESS_UCS_RF__,
//		1000, // 1000 khz
//		31   //  1000 kHz / 32.768 Khz (Crystal)
//		);

	_BIS_SR(SCG0);                  // Disable the FLL control loop
	UCS_initFLLSettle(
			__MSP430_BASEADDRESS_UCS_RF__,
			target_clock_speed_kHz, // 10000 khz
			(uint16_t) ((target_clock_speed_kHz * 1000) / 32768)   //  10000 kHz / 32.768 Khz  = 305(Crystal)
			);
	_BIC_SR(SCG0);                  // Enable the FLL control loop


	clock_speed = UCS_getSMCLK(__MSP430_BASEADDRESS_UCS_RF__);
	//unsigned long clockValueMCLK = UCS_getMCLK(__MSP430_BASEADDRESS_UCS_RF__);
	//unsigned long clockValueCLK = UCS_getACLK(__MSP430_BASEADDRESS_UCS_RF__);
}
Example #14
0
/**
 * setMCLK
 *
 * Config MCLK registers
 *
 * @param dcorsel CPU DCORSEL value
 * @param flln MCLK multiplier bits
 */
void __inline__ CC430CORE::setMCLK(uint16_t dcorsel, uint16_t flln)
{
  /**
   * Configure CPU clock for 8MHz
   */
  _BIS_SR(SCG0);              // Disable the FLL control loop
  UCSCTL0 = 0x0000;           // Set lowest possible DCOx, MODx
  UCSCTL1 = dcorsel;          // Select suitable range
  UCSCTL2 = FLLD_1 + flln;    // Set DCO Multiplier
  _BIC_SR(SCG0);              // Enable the FLL control loop

  // Worst-case settling time for the DCO when the DCO range bits have been
  // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
  // UG for optimization.
  // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
  //__delay_cycles(250000);
  delayClockCycles(0xFFFF);
}
Example #15
0
void init_devices(void)
{
 //1. Stop errant interrupts until set up
 _BIC_SR(GIE); // Disable interrupts during initialization process
 //2. Init System Clock
 // By defaut the FLL stabilizes MCLK and SMCLK to 1.048576 MHz and fDCO = 2.097152 MHz.
 
 //3. Init Peripherals
 //RTC_Clock_init();
 ports_init();
 timer1_A3_init();
 timer1_A3_Stop_Mode;
  
 //P3DIR |= BIT7;                  // Show SMCLK to P3.7
 //P3SEL |= BIT7;

 _BIS_SR(GIE); // Global Interrupt enabled. Do this at the END of the initialization!!!!!!!!
 //all peripherals are now initialized
}
Example #16
0
void init_clock(void){
  volatile unsigned int i;

  /* XTAL = LF crystal, ACLK = LFXT1/1, DCO Rset = 4, XT2 = ON */
  BCSCTL1 = 0x04;
  
  /* Clear OSCOFF flag - start oscillator */
  _BIC_SR( OSCOFF );
  do{
    /* Clear OSCFault flag */
    IFG1 &= ~OFIFG; 
    /* Wait for flag to set */
    for( i = 255; i > 0; i-- )
      ;
  } while(( IFG1 & OFIFG ) != 0);
  
  /* Set MCLK to XT2CLK and SMCLK to XT2CLK */
  BCSCTL2 = 0x88; 
}
Example #17
0
//	vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv DO NOT ALTER vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//******************************************************************************
//	Call display_results after every generation
//
//	returns TRUE when MAX_TIME is reached or switch is pressed
//
int display_results(void)
{
	//LED_RED_ON;						// turn red LED on
	generation++;					// next generation
	lcd_mode(0);
	lcd_cursor(4, 1);
	lcd_printf("%d", generation);

	// only update when seconds changes
	if (seconds != old_seconds)
	{
		old_seconds = seconds;
		printf("/%d", seconds);
		lcd_cursor(145, 1);
		printf("%2d", generation / seconds);
	}

	// check for MAX_GENERATION or MAX_TIME exceeded
	if ((generation >= MAX_GENERATION) || (seconds >= MAX_TIME))
	{
		long hSecs, hGensPerSec;
		_BIC_SR(GIE);
		lcd_cursor(4, 1);			// output results
		lcd_printf("%d/%d", generation, seconds);
		lcd_cursor(145, 1);
		printf("%2d", generation / seconds);
		lcd_cursor(50, 80);
		hSecs = ((long)seconds * 100) + (((WDT_1SEC_CNT - WDT_sec_cnt) * 100) / WDT_1SEC_CNT);
		hGensPerSec = ((long)generation * 100 * 100) / hSecs;
		lcd_printf("\a\b\t%ld.%02ld", hGensPerSec / 100, hGensPerSec % 100);
		if (generation < MAX_TIME * 5)
		{
			lcd_cursor(30, 30);
			lcd_printf("\a\b\tTOO SLOW!");
		}
		_BIS_SR(GIE);
		switches = 0;				// clear any pending switches
		while (!switches);			// wait for any switch
	}
	//LED_RED_OFF;					// turn red LED off
	return switches;				// return switch value
} // end display_results
Example #18
0
void sleep_ms(unsigned short delay)
{
	_BIC_SR(GIE); /* Disable all interrupts so we can setup sleep */
	
	/* Disable all interrupts */
	P1IE = 0;
	P2IE = 0;
	
	/* Setup timer B, compare */
	TBCCTL0 = CCIE;
	/* ACLK at 32768 Hz, this converts to ms */
	/* 4096/125 = 32.768 */
	TBCCR0 = (unsigned short) (((unsigned int) (delay) * 4096) / 125);
	/**
	 * Setup timer B, with capture 0.
	 * MC_1 - Count up to TBCCR0
	 * TBSSEL_1 - We use the ACLK as our clock
	 * TBCLR - Reset the clock to TBR == 0
	 */
	TBCTL = MC_1 + TBSSEL_1 + TBCLR;
	_BIS_SR(LPM3_bits + GIE);
}
Example #19
0
inline void sleep()
{
  P1OUT &= ~RX_EN_PIN;
  // enable port interrupt for voltage supervisor
  P2IES = 0;
  P2IFG = 0;
  P2IE |= VOLTAGE_SV_PIN;
  P1IE = 0;
  P1IFG = 0;
  TACTL = 0;

  _BIC_SR(GIE); // temporarily disable GIE so we can sleep and enable interrupts
                // at the same time
  P2IE |= VOLTAGE_SV_PIN; // Enable Port 2 interrupt

  if (is_power_good())
    P2IFG = VOLTAGE_SV_PIN;

  _BIS_SR(LPM4_bits | GIE);

  return;
}
Example #20
0
/**
 * Startup routine for 32kHz Cristal on LFXT1
 *
*/
void LFXT_Start(uint16_t xtdrive)
{
	//SetVCore(3);

  //UCSCTL6_L |= XT1DRIVE1_L+XT1DRIVE0_L; // Highest drive setting for XT1 startup
	/* Enable 32K ACLK */
	P5SEL |= 0x03;				/* Select XIN XOUT on P5.0 P5.1 */
	UCSCTL6 &= ~XT1OFF;			/* XT1 ON highest drive strenght */
	UCSCTL6 |= XCAP_3;			/* Internal load cap */

	UCSCTL3 = SELA__XT1CLK;		/* Select XT1 as FLL reference */
	UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV;

	/* Set MCLK for 12MHz */
	//__bis_SR_register(SCG0);	/* Disable the FLL control loop */
	_BIS_SR(SCG0);
	UCSCTL0 = 0x0000;			/* Set lowest possible DCOx and MODx */
	UCSCTL1 = DCORSEL_5;		/* Select Divider range for 12MHz */
	UCSCTL2 = FLLD_1 + 0x16E;	/* Set DCO multiplier */
	//__bic_SR_register(SCG0);	/* Enable FLL control loop */
	_BIC_SR(SCG0);

	__delay_cycles(250000);

	/* Loop until it stabilizes ensuring to perform at least once the instructions*/
	do
	{
		UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
		SFRIFG1 &= ~OFIFG;		/* Clear fault flags */
	}
	while ((SFRIFG1 & OFIFG));

  /*while (SFRIFG1 & OFIFG) {   // check OFIFG fault flag
    UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT1HFOFFG+XT2OFFG); // Clear OSC flaut Flags fault flags
    SFRIFG1 &= ~OFIFG;        // Clear OFIFG fault flag
  }*/
  UCSCTL6 = (UCSCTL6 & ~(XT1DRIVE_3)) |(xtdrive); // set Drive mode
}
Example #21
0
static void ISR_timer0_a1() {
    _BIC_SR(GIE);

    switch(TAIV)
    {
        case 0x02:
            clear_pin(PWM_PINS[current_servo]);

            if(current_servo == 0)
            {
                TA0CCR0 = last_period;
            } else {
                TA0CCR0 = norm_period;
            }
            break;

        default:

            break;
    }

    _BIS_SR_IRQ(GIE);
}
Example #22
0
void ISR_timer0_a0()
{
    _BIC_SR(GIE);

    current_servo++;
    if(current_servo == NUM_SERVOS)
    {
        current_servo = 0;
    }

    set_pin(PWM_PINS[current_servo]);

    /*
     * If the control structure is not locked, go ahead and access it
     * (Also access if there was no busy query function specified)
     */
    if(!servo_ctl_busy || !servo_ctl_busy())
    {
        current_servo_pos = servo_ctl->pos[current_servo];
        servo_ctl_buffer.pos[current_servo] = current_servo_pos;
        memcpy(&servo_ctl_buffer.baseband, &servo_ctl->baseband, 4);
    }
    else
    {
        current_servo_pos = servo_ctl_buffer.pos[current_servo];
    }

    // Clamp servo position
    uint16_t maxband_diff = servo_ctl_buffer.maxband -
                            servo_ctl_buffer.baseband;
    if(current_servo_pos > maxband_diff)
        current_servo_pos = maxband_diff;

    TA0CCR1 = servo_ctl_buffer.baseband + current_servo_pos;

    _BIS_SR_IRQ(GIE);
}
Example #23
0
//************************** SETUP TO RECEIVE  *********************************
// note: port interrupt can also reset, but it doesn't call this function
//       because function call causes PUSH instructions prior to bit read
//       at beginning of interrupt, which screws up timing.  so, remember
//       to change things in both places.
static inline void setup_to_receive()
{
  _BIC_SR(GIE); // temporarily disable GIE so we can sleep and enable interrupts
                // at the same time

  P1OUT |= RX_EN_PIN;

  delimiterNotFound = 0;
  // setup port interrupt on pin 1.2
  P1SEL &= ~BIT2;  //Disable TimerA2, so port interrupt can be used
  // Setup timer. It has to setup because there is no setup time after done with
  // port1 interrupt.
  TACTL = 0;
  TAR = 0;
  TACCR0 = 0xFFFF;    // Set up TimerA0 register as Max
  TACCTL0 = 0;
  TACCTL1 = SCS + CAP;   //Synchronize capture source and capture mode
  TACTL = TASSEL1 + MC1 + TAIE;  // SMCLK and continuous mode and Timer_A
                                 // interrupt enabled.

  // initialize bits
  bits = 0;
  // initialize dest
  dest = destorig;  // = &cmd[0]
  // clear R6 bits of word counter from prior communications to prevent dest++
  // on 1st port interrupt
  asm("CLR R6");

  P1IE = 0;
  P1IES &= ~RX_PIN; // Make positive edge for port interrupt to detect start of
                    // delimiter
  P1IFG = 0;  // Clear interrupt flag

  P1IE  |= RX_PIN; // Enable Port1 interrupt
  _BIS_SR(LPM4_bits | GIE);
  return;
}
Example #24
0
// *************************************************************************************************
// @fn          init_application
// @brief       Initialize the microcontroller.
// @param       none
// @return      none
// *************************************************************************************************
void init_application(void)
{
	volatile unsigned char *ptr;
	  
#ifndef EMU
	// ---------------------------------------------------------------------
	// Enable watchdog
	
	// Watchdog triggers after 16 seconds when not cleared
#ifdef USE_WATCHDOG		
	WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK;
#else
	WDTCTL = WDTPW + WDTHOLD;
#endif
	
	// ---------------------------------------------------------------------
	// Configure PMM
	SetVCore(3);
	
	// Set global high power request enable
	PMMCTL0_H  = 0xA5;
	PMMCTL0_L |= PMMHPMRE;
	PMMCTL0_H  = 0x00;	

	// ---------------------------------------------------------------------
	// Enable 32kHz ACLK	
	P5SEL |= 0x03;                            // Select XIN, XOUT on P5.0 and P5.1
	UCSCTL6 &= ~XT1OFF;        				  // XT1 On, Highest drive strength
	UCSCTL6 |= XCAP_3;                        // Internal load cap

	UCSCTL3 = SELA__XT1CLK;                   // Select XT1 as FLL reference
	UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV;      
	
	// ---------------------------------------------------------------------
	// Configure CPU clock for 12MHz
	_BIS_SR(SCG0);                  // Disable the FLL control loop
	UCSCTL0 = 0x0000;          // Set lowest possible DCOx, MODx
	UCSCTL1 = DCORSEL_5;       // Select suitable range
	UCSCTL2 = FLLD_1 + 0x16E;  // Set DCO Multiplier
	_BIC_SR(SCG0);                  // Enable the FLL control loop

    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
    __delay_cycles(250000);
  
	// Loop until XT1 & DCO stabilizes, use do-while to insure that 
	// body is executed at least once
	do
	{
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
		SFRIFG1 &= ~OFIFG;                      // Clear fault flags
	} while ((SFRIFG1 & OFIFG));	

	
	// ---------------------------------------------------------------------
	// Configure port mapping
	
	// Disable all interrupts
	__disable_interrupt();
	// Get write-access to port mapping registers:
	PMAPPWD = 0x02D52;
	// Allow reconfiguration during runtime:
	PMAPCTL = PMAPRECFG;

	// P2.7 = TA0CCR1A or TA1CCR0A output (buzzer output)
	ptr  = &P2MAP0;
	*(ptr+7) = PM_TA1CCR0A;
	P2OUT &= ~BIT7;
	P2DIR |= BIT7;

	// P1.5 = SPI MISO input
	ptr  = &P1MAP0;
	*(ptr+5) = PM_UCA0SOMI;
	// P1.6 = SPI MOSI output
	*(ptr+6) = PM_UCA0SIMO;
	// P1.7 = SPI CLK output
	*(ptr+7) = PM_UCA0CLK;

	// Disable write-access to port mapping registers:
	PMAPPWD = 0;
	// Re-enable all interrupts
	__enable_interrupt();
#endif
	
	// ---------------------------------------------------------------------
	// Configure ports

	// ---------------------------------------------------------------------
	// Reset radio core
	radio_reset();
	radio_powerdown();	
	
	// ---------------------------------------------------------------------
	// Init acceleration sensor
	as_init();
	
	// ---------------------------------------------------------------------
	// Init LCD
	lcd_init();
  
	// ---------------------------------------------------------------------
	// Init buttons
	init_buttons();

	// ---------------------------------------------------------------------
	// Configure Timer0 for use by the clock and delay functions
	Timer0_Init();
	
	// ---------------------------------------------------------------------
	// Init pressure sensor
	ps_init();
}
__interrupt void watchdog_timer(void)
{
  _BIC_SR(GIE); // Disable interrupts

  if(count % 13 == 0)
  {
    switch(adc_channel)
    {
      case 0:
      ADC10CTL1 &= ~INCH_2;
      ADC10CTL1 = INCH_3;
      ADC10AE0 &= ~BIT2;
      ADC10AE0 |= BIT3;
      break;

      case 1:
      ADC10CTL1 &= ~INCH_3;
      ADC10CTL1 = INCH_1;
      ADC10AE0 &= ~BIT3;
      ADC10AE0 |= BIT1;
      break;

      case 2:
      ADC10CTL1 &= ~INCH_1;
      ADC10CTL1 |= INCH_2;
      ADC10AE0 &= ~BIT1;
      ADC10AE0 |= BIT2;
      break;
    }
    ADC10CTL0 |= ENC + ADC10SC;
  }
  if(count >= MAX)
  {
    P1OUT |= BIT7 + BIT4 + BIT5; // Turn on power to all outputs
    pwm1_off = 0;
    pwm2_off = 0;
    pwm3_off = 0;
    count = 0; // and reset count.
  }
  else// if(!(pwm1_off + pwm2_off + pwm3_off == 3))
  {
    if( count > pwm1_val )
    {
      P1OUT &= ~BIT7; // Turn off power to this output.
      pwm1_off = 1;
    }
    if(count >= pwm2_val)
    {
      P1OUT &= ~BIT4;
      pwm2_off = 1;
    }
    if(count > pwm3_val)
    {
      P1OUT &= ~BIT5;
      pwm3_off = 1;
    }
  }

  if(count % 19 == 0 )
  {
    switch(adc_channel)
    {
      case 0:
      pwm1_val = (ADC10MEM);
      adc_channel = 1;
      break;

      case 1:
      pwm2_val = (ADC10MEM);
      adc_channel = 2;
      break;

      case 2:
      pwm3_val = (ADC10MEM);
      adc_channel = 0;
      break;
    }
    ADC10CTL0 &= ~(ENC + ADC10SC);
  }

  count++;

  _BIS_SR(GIE); // Reenable Interrupts.
}
Example #26
0
port1(void) {
    wdtCounter = 0;
    P1OUT |= 0x01;
    P1IFG &= ~0x08;
    _BIC_SR(LPM0_EXIT);
}
Example #27
0
void main(void)
{

  // Disable Entire System
//  _BIS_SR(LPM4_bits);
  
  // Turn DCO to slowest clock (method from Errata sheet)
  DCOCTL = 0x00;
  // Set RSEL bits
  BCSCTL1 &= 0xF0;    // 0b1111_0000 -> Clear out previous setting
  /*BCSCTL1 |= 0x00;    // Place new setting for RSEL : 0b0000_xxxx
  DCOCTL |= 0x00;     // Place new setting for DCO  : 0bxxx0_0000*/
  BCSCTL2 |= DIVM0; //Divide MCLK by 2

  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
  
  // Turn OFF SMCLK and external Oscillator
  _BIS_SR(OSCOFF + SCG1);
  
  // Set P1.ALL to be Output ports
  P1OUT = 0x00;
  //      1111_1110
  P1DIR = ~(0x01);
  P1SEL = 0x00;
  
  // Setup ACLK source to be from internal VLOCLK (~10 kHz)
  BCSCTL3 |= LFXT1S_2;
  // Setup ACLK to be dvided by 8
  BCSCTL1 |= DIVA1 + DIVA0;
  
  // Sleep 20 ms
  // Initialize timerA0
  //TACTL &= TACLR;
  CCTL0 = CCIE;                             // CCR0 interrupt enabled
  CCR0 = 900;                              // 10 khz source * 900 ms = 9,000  cycles
  TACTL = TACLR + TASSEL_1 + MC_1;                  // Source: ACLK, Mode: UP
  // Enter LPM3 Mode
  _BIC_SR(OSCOFF);
  _BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interrupts
  // -- Wake up -- //
  
  // Turn OFF SMCLK and external Oscillator
  _BIS_SR(OSCOFF + SCG1);
  
 while (1)
 {
   // Generate 5.0 kHz tone -- Tone 1
   for ( unsigned short i = 175 ; i != 0 ; i-- )
   {
     // Toggle Pin ON
     P1OUT ^= 0x04;
     // Delay for 1/2 period of 2.5 kHz (10 cycles)
     //__delay_cycles(1);
     
     // Toggle Pin OFF
     P1OUT ^= 0x04;
     // Delay
     __delay_cycles(1);
   }
   
/*
   // -- Toggle LED 1 (Red- //
   P1OUT ^= 0x20;

   // -- Toggle LED 2 (Green)/
   P1OUT ^= 0x40;
   
   // -- Toggle LED 3 (Yellow)-- //
   P1OUT ^= 0x80;
*/
   
   // Sleep  LONG ms
   // Initialize timerA0
   //TACTL &= TACLR;
   CCTL0 = CCIE;                             // CCR0 interrupt enabled
   CCR0 = 700;                              // 10 khz source * 900 ms = 9,000  cycles
   TACTL = TACLR + TASSEL_1 + MC_1;                  // Source: ACLK, Mode: UP

   // Enter LPM3 Mode
   _BIC_SR(OSCOFF);
   _BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interrupts
   // -- Wake up -- //

   // Turn OFF SMCLK and external Oscillator
   _BIS_SR(OSCOFF + SCG1);
   
 }
}
Example #28
0
int main(void) {

  //if (!(P1IN&usbminus)) usbwait = 0;  // no usb D- pullup, no bootloader
  // no pull-up, app present, run app
  if (!(P1IN&usbminus) && (*((char*) *((uint16_t*) 0xffbe)) != -1))
    asm("br &0xffbe");

  WDTCTL = WDTPW | WDTHOLD;     // Stop watchdog
  P1OUT = 0;              // Prepare Port 1
  usbdir = ~(usbplus | usbminus);   // USB lines are inputs
  //P1SEL |= BIT4;          // SMCLK for measurements on P1.4

  P1DIR |= BIT5;

#ifdef USE_32768HZ_XTAL
  BCSCTL1 = DIVA_3 | 15;        // ACLK / 8, Range 15
  DCOCTL = 127;           // ~15 MHz
  TACTL = TASSEL_2 | MC_2 | TACLR;  // Continous up mode with clocking from SMCLK
  TACCTL0 = CM_1 | CCIS_1 | CAP | CCIE; // Setup CCR0 for capturing on rising edges of ACLK with enabled interrupts
  __eint();
#else
  P2SEL = 0;
  P2DIR = BIT6|BIT7;          // indicator led
  P2OUT = 0;

  BCSCTL1 = 15;           // Range 15
  DCOCTL = 127;           // ~15 MHz
#endif

  __delay_cycles(2000000);      // Allow some time to stabilize power
  uint8_t usbwait=12;


  usbies = 0;       // Interrupt on rising edge of D+ because there is keep-alive signaling on
                    //   D- that would cause false syncs
  usbifg = 0;       // No interrupt pending

  uint16_t addrStart=0, addrEnd=0, addrCurrent=0, addrSave=0;
  uint8_t  initialized=0;
  uint16_t heartbeat = 0;

  uint8_t idx=0, inBuf[48];
  uint8_t *buffUp=0;
  uint8_t next_time_flash_erase = 0;

  static uint16_t const USB_IDLE_DETECT_THRESHOLD = 16384;
  uint16_t usb_idle_detect_counter = 0;
  uint8_t usb_idle = 0;

  /*    What is this usb idle thing ?
     We are in a bootloader, its aim is to receive via usb a new
     program to be flashed. But erasing and writing to flash takes
     quite a big time, and usb timing is tight. The usb protocol
     needs that response packets be sent within a certain time
     frame, and if the mcu misses that time frame, the host can
     consider the device as malfunctioning.
     The idea behind the usb idle thing is to delay operations that
     take time to a moment where we hope the mcu will not have any
     usb packet to answer.
     Specifically :
     1. when the host side sends an address where flash must be
        erased, the host sleeps for a certain amount T of milliseconds
        before sending another command. Within T milliseconds, the
        mcu has time to answer remaining usb packets and erase the
        requested flash segment.
     2. when the host side sends payload bytes (which are bytes of
        the program to be flashed), the mcu has no time to write them
        into flash and answer usb packets. It stores them in a small
        RAM buffer, and writes them to flash once the host sleeps a
        bit. Here, the host sends 32 bytes before sleeping and letting
        the mcu write those bytes to flash.
     To detect usb idle, we simply count how many "for-ever" loops we
     have done since last received usb packet, and beyond a threshold,
     we consider being in usb idle mode, that is to say : we consider
     the host will not send any other usb packet before we have
     finished with flashing and being able to handle a new usb packet.
  */

  for (;;) // for-ever
  {
    // Detect USB idle
    if(initialized && !usb_idle)
    {
      usb_idle_detect_counter++;
      if(usb_idle_detect_counter > USB_IDLE_DETECT_THRESHOLD)
        usb_idle = 1;
    }

    if (!heartbeat++)
    {
      if (initialized) // usb reset from host occured
      {
        P2OUT ^= BIT6;
      }//if
      else
      { // no reset, run app if present
        //if (!usbwait && (*((char*) 0xc000) != -1)) {
        if (!usbwait && (*((char*) *((uint16_t*) 0xffbe)) != -1))
        {
          _BIC_SR(GIE);
          TACTL = 0;
          P2DIR = P1DIR = 0;
          P2OUT = P1OUT = 0;
          asm("br &0xffbe");
        }
        else
        {
          usbwait--;
        }
      }
    }

    unsigned n = 80;        // Reset if both D+ and D- stay low for a while
                    // 10 ms in SE0 is reset
                    // Should this be done in the ISR somehow???
    while (!initialized && !(usbin & (usbplus | usbminus)))
    {
      if (!--n)
      {
        CurrentAddress = 0;   // Device has initial address of 0
        NewAddress = 0;     //
        addrCurrent = addrStart = addrEnd = 0;

#ifndef USE_32768HZ_XTAL
        if (!initialized)
        {
          TACTL = TASSEL_2 | MC_2 | TACLR;  // Continous up mode with clocking from SMCLK
          initialized = 1;
          //P2OUT |= BIT6;  // debug use, led indicate we are trying sync
          n = 1000; // time to stabilize clock
          while (--n)
          {
            while (!(usbin&usbminus));
            TACTL |= TACLR;
            while ((usbin&usbminus));
            if (TAR < 15000) ++DCOCTL;
            else --DCOCTL;
          }
          usbie = usbplus;
          _BIS_SR(GIE);
        }
#else
        usbie = usbplus;
        _BIS_SR(GIE);
        initialized = 1;
#endif

        break;
      }
    }


    if(DataPacketBuffer[0]) // Check if the USB SIE has received a packet
    {
	  uint8_t packet_size = *DataPacketBuffer;	// we save packet_size here to avoid it being
      DataPacketBuffer[0] = 0;					// overwritten by "fast" status packet that follows
      usb_idle_detect_counter = 0;
      usb_idle = 0;

      // At the end of the buffer is the PID of the preceding token packet
      // Check if it is a SETUP packet
      if(DataPacketBuffer[15] == USB_PID_SETUP)
      {
        // Handle the packet, get a response
        if((DataToTransmit = ProtocolSetupPacket(DataPacketBuffer)))
        {
          // Setup to send the response
          Data_PID_Toggle = USB_PID_DATA0;
          DataToTransmitOffset = 1;
        }
        else
        {
          // Send STALL PID if there is no response
          ReadyForTransmit = usb_packet_stall;
        }
      }
      else if (DataPacketBuffer[15] == USB_PID_OUT) // Check if it is an OUT packet
      {
        // will be getting stuffs here
        // incoming LL-PP-RI-(d0-d1-d2-d3-d4-d5)-C1-C2
        // ex.      0a-4b-01-(00-4b-0e-8d-0d-4e)-56-fa
        // LL - length, ours are always 0a or 08
        // PP - PID, should only be DATA0 or DATA1 (0xc3 or 0x4b) - 4b for us
        // RI - application level control byte - the HID report id. Here :
        //      == 1, request flash write, start address / length follows
        //      == 2, no special instruction, just carry data
        // d? - firmware data, each packet carries up to LL-4 bytes of data
        //      for report id 1 : report count = 6, LL = 0a, data bytes = 6
        //      for report id 2 : report count = 4, LL = 08, data bytes = 4
        // C? - packet checksum, application does not use these
        //

        uint8_t *cp = DataPacketBuffer+2;
        //if (*DataPacketBuffer == 0x0A && *cp == 0x01)
        if (packet_size == 0x0A)
        { // flash write request (report id 1)
          cp++;
          addrCurrent = addrStart = (*cp<<8) + *(cp+1); // get start address high bytes
          cp += 2;
          addrEnd = (*cp<<8) + *(cp+1);
          //______________ interrupt vector, don't do immediate flash write
          if (addrStart >= 0xff00)
          {
            buffUp = inBuf;
          }
          else
          {
            addrSave = addrEnd;
            buffUp = 0;
            idx = 0;
            next_time_flash_erase = 1;
          }
        }
        //else if (*DataPacketBuffer == 0x08 && *cp == 0x02)
        else if (packet_size == 0x08)
        {
          uint8_t c=0; // receive bytes (report id 2)
          cp++; // skip report id
          if (buffUp) // we are receiving interrupt vector bytes
          {
            for (c=0;c<4;c++)
              *((uint8_t *) buffUp++) = *cp++;
            addrCurrent += 4;
          }
          else
          { // we are receiving normal data
            for (c=0;c<4;c++)
              inBuf[c+idx] = *cp++;
            idx += 4;
          }
        }

      } // else if USB_PID_OUT
      //DataPacketBuffer[0] = 0; // Done with received packet, don't process again, allow USB SIE to receive the next packet
    } // if USB SIE has received a packet

    // Check if an outgoing packet needs chunking and the USB SIE
    //   is ready for it
    if (DataToTransmit && !ReadyForTransmit)
    {
      PacketGenerator(); // Make a chunk with CRC
    }

    if (!ReadyForTransmitIrqIn)
    { // Check if the USB SIE is ready for an endpoint 1 packet
      /*
      IrqIn(IrqInSendPacketBuffer); // Build the packet
      CRC(IrqInSendPacketBuffer); // Append CRC
      ReadyForTransmitIrqIn = IrqInSendPacketBuffer; // Send it
      */
    }


    // We have received interrupt vector address, and data bytes.
    // USB is idle which means we can write to flash
    if(usb_idle && buffUp && addrCurrent > addrStart && addrStart >= 0xff00)
    {
      //_____ we doing interrupt vector, so don't be interrupted
      uint16_t savIntr  = *((uint16_t *) 0xffe4);
      uint16_t savReset = *((uint16_t *) 0xfffe);
      _BIC_SR(GIE);
      FCTL1 = FWKEY+ERASE;
      FCTL3 = FWKEY;
      *((uint8_t *) 0xff00) = 0;
      FCTL1 = FWKEY+WRT;

      uint8_t *dp = (uint8_t *) 0xffa0;
      uint8_t *vp = (uint8_t *) 0xffe0;
      uint8_t *cp = inBuf;
      uint8_t i=0x20;
      while (i--) *dp++ = *cp++;  // write to flash backup copy

      *((uint16_t *) (inBuf+4))  = savIntr; // use bootloader's interrupt
      *((uint16_t *) (inBuf+30)) = savReset;// reset goes to bootloader

      i=0x20; cp = inBuf;
      while (i--) *vp++ = *cp++;  // write to flash real vector
      *((uint16_t *) (0xff80)) = addrSave; // save application's end address
      *((uint16_t *) (0xffde)) = 0xaa55;  // disable factory BSL
      buffUp = 0;
      FCTL1 = FWKEY;
      FCTL3 = FWKEY+LOCK;

      _BIS_SR(GIE);
    }


    // We have received addresses. USB is idle : erase flash.
    if(usb_idle && next_time_flash_erase)
    {
      FCTL2 = FWKEY+FSSEL0+(30);
      FCTL1 = FWKEY+ERASE;
      FCTL3 = FWKEY;
      *((uint8_t *) addrCurrent) = 0;
      FCTL1 = FWKEY+WRT;
      next_time_flash_erase = 0;
    }


    // We have received data bytes, and USB is idle : flash them.
    if(usb_idle && !buffUp && addrStart < 0xff00 && idx)
    {
      uint8_t c=0;
      for(c = 0; c < idx; c++)
        *((uint8_t *) addrCurrent++) = inBuf[c];
      idx = 0;

      if (!(addrCurrent&0x01ff))
      {
        //____ we are crossing 512byte/block boundary
        //____ erase and get ready for next block
        FCTL1 = FWKEY+ERASE;
        FCTL3 = FWKEY;
        *((uint8_t *) addrCurrent) = 0;
        FCTL1 = FWKEY+WRT;
      }
    }


    if(addrCurrent >= addrEnd && !buffUp) // !buffUp means that we have handled the interrupt vector in an usb idle time
    {
      //____ lockup flash, we are over.
      FCTL1 = FWKEY;
      FCTL3 = FWKEY+LOCK;

      addrCurrent = addrStart = addrEnd = 0;
      idx = 0;
    }

  }//for-ever
}
Example #29
0
void cc430_cpu_init(void)
{
    volatile uint16_t i;
    volatile unsigned char *ptr;

    /* disable watchdog */
    WDTCTL = WDTPW + WDTHOLD;

    // ---------------------------------------------------------------------
    // Enable 32kHz ACLK
    P5SEL |= 0x03;                            // Select XIN, XOUT on P5.0 and P5.1
    UCSCTL6 &= ~XT1OFF;                       // XT1 On, Highest drive strength
    UCSCTL6 |= XCAP_3;                        // Internal load cap

    UCSCTL3 = SELA__XT1CLK;                   // Select XT1 as FLL reference
    UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV;

    // ---------------------------------------------------------------------
    // Configure CPU clock for 12MHz
    _BIS_SR(SCG0);                  // Disable the FLL control loop
    UCSCTL0 = 0x0000;          // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_5;       // Select suitable range
    UCSCTL2 = FLLD_1 + 0x16E;  // Set DCO Multiplier
    _BIC_SR(SCG0);                  // Enable the FLL control loop

    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
    for (i = 0xFF; i > 0; i--); // Time for flag to set

    // Loop until XT1 & DCO stabilizes, use do-while to insure that
    // body is executed at least once
    do {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
        SFRIFG1 &= ~OFIFG;                      // Clear fault flags
    }
    while ((SFRIFG1 & OFIFG));

    // Disable all interrupts
    __disable_interrupt();
    // Get write-access to port mapping registers:
    PMAPPWD = 0x02D52;
    // Allow reconfiguration during runtime:
    PMAPCTL = PMAPRECFG;

    // P2.7 = TA0CCR1A or TA1CCR0A output (buzzer output)
    ptr  = &P2MAP0;
    *(ptr + 7) = PM_TA1CCR0A;
    P2OUT &= ~BIT7;
    P2DIR |= BIT7;

    // P1.5 = SPI MISO input
    ptr  = &P1MAP0;
    *(ptr + 5) = PM_UCA0SOMI;
    // P1.6 = SPI MOSI output
    *(ptr + 6) = PM_UCA0SIMO;
    // P1.7 = SPI CLK output
    *(ptr + 7) = PM_UCA0CLK;

    // Disable write-access to port mapping registers:
    PMAPPWD = 0;
    // Re-enable all interrupts
    irq_enable();

}
Example #30
0
int
main(void)
{
#if WITH_SD
  int r;
#endif /* WITH_SD */

  msp430_cpu_init();	
  watchdog_stop();

  /* Platform-specific initialization. */
  msb_ports_init();
  adc_init();

  clock_init();
  rtimer_init();

  sht11_init();
  leds_init();
  leds_on(LEDS_ALL);

  irq_init();
  process_init();

  /* serial interface */
  rs232_set_input(serial_line_input_byte);
  rs232_init();
  serial_line_init();

  uart_lock(UART_MODE_RS232);
  uart_unlock(UART_MODE_RS232);
#if WITH_UIP
  slip_arch_init(BAUD2UBR(115200));
#endif


#if WITH_SD
  r = sd_initialize();
  if(r < 0) {
    printf("Failed to initialize the SD driver: %s\n", sd_error_string(r));
  } else {
    sd_offset_t capacity;
    printf("The SD driver was successfully initialized\n");
    capacity = sd_get_capacity();
    if(capacity < 0) {
      printf("Failed to get the SD card capacity: %s\n", sd_error_string(r));
    } else {
      printf("SD card capacity: %u MB\n",
	(unsigned)(capacity / (1024UL * 1024)));
    }
  }
#endif

  /* System services */
  process_start(&etimer_process, NULL);
  ctimer_init();

  node_id_restore();

  init_net();

  energest_init();
 
#if PROFILE_CONF_ON
  profile_init();
#endif /* PROFILE_CONF_ON */
 
  leds_off(LEDS_ALL);

  printf(CONTIKI_VERSION_STRING " started. Node id %u, using %s.\n", 
         node_id, rime_mac->name);

  autostart_start(autostart_processes);

  /*
   * This is the scheduler loop.
   */
  ENERGEST_ON(ENERGEST_TYPE_CPU);

  while (1) {
    int r;
#if PROFILE_CONF_ON
    profile_episode_start();
#endif /* PROFILE_CONF_ON */
    do {
      /* Reset watchdog. */
      watchdog_periodic();
      r = process_run();
    } while(r > 0);

#if PROFILE_CONF_ON
    profile_episode_end();
#endif /* PROFILE_CONF_ON */

    /*
     * Idle processing.
     */
    int s = splhigh();		/* Disable interrupts. */
    if (process_nevents() != 0) {
      splx(s);			/* Re-enable interrupts. */
    } else {
      static unsigned long irq_energest = 0;
      /* Re-enable interrupts and go to sleep atomically. */
      ENERGEST_OFF(ENERGEST_TYPE_CPU);
      ENERGEST_ON(ENERGEST_TYPE_LPM);
     /*
      * We only want to measure the processing done in IRQs when we
      * are asleep, so we discard the processing time done when we
      * were awake.
      */
      energest_type_set(ENERGEST_TYPE_IRQ, irq_energest);

      if (uart_edge) {
	_BIC_SR(LPM1_bits + GIE);
      } else {
	_BIS_SR(LPM1_bits + GIE);
      }

      /*
       * We get the current processing time for interrupts that was
       * done during the LPM and store it for next time around. 
       */
      dint();
      irq_energest = energest_type_time(ENERGEST_TYPE_IRQ);
      eint();
      ENERGEST_OFF(ENERGEST_TYPE_LPM);
      ENERGEST_ON(ENERGEST_TYPE_CPU);
#if PROFILE_CONF_ON
      profile_clear_timestamps();
#endif /* PROFILE_CONF_ON */
    }
  }

  return 0;
}