Ejemplo n.º 1
0
void
selftest(void)
{
	emu_inhibit_gui = 1;
	emu_timestamp(); printf("selftesting: 0.5 sec sleep\n");
	Timer0_A4_Delay(16000);
	emu_timestamp(); printf("once more 0.5 sec sleep...\n");
	Timer0_A4_Delay(16000);
	emu_timestamp(); printf("ok\n");
	test_keys();
	emu_inhibit_gui = 0;
}
Ejemplo n.º 2
0
// *************************************************************************************************
// @fn          main
// @brief       Main routine
// @param       none
// @return      none
// *************************************************************************************************
int main(void)
{
	LED_On();

    // Init MCU
    init_application();

    // Assign initial value to global variables
    init_global_variables();

    //timestampInit(1396556875);

    // Main control loop: wait in low power mode until some event needs to be processed
    while (1)
    {
    	// Do the SHM specific stuff here.
    	shmApp();

    	// Now for the predetermined time we should sleep here...
    	P1OUT ^= 0x01;
    	uint8_t i = 3;
    	while (i--)
    	{
        	Timer0_A4_Delay(CONV_MS_TO_TICKS(1000));
    	}
    }
}
Ejemplo n.º 3
0
 	 	// *************************************************************************************************
// @fn          bmp_ps_init
// @brief       Init pressure sensor I/O
// @param       none
// @return      none
// *************************************************************************************************
void i2c_init(void)
{

    I2C_OUT |= SCL_PIN + SDA_PIN; // SCL and SDA are high by default
    I2C_DIR |= SCL_PIN + SDA_PIN; // SCL and SDA are outputs by default

    // 100msec delay to guarantee stable operation
    Timer0_A4_Delay(CONV_MS_TO_TICKS(100));
}
// *************************************************************************************************
// @fn          simpliciti_main_sync
// @brief       Send ready-to-receive packets in regular intervals. Listen shortly for host reply.
//				Decode received host command and trigger action.
// @param       none
// @return      none
// *************************************************************************************************
void simpliciti_main_sync(void)
{
    uint8_t len, i;
    uint8_t ed_data[2];

    while (1)
    {
        // Sleep 0.5sec between ready-to-receive packets
        // SimpliciTI has no low power delay function, so we have to use ours
        Timer0_A4_Delay(CONV_MS_TO_TICKS(500));

        // Get radio ready. Radio wakes up in IDLE state.
        SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);

        // Send 2 byte long ready-to-receive packet to stimulate host reply
        ed_data[0] = SYNC_ED_TYPE_R2R;
        ed_data[1] = 0xCB;
        SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE);

        // Wait shortly for host reply
        SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);
        NWK_DELAY(10);

        // Check if a command packet was received
        while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS)
        {
            // Decode received data
            if (len > 0)
            {
                // Use callback function in application to decode data and react
                simpliciti_sync_decode_ap_cmd_callback();

                // Get reply data and send out reply packet burst (19 bytes each)
                for (i = 0; i < simpliciti_reply_count; i++)
                {
                    NWK_DELAY(10);
                    simpliciti_sync_get_data_callback(i);
                    SMPL_SendOpt(sLinkID1, simpliciti_data, BM_SYNC_DATA_LENGTH, SMPL_TXOPTION_NONE);
                }
            }
        }

        // Put radio back to sleep
        SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);

        // Service watchdog
        WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;

        // Exit when flag bit SIMPLICITI_TRIGGER_STOP is set
        if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP))
        {
            // Clean up SimpliciTI stack to enable restarting
            sInit_done = 0;
            break;
        }
    }
}
Ejemplo n.º 5
0
// *************************************************************************************************
// @fn          cma_as_start
// @brief       Power-up and initialize acceleration sensor
// @param       none
// @return      none
// *************************************************************************************************
void cma_as_start(void)
{
    volatile uint16_t Counter_uint16_t;
    uint8_t bConfig;

    // Initialize SPI interface to acceleration sensor
    AS_SPI_CTL0 |= UCSYNC | UCMST | UCMSB        // SPI master, 8 data bits,  MSB first,
                   | UCCKPH;                     //  clock idle low, data output on falling
                                                 // edge
    AS_SPI_CTL1 |= UCSSEL1;                      // SMCLK as clock source
    AS_SPI_BR0 = CMA_AS_BR_DIVIDER;              // Low byte of division factor for baud rate
    AS_SPI_BR1 = 0x00;                           // High byte of division factor for baud
                                                 // rate
    AS_SPI_CTL1 &= ~UCSWRST;                     // Start SPI hardware

    // Configure interface pins
    as_start();

    // Configure sensor and start to sample data
#if (CMA_AS_RANGE == 2)
    bConfig = 0x80;
#    if (CMA_AS_SAMPLE_RATE == 100)
    bConfig |= 0x02;
#    elif (CMA_AS_SAMPLE_RATE == 400)
    bConfig |= 0x04;
#    else
#        error "Sample rate not supported"
#    endif
#elif (CMA_AS_RANGE == 8)
    bConfig = 0x00;
#    if (CMA_AS_SAMPLE_RATE == 40)
    bConfig |= 0x06;
#    elif (CMA_AS_SAMPLE_RATE == 100)
    bConfig |= 0x02;
#    elif (CMA_AS_SAMPLE_RATE == 400)
    bConfig |= 0x04;
#    else
#        error "Sample rate not supported"
#    endif
#else
#    error "Measurement range not supported"
#endif

    // Reset sensor
    cma_as_write_register(0x04, 0x02);
    cma_as_write_register(0x04, 0x0A);
    cma_as_write_register(0x04, 0x04);

    // Wait 5 ms before starting sensor output
    Timer0_A4_Delay(CONV_MS_TO_TICKS(5));

    // Set 2g measurement range, start to output data with 100Hz rate
    cma_as_write_register(0x02, bConfig);
}
Ejemplo n.º 6
0
// *************************************************************************************************
// @fn          start_simpliciti_sync
// @brief       Start SimpliciTI (sync mode).
// @param       none
// @return      none
// *************************************************************************************************
void start_simpliciti_sync(void)
{
    // Clear LINE1
    clear_line(LINE1);
    fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR);

    // Stop data logging and close session
    stop_datalog();

    // Turn on beeper icon to show activity
    display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON);
    display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON);
    display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON);

    // Prepare radio for RF communication
    open_radio();

    // Set SimpliciTI mode
    sRFsmpl.mode = SIMPLICITI_SYNC;

    // Set SimpliciTI timeout to save battery power
    sRFsmpl.timeout = SIMPLICITI_TIMEOUT;

    // Start SimpliciTI stack. Try to link to access point.
    // Exit with timeout or by a DOWN button press.
    if (simpliciti_link())
    {
        // Enter sync routine. This will send ready-to-receive packets at regular intervals to the
        // access point.
        // The access point always replies a command (NOP if no other command is set)
        simpliciti_main_sync();
    }

    // Set SimpliciTI state to OFF
    sRFsmpl.mode = SIMPLICITI_OFF;

    // Powerdown radio
    close_radio();

    // Clear last button events
    Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT));
    BUTTONS_IFG = 0x00;
    button.all_flags = 0;

    // Clear icons
    display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF);
    display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF);
    display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF);

    // Force full display update
    display.flag.full_update = 1;
}
Ejemplo n.º 7
0
// *************************************************************************************************
// @fn          bmp_ps_init
// @brief       Init pressure sensor I/O
// @param       none
// @return      none
// *************************************************************************************************
void ps_init(void)
{
    PS_INT_DIR &= ~PS_INT_PIN;           // EOC is input
    PS_INT_IES &= ~PS_INT_PIN;           // Interrupt on EOC rising edge
    PS_I2C_OUT |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are high by default
    PS_I2C_DIR |= PS_SCL_PIN + PS_SDA_PIN; // SCL and SDA are outputs by default

    // Reset global ps_ok flag
    ps_ok = 0;

    // 100msec delay to guarantee stable operation
    Timer0_A4_Delay(CONV_MS_TO_TICKS(100));
}
Ejemplo n.º 8
0
// *************************************************************************************************
// @fn          adc12_single_conversion
// @brief       Init ADC12. Do single conversion. Turn off ADC12.
// @param       none
// @return      none
// *************************************************************************************************
u16 adc12_single_conversion(u16 ref, u16 sht, u16 channel)
{
	// Initialize the shared reference module 
	REFCTL0 |= REFMSTR + ref + REFON;    		// Enable internal reference (1.5V or 2.5V)
  
	// Initialize ADC12_A 
	ADC12CTL0 = sht + ADC12ON;					// Set sample time 
	ADC12CTL1 = ADC12SHP;                     	// Enable sample timer
	ADC12MCTL0 = ADC12SREF_1 + channel;  		// ADC input channel  
	ADC12IE = 0x001;                          	// ADC_IFG upon conv result-ADCMEMO
  
  	// Wait 2 ticks (66us) to allow internal reference to settle
	Timer0_A4_Delay(2);       
	
	// Start ADC12
	ADC12CTL0 |= ADC12ENC;                             		  	

	// Clear data ready flag
  	adc12_data_ready = 0;
  	
  	// Sampling and conversion start  
    ADC12CTL0 |= ADC12SC;                   	
    
    // Wait until ADC12 has finished
    Timer0_A4_Delay(5);       
	while (!adc12_data_ready);
	
	// Shut down ADC12
	ADC12CTL0 &= ~(ADC12ENC | ADC12SC | sht);
	ADC12CTL0 &= ~ADC12ON;
	
	// Shut down reference voltage 	
	REFCTL0 &= ~(REFMSTR + ref + REFON); 
	
	ADC12IE = 0;                          	
	
	// Return ADC result
	return (adc12_result);
}
Ejemplo n.º 9
0
// *************************************************************************************************
// @fn          CW_Send_Char
// @brief       Send (via the buzzer) an alphanumeric character ("letter")
// @param       letter		character to send, in range 39 (''') to 90 ('Z'), inclusive
// @return      none
// *************************************************************************************************
void CW_Send_Char(u8 letter)
{
    
    if ((letter >= 39) && (letter <= 90)) { // In range
		letter = CW_Char[letter - 39]; // Get first "letter"
		//gibbons TODO: check if '=' operator or memcpy(...) is more appropriate
    }
    else if (letter == ' ') { // Send space (inter-word pause)
		Timer0_A4_Delay(CONV_MS_TO_TICKS(CW_WORD_PAUSE * CW_DOT_LENGTH));
		return;
    }
    else { // Invalid character
		return;
    }
    
    int i = 0x80; // Mask bit, starting at 0x80 = 1000 0000b
    while (i > letter) i >>= 1; // Find start bit
    i >>= 1; // Needed to skip over start bit, otherwise all letters start with an extra DASH!
    while (i > 0) {
		if (i & letter) { // Send dash (and pause after it)
			start_buzzer(1, CONV_MS_TO_TICKS(3*CW_DOT_LENGTH), CONV_MS_TO_TICKS(CW_SIGNAL_PAUSE * CW_DOT_LENGTH));
		}
		else { // Send dot (and pause after it)
			start_buzzer(1, CONV_MS_TO_TICKS(CW_DOT_LENGTH), CONV_MS_TO_TICKS(CW_SIGNAL_PAUSE * CW_DOT_LENGTH));
		}
		i >>= 1; // Move mask bit to the right one
		
		// Wait until finished buzzing
		while (is_buzzer()) {
			Timer0_A4_Delay(CONV_MS_TO_TICKS(2*CW_DOT_LENGTH)); // Go into LPM3
		}
    }
    
    // Now send inter-letter pause (space between successive letters)
    Timer0_A4_Delay(CONV_MS_TO_TICKS(CW_LETTER_PAUSE * CW_DOT_LENGTH));
	
	// Clean up display
	display.flag.full_update = 1;
}
Ejemplo n.º 10
0
// *************************************************************************************************
// @fn          mx_rfblue
// @brief       BlueRobin sub menu. Button STAR resets chest strap ID to 0 and searches for next chest strap in range.
// @param       u8 line	LINE2
// @return      none
// *************************************************************************************************
void mx_bluerobin(u8 line)
{
#if REMEMBER_TX_ID == TRUE
  u8 i;

	// Reset chest strap ID
	sBlueRobin.cs_id = 0;

  display_chars(LCD_SEG_L1_2_0, (u8*)"CLR", SEG_ON);
  for (i=0; i<4; i++) Timer0_A4_Delay(CONV_MS_TO_TICKS(500));
#endif

	// Clear simulated button event
	button.all_flags = 0;
}
Ejemplo n.º 11
0
// *************************************************************************************************
// @fn          as_start
// @brief       Power-up and initialize acceleration sensor
// @param       none
// @return      none
// *************************************************************************************************
void as_start(void)
{
    // Initialize interrupt pin for data read out from acceleration sensor
    AS_INT_IES &= ~AS_INT_PIN;                   // Interrupt on rising edge

    // Enable interrupt
    AS_INT_DIR &= ~AS_INT_PIN;                   // Switch INT pin to input
    AS_SPI_DIR &= ~AS_SDI_PIN;                   // Switch SDI pin to input
    AS_SPI_REN |= AS_SDI_PIN;                    // Pulldown on SDI pin
    AS_SPI_SEL |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function
    AS_CSN_OUT |= AS_CSN_PIN;                    // Deselect acceleration sensor
    AS_PWR_OUT |= AS_PWR_PIN;                    // Power on active high

    // Delay of >5ms required between switching on power and configuring sensor
    Timer0_A4_Delay(CONV_MS_TO_TICKS(10));

    // Initialize interrupt pin for data read out from acceleration sensor
    AS_INT_IFG &= ~AS_INT_PIN;                   // Reset flag
    AS_INT_IE |= AS_INT_PIN;                     // Enable interrupt
}
Ejemplo n.º 12
0
void
sx_gate (u8 line)
{
  u16 i;
  if (button.flag.down)
    {
	display_symbol (LCD_ICON_BEEPER1, SEG_ON);
	open_radio();
	gate_init();
	for(i=0;i<50;i++) {
	    GATE_Transmit(open, GATE_SETTING_PKTLEN);
	    Timer0_A4_Delay(CONV_MS_TO_TICKS(11));
	}
	close_radio();
	display_symbol (LCD_ICON_BEEPER1, SEG_OFF);
    }
  else
    {
    }

}
Ejemplo n.º 13
0
// *************************************************************************************************
// @fn          start_altitude_measurement
// @brief       Start altitude measurement
// @param       none
// @return      none
// *************************************************************************************************
void start_altitude_measurement(void)
{
   u8 timeout = 15;

   // Already on?
   if (sAlt.on)
      return;

   // Show warning if pressure sensor was not initialised properly
   if (!ps_ok)
   {
      display_chars(LCD_SEG_L1_2_0, (u8 *) "ERR", SEG_ON);
      return;
   }

   // Enable DRDY IRQ on rising edge
   PS_INT_IFG &= ~PS_INT_PIN;
   PS_INT_IE |= PS_INT_PIN;

   // Start pressure sensor
   ps_start();

   // Set altitude measurement flag
   sAlt.on = 1;

   // Get updated altitude
   while (((PS_INT_IN & PS_INT_PIN) == 0) && (timeout > 0))
   {
      Timer0_A4_Delay(CONV_MS_TO_TICKS(100));
      timeout--;
   }

   // Failed to start?
   if (timeout == 0)
   {
      sAlt.on = 0;
   }

   do_altitude_measurement(FILTER_OFF);
}
Ejemplo n.º 14
0
Archivo: ports.c Proyecto: epall/cage
__interrupt void PORT2_ISR(void)
{
	u8 int_flag, int_enable;
	u8 buzzer = 0;
	u8 simpliciti_button_event = 0;
	static u8 simpliciti_button_repeat = 0;

	// Clear button flags
	button.all_flags = 0;

	// Remember interrupt enable bits
	int_enable = BUTTONS_IE;

	// Store valid button interrupt flag
	int_flag = BUTTONS_IFG & int_enable;

	// ---------------------------------------------------
	// While SimpliciTI stack is active, buttons behave differently:
	//  - Store M1/M2/S1 button events in SimpliciTI packet data
	//  - Exit SimpliciTI when S2 was pressed 
  	if (is_rf())
  	{
  		// Erase previous button press after a number of resends (increase number if link quality is low)
  		// This will create a series of packets containing the same button press
  		// Necessary because we have no acknowledge
  		// Filtering (edge detection) will be done by receiver software
  		if (simpliciti_button_repeat++ > 6) 
  		{
  			simpliciti_data[0] &= ~0xF0;
  			simpliciti_button_repeat = 0;
  		}
  		
  		if ((int_flag & BUTTON_M1_PIN) == BUTTON_M1_PIN)			
  		{
  			simpliciti_data[0] |= SIMPLICITI_BUTTON_M1;
  			simpliciti_button_event = 1;
  		}
  		else if ((int_flag & BUTTON_M2_PIN) == BUTTON_M2_PIN)	
  		{
  			simpliciti_data[0] |= SIMPLICITI_BUTTON_M2;
  			simpliciti_button_event = 1;
  		}
		else if ((int_flag & BUTTON_S1_PIN) == BUTTON_S1_PIN)	
		{
			simpliciti_data[0] |= SIMPLICITI_BUTTON_S1;
			simpliciti_button_event = 1;
		}
		else if ((int_flag & BUTTON_S2_PIN) == BUTTON_S2_PIN)	
		{
			simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
		}
		
		// Trigger packet sending inside SimpliciTI stack
		if (simpliciti_button_event) simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA;
  	}
  	else // Normal operation
  	{
		// Debounce buttons
		if ((int_flag & ALL_BUTTONS) != 0)
		{ 
			// Disable PORT2 IRQ
			__disable_interrupt();
			BUTTONS_IE = 0x00; 
			__enable_interrupt();
	
			// Debounce delay 1
			Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN));
	
			// Reset inactivity detection
			sTime.last_activity = sTime.system_time;
			
			// Reset M button high detection
			sTime.previous_m_button_event = sTime.system_time;
		}

		// ---------------------------------------------------
		// M1 button IRQ
		if (IRQ_TRIGGERED(int_flag, BUTTON_M1_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_M1_IS_PRESSED)
			{
				button.flag.m1 = 1;
				
				sys.flag.mask_m1_button = 0;
		
				// Generate button click
				buzzer = 1;
			}
		}
		// ---------------------------------------------------
		// M2 button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_M2_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_M2_IS_PRESSED)
			{
				button.flag.m2 = 1;
				
				sys.flag.mask_m2_button = 0;
	
				// Generate button click
				buzzer = 1;
			}
		}
		// ---------------------------------------------------
		// S1 button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_S1_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_S1_IS_PRESSED)
			{
				button.flag.s1 = 1;
		
				// Generate button click
				buzzer = 1;
			}
		}
		// ---------------------------------------------------
		// S2 button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_S2_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_S2_IS_PRESSED)
			{
				button.flag.s2 = 1;
	
				// Generate button click
				buzzer = 1;
				
				// Faster reaction for stopwatch stop button press
				if (is_stopwatch()) 
				{
					stop_stopwatch();
					button.flag.s2 = 0;
				}
					
			}
		}
		// ---------------------------------------------------
		// B/L button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_BL_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_BL_IS_PRESSED)
			{
				button.flag.bl = 1;
			}
		}	
	}

	// Generate button click when button was activated
	if (buzzer)
	{
		// Any button event stops active alarm
		if (sAlarm.state == ALARM_ON) 
		{
			stop_alarm();
			button.all_flags = 0;
		}
		else if (!sys.flag.s_button_repeat_enabled)
		{
			start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150));
		}
		
		// Debounce delay 2
		Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT));
	}
	
	// ---------------------------------------------------
	// Acceleration sensor IRQ
	if (IRQ_TRIGGERED(int_flag, AS_INT_PIN))
	{
		// Get data from sensor
		request.flag.acceleration_measurement = 1;
  	}
  	
  	// ---------------------------------------------------
	// Pressure sensor IRQ
	if (IRQ_TRIGGERED(int_flag, PS_INT_PIN)) 
	{
		// Get data from sensor
		request.flag.altitude_measurement = 1;
  	}
  	
  	// ---------------------------------------------------
  	// Enable safe long button event detection
  	if(button.flag.m1 || button.flag.m2) 
	{
		// Additional debounce delay to enable safe high detection
		Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_M));
	
		// Check if this button event is short enough
		if (BUTTON_M1_IS_PRESSED) button.flag.m1 = 0;
		if (BUTTON_M2_IS_PRESSED) button.flag.m2 = 0;	
	}
	
	// Reenable PORT2 IRQ
	__disable_interrupt();
	BUTTONS_IFG = 0x00; 	
	BUTTONS_IE  = int_enable; 	
	__enable_interrupt();

	// Exit from LPM3/LPM4 on RETI
	__bic_SR_register_on_exit(LPM4_bits); 
}
__interrupt void PORT2_ISR(void)
{
    // Clear flags
    unsigned char int_flag, int_enable;
    unsigned char buzzer = 0;

    // Remember interrupt enable bits
    int_enable = BUTTONS_IE;

    if ((!button.flag.star_long) && (!button.flag.num_long))
    {
        // Clear button flags
        button.all_flags = 0;

        // Store valid button interrupt flag
        int_flag = BUTTONS_IFG & int_enable;

        {
            // Debounce buttons
            if ((int_flag & ALL_BUTTONS) != 0)
            {
                // Disable PORT2 IRQ
                __disable_interrupt();
                BUTTONS_IE = 0x00;
                __enable_interrupt();

                // Debounce delay 1
                Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN));
            }

            // ---------------------------------------------------
            // STAR button IRQ
            if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_STAR_IS_PRESSED)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_STAR_PIN;
                }
            }
            // ---------------------------------------------------
            // NUM button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_NUM_IS_PRESSED)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_NUM_PIN;
                }
            }
            // ---------------------------------------------------
            // UP button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_UP_IS_PRESSED)
                {
                    button.flag.up = 1;

                    // Generate button click
                    buzzer = 1;
                }
            }
            // ---------------------------------------------------
            // DOWN button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_DOWN_IS_PRESSED)
                {
                    button.flag.down = 1;

                    // Generate button click
                    buzzer = 1;

                    // Faster reaction for stopwatch stop button press
                    if (is_stopwatch() && !sys.flag.lock_buttons)
                    {
                        stop_stopwatch();
                        button.flag.down = 0;
                    }
                }
            }
            // ---------------------------------------------------
            // B/L button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_BACKLIGHT_IS_PRESSED)
                {
                    sButton.backlight_status = 1;
                    sButton.backlight_timeout = 0;
                    P2OUT |= BUTTON_BACKLIGHT_PIN;
                    P2DIR |= BUTTON_BACKLIGHT_PIN;
                }
            }
        }

        // Trying to lock/unlock buttons?
        if (button.flag.num && button.flag.down)
        {
            // No buzzer output
            buzzer = 0;
            button.all_flags = 0;
        }

        // ---------------------------------------------------
        // Acceleration sensor IRQ
        if (IRQ_TRIGGERED(int_flag, AS_INT_PIN))
        {
            // Get data from sensor
            request.flag.acceleration_measurement = 1;
        }

        // ---------------------------------------------------
        // Safe long button event detection
        if (button.flag.star || button.flag.num)
        {
            // Additional debounce delay to enable safe high detection - 50ms
            Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT));

            // Check if this button event is short enough
            if (BUTTON_STAR_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_STAR_PIN;
                button.flag.star = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.star_not_long = 1;
            }
            if (BUTTON_NUM_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_NUM_PIN;
                button.flag.num = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.num_not_long = 1;
            }
        }

    }
    // Reenable PORT2 IRQ
    __disable_interrupt();
    BUTTONS_IFG = 0x00;
    BUTTONS_IE = int_enable;
    __enable_interrupt();

    // Exit from LPM3/LPM4 on RETI
    __bic_SR_register_on_exit(LPM4_bits);
}
Ejemplo n.º 16
0
// *************************************************************************************************
// @fn          sx_bluerobin
// @brief       BlueRobin direct function. Button UP connects/disconnects with sender unit.
// @param       u8 line		LINE1
// @return      none
// *************************************************************************************************
void sx_bluerobin(u8 line)
{
	u8 stop = 0;
	
	// Exit if battery voltage is too low for radio operation
	if (sys.flag.low_battery) return;
	
	// Exit if SimpliciTI stack is active
	if (is_rf()) return;
		
	// UP: connect / disconnect transmitter
	if(button.flag.up)
	{
		if (sBlueRobin.state == BLUEROBIN_OFF)
		{
			// Init BlueRobin timer and radio
			open_radio();

			// Initialize BR library
			BRRX_Init_v();
			  
			// Set BR data transmission properties
			BRRX_SetPowerdownDelay_v(10);       // Power down channel after 10 consecutive lost data packets (~9 seconds)
			BRRX_SetSearchTimeout_v(8);         // Stop searching after 8 seconds
			
			// Sensitivity in learn mode reduced --> connect only to close transmitters
			// Skip this part if chest strap id was set in a previous learn mode run
#if REMEMBER_TX_ID == TRUE
			if (sBlueRobin.cs_id == 0) BRRX_SetSignalLevelReduction_v(5);

#else
			// Forget previously learned transmitter ID and connect to next close transmitter
			sBlueRobin.cs_id = 0;
			BRRX_SetSignalLevelReduction_v(5);  	
#endif

			// Apply frequency offset compensation to radio register FSCTRL0
			// If calibration memory was erased, rf_frequoffset defaults to 0x00 and has no effect
			WriteSingleReg(FSCTRL0, rf_frequoffset);

			// New state is SEARCH			
			sBlueRobin.state = BLUEROBIN_SEARCHING;	

			// Blink RF icon to show searching
			display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON);
			display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON);
			display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON);

			// Turn on radio and establish connection if channel not already started
			if (BRRX_GetState_t(HR_CHANNEL) == TX_OFF)
			{
				// Start in learn mode (connect to closest heart rate transmitter)
				BRRX_SetID_v(HR_CHANNEL, sBlueRobin.cs_id);
				BRRX_Start_v(HR_CHANNEL);

				// Wait until learning phase is over
			 	while (BRRX_GetState_t(HR_CHANNEL)==TX_SEARCH) 
			 	{
					Timer0_A4_Delay(CONV_MS_TO_TICKS(200));
    			}
			}
			
		 	// Check if connection attempt was successful
			if (BRRX_GetState_t(HR_CHANNEL)==TX_ACTIVE)	
			{
				// Successfully connected to transmitter
				sBlueRobin.state = BLUEROBIN_CONNECTED;		
				
				// When in learn mode, copy chest strap ID
				if (sBlueRobin.cs_id == 0) 
				{
					sBlueRobin.cs_id = BRRX_GetID_u32(HR_CHANNEL);
				}

				// Show steady RF icon to indicate established connection
				display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF);
				display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF);
				display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF);
				// Show blinking icon
				display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON);
			}
			else // Error -> Shutdown connection
			{
			  	stop = 1;
			}			
		}
		else if (sBlueRobin.state == BLUEROBIN_CONNECTED)
		{
			// Shutdown connection
			stop = 1;
		}
	}	
	
	// Shutdown connection
	if (stop)
	{
		stop_bluerobin();		
	}
}
// *************************************************************************************************
// @fn          simpliciti_get_ed_data_callback
// @brief       Callback function to read end device data from acceleration sensor (if available)
//                              and trigger sending. Can be also be used to transmit other data at
// different packet rates.
//                              Please observe the applicable duty limit in the chosen ISM band.
// @param       none
// @return      none
// *************************************************************************************************
void simpliciti_get_ed_data_callback(void)
{
    static u8 packet_counter = 0;

    if (sRFsmpl.mode == SIMPLICITI_ACCELERATION)
    {
        // Wait for next sample
        Timer0_A4_Delay(CONV_MS_TO_TICKS(5));

        // Read from sensor if DRDY pin indicates new data (set in PORT2 ISR)
        if (request.flag.acceleration_measurement && ((AS_INT_IN & AS_INT_PIN) == AS_INT_PIN))
        {
            // Clear flag
            request.flag.acceleration_measurement = 0;

            // Get data from sensor
            as_get_data(sAccel.xyz);

            // Transmit only every 3rd data set (= 33 packets / second)
            if (packet_counter++ > 1)
            {
                // Reset counter
                packet_counter = 0;

                // Store XYZ data in SimpliciTI variable
                simpliciti_data[1] = sAccel.xyz[0];
                simpliciti_data[2] = sAccel.xyz[1];
                simpliciti_data[3] = sAccel.xyz[2];

                // Trigger packet sending
                simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA;
            }
        }
    }
    else                        // transmit only button events
    {
        // New button event is stored in data
        if ((packet_counter == 0) && (simpliciti_data[0] & 0xF0) != 0)
        {
            packet_counter = 5;
        }

        // Send packet several times
        if (packet_counter > 0)
        {
            // Clear button event when sending last packet
            if (--packet_counter == 0)
            {
                simpliciti_data[0] &= ~0xF0;
            }
            else
            {
                // Trigger packet sending in regular intervals
                Timer0_A4_Delay(CONV_MS_TO_TICKS(30));
                simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA;
            }
        }
        else
        {
            // Wait in LPM3 for next button press
            _BIS_SR(LPM3_bits + GIE);
            __no_operation();
        }
    }

    // Update clock every 1/1 second
    if (display.flag.update_time)
    {
        display_time(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
        display.flag.update_time = 0;

        // Service watchdog
        WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
    }
}
Ejemplo n.º 18
0
// *************************************************************************************************
// @fn          start_bluerobin
// @brief       Start BlueRobin stack and search for a transmitter.
// @param       none
// @return      0 = no transmitter found, 1 = connected to a transmitter
// *************************************************************************************************
u8 start_bluerobin(void)
{
    u8 timeout, i;

    // Init BlueRobin timer and radio
    // Enable high current mode
    open_radio();

    // Initialize BR library
    BRRX_Init_v();

    // Set BR data transmission properties
    BRRX_SetPowerdownDelay_v(10); // Power down channel after 10 consecutive lost data packets (~9
                                  // seconds)
    BRRX_SetSearchTimeout_v(6);   // Stop searching after 8 seconds

    // Sensitivity in learn mode reduced --> connect only to close transmitters
    // Skip this part if chest strap id was set in a previous learn mode run
#if REMEMBER_TX_ID == TRUE
    if (sBlueRobin.cs_id == 0)
        BRRX_SetSignalLevelReduction_v(5);
#else
    // Forget previously learned transmitter ID and connect to next close transmitter
    sBlueRobin.cs_id = 0;
    BRRX_SetSignalLevelReduction_v(5);
#endif

    // Apply frequency offset compensation to radio register FSCTRL0
    // If calibration memory was erased, rf_frequoffset defaults to 0x00 and has no effect
    WriteSingleReg(FSCTRL0, rf_frequoffset);

    // New state is SEARCH
    sBlueRobin.state = BLUEROBIN_SEARCHING;

    // Blink RF icon to show searching
    display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON);
    display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON);
    display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON);

    // Turn on radio and establish connection if channel not already started
    if (BRRX_GetState_t(HR_CHANNEL) == TX_OFF)
    {
        // Start in learn mode (connect to closest heart rate transmitter)
        BRRX_SetID_v(HR_CHANNEL, sBlueRobin.cs_id);
        BRRX_Start_v(HR_CHANNEL);

        // Wait until learning phase is over, additional timeout prevents race condition if hardware
        // works incorrect
        timeout = 40;
        while ((BRRX_GetState_t(HR_CHANNEL) == TX_SEARCH) && (timeout-- > 0))
        {
            Timer0_A4_Delay(CONV_MS_TO_TICKS(200));
        }

        // Timeout?
        if (timeout == 0)
        {
            display_chars(LCD_SEG_L1_3_0, (u8 *) "FAIL", SEG_ON);
            for (i = 0; i < 4; i++)
                Timer0_A4_Delay(CONV_MS_TO_TICKS(500));
        }
    }

    // Check if connection attempt was successful
    if (BRRX_GetState_t(HR_CHANNEL) == TX_ACTIVE)
    {
        // Successfully connected to transmitter
        sBlueRobin.state = BLUEROBIN_CONNECTED;

        // When in learn mode, copy chest strap ID
        if (sBlueRobin.cs_id == 0)
            sBlueRobin.cs_id = BRRX_GetID_u32(HR_CHANNEL);

        // Show steady RF icon to indicate established connection
        display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_OFF);
        display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_OFF);
        display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_OFF);

        // Show blinking icon
        display_symbol(LCD_ICON_HEART, SEG_ON_BLINK_ON);

        return (1);
    }
    else                        // Error -> Shutdown connection
    {
        // Clear RF icon
        display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF);
        display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF);
        display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF);

        return (0);
    }
}
// *************************************************************************************************
// @fn          start_simpliciti_tx_only
// @brief       Start SimpliciTI (tx only).
// @param       simpliciti_state_t              SIMPLICITI_ACCELERATION, SIMPLICITI_BUTTONS
// @return      none
// *************************************************************************************************
void start_simpliciti_tx_only(simpliciti_mode_t mode)
{
    // Display time in line 1
    clear_line(LINE1);
    fptr_lcd_function_line1(LINE1, DISPLAY_LINE_CLEAR);
    display_time(LINE1, DISPLAY_LINE_UPDATE_FULL);

    // Preset simpliciti_data with mode (key or mouse click) and clear other data bytes
    if (mode == SIMPLICITI_ACCELERATION)
    {
        simpliciti_data[0] = SIMPLICITI_MOUSE_EVENTS;
    }
    else
    {
        simpliciti_data[0] = SIMPLICITI_KEY_EVENTS;
    }
    simpliciti_data[1] = 0;
    simpliciti_data[2] = 0;
    simpliciti_data[3] = 0;

    // Turn on beeper icon to show activity
    display_symbol(LCD_ICON_BEEPER1, SEG_ON_BLINK_ON);
    display_symbol(LCD_ICON_BEEPER2, SEG_ON_BLINK_ON);
    display_symbol(LCD_ICON_BEEPER3, SEG_ON_BLINK_ON);

    // Debounce button event
    Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT));

    // Prepare radio for RF communication
    open_radio();

    // Set SimpliciTI mode
    sRFsmpl.mode = mode;

    // Set SimpliciTI timeout to save battery power
    sRFsmpl.timeout = SIMPLICITI_TIMEOUT;

    // Start SimpliciTI stack. Try to link to access point.
    // Exit with timeout or by a button DOWN press.
    if (simpliciti_link())
    {
        if (mode == SIMPLICITI_ACCELERATION)
        {
            // Start acceleration sensor
            as_start();
        }

        // Enter TX only routine. This will transfer button events and/or acceleration data to
        // access point.
        simpliciti_main_tx_only();
    }

    // Set SimpliciTI state to OFF
    sRFsmpl.mode = SIMPLICITI_OFF;

    // Stop acceleration sensor
    as_stop();

    // Powerdown radio
    close_radio();

    // Clear last button events
    Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT));
    BUTTONS_IFG = 0x00;
    button.all_flags = 0;

    // Clear icons
    display_symbol(LCD_ICON_BEEPER1, SEG_OFF_BLINK_OFF);
    display_symbol(LCD_ICON_BEEPER2, SEG_OFF_BLINK_OFF);
    display_symbol(LCD_ICON_BEEPER3, SEG_OFF_BLINK_OFF);

    // Clean up line 1
    clear_line(LINE1);
    display_time(LINE1, DISPLAY_LINE_CLEAR);

    // Force full display update
    display.flag.full_update = 1;
}
Ejemplo n.º 20
0
// *************************************************************************************************
// @fn          as_start
// @brief       Power-up and initialize acceleration sensor
// @param       none
// @return      none
// *************************************************************************************************
void as_start(void)
{
	volatile u16 Counter_u16;
	u8 bConfig;//, bStatus;
	
	// Initialize SPI interface to acceleration sensor
	AS_SPI_CTL0 |= UCSYNC | UCMST | UCMSB // SPI master, 8 data bits,  MSB first,
	               | UCCKPH;              //  clock idle low, data output on falling edge
	AS_SPI_CTL1 |= UCSSEL1;               // SMCLK as clock source
	AS_SPI_BR0   = AS_BR_DIVIDER;         // Low byte of division factor for baud rate
	AS_SPI_BR1   = 0x00;                  // High byte of division factor for baud rate
	AS_SPI_CTL1 &= ~UCSWRST;              // Start SPI hardware
  
	// Initialize interrupt pin for data read out from acceleration sensor
	AS_INT_IES &= ~AS_INT_PIN;            // Interrupt on rising edge

#ifdef AS_DISCONNECT	  
	// Enable interrupt 
	AS_INT_DIR &= ~AS_INT_PIN;            // Switch INT pin to input
	AS_SPI_DIR &= ~AS_SDI_PIN;            // Switch SDI pin to input
	AS_SPI_REN |=  AS_SDI_PIN;            // Pulldown on SDI pin
	AS_SPI_SEL |=  AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Port pins to SDO, SDI and SCK function
	AS_CSN_OUT |=  AS_CSN_PIN;            // Deselect acceleration sensor
	AS_PWR_OUT |=  AS_PWR_PIN;            // Power on active high
#endif

	// Delay of >5ms required between switching on power and configuring sensor
	Timer0_A4_Delay(CONV_MS_TO_TICKS(10));
	
	// Initialize interrupt pin for data read out from acceleration sensor
	AS_INT_IFG &= ~AS_INT_PIN;            // Reset flag
	AS_INT_IE  |=  AS_INT_PIN;            // Enable interrupt
	
	// Configure sensor and start to sample data
#if (AS_RANGE == 2)
  bConfig = 0x80;
  #if (AS_SAMPLE_RATE == 100)
    bConfig |= 0x02;
  #elif (AS_SAMPLE_RATE == 400)
    bConfig |= 0x04;
  #else
    #error "Sample rate not supported"
  #endif
#elif (AS_RANGE == 8)
  bConfig = 0x00;
  #if (AS_SAMPLE_RATE == 40)
    bConfig |= 0x06;
  #elif (AS_SAMPLE_RATE == 100)
    bConfig |= 0x02;
  #elif (AS_SAMPLE_RATE == 400)
    bConfig |= 0x04;
  #else
    #error "Sample rate not supported"
  #endif
#else
  #error "Measurement range not supported"    
#endif  

	// Reset sensor
	as_write_register(0x04, 0x02);   
	as_write_register(0x04, 0x0A);   
	as_write_register(0x04, 0x04);   
	
	// Wait 5 ms before starting sensor output
	Timer0_A4_Delay(CONV_MS_TO_TICKS(5));
	
	// Set 2g measurement range, start to output data with 100Hz rate
	as_write_register(0x02, bConfig);   
}
Ejemplo n.º 21
0
// *************************************************************************************************
// @fn          test_mode
// @brief       Manual test mode. Activated by holding buttons STAR and UP simultaneously.
//                              Cancelled by any other button press.
// @param       none
// @return      none
// *************************************************************************************************
void test_mode(void)
{
    u8 test_step, start_next_test;
    u8 *str;
    u8 i;

    // Disable timer - no need for a clock tick
    Timer0_Stop();

    // Disable LCD charge pump while in standby mode
    // This reduces current consumption by ca. 5�A to ca. 10�A
    LCDBVCTL = 0;

    // Show welcome screen
    display_chars(LCD_SEG_L1_3_0, (u8 *) " DC ", SEG_ON);
    display_chars(LCD_SEG_L2_4_0, (u8 *) "44 20", SEG_ON);
    display_symbol(LCD_SEG_L1_COL, SEG_ON);
    display_symbol(LCD_ICON_HEART, SEG_ON);
    display_symbol(LCD_ICON_STOPWATCH, SEG_ON);
    display_symbol(LCD_ICON_RECORD, SEG_ON);
    display_symbol(LCD_ICON_ALARM, SEG_ON);
    display_symbol(LCD_ICON_BEEPER1, SEG_ON);
    display_symbol(LCD_ICON_BEEPER2, SEG_ON);
    display_symbol(LCD_ICON_BEEPER3, SEG_ON);
    display_symbol(LCD_SYMB_ARROW_UP, SEG_ON);
    display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON);
    display_symbol(LCD_SYMB_AM, SEG_ON);

    // Hold watchdog
    WDTCTL = WDTPW + WDTHOLD;

    // Wait for button press
    _BIS_SR(LPM3_bits + GIE);
    __no_operation();

    // Clear display
    display_all_off();

#ifdef USE_LCD_CHARGE_PUMP
    // Charge pump voltage generated internally, internal bias (V2-V4) generation
    // This ensures that the contrast and LCD control is constant for the whole battery lifetime
    LCDBVCTL = LCDCPEN | VLCD_2_72;
#endif

    // Renenable timer
    Timer0_Start();

    // Debounce button press
    Timer0_A4_Delay(CONV_MS_TO_TICKS(100));

    while (1)
    {
        // Check button event
        if (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED)
        {
            // Start with test #0
            test_step = 0;
            start_next_test = 1;
            while (1)
            {
                if (start_next_test)
                {
                    // Clean up previous test display
                    display_all_off();

                    start_next_test = 0;

                    switch (test_step)
                    {
                        case 0: // All LCD segments on
                            display_all_on();
                            // Wait until buttons are off
                            while (BUTTON_STAR_IS_PRESSED && BUTTON_UP_IS_PRESSED) ;
                            break;
//                        case 1: // Altitude measurement
//                            display_altitude(LINE1, DISPLAY_LINE_UPDATE_FULL);
//                            for (i = 0; i < 2; i++)
//                            {
//                                while ((PS_INT_IN & PS_INT_PIN) == 0) ;
//                                do_altitude_measurement(FILTER_OFF);
//                                display_altitude(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
//                            }
//                            stop_altitude_measurement();
//                            break;
//                        case 2: // Temperature measurement
//                            display_temperature(LINE1, DISPLAY_LINE_UPDATE_FULL);
//                            for (i = 0; i < 4; i++)
//                            {
//                                Timer0_A4_Delay(CONV_MS_TO_TICKS(250));
//                                temperature_measurement(FILTER_OFF);
//                                display_temperature(LINE1, DISPLAY_LINE_UPDATE_PARTIAL);
//                            }
//                            break;
//                        case 3: // Acceleration measurement
//                            as_start();
//                            for (i = 0; i < 4; i++)
//                            {
//                                Timer0_A4_Delay(CONV_MS_TO_TICKS(250));
//                                as_get_data(sAccel.xyz);
//                                str = int_to_array(sAccel.xyz[0], 3, 0);
//                                display_chars(LCD_SEG_L1_2_0, str, SEG_ON);
//                                str = int_to_array(sAccel.xyz[2], 3, 0);
//                                display_chars(LCD_SEG_L2_2_0, str, SEG_ON);
//                            }
//                            as_stop();
//                            break;
//                        case 4: // BlueRobin test
//                            button.flag.up = 1;
//                            sx_bluerobin(LINE1);
//                            Timer0_A4_Delay(CONV_MS_TO_TICKS(100));
//                            get_bluerobin_data();
//                            display_heartrate(LINE1, DISPLAY_LINE_UPDATE_FULL);
//                            stop_bluerobin();
//                            break;
                    }

                    // Debounce button
                    Timer0_A4_Delay(CONV_MS_TO_TICKS(200));
                }

                // Check button event
                if (BUTTON_STAR_IS_PRESSED)
                {
                    test_step = 1;
                    start_next_test = 1;
                }
                else if (BUTTON_NUM_IS_PRESSED)
                {
                    test_step = 2;
                    start_next_test = 1;
                }
                else if (BUTTON_UP_IS_PRESSED)
                {
                    test_step = 3;
                    start_next_test = 1;
                }
                else if (BUTTON_DOWN_IS_PRESSED)
                {
                    test_step = 4;
                    start_next_test = 1;
                }
                else if (BUTTON_BACKLIGHT_IS_PRESSED)
                {
                    // Wait until button has been released (avoid restart)
                    while (BUTTON_BACKLIGHT_IS_PRESSED) ;

                    // Disable LCD and LCD charge pump
                    LCDBCTL0 &= ~BIT0;
                    LCDBVCTL = 0;

                    // Debounce button press
                    Timer0_A4_Delay(CONV_MS_TO_TICKS(500));

                    // Disable timer - no need for a clock tick
                    Timer0_Stop();

                    // Hold watchdog
                    WDTCTL = WDTPW + WDTHOLD;

                    // Sleep until button is pressed (ca. 4�A current consumption)
                    _BIS_SR(LPM4_bits + GIE);
                    __no_operation();

                    // Force watchdog reset for a clean restart
                    WDTCTL = 1;
                }

#ifdef USE_WATCHDOG
                // Service watchdog
                WDTCTL = WDTPW + WDTIS__512K + WDTSSEL__ACLK + WDTCNTCL;
#endif
                // To LPM3
                _BIS_SR(LPM3_bits + GIE);
                __no_operation();
            }
        }
        else
        {
            // Debounce button
            Timer0_A4_Delay(CONV_MS_TO_TICKS(100));
            button.all_flags = 0;

            // Turn off backlight
            P2OUT &= ~BUTTON_BACKLIGHT_PIN;
            P2DIR &= ~BUTTON_BACKLIGHT_PIN;
            break;
        }
    }
}
Ejemplo n.º 22
0
// *************************************************************************************************
// @fn          simpliciti_main_tx_only
// @brief       Get data through callback. Transfer data when external trigger is set.
// @param       none
// @return      none
// *************************************************************************************************
void simpliciti_main_tx_only(void)
{
	uint8_t len, i;
	uint8_t ed_data[2];

	while(1)
	{
		// Get end device data from callback function 
		simpliciti_get_ed_data_callback();

		// Get radio ready. Wakes up in IDLE state.
		if(getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA) || 
		   getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_RECEIVE_DATA)) {

			SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);

			// Send data when flag bit SIMPLICITI_TRIGGER_SEND_DATA is set
			if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA)) 
			{
			  // Acceleration / button events packets are 4 bytes long
              SMPL_SendOpt(sLinkID1, simpliciti_data, simpliciti_payload_length, SMPL_TXOPTION_NONE);
			  //SMPL_SendOpt(sLinkID1, simpliciti_data, simpliciti_payload_length, simpliciti_options);
              // reset options to default
              //simpliciti_options =  SMPL_TXOPTION_NONE;
			  clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_SEND_DATA);
			}
			// Receive data when flag bit SIMPLICITI_TRIGGER_RECEIVE_DATA is set
			if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_RECEIVE_DATA)) {
				// Send 2 byte long ready-to-receive packet to stimulate host reply
				clearFlag(simpliciti_flag, SIMPLICITI_TRIGGER_RECEIVE_DATA);

				// clean up tha buffer first
				simpliciti_data[0] = 0x00;
				simpliciti_data[1] = 0x00;
				simpliciti_data[3] = 0x00;
				simpliciti_data[4] = 0x00;

				// generate a ready to receive packet
				ed_data[0] = SYNC_ED_TYPE_R2R;
				ed_data[1] = 0xCB;

				SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);

				// we try to receive 9 times by sending a R2R packet
				for (i = 0; i < 10; i++) {
					SMPL_SendOpt(sLinkID1, ed_data, 2, SMPL_TXOPTION_NONE);

					//WDTCTL = WDTPW + WDTHOLD;

					// Wait shortly for host reply
					NWK_DELAY(10);

					while (SMPL_Receive(sLinkID1, simpliciti_data, &len) == SMPL_SUCCESS) 
					{
						if (len > 0)
						{
							// Decode received data
							if(simpliciti_get_rvc_callback(len))
							{
								// stop retry loop
								i = 10;
								break;
							}
						}
					}
                    Timer0_A4_Delay(CONV_MS_TO_TICKS(500));
				}
			}

			// Put radio back to SLEEP state
			SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);
		}
		// Exit when flag bit SIMPLICITI_TRIGGER_STOP is set
		if (getFlag(simpliciti_flag, SIMPLICITI_TRIGGER_STOP)) 
		{
			// Clean up SimpliciTI stack to enable restarting
			sInit_done = 0;
			break;
		}
	}
}
Ejemplo n.º 23
0
__interrupt void PORT2_ISR(void)
{
    // Clear flags
    u8 int_flag, int_enable;
    u8 buzzer = 0;
    u8 simpliciti_button_event = 0;
    static u8 simpliciti_button_repeat = 0;

    // Remember interrupt enable bits
    int_enable = BUTTONS_IE;

    if ((!button.flag.star_long) && (!button.flag.num_long))
    {
        // Clear button flags
        button.all_flags = 0;

        // Store valid button interrupt flag
        int_flag = BUTTONS_IFG & int_enable;

        // ---------------------------------------------------
        // While SimpliciTI stack is active, buttons behave differently:
        //  - Store button events in SimpliciTI packet data
        //  - Exit SimpliciTI when button DOWN was pressed
        if (is_rf())
        {
            // Erase previous button press after a number of resends (increase number if link
            // quality is low)
            // This will create a series of packets containing the same button press
            // Necessary because we have no acknowledge
            // Filtering (edge detection) will be done by receiver software
            if (simpliciti_button_repeat++ > 6)
            {
                simpliciti_data[0] &= ~0xF0;
                simpliciti_button_repeat = 0;
            }

            if ((int_flag & BUTTON_STAR_PIN) == BUTTON_STAR_PIN)
            {
                simpliciti_data[0] |= SIMPLICITI_BUTTON_STAR;
                simpliciti_button_event = 1;
            }
            else if ((int_flag & BUTTON_NUM_PIN) == BUTTON_NUM_PIN)
            {
                simpliciti_data[0] |= SIMPLICITI_BUTTON_NUM;
                simpliciti_button_event = 1;
            }
            else if ((int_flag & BUTTON_UP_PIN) == BUTTON_UP_PIN)
            {
                simpliciti_data[0] |= SIMPLICITI_BUTTON_UP;
                simpliciti_button_event = 1;
            }
            else if ((int_flag & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN)
            {
                simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
            }

            // Trigger packet sending inside SimpliciTI stack
            if (simpliciti_button_event)
                simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA;
        }
        else                    // Normal operation
        {
            // Debounce buttons
            if ((int_flag & ALL_BUTTONS) != 0)
            {
                // Disable PORT2 IRQ
                __disable_interrupt();
                BUTTONS_IE = 0x00;
                __enable_interrupt();

                // Debounce delay 1
                Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN));

                // Reset inactivity detection
                sTime.last_activity = sTime.system_time;
            }

            // ---------------------------------------------------
            // STAR button IRQ
            if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_STAR_IS_PRESSED)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_STAR_PIN;
                }
            }
            // ---------------------------------------------------
            // NUM button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_NUM_IS_PRESSED)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_NUM_PIN;
                }
            }
            // ---------------------------------------------------
            // UP button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_UP_IS_PRESSED)
                {
                    button.flag.up = 1;

                    // Generate button click
                    buzzer = 1;
                }
            }
            // ---------------------------------------------------
            // DOWN button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_DOWN_IS_PRESSED)
                {
                    button.flag.down = 1;

                    // Generate button click
                    buzzer = 1;

                    // Faster reaction for stopwatch stop button press
                    if (is_stopwatch() && !sys.flag.lock_buttons)
                    {
                        stop_stopwatch();
                        button.flag.down = 0;
                    }
                }
            }
            // ---------------------------------------------------
            // B/L button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_BACKLIGHT_IS_PRESSED)
                {
                    sButton.backlight_status = 1;
                    sButton.backlight_timeout = 0;
                    P2OUT |= BUTTON_BACKLIGHT_PIN;
                    P2DIR |= BUTTON_BACKLIGHT_PIN;
                }
            }
        }

        // Trying to lock/unlock buttons?
        if (button.flag.num && button.flag.down)
        {
            // No buzzer output
            buzzer = 0;
            button.all_flags = 0;
        }

        // Generate button click when button was activated
        if (buzzer)
        {
            // Any button event stops active alarm
            if (sAlarm.state == ALARM_ON)
            {
                stop_alarm();
                button.all_flags = 0;
            }
            else if (!sys.flag.up_down_repeat_enabled)
            {
                start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150));
            }

            // Debounce delay 2
            Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT));
        }

        // ---------------------------------------------------
        // Acceleration sensor IRQ
        if (IRQ_TRIGGERED(int_flag, AS_INT_PIN))
        {
            // Get data from sensor
            request.flag.acceleration_measurement = 1;
        }

        // ---------------------------------------------------
        // Pressure sensor IRQ
        if (IRQ_TRIGGERED(int_flag, PS_INT_PIN))
        {
            // Get data from sensor
            request.flag.altitude_measurement = 1;
        }

        // ---------------------------------------------------
        // Safe long button event detection
        if (button.flag.star || button.flag.num)
        {
            // Additional debounce delay to enable safe high detection - 50ms
            Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT));

            // Check if this button event is short enough
            if (BUTTON_STAR_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_STAR_PIN;
                button.flag.star = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.star_not_long = 1;
            }
            if (BUTTON_NUM_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_NUM_PIN;
                button.flag.num = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.num_not_long = 1;
            }
        }

    }
    // Reenable PORT2 IRQ
    __disable_interrupt();
    BUTTONS_IFG = 0x00;
    BUTTONS_IE = int_enable;
    __enable_interrupt();

    // Exit from LPM3/LPM4 on RETI
    __bic_SR_register_on_exit(LPM4_bits);
}