예제 #1
0
void bma020_chip_init(void)
{
	/*assign register memory to bma020 object */
	bma020.image = &bma020regs;

	bma020.bma020_bus_write = i2c_acc_bma020_write;
	bma020.bma020_bus_read  = i2c_acc_bma020_read;

#ifdef CONFIG_HAS_EARLYSUSPEND
	bma020.early_suspend.suspend = bma020_early_suspend;
	bma020.early_suspend.resume = bma020_late_resume;
	register_early_suspend(&bma020.early_suspend);
#endif

	/*call init function to set read write functions, read registers */
	bma020_init( &bma020 );

	/* from this point everything is prepared for sensor communication */


	/* set range to 2G mode, other constants: 
	 * 	   			4G: BMA020_RANGE_4G, 
	 * 	    		8G: BMA020_RANGE_8G */

	bma020_set_range(BMA020_RANGE_2G); 

	/* set bandwidth to 25 HZ */
	bma020_set_bandwidth(BMA020_BW_25HZ);

	/* for interrupt setting */
//	bma020_set_low_g_threshold( BMA020_HG_THRES_IN_G(0.35, 2) );

//	bma020_set_interrupt_mask( BMA020_INT_LG );

}
예제 #2
0
/**
 * @brief BMA020 ioctl control entry point
 *
 *
 * @param hal       Address of an initialized sensor device descriptor.
 * @param cmd       Command to execute
 * @param arg       Argument for command (varies)
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool bma020_ioctl(sensor_t *sensor, sensor_command_t cmd,
                         void *arg)
{
    sensor_hal_t *const hal = sensor->hal;
    sensor_data_t sample = {.scaled = true};

    switch (cmd) {
    case SENSOR_SET_RANGE:
        return bma020_set_range(hal, *((uint16_t *)arg));

    case SENSOR_SET_BANDWIDTH:
        return bma020_set_bandwidth(hal, *((uint16_t *)arg));

    case SENSOR_READ_VECTOR:
        if (bma020_get_accel(hal, &sample)) {
            vector3_t *const pvec = (vector3_t *)arg;
            pvec->x = sample.axis.x;
            pvec->y = sample.axis.y;
            pvec->z = sample.axis.z;
            return true;
        } else {
            return false;
        }

    default:
        sensor->err = SENSOR_ERR_UNSUPPORTED;
        return false;
    }
}
예제 #3
0
static ssize_t bma020_show_accel_value(struct device *dev,struct device_attribute *attr, char *buf)
{   
	bma020acc_t accel; 
	
	bma020_set_mode(BMA020_MODE_NORMAL);
	bma020_set_range(BMA020_RANGE_2G); 
	bma020_set_bandwidth(BMA020_BW_100HZ);
	
	bma020_read_accel_xyz( &accel);	
    return sprintf(buf, "%d,%d,%d\n", accel.x,accel.y,accel.z);
}
int bma020_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,  unsigned long arg)
{
    int err = 0;
    unsigned char data[6];

    /* check cmd */
    if(_IOC_TYPE(cmd) != BMA150_IOC_MAGIC)
    {
#if DEBUG
        printk("cmd magic type error\n");
#endif
        return -ENOTTY;
    }
    if(_IOC_NR(cmd) > BMA150_IOC_MAXNR)
    {
#if DEBUG
        printk("cmd number error\n");
#endif
        return -ENOTTY;
    }

    if(_IOC_DIR(cmd) & _IOC_READ)
        err = !access_ok(VERIFY_WRITE,(void __user*)arg, _IOC_SIZE(cmd));
    else if(_IOC_DIR(cmd) & _IOC_WRITE)
        err = !access_ok(VERIFY_READ, (void __user*)arg, _IOC_SIZE(cmd));
    if(err)
    {
#if DEBUG
        printk("cmd access_ok error\n");
#endif
        return -EFAULT;
    }
#if 0
    /* check bam150_client */
    if( bma150_client == NULL)
    {
#if DEBUG
        printk("I2C driver not install\n");
#endif
        return -EFAULT;
    }
#endif

    switch(cmd)
    {
    case BMA150_READ_ACCEL_XYZ:
        err = bma020_read_accel_xyz((bma020acc_t*)data);
        if(copy_to_user((bma020acc_t*)arg,(bma020acc_t*)data,6)!=0)
        {
#if DEBUG
            printk("copy_to error\n");
#endif
            return -EFAULT;
        }
        return err;

    case BMA150_SET_RANGE:
        if(copy_from_user(data,(unsigned char*)arg,1)!=0)
        {
#if DEBUG
            printk("[BMA150] copy_from_user error\n");
#endif
            return -EFAULT;
        }
        err = bma020_set_range(*data);
        return err;

    case BMA150_SET_MODE:
        if(copy_from_user(data,(unsigned char*)arg,1)!=0)
        {
#if DEBUG
            printk("[BMA150] copy_from_user error\n");
#endif
            return -EFAULT;
        }
        err = bma020_set_mode(*data);
        return err;

    case BMA150_SET_BANDWIDTH:
        if(copy_from_user(data,(unsigned char*)arg,1)!=0)
        {
#if DEBUG
            printk("[BMA150] copy_from_user error\n");
#endif
            return -EFAULT;
        }
        err = bma020_set_bandwidth(*data);
        return err;

    default:
        return 0;
    }
}
int bma020_calibrate(bma020acc_t orientation, int *tries)
{

	unsigned short offset_x, offset_y, offset_z;
	unsigned short old_offset_x, old_offset_y, old_offset_z;
	unsigned short changed_offset_x, changed_offset_y, changed_offset_z;
	int need_calibration=0, min_max_ok=0;	
	int ltries;
	int retry = 30;

	bma020acc_t min,max,avg;
	
	printk("[%s] +\n", __func__);

	bma020_set_range(BMA020_RANGE_2G);
	bma020_set_bandwidth(BMA020_BW_25HZ);

	bma020_set_ee_w(1);  
	
	bma020_get_offset(0, &offset_x);
	bma020_get_offset(1, &offset_y);
	bma020_get_offset(2, &offset_z);	

	old_offset_x = offset_x;
	old_offset_y = offset_y;
	old_offset_z = offset_z;
	ltries = *tries;
	
	printk("[%s] old offset_x = %d, offset_y = %d, offset_z = %d\n", __func__, old_offset_x, offset_y, offset_z);
	
	orientation.x = 0;
	orientation.y = 0;
	orientation.z = 1;

	do {
		bma020_read_accel_avg(10, &min, &max, &avg);  /* read acceleration data min, max, avg */

		min_max_ok = bma020_verify_min_max(min, max, avg);

		if(!min_max_ok)
		{
			retry--;
			if(retry <= 0)
				return (-1);
		}
		
		/* check if calibration is needed */
		if (min_max_ok)
			need_calibration = bma020_calc_new_offset(orientation, avg, &offset_x, &offset_y, &offset_z);		
		  
		if (*tries==0) /*number of maximum tries reached? */
			break;

		if (need_calibration) {   
			/* when needed calibration is updated in image */
			printk("[%s] need calibration. tries = %d. changed offset x = %d, y = %d, z = %d\n", __func__, *tries, offset_x, offset_y, offset_z);
			(*tries)--;
			bma020_set_offset(0, offset_x); 
   		 	bma020_set_offset(1, offset_y);
 	  	 	bma020_set_offset(2, offset_z);
			bma020_pause(20);
		}
		printk("\n");
    } while (need_calibration || !min_max_ok);

	        		
    if (*tries>0 && *tries < ltries) {
		printk("[%s] eeprom is updated. new offset x=%d, y=%d, z=%d\n", 
					__func__, offset_x, offset_y, offset_z);
		
		if (old_offset_x!= offset_x) 
			bma020_set_offset_eeprom(0, offset_x);

		if (old_offset_y!= offset_y) 
	   		bma020_set_offset_eeprom(1,offset_y);

		if (old_offset_z!= offset_z) 
	   		bma020_set_offset_eeprom(2, offset_z);
	}	
	
	printk("[%s] tries = %d\n", __func__, *tries);
		
	bma020_set_ee_w(0);	    
    bma020_pause(20);
	*tries = ltries - *tries;
	
	printk("[%s] -\n", __func__);

	return !need_calibration;
}
예제 #6
0
/**
 * @brief Bosch BMA020 accelerometer driver initialization.
 *
 * This is the main initialization function for the BMA020 device.
 * The accelerometer range and bandwidth are set based on user-specified
 * values from the system configuration.
 *
 * @param sensor    Address of a sensor device descriptor.
 * @param resvd     Reserved value.
 * @return bool     true if the call succeeds, else false is returned.
 */
bool bma020_init(sensor_t *sensor, int resvd)
{
    bool status = false;

    sensor_hal_t *const hal = sensor->hal;

    if (BMA020_ID_VAL == sensor_bus_get(hal, BMA020_CHIP_ID)) {
        /* Set the driver function table and capabilities pointer. */
        static const sensor_device_t bma020_device = {
            .func.read        = bma020_read,
            .func.ioctl       = bma020_ioctl,

            .caps.feature     = SENSOR_CAPS_3_AXIS     |
            SENSOR_CAPS_SELFTEST   |
            SENSOR_CAPS_HI_G_EVENT |
            SENSOR_CAPS_LO_G_EVENT,

            .caps.vendor      = SENSOR_VENDOR_BOSCH,
            .caps.range_table = range_table,
            .caps.band_table  = band_table,
            .caps.range_count = ARRAYSIZE(range_table),
            .caps.band_count  = ARRAYSIZE(band_table),
            .caps.units       = SENSOR_UNITS_g0,
            .caps.scale       = SENSOR_SCALE_milli,
            .caps.name = "BMA020 Digital, triaxial acceleration sensor"
        };

        sensor->drv = &bma020_device;

        /* Set the driver (device) default range, bandwidth, and
         * resolution.
         */
        hal->range      = 2000; /* milli-g */
        hal->bandwidth  = 25;   /* Hertz */
        hal->resolution = BMA020_DATA_RESOLUTION;

        bma020_set_range(hal, 0);
        bma020_set_bandwidth(hal, 0);

        /* Set the device burst read base address. */
        hal->burst_addr = BMA020_ACC_X_LSB;

        status = (STATUS_OK == hal->bus.status);
    }

    return status;
}

/**
 * @brief Read accelerometer device ID and revision numbers.
 *
 * This function reads the accelerometer hardware identification registers
 * and returns these values in the specified data structure.
 *
 * @param hal       Address of an initialized sensor hardware descriptor.
 * @param data      Address of sensor_data_t structure to return values.
 * @return bool     true if the call succeeds, else false is returned.
 */
static bool bma020_device_id(sensor_hal_t *hal, sensor_data_t *data)
{
    data->device.id      = sensor_bus_get(hal, BMA020_CHIP_ID);
    data->device.version = sensor_bus_get(hal, BMA020_CHIP_VERSION);

    return true;
}