void test_as_start(void) { Manual mem = (Manual) priv_imalloc(1 Mb, MANUAL + ASCENDING_SIZE); Priv_mem new_mem = style_to_priv((Memory) mem); CU_ASSERT(as_start(new_mem) == new_mem->as->start); free_lists(new_mem->lists); free(new_mem->as->start); free(new_mem); }
// ************************************************************************************************* // @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); }
void start_acceleration_measurement(void) { if (!is_acceleration_measurement()) { // Start sensor as_start(); // Set timeout counter sAccel.timeout = ACCEL_MEASUREMENT_TIMEOUT; // Set mode sAccel.mode = ACCEL_MODE_ON; } }
// ************************************************************************************************* // @fn doorlock_random // @brief garther random bits using accelerometer // @param random bits (output) // @return none // ************************************************************************************************* void doorlock_random(u8 random[16]) { u8 longrandom[32] = {0}; // initialize doorlock_random_index = 0; // start accelerometer as_start(AS_MODE_2G_100HZ); // start timer fptr_Timer0_A1_function = doorlock_random_timer; Timer0_A1_Start(CONV_MS_TO_TICKS(DOORLOCK_RANDOM_INTERVAL)); for(;;) { idle(); if (doorlock_random_index >= 32) { as_stop(); break; } // look for accelerometer data ready event if (!request.flag.acceleration_measurement) { continue; } request.flag.acceleration_measurement = 0; // "randomly" flipping bits longrandom[(doorlock_random_index + 0) % 32] ^= as_get_x(); longrandom[(doorlock_random_index + 10) % 32] ^= as_get_y(); longrandom[(doorlock_random_index + 20) % 32] ^= as_get_z(); } // just to make sure Timer0_A1_Stop(); // now encrypt aes_encrypt(longrandom, longrandom + 16); // done memcpy(random, longrandom, sizeof(u8) * 16); }
// ************************************************************************************************* // @fn start_agility // @brief Start agility measurement // @param none // @return none // ************************************************************************************************* void start_agility(void) { // Start sensor data acquisition if not already started by modul acceleration.c if(sAccel.mode == ACCEL_MODE_OFF) { // Start sensor incl. ISR as_start(); // Set acceleration timeout counter to prevent an undesired stop from module timer.c if(sAccel.timeout < ACCEL_TIMEOUT_PREVENTION) { sAccel.timeout = ACCEL_TIMEOUT_PREVENTION; } } // Reset timeout and cycles if cycles elapsed if(sAgil.cycles == 0) { sAgil.timeout = sAgil.TimeoutSetting; sAgil.cycles = sAgil.CycleSetting; } // Set state to RUN sAgil.state = AGIL_RUN; }
// ************************************************************************************************* // @fn display_acceleration // @brief Display routine. // @param u8 line LINE1 // u8 update DISPLAY_LINE_UPDATE_FULL, DISPLAY_LINE_CLEAR // @return none // ************************************************************************************************* void display_acceleration(u8 line, u8 update) { u8 * str; u8 raw_data; u16 accel_data; // Show warning if acceleration sensor was not initialised properly if (!as_ok) { display_chars(LCD_SEG_L1_2_0, (u8*)"ERR", SEG_ON); } else { // Redraw whole screen if (update == DISPLAY_LINE_UPDATE_FULL) { { // Start acceleration sensor if (!is_acceleration_measurement()) { // Clear previous acceleration value sAccel.data = 0; // Start sensor as_start(); // Set timeout counter sAccel.timeout = ACCEL_MEASUREMENT_TIMEOUT; // Set mode sAccel.mode = ACCEL_MODE_ON; // Start with Y-axis values sAccel.view_style = DISPLAY_ACCEL_X; } // Display decimal point display_symbol(LCD_SEG_L1_DP1, SEG_ON); } } else if (update == DISPLAY_LINE_UPDATE_PARTIAL) { // Convert X/Y/Z values to mg switch (sAccel.view_style) { case DISPLAY_ACCEL_X: raw_data = sAccel.xyz[0]; display_char(LCD_SEG_L1_3, 'X', SEG_ON); break; case DISPLAY_ACCEL_Y: raw_data = sAccel.xyz[1]; display_char(LCD_SEG_L1_3, 'Y', SEG_ON); break; default: raw_data = sAccel.xyz[2]; display_char(LCD_SEG_L1_3, 'Z', SEG_ON); break; } accel_data = convert_acceleration_value_to_mgrav(raw_data) / 10; // Filter acceleration #ifdef FIXEDPOINT accel_data = (u16)(((accel_data * 2) + (sAccel.data * 8))/10); #else accel_data = (u16)((accel_data * 0.2) + (sAccel.data * 0.8)); #endif // Store average acceleration sAccel.data = accel_data; // Display acceleration in x.xx format str = itoa(accel_data, 3, 0); display_chars(LCD_SEG_L1_2_0, str, SEG_ON); // Display sign if (acceleration_value_is_positive(raw_data)) { display_symbol(LCD_SYMB_ARROW_UP, SEG_ON); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } else { display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_ON); } } else if (update == DISPLAY_LINE_CLEAR) { // Stop acceleration sensor as_stop(); // Clear mode sAccel.mode = ACCEL_MODE_OFF; // Clean up display display_symbol(LCD_SEG_L1_DP1, SEG_OFF); display_symbol(LCD_SYMB_ARROW_UP, SEG_OFF); display_symbol(LCD_SYMB_ARROW_DOWN, SEG_OFF); } } }
// ************************************************************************************************* // @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; }
// ************************************************************************************************* // @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*)"0430", SEG_ON); display_chars(LCD_SEG_L2_4_0, (u8*)"CC430", 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 #ifdef CONFIG_ALTITUDE 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(); #endif 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 = itoa( sAccel.xyz[0], 3, 0); display_chars(LCD_SEG_L1_2_0, str, SEG_ON); str = itoa( sAccel.xyz[2], 3, 0); display_chars(LCD_SEG_L2_2_0, str, SEG_ON); } as_stop(); break; //pfs #ifndef ELIMINATE_BLUEROBIN 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; #endif } // 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; break; } } }
/* Enter the accelerometer menu */ static void acc_activated() { //register to the system bus for vti events as well as the RTC minute events sys_messagebus_register(&as_event, SYS_MSG_AS_INT | SYS_MSG_RTC_MINUTE | SYS_MSG_RTC_SECOND); /* create two screens, the first is always the active one */ lcd_screens_create(2); /* screen 0 will contain the menu structure and screen 1 the raw accelerometer data */ // Show warning if acceleration sensor was not initialised properly if (!as_ok) { display_chars(0, LCD_SEG_L1_3_0, "ERR", SEG_SET); } else { /* Initialization is required only if not in background mode! */ if (sAccel.mode != ACCEL_MODE_BACKGROUND) { // Clear previous acceleration value sAccel.data = 0; // 2 g range as_config.range=2; // 100 Hz sampling rate as_config.sampling=SAMPLING_10_HZ; // keep mode as_config.mode=ACTIVITY_MODE; //time window is 10 msec for free fall and 100 msec for activity //2g multiple 71 mg: 0F=4 * 71 mg= 1.065 g as_config.MDTHR=2; as_config.MDFFTMR=1; // Set timeout counter sAccel.timeout = ACCEL_MEASUREMENT_TIMEOUT; // Set mode for screen sAccel.mode = ACCEL_MODE_ON; // Start with mode selection submenu_state=VIEW_SET_MODE; // Select Axis X sAccel.view_style=DISPLAY_ACCEL_Z; // Start sensor in motion detection mode as_start(ACTIVITY_MODE); // After this call interrupts will be generated } if (!as_ok) { display_chars(0, LCD_SEG_L1_3_0, "FAIL", SEG_SET); } display_chars(0, LCD_SEG_L1_3_0 , "ACTI", SEG_SET); display_chars(0, LCD_SEG_L2_4_0 , "MODE", SEG_SET); } /* return to main screen */ lcd_screen_activate(0); }
// ************************************************************************************************* // @fn bmp_as_start // @brief Power-up and initialize acceleration sensor // @param none // @return none // ************************************************************************************************* void bmp_as_start(void) { u8 bGRange; // g Range; u8 bBwd; // Bandwidth u8 bSleep; // Sleep phase // 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 = BMP_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 (BMP_AS_RANGE == 2) bGRange = 0x03; #elif (BMP_AS_RANGE == 4) bGRange = 0x05; #elif (BMP_AS_RANGE == 8) bGRange = 0x08; #elif (BMP_AS_RANGE == 16) bGRange = 0x0C; #else #error "Measurement range not supported" #endif #if (BMP_AS_BANDWIDTH == 8) bBwd = 0x08; #elif (BMP_AS_BANDWIDTH == 16) bBwd = 0x09; #elif (BMP_AS_BANDWIDTH == 31) bBwd = 0x0A; #elif (BMP_AS_BANDWIDTH == 63) bBwd = 0x0B; #elif (BMP_AS_BANDWIDTH == 125) bBwd = 0x0C; #elif (BMP_AS_BANDWIDTH == 250) bBwd = 0x0D; #elif (BMP_AS_BANDWIDTH == 500) bBwd = 0x0E; #elif (BMP_AS_BANDWIDTH == 1000) bBwd = 0x0F; #else #error "Sample rate not supported" #endif #if (BMP_AS_SLEEPPHASE == 1) bSleep = 0x4C; #elif (BMP_AS_SLEEPPHASE == 2) bSleep = 0x4E; #elif (BMP_AS_SLEEPPHASE == 4) bSleep = 0x50; #elif (BMP_AS_SLEEPPHASE == 6) bSleep = 0x52; #elif (BMP_AS_SLEEPPHASE == 10) bSleep = 0x54; #elif (BMP_AS_SLEEPPHASE == 25) bSleep = 0x56; #elif (BMP_AS_SLEEPPHASE == 50) bSleep = 0x58; #else #error "Sleep phase duration not supported" #endif // write sensor configuration bmp_as_write_register(BMP_GRANGE, bGRange); // Set measurement range bmp_as_write_register(BMP_BWD, bBwd); // Set filter bandwidth bmp_as_write_register(BMP_PM, bSleep); // Set filter bandwidth #ifndef BMP_AS_FILTERING bmp_as_write_register(BMP_SCR, 0x80); // acquire unfiltered acceleration data #endif // configure sensor interrupt bmp_as_write_register(BMP_IMR2, 0x01); // map new data interrupt to INT1 pin bmp_as_write_register(BMP_ISR2, 0x10); // enable new data interrupt // enable CC430 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 }