/**************************************************************************** * * \section Disclaimer * * Common: * Bosch Sensortec products are developed for the consumer goods industry. * They may only be used within the parameters of the respective valid * product data sheet. Bosch Sensortec products are provided with the * express understanding that there is no warranty of fitness for a * particular purpose.They are not fit for use in life-sustaining, * safety or security sensitive systems or any system or device * that may lead to bodily harm or property damage if the system * or device malfunctions. In addition,Bosch Sensortec products are * not fit for use in products which interact with motor vehicle systems. * The resale and or use of products are at the purchasers own risk and * his own responsibility. The examination of fitness for the intended use * is the sole responsibility of the Purchaser. * * The purchaser shall indemnify Bosch Sensortec from all third party * claims, including any claims for incidental, or consequential damages, * arising from any product use not covered by the parameters of * the respective valid product data sheet or not approved by * Bosch Sensortec and reimburse Bosch Sensortec for all costs in * connection with such claims. * * The purchaser must monitor the market for the purchased products, * particularly with regard to product safety and inform Bosch Sensortec * without delay of all security relevant incidents. * * Engineering Samples are marked with an asterisk (*) or (e). * Samples may vary from the valid technical specifications of the product * series. They are therefore not intended or fit for resale to third * parties or for use in end products. Their sole purpose is internal * client testing. The testing of an engineering sample may in no way * replace the testing of a product series. Bosch Sensortec assumes * no liability for the use of engineering samples. * By accepting the engineering samples, the Purchaser agrees to indemnify * Bosch Sensortec from all claims arising from the use of engineering * samples. * * Special: * This software module (hereinafter called "Software") and any information * on application-sheets (hereinafter called "Information") is provided * free of charge for the sole purpose to support your application work. * The Software and Information is subject to the following * terms and conditions: * * The Software is specifically designed for the exclusive use for * Bosch Sensortec products by personnel who have special experience * and training. Do not use this Software if you do not have the * proper experience or training. * * This Software package is provided `` as is `` and without any expressed * or implied warranties,including without limitation, the implied warranties * of merchantability and fitness for a particular purpose. * * Bosch Sensortec and their representatives and agents deny any liability * for the functional impairment * of this Software in terms of fitness, performance and safety. * Bosch Sensortec and their representatives and agents shall not be liable * for any direct or indirect damages or injury, except as * otherwise stipulated in mandatory applicable law. * * The Information provided is believed to be accurate and reliable. * Bosch Sensortec assumes no responsibility for the consequences of use * of such Information nor for any infringement of patents or * other rights of third parties which may result from its use. * No license is granted by implication or otherwise under any patent or * patent rights of Bosch. Specifications mentioned in the Information are * subject to change without notice. **************************************************************************/ #include "bma253_task.h" #ifdef BMA253_SENSOR_REG //#include "./bma421_v1.4.1/bma421.h" //The Slave ADdress 0011000b shift 1 (the LSb value is '0') #define GSENSOR_BMA253_I2C_ADDR 0x18//0x30 //Data Define #define CHIP_ID 0xFA //Data Define End //Digital Gyro Register Define #define REG_BGW_CHIPID 0x00 #define REG_ACCD_X_LSB 0x02 #define REG_ACCD_X_MSB 0x03 #define REG_ACCD_Y_LSB 0x04 #define REG_ACCD_Y_MSB 0x05 #define REG_ACCD_Z_LSB 0x06 #define REG_ACCD_Z_MSB 0x07 #define REG_ACCD_TEMP 0x08 #define REG_INT_STATUS_0 0x09 #define REG_INT_STATUS_1 0x0A #define REG_INT_STATUS_2 0x0B #define REG_INT_STATUS_3 0x0C #define REG_FIFO_STATUS 0x0E #define REG_PMU_RANGE 0x0F #define REG_PMU_BW 0x10 #define REG_PMU_LPW 0x11 #define REG_PMU_LOW_POWER 0x12 #define REG_ACCD_HBW 0x13 #define REG_BGW_SOFTRESET 0x14 #define REG_INT_EN_0 0x16 #define REG_INT_EN_1 0x17 #define REG_INT_EN_2 0x18 #define REG_INT_MAP_0 0x19 #define REG_INT_MAP_1 0x1A #define REG_INT_MAP_2 0x1B #define REG_INT_SRC 0x1E #define REG_INT_OUT_CTRL 0x20 #define REG_INT_RST_LATCH 0x21 #define REG_INT_0 0x22 #define REG_INT_1 0x23 #define REG_INT_2 0x24 #define REG_INT_3 0x25 #define REG_INT_4 0x26 #define REG_INT_5 0x27 #define REG_INT_6 0x28 #define REG_INT_7 0x29 #define REG_INT_8 0x2A #define REG_INT_9 0x2B #define REG_INT_A 0x2C #define REG_INT_B 0x2D #define REG_INT_C 0x2E #define REG_INT_D 0x2F #define REG_FIFO_CONFIG_0 0x30 #define REG_PMU_SELF_TEST 0x32 #define REG_TRIM_NVM_CTRL 0x33 #define REG_BGW_SPI3_WDT 0x34 #define REG_OFC_CTRL 0x36 #define REG_OFC_SETTING 0x37 #define REG_OFC_OFFSET_X 0x38 #define REG_OFC_OFFSET_Y 0x39 #define REG_OFC_OFFSET_Z 0x3A #define REG_TRIM_GP0 0x3B #define REG_TRIM_GP1 0x3C #define REG_FIFO_CONFIG_1 0x3E #define REG_FIFO_DATA 0x3F #define MAX_REG 0x40 #undef I2C_ADDRESS #define I2C_ADDRESS 0x18//0x19//0x18 extern volatile uint8_t int0_flag; extern volatile uint8_t int1_flag; #define GRAVITY_EARTH (9.80665f) /* Earth's gravity in m/s^2 */ /*! * @brief This internal API is used to convert lsb to ms2 * * @param[in] val: value * @param[in] range: range value * @param[in] bit_width * * @return float value in ms2 * */ float lsb_to_ms2(int16_t val, float g_range, uint8_t bit_width) { float half_scale = (float)(1 << bit_width) / 2.0f; return GRAVITY_EARTH * val * g_range / half_scale; } #ifdef SUPPORT_I2C int8_t BST_sensor_i2c_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len) { return SensorAPI_I2Cx_Read(dev_addr, reg_addr, data, len); } int8_t BST_sensor_i2c_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len) { return SensorAPI_I2Cx_Write(dev_addr, reg_addr, data, len); } #endif #ifdef SUPPORT_SPI int8_t BST_sensor_spi_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len) { // reg_addr |=0x80; return SensorAPI_SPIx_Read(dev_addr, reg_addr, data, len); } int8_t BST_sensor_spi_write(uint8_t dev_addr,uint8_t reg_addr, uint8_t *data, uint16_t len) { // reg_addr &=0x7f; HAL_Delay(1); return SensorAPI_SPIx_Write(dev_addr, reg_addr, data, len); } #endif #if 1 int8_t bus_write(uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) { // ... // Please insert system specific function to write to the bus where BME680 is connected // ... uint8_t dev_addr = 0; #if defined(SUPPORT_I2C) dev_addr = I2C_ADDRESS<<1; BST_sensor_i2c_write(dev_addr,reg_addr,reg_data_ptr,data_len); #endif #if defined(SUPPORT_SPI) reg_addr = reg_addr & 0x7f;//; BST_sensor_spi_write(dev_addr,reg_addr,reg_data_ptr,data_len); #endif HAL_Delay(1); return 0; } /*! * @brief Read operation in either I2C or SPI * * param[in] dev_addr I2C or SPI device address * param[in] reg_addr register address * param[out] reg_data_ptr pointer to the memory to be used to store the read data * param[in] data_len number of bytes to be read * * @return result of the bus communication function */ int8_t bus_read(uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) { // ... // Please insert system specific function to read from bus where BME680 is connected // ... uint8_t dev_addr = 0; #if defined(SUPPORT_I2C) dev_addr = I2C_ADDRESS<<1; BST_sensor_i2c_read(dev_addr,reg_addr,reg_data_ptr,data_len); #endif #if defined(SUPPORT_SPI) reg_addr = reg_addr | 0x80;//BMA4_SPI_RD_MASK; BST_sensor_spi_read(dev_addr,reg_addr,reg_data_ptr,data_len); #endif // HAL_Delay(1); return 0; } #endif int8_t bma253_write_reg(uint8_t reg_addr, uint8_t reg_data) { bus_write(reg_addr,®_data,1); return 0; } int8_t bma253_read_reg(uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) { bus_read(reg_addr,reg_data_ptr,(uint16_t)data_len); return 0; } void GSENSOR_BMA253_Init(void) { uint8_t Data; uint8_t test_data[3]; bma253_read_reg(0x00,test_data,1); PDEBUG("test_data =%d\n\r",test_data[0]); bma253_write_reg(0x14,0xb6); HAL_Delay(500); bma253_read_reg(0x2d,test_data,3); PDEBUG("test_data1 =%d,test_data1 =%d,test_data1 =%d\n\r",test_data[0],test_data[1],test_data[2]); bma253_write_reg(0x0f,0x05); //4g bma253_write_reg(0x10,0x0c); //BW 31.25 #ifdef FIFO_FUNCTION bma253_write_reg(0x30,0x1f); //fifo length 31 bma253_write_reg(0x3e,0x80); //80 ---> stream, 40--->fifo #endif bma253_write_reg(0x11,0x56); bma253_write_reg(0x12,0x60); } #define BMA2_FIFO_CONF_DATA_MASK 0x0C /**\name BMA2 SPI Register Addresses masks */ #define BMA2_NORMAL_MODE 0x00 #define BMA2_DEEP_SUSPEND_MODE 0x01 #define BMA2_LOW_POWER1_MODE 0x02 #define BMA2_SUSPEND_MODE 0x04 #define BMA2_LOW_POWER2_MODE 0x0A #define BMA2_STANDBY_MODE 0x0C #define BMA2_POWER_MODE_EXTRACT_MSK 0x08 #define BMA2_POWER_MODE_EXTRACT_POS 0x03 #define BMA2_POWER_MODE_CTRL_MSK 0xE0 #define BMA2_POWER_MODE_CTRL_POS 0x05 #define BMA2_LOW_POWER_MODE_MSK 0x40 #define BMA2_LOW_POWER_MODE_POS 0x06 #define BMA2_POWER_MODE_MASK 0x07 #define BMA2_SET_BITS(reg_data, bitname, data) ((reg_data & ~(bitname##_MSK)) \ | ((data << bitname##_POS) & bitname##_MSK)) #define BMA2_GET_BITS(reg_data, bitname) ((reg_data & (bitname##_MSK)) >> (bitname##_POS)) uint8_t bma253_fifo_conf=0; void bma2_set_power_mode(uint8_t power_mode) { // int rslt; uint8_t reg_data[2]; uint8_t low_power_en; uint8_t pre_fifo_config; uint8_t Data = 0; // rslt = assert_dev(dev); // if (rslt == BMA2_OK) { /* Read the 0x11 and 0x12 registers */ // rslt = bma2_get_regs(BMA2_MODE_CTRL_ADDR, reg_data, 2, dev); bma253_read_reg(REG_PMU_LPW, &Data,1); reg_data[0] = Data; Data =0; bma253_read_reg(REG_PMU_LOW_POWER, &Data,1); reg_data[1] = Data; // if (rslt == BMA2_OK) { /* Copy the previous FIFO config mode */ pre_fifo_config = bma253_fifo_conf;//dev->fifo_conf; pre_fifo_config |= BMA2_FIFO_CONF_DATA_MASK; /* Set the power mode to the register value 0x12 */ low_power_en = BMA2_GET_BITS(power_mode, BMA2_POWER_MODE_EXTRACT); reg_data[1] = BMA2_SET_BITS(reg_data[1], BMA2_LOW_POWER_MODE, low_power_en); /* Write power mode to the register 0x12 in sensor */ // rslt = bma2_set_regs(BMA2_LOW_POWER_EN_ADDR, ®_data[1], 1, dev); bma253_write_reg(REG_PMU_LOW_POWER, reg_data[1]); // if (rslt == BMA2_OK) { /* Power mode switching delay */ // dev->delay_ms(BMA2_POWER_MODE_SWITCH_DELAY); HAL_Delay(3); // if (((dev->power_mode == BMA2_LOW_POWER1_MODE) || (dev->power_mode == BMA2_LOW_POWER2_MODE)) && // (power_mode == BMA2_NORMAL_MODE)) if (((reg_data[0]&0x40)== 0x40) && (power_mode == BMA2_NORMAL_MODE)) { /* Enter the suspend power mode */ reg_data[0] = BMA2_SET_BITS(reg_data[0], BMA2_POWER_MODE_CTRL, BMA2_SUSPEND_MODE); // rslt = bma2_set_regs(BMA2_MODE_CTRL_ADDR, ®_data[0], 1, dev); bma253_write_reg(REG_PMU_LPW, reg_data[0]); // if (rslt == BMA2_OK) { /* Re-write FIFO_CONFIG_0 register */ // rslt = bma2_set_regs(BMA2_FIFO_MODE_ADDR, &pre_fifo_config, 1, dev); bma253_write_reg(REG_FIFO_CONFIG_1, pre_fifo_config); } } // if (rslt == BMA2_OK) { /* Write the power mode to the register 0x11 */ power_mode = power_mode & BMA2_POWER_MODE_MASK; reg_data[0] = BMA2_SET_BITS(reg_data[0], BMA2_POWER_MODE_CTRL, power_mode); // rslt = bma2_set_regs(BMA2_MODE_CTRL_ADDR, ®_data[0], 1, dev); bma253_write_reg(REG_PMU_LPW, reg_data[0]); // if (rslt == BMA2_OK) { /* Power mode switching delay */ // dev->delay_ms(BMA2_POWER_MODE_SWITCH_DELAY); HAL_Delay(3); /* Re-write FIFO_CONFIG_0 register */ // rslt = bma2_set_regs(BMA2_FIFO_MODE_ADDR, &pre_fifo_config, 1, dev); bma253_write_reg(REG_FIFO_CONFIG_1, pre_fifo_config); /* Store the power mode */ // dev->power_mode = power_mode; } } } } } PDEBUG("bma2_set_power_mode: reg_data[0]=0x%x reg_data[1]=0x%x \r\n", reg_data[0],reg_data[1]); // return rslt; } #ifdef FIFO_FUNCTION uint8_t bma253_get_fifo_length(void) { uint8_t len; bma253_read_reg(0x0e, &len, 1); len = len & 0x7f; return len; } uint8_t fifo_data[255]; void vBMA253Fifo(void) { uint8_t fifo_len; fifo_len =bma253_get_fifo_length(); PDEBUG("fifo_len = %d\r\n",fifo_len); if(fifo_len>0) bma253_read_reg(0x3f, fifo_data, fifo_len*6); } #endif #ifdef POLLING_DATA void vPollingData(void) { uint8_t regdata[8] ={0}; float ax,ay,az; float gx,gy,gz; int16_t accx,accy,accz; int16_t gyrox,gyroy,gyroz; /* Variable to define LSB */ uint16_t lsb = 0; /* Variable to define MSB */ uint16_t msb = 0; bma253_read_reg(0x02,regdata,6);//acc data /* Accelerometer data x axis */ msb = regdata[1]; lsb = regdata[0]&0xf0; accx = ((int16_t)((msb << 8) | lsb))>>4; /* Accelerometer data y axis */ msb = regdata[3]; lsb = regdata[2]&0xf0; accy = ((int16_t)((msb << 8) | lsb))>>4; /* Accelerometer data z axis */ msb = regdata[5]; lsb = regdata[4]&0xf0; accz = ((int16_t)((msb << 8) | lsb))>>4; ax = lsb_to_ms2(accx, 4, 12); ay = lsb_to_ms2(accy, 4, 12); az = lsb_to_ms2(accz, 4, 12); PDEBUG("data[m/s2]: ax:%.4f\tay:%.4f\taz:%.4f\n", ax, ay, az); } #endif void vTaskBMA253(void) { uint8_t fifo_len; #ifdef FIFO_FUNCTION vBMA253Fifo(); #endif #ifdef POLLING_DATA vPollingData(); #endif HAL_Delay(100); } void StartBstTask(void const * argument) { // PDEBUG("\n"); // PDEBUG("***************Enter BMA253 StartBstTask()!************************\r\n"); // PDEBUG("\n"); BMI4XX_CHIP_ID(0x18); BMI4XX_CHIP_ID(0x18); BMI4XX_CHIP_ID(0x18); HAL_Delay(1); GSENSOR_BMA253_Init(); HAL_Delay(1000); PDEBUG("Enter BMA253 Task Loop!\r\n"); for(;;) { vTaskBMA253(); osDelay(1); } } #endif