Example #1
0
void register_write_memory(void *opaque, hwaddr addr,
                           uint64_t value, unsigned size)
{
    RegisterInfoArray *reg_array = opaque;
    RegisterInfo *reg = NULL;
    uint64_t we;
    int i;

    for (i = 0; i < reg_array->num_elements; i++) {
        if (reg_array->r[i]->access->addr == addr) {
            reg = reg_array->r[i];
            break;
        }
    }

    if (!reg) {
        qemu_log_mask(LOG_GUEST_ERROR, "Write to unimplemented register at " \
                      "address: %#" PRIx64 "\n", addr);
        return;
    }

    /* Generate appropriate write enable mask */
    if (reg->data_size < size) {
        we = MAKE_64BIT_MASK(0, reg->data_size * 8);
    } else {
        we = MAKE_64BIT_MASK(0, size * 8);
    }

    register_write(reg, value, we, reg_array->prefix,
                   reg_array->debug);
}
/*
  set the DLPF filter frequency. Assumes caller has taken semaphore
 */
void AP_InertialSensor_MPU6000::_set_filter_register(uint8_t filter_hz, uint8_t default_filter)
{
    uint8_t filter = default_filter;
    // choose filtering frequency
    switch (filter_hz) {
    case 5:
        filter = BITS_DLPF_CFG_5HZ;
        break;
    case 10:
        filter = BITS_DLPF_CFG_10HZ;
        break;
    case 20:
        filter = BITS_DLPF_CFG_20HZ;
        break;
    case 42:
        filter = BITS_DLPF_CFG_42HZ;
        break;
    case 98:
        filter = BITS_DLPF_CFG_98HZ;
        break;
    }

    if (filter != 0) {
        _last_filter_hz = filter_hz;

        register_write(MPUREG_CONFIG, filter);
    }
}
Example #3
0
static inline void
far_increment_mna(bitstream_parser_t *bitstream) {
  const id_vlx_t chiptype = bitstream->type;
  sw_far_t far;
  fill_swfar(&far, register_read(bitstream, FAR));
  _far_increment_mna(chiptype, &far);
  register_write(bitstream, FAR, get_hwfar(&far));
}
Example #4
0
// Update gyro offsets with new values. New offset values are substracted to actual offset values.
// offset values in gyro LSB units (as read from registers)
void MPU6000::set_gyro_offsets(int16_t offsetX, int16_t offsetY, int16_t offsetZ)
{
	int16_t aux_int;

	if (offsetX != 0){
		// Read actual value
		aux_int = (register_read(MPUREG_XG_OFFS_USRH)<<8) | register_read(MPUREG_XG_OFFS_USRL);
		aux_int -= offsetX<<1;   // Adjust to internal units
		// Write to MPU registers
		register_write(MPUREG_XG_OFFS_USRH, (aux_int>>8)&0xFF);
		register_write(MPUREG_XG_OFFS_USRL, aux_int&0xFF);
	}
static void rpu_write(void *opaque, hwaddr addr, uint64_t value,
                      unsigned size)
{
    RPU *s = XILINX_RPU(opaque);
    RegisterInfo *r = &s->regs_info[addr / 4];

    if (!r->data) {
        qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
                 object_get_canonical_path(OBJECT(s)),
                 addr, value);
        return;
    }
    register_write(r, value, ~0);
}
Example #6
0
static void gic_proxy_write(void *opaque, hwaddr addr, uint64_t value,
                      unsigned size)
{
    GICProxy *s = XILINX_GIC_PROXY(opaque);
    RegisterInfo *r = &s->regs_info[addr / 4];

    if (!r->data) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Decode error: write %" HWADDR_PRIx "=%" PRIx64 "\n",
                      object_get_canonical_path(OBJECT(s)),
                      addr, value);
        return;
    }
    register_write(r, value, ~0);
}
void AP_InertialSensor_MPU6000::hardware_init()
{
    // MPU6000 chip select setup
    pinMode(_cs_pin, OUTPUT);
    digitalWrite(_cs_pin, HIGH);
    delay(1);

    // Chip reset
    register_write(MPUREG_PWR_MGMT_1, BIT_H_RESET);
    delay(100);
    // Wake up device and select GyroZ clock (better performance)
    register_write(MPUREG_PWR_MGMT_1, MPU_CLK_SEL_PLLGYROZ);
    delay(1);
    // Disable I2C bus (recommended on datasheet)
    register_write(MPUREG_USER_CTRL, BIT_I2C_IF_DIS);
    delay(1);
    // SAMPLE RATE
    register_write(MPUREG_SMPLRT_DIV,0x04);     // Sample rate = 200Hz    Fsample= 1Khz/(4+1) = 200Hz
    delay(1);
    // FS & DLPF   FS=2000º/s, DLPF = 98Hz (low pass filter)
    register_write(MPUREG_CONFIG, BITS_DLPF_CFG_98HZ);
    delay(1);
    register_write(MPUREG_GYRO_CONFIG,BITS_FS_2000DPS);  // Gyro scale 2000º/s
    delay(1);
    register_write(MPUREG_ACCEL_CONFIG,0x08);           // Accel scele 4g (4096LSB/g)
    delay(1);

    // INT CFG => Interrupt on Data Ready
    register_write(MPUREG_INT_ENABLE,BIT_RAW_RDY_EN);         // INT: Raw data ready
    delay(1);
    register_write(MPUREG_INT_PIN_CFG,BIT_INT_ANYRD_2CLEAR);  // INT: Clear on any read
    delay(1);
    // Oscillator set
    // register_write(MPUREG_PWR_MGMT_1,MPU_CLK_SEL_PLLGYROZ);
    delay(1);

    attachInterrupt(6,data_interrupt,RISING);
}
Example #8
0
static gint
handle_cmd_write(bitstream_parsed_t *parsed,
		 bitstream_parser_t *parser) {
  cmd_code_t cmd = register_read(parser, CMD);

  switch(cmd) {
  case MFW:
    debit_log(L_BITSTREAM,"Executing multi-frame write");
    record_frame(parsed, parser, register_read(parser, FAR));
    break;
  case RCRC:
    debit_log(L_BITSTREAM,"Resetting CRC");
    register_write(parser, CRC, 0);
    break;
  default:
    debit_log(L_BITSTREAM,"execution of %i:%s is a noop",
	      cmd, cmd_names[cmd]);
    break;
  }

  return 0;

}
Example #9
0
void MPU6000::hardware_init()
{
    // MPU6000 chip select setup
    pinMode(_cs_pin, OUTPUT);
    digitalWrite(_cs_pin, HIGH);
    delay(1);

    // Chip reset
    register_write(MPUREG_PWR_MGMT_1, BIT_PWR_MGMT_1_DEVICE_RESET);
    delay(100);
    // Wake up device and select GyroZ clock (better performance)
    register_write(MPUREG_PWR_MGMT_1, BIT_PWR_MGMT_1_CLK_ZGYRO);
    delay(1);

	register_write(MPUREG_PWR_MGMT_2, 0x00);	// only used for wake-up in accelerometer only low power mode
	delay(1);

    // Disable I2C bus (recommended on datasheet)
    register_write(MPUREG_USER_CTRL, BIT_USER_CTRL_I2C_IF_DIS);
    delay(1);
    // SAMPLE RATE
    register_write(MPUREG_SMPLRT_DIV, MPUREG_SMPLRT_200HZ);     // Sample rate = 200Hz    Fsample= 1Khz/(4+1) = 200Hz
    delay(1);
    // FS & DLPF   FS=2000º/s, DLPF = 98Hz (low pass filter)
    register_write(MPUREG_CONFIG, BITS_DLPF_CFG_98HZ);
    delay(1);
    register_write(MPUREG_GYRO_CONFIG, BITS_GYRO_FS_2000DPS);  // Gyro scale 2000º/s
    delay(1);
	
	_product_id = register_read(MPUREG_PRODUCT_ID); // read the product ID rev c has 1/2 the sensitivity of rev d
	//Serial.printf("Product_ID= 0x%x\n", (unsigned) _product_id);
	
	if ((_product_id == MPU6000ES_REV_C4) || (_product_id == MPU6000ES_REV_C5) ||
		(_product_id == MPU6000_REV_C4)   || (_product_id == MPU6000_REV_C5)){
		// Accel scale 8g (4096 LSB/g)
		// Rev C has different scaling than rev D
		register_write(MPUREG_ACCEL_CONFIG,1<<3);
	} else {
		// Accel scale 8g (4096 LSB/g)
		register_write(MPUREG_ACCEL_CONFIG,2<<3);
	}
    delay(1);

    register_write(MPUREG_INT_ENABLE, BIT_RAW_RDY_EN);			// configure interrupt to fire when new data arrives
    delay(1);
    register_write(MPUREG_INT_PIN_CFG, BIT_INT_RD_CLEAR);		// clear interrupt on any read
    delay(1);

    attachInterrupt(6,data_interrupt,RISING);

	// initialise DMP.  Should we only do this when we know we want to use the DMP for attitude sensing as well?
	dmp_init();
}
Example #10
0
void io_write_changed(uint8_t reg) 
{  
  if (io_reg_buffer[reg] != reg_mirror[reg]) {

    if (reg == 0x03 || reg == 0x07) {

      /* Trick for avoiding phase reset when changing high bits of timer period */
      
	if ((reg_mirror[reg] & 0x07) - (io_reg_buffer[reg] & 0x07) == 1) {
	  uint8_t low_val = reg_mirror[0x02];
	  register_write(0x02, 0);    // low value = 0
	  register_write(0x01, 0x8F); // enable sweep, negate, shift = 7
	  register_write(0x17, 0xC0); // clock sweep immediately
	  register_write(0x01, 0x0F); // disable sweep 
	  register_write(0x02, low_val); // put back low value
	  reg_mirror[0x02] = low_val;
	  reg_mirror[reg] = io_reg_buffer[reg];
	}

	else if ((io_reg_buffer[reg] & 0x07) - (reg_mirror[reg] & 0x07) == 1) {
	  uint8_t low_val = reg_mirror[0x02];
	  register_write(0x02, 0xFF);
	  register_write(0x01, 0x87); // enable sweep, negate, shift = 7
	  register_write(0x17, 0xC0); // clock sweep immediately
	  register_write(0x01, 0x0F); // disable sweep 
	  register_write(0x02, low_val); // put back low value
	  reg_mirror[0x02] = low_val;
	  reg_mirror[reg] = io_reg_buffer[reg];
	}
	
	else
	  register_write(reg, io_reg_buffer[reg]);
    }

    else 
      register_write(reg, io_reg_buffer[reg]);

//    reg_mirror[reg] = io_reg_buffer[reg];
  }
}
Example #11
0
void io_register_write(uint8_t reg, uint8_t value)
{
    register_write(reg, value);
}
bool AP_InertialSensor_MPU6000::hardware_init(Sample_rate sample_rate)
{
    if (!_spi_sem->take(100)) {
        hal.scheduler->panic(PSTR("MPU6000: Unable to get semaphore"));
    }

    // Chip reset
    uint8_t tries;
    for (tries = 0; tries<5; tries++) {
        register_write(MPUREG_PWR_MGMT_1, BIT_PWR_MGMT_1_DEVICE_RESET);
        hal.scheduler->delay(100);

        // Wake up device and select GyroZ clock. Note that the
        // MPU6000 starts up in sleep mode, and it can take some time
        // for it to come out of sleep
        register_write(MPUREG_PWR_MGMT_1, BIT_PWR_MGMT_1_CLK_ZGYRO);
        hal.scheduler->delay(5);

        // check it has woken up
        if (_register_read(MPUREG_PWR_MGMT_1) == BIT_PWR_MGMT_1_CLK_ZGYRO) {
            break;
        }
#if MPU6000_DEBUG
        _dump_registers();
#endif
    }
    if (tries == 5) {
        hal.console->println_P(PSTR("Failed to boot MPU6000 5 times"));
        _spi_sem->give();
        return false;
    }

    register_write(MPUREG_PWR_MGMT_2, 0x00);            // only used for wake-up in accelerometer only low power mode
    hal.scheduler->delay(1);

    // Disable I2C bus (recommended on datasheet)
    register_write(MPUREG_USER_CTRL, BIT_USER_CTRL_I2C_IF_DIS);
    hal.scheduler->delay(1);

    uint8_t default_filter;

    // sample rate and filtering
    // to minimise the effects of aliasing we choose a filter
    // that is less than half of the sample rate
    switch (sample_rate) {
    case RATE_50HZ:
        // this is used for plane and rover, where noise resistance is
        // more important than update rate. Tests on an aerobatic plane
        // show that 10Hz is fine, and makes it very noise resistant
        default_filter = BITS_DLPF_CFG_10HZ;
        _sample_shift = 2;
        break;
    case RATE_100HZ:
        default_filter = BITS_DLPF_CFG_20HZ;
        _sample_shift = 1;
        break;
    case RATE_200HZ:
    default:
        default_filter = BITS_DLPF_CFG_20HZ;
        _sample_shift = 0;
        break;
    }

    _set_filter_register(_mpu6000_filter, default_filter);

    // set sample rate to 200Hz, and use _sample_divider to give
    // the requested rate to the application
    register_write(MPUREG_SMPLRT_DIV, MPUREG_SMPLRT_200HZ);
    hal.scheduler->delay(1);

    register_write(MPUREG_GYRO_CONFIG, BITS_GYRO_FS_2000DPS);  // Gyro scale 2000º/s
    hal.scheduler->delay(1);

    // read the product ID rev c has 1/2 the sensitivity of rev d
    _mpu6000_product_id = _register_read(MPUREG_PRODUCT_ID);
    //Serial.printf("Product_ID= 0x%x\n", (unsigned) _mpu6000_product_id);

    if ((_mpu6000_product_id == MPU6000ES_REV_C4) || (_mpu6000_product_id == MPU6000ES_REV_C5) ||
        (_mpu6000_product_id == MPU6000_REV_C4)   || (_mpu6000_product_id == MPU6000_REV_C5)) {
        // Accel scale 8g (4096 LSB/g)
        // Rev C has different scaling than rev D
        register_write(MPUREG_ACCEL_CONFIG,1<<3);
    } else {
        // Accel scale 8g (4096 LSB/g)
        register_write(MPUREG_ACCEL_CONFIG,2<<3);
    }
    hal.scheduler->delay(1);

    // configure interrupt to fire when new data arrives
    register_write(MPUREG_INT_ENABLE, BIT_RAW_RDY_EN);
    hal.scheduler->delay(1);

    // clear interrupt on any read, and hold the data ready pin high
    // until we clear the interrupt
    register_write(MPUREG_INT_PIN_CFG, BIT_INT_RD_CLEAR | BIT_LATCH_INT_EN);
    hal.scheduler->delay(1);

    _spi_sem->give();

    return true;
}