/* 100 Hz -> 30 msec */ void write_FFTMR(uint8_t multiplier) { uint8_t bData = multiplier; /* The address of the register name MDFFTMR is 0Ah */ /* Bits FFTMR [3:0] RW Initial Value 3h */ /* FFTMRLSB[sec]=1/ODR[HZ] */ /* ODR is the current output data rate defined by Mode bits */ /* First conver the seconds in the register value with the bit weighting scheme */ /* in manual page 15 of cm3000-dx */ /* if (sAccel.sampling == 100) { / * in this sampling mode: 1/100 s=10 msec * / / * min: 10 msec -> b0 max: 80+40+20+10=150 msec b2 b1 b0 * / bData=multiplier; } else if (sAccel.sampling == 400) { / * in this sampling mode: 1/400 s=2.5 msec * / / * min: 10 msec -> b0 max: 20+10+5+2.5=37.5 msec b2 b1 b0 * / bData=multiplier; } else return; */ /* Take only the 4 LSB */ bData &= (0x0F); as_write_register(ADDR_MDFFTMR, bData); }
// ************************************************************************************************* // @fn cma_as_write_register // @brief Write a byte to the acceleration sensor // @param u8 bAddress Register address // u8 bData Data to write // @return u8 0 or bResult Register content // If the returned value is 0 there was an error. // ************************************************************************************************* u8 cma_as_write_register(u8 bAddress, u8 bData) { bAddress <<= 2; // Address to be shifted left by 1 bAddress |= BIT1; // RW bit to be set return as_write_register(bAddress, bData); }
/* B4= 100 msec */ void write_MDTMR(uint8_t multiplier) { /* 0x50=400+100 msec=500 msec */ /* mask the B6:B4 bits */ uint8_t bData = (multiplier << 4) & 0x70; as_write_register(ADDR_MDFFTMR, bData); }
void as_start(uint8_t mode) { /* 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_delay(10, LPM3_bits); /* 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 */ /* 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_delay(5, LPM3_bits); /* then select modality */ change_mode(mode); }
// ************************************************************************************************* // @fn as_stop // @brief Power down acceleration sensor // @param none // @return none // ************************************************************************************************* void as_stop(void) { // Disable interrupt AS_INT_IE &= ~AS_INT_PIN; // Disable interrupt #ifdef AS_DISCONNECT // Power-down sensor AS_PWR_OUT &= ~AS_PWR_PIN; // Power off AS_INT_OUT &= ~AS_INT_PIN; // Pin to low to avoid floating pins AS_SPI_OUT &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Pins to low to avoid floating pins AS_SPI_SEL &= ~(AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN); // Port pins to I/O function AS_CSN_OUT &= ~AS_CSN_PIN; // Pin to low to avoid floating pins AS_INT_DIR |= AS_INT_PIN; // Pin to output to avoid floating pins AS_SPI_DIR |= AS_SDO_PIN + AS_SDI_PIN + AS_SCK_PIN; // Pins to output to avoid floating pins AS_CSN_DIR |= AS_CSN_PIN; // Pin to output to avoid floating pins #else // Reset sensor -> sensor to powerdown as_write_register(0x04, 0x02); as_write_register(0x04, 0x0A); as_write_register(0x04, 0x04); #endif }
void write_FFTHR(uint8_t multiplier) { // bData = 1100 will set the center bits for both cases uint8_t bData = 0x0C; if (as_config.range == 2) { bData = multiplier << 2; } else if (as_config.range == 8) { bData = multiplier; } //Take only the 6 LSB: 111111 bData &= (0x3F); as_write_register(ADDR_FFTHR, bData); }
//Set the MDTHR motion detection threshold value register // Default value is 8h=1000 that amounts to 143 mg at 400 Hz and 2g range void write_MDTHR(uint8_t multiplier) { uint8_t bData = 0x00; if (as_config.range == 2) { bData = multiplier << 2; //for safety only takes B5-B1 //this is also the max allowed value bData &= (0x3C); } else if (as_config.range == 8) { bData = multiplier; //for safety only takes B5-B1 bData &= (0x7F); //max range is 0x3C } //TODO force it to 0x39 for some tests as_write_register(ADDR_MDTHR,bData); }
// ************************************************************************************************* // @fn as_start // @brief Power-up and initialize acceleration sensor // @param none // @return none // ************************************************************************************************* void as_start(void) { volatile unsigned short Counter_u16; unsigned 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 wait_ms(5); // 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 wait_ms(5); // Set 2g measurement range, start to output data with 100Hz rate as_write_register(0x02, bConfig); }
// ************************************************************************************************* // @fn as_start // @brief Power-up and initialize acceleration sensor // @param none // @return none // ************************************************************************************************* void 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_common(); // 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 as_write_register(BMP_GRANGE, bGRange); // Set measurement range as_write_register(BMP_BWD, bBwd); // Set filter bandwidth as_write_register(BMP_PM, bSleep); // Set filter bandwidth #ifndef BMP_AS_FILTERING as_write_register(BMP_SCR, 0x80); // acquire unfiltered acceleration data #endif // configure sensor interrupt as_write_register(BMP_IMR2, 0x01); // map new data interrupt to INT1 pin 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 }
// ************************************************************************************************* // @fn as_start // @brief Power-up and initialize acceleration sensor // @param none // @return none // ************************************************************************************************* void as_start(uint8_t mode) { volatile uint16_t Counter_u16; uint8_t 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_delay(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 // 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_delay(5); // Configure sensor and start to sample data switch (mode) { case FALL_MODE: if (as_config.range == 2) { bConfig = 0x80; if (as_config.sampling == SAMPLING_100_HZ) bConfig |= 0x0A; else if (as_config.sampling == SAMPLING_400_HZ) bConfig |= 0x0C; } else if (as_config.range == 8) { bConfig = 0x00; if (as_config.sampling == SAMPLING_100_HZ) bConfig |= 0x0A; else if (as_config.sampling == SAMPLING_400_HZ) bConfig |= 0x0C; } // fall time as long as possible 150 msec at 100 Hz write_FFTMR(as_config.MDFFTMR); //threshold for computation write_FFTHR(as_config.FFTHR); break; case MEASUREMENT_MODE: // Configure sensor and start to sample data if (as_config.range == 2) { bConfig = 0x80; if (as_config.sampling == SAMPLING_100_HZ) bConfig |= 0x02; else if (as_config.sampling == SAMPLING_400_HZ) bConfig |= 0x04; } else if (as_config.range == 8) { bConfig = 0x00; if (as_config.sampling == SAMPLING_40_HZ) bConfig |= 0x06; else if (as_config.sampling == SAMPLING_100_HZ) bConfig |= 0x02; else if (as_config.sampling == SAMPLING_400_HZ) bConfig |= 0x04; } break; case ACTIVITY_MODE: // Configure sensor and start to sample data if (as_config.range == 2) { bConfig = 0x80; if (as_config.sampling == SAMPLING_10_HZ) bConfig |= 0x08; } else if (as_config.range == 8) { bConfig = 0x00; if (as_config.sampling == SAMPLING_10_HZ) bConfig |= 0x08; } bConfig |= MDET_EXIT<<5; // fall time as long as possible 150 msec at 100 Hz write_MDTMR(as_config.MDFFTMR); //check if lower than 571 mgrav //write_MDTHR(sAccel.MDTHR); write_MDTHR(as_config.MDTHR); break; default: bConfig = 0x80; break; } // Wait 2 ms before entering modality to settle down timer0_delay(2); //write the configuration as_write_register(ADDR_CTRL, bConfig); // Wait 2 ms before entering modality to settle down timer0_delay(2); }
void change_mode(uint8_t mode) { uint8_t bConfig = 0x00; /* Configure sensor and start to sample data */ switch (mode) { case FALL_MODE: if (as_config.range == 2) { bConfig = 0x80; if (as_config.sampling == SAMPLING_100_HZ) bConfig |= 0x0A; else if (as_config.sampling == SAMPLING_400_HZ) bConfig |= 0x0C; } else if (as_config.range == 8) { bConfig = 0x00; if (as_config.sampling == SAMPLING_100_HZ) bConfig |= 0x0A; else if (as_config.sampling == SAMPLING_400_HZ) bConfig |= 0x0C; } /* fall time as long as possible 150 msec at 100 Hz */ write_FFTMR(as_config.MDFFTMR); /* threshold for computation */ write_FFTHR(as_config.FFTHR); break; case MEASUREMENT_MODE: /* Configure sensor and start to sample data */ if (as_config.range == 2) { bConfig = 0x80; if (as_config.sampling == SAMPLING_100_HZ) bConfig |= 0x02; else if (as_config.sampling == SAMPLING_400_HZ) bConfig |= 0x04; } else if (as_config.range == 8) { bConfig = 0x00; if (as_config.sampling == SAMPLING_40_HZ) bConfig |= 0x06; else if (as_config.sampling == SAMPLING_100_HZ) bConfig |= 0x02; else if (as_config.sampling == SAMPLING_400_HZ) bConfig |= 0x04; } break; case ACTIVITY_MODE: /* Configure sensor and start to sample data */ if (as_config.range == 2) { bConfig = 0x80; if (as_config.sampling == SAMPLING_10_HZ) bConfig |= 0x08; } else if (as_config.range == 8) { bConfig = 0x00; if (as_config.sampling == SAMPLING_10_HZ) bConfig |= 0x08; } bConfig |= MDET_EXIT << 5; /* fall time as long as possible 150 msec at 100 Hz */ write_MDTMR(as_config.MDFFTMR); /* check if lower than 571 mgrav */ /* write_MDTHR(sAccel.MDTHR); */ write_MDTHR(as_config.MDTHR); break; default: bConfig = 0x80; break; } /* Wait 2 ms before entering modality to settle down */ timer0_delay(2, LPM3_bits); /* write the configuration */ as_write_register(ADDR_CTRL, bConfig); /* Wait 2 ms before entering modality to settle down */ timer0_delay(2, LPM3_bits); }
// ************************************************************************************************* // @fn bmp_as_write_register // @brief Write a byte to the acceleration sensor // @param u8 bAddress Register address // u8 bData Data to write // @return u8 // ************************************************************************************************* u8 bmp_as_write_register(u8 bAddress, u8 bData) { bAddress &= ~BIT8; // R/W bit to be not set return as_write_register(bAddress, bData); }