/** * Timer process to poll for new data from the MPU6000. */ void AP_InertialSensor_MPU6000::_poll_data(void) { if (hal.scheduler->in_timerprocess()) { if (!_spi_sem->take_nonblocking()) { /* the semaphore being busy is an expected condition when the mainline code is calling wait_for_sample() which will grab the semaphore. We return now and rely on the mainline code grabbing the latest sample. */ return; } if (_data_ready()) { _last_sample_time_micros = hal.scheduler->micros(); _read_data_transaction(); } _spi_sem->give(); } else { /* Synchronous read - take semaphore */ if (_spi_sem->take(10)) { if (_data_ready()) { _last_sample_time_micros = hal.scheduler->micros(); _read_data_transaction(); } _spi_sem->give(); } else { hal.scheduler->panic( PSTR("PANIC: AP_InertialSensor_MPU6000::_poll_data " "failed to take SPI semaphore synchronously")); } } }
uint16_t AP_InertialSensor_MPU6000::_init_sensor( Sample_rate sample_rate ) { if (_initialised) return _mpu6000_product_id; _initialised = true; _spi = hal.spi->device(AP_HAL::SPIDevice_MPU6000); _spi_sem = _spi->get_semaphore(); /* Pin 70 defined especially to hook up PE6 to the hal.gpio abstraction. (It is not a valid pin under Arduino.) */ _drdy_pin = hal.gpio->channel(70); hal.scheduler->suspend_timer_procs(); uint8_t tries = 0; do { bool success = _hardware_init(sample_rate); if (success) { hal.scheduler->delay(5+2); if (!_spi_sem->take(100)) { hal.scheduler->panic(PSTR("MPU6000: Unable to get semaphore")); } if (_data_ready()) { _spi_sem->give(); break; } else { hal.console->println_P( PSTR("MPU6000 startup failed: no data ready")); } _spi_sem->give(); } if (tries++ > 5) { hal.scheduler->panic(PSTR("PANIC: failed to boot MPU6000 5 times")); } } while (1); hal.scheduler->resume_timer_procs(); /* read the first lot of data. * _read_data_transaction requires the spi semaphore to be taken by * its caller. */ _last_sample_time_micros = hal.scheduler->micros(); hal.scheduler->delay(10); if (_spi_sem->take(100)) { _read_data_transaction(); _spi_sem->give(); } // start the timer process to read samples hal.scheduler->register_timer_process(AP_HAL_MEMBERPROC(&AP_InertialSensor_MPU6000::_poll_data)); #if MPU6000_DEBUG _dump_registers(); #endif return _mpu6000_product_id; }
/** * Timer process to poll for new data from the MPU6000. */ void AP_InertialSensor_MPU6000::_poll_data(void) { if (!_spi_sem->take_nonblocking()) { return; } if (_data_ready()) { _read_data_transaction(); } _spi_sem->give(); }
/** * Timer process to poll for new data from the MPU9250. */ void AP_InertialSensor_MPU9250::_poll_data(void) { if (!_spi_sem->take_nonblocking()) { /* the semaphore being busy is an expected condition when the mainline code is calling wait_for_sample() which will grab the semaphore. We return now and rely on the mainline code grabbing the latest sample. */ return; } _read_data_transaction(); _spi_sem->give(); }
void AP_InertialSensor_MPU6000_I2C::_read_data_from_timerprocess() { if (!_i2c_sem->take_nonblocking()) { /* the semaphore being busy is an expected condition when the mainline code is calling sample_available() which will grab the semaphore. We return now and rely on the mainline code grabbing the latest sample. */ return; } _read_data_transaction(); _i2c_sem->give(); }
uint16_t AP_InertialSensor_MPU6000_I2C::_init_sensor(Sample_rate sample_rate ) { if (_initialised) return _mpu6000_product_id; _initialised = true; _i2c_sem = hal.i2c->get_semaphore(); hal.scheduler->suspend_timer_procs(); uint8_t tries = 0; do { bool success = hardware_init(sample_rate); if (success) { break; } else { hal.scheduler->delay(50); // delay for 50ms hal.console->println_P( PSTR("MPU6000 init failed")); } if (tries++ > 5) { hal.scheduler->panic(PSTR("PANIC: failed to boot MPU6000 5 times")); } } while (1); hal.scheduler->resume_timer_procs(); /* read the first lot of data. * _read_data_transaction requires the spi semaphore to be taken by * its caller. */ _ins_timer = hal.scheduler->micros(); _read_data_transaction(); hal.gpio->pinMode(46, GPIO_OUTPUT); // Debug output hal.gpio->write(46,0); hal.gpio->pinMode(45, GPIO_OUTPUT); // Debug output hal.gpio->write(45,0); // start the timer process to read samples hal.scheduler->register_timer_process(AP_HAL_MEMBERPROC(&AP_InertialSensor_MPU6000_I2C::_poll_data)); return _mpu6000_product_id; }
/*================ HARDWARE FUNCTIONS ==================== */ void AP_InertialSensor_ITG3200::_read_data_from_timerprocess() { static uint8_t semfail_ctr = 0; bool got = _i2c_sem->take_nonblocking(); if (!got) { semfail_ctr++; if (semfail_ctr > 100) { hal.scheduler->panic(PSTR("PANIC: failed to take I2C semaphore " "100 times in AP_InertialSensor_ITG3200::" "_read_data_from_timerprocess")); } return; } else { semfail_ctr = 0; } _read_data_transaction(); _i2c_sem->give(); }
/** * Timer process to poll for new data from the MPU6000. */ void AP_InertialSensor_MPU6000::_poll_data(void) { if (_data_ready()) { if (hal.scheduler->in_timerprocess()) { _read_data_from_timerprocess(); } else { /* Synchronous read - take semaphore */ bool got = _spi_sem->take(10); if (got) { _last_sample_time_micros = hal.scheduler->micros(); _read_data_transaction(); _spi_sem->give(); } else { hal.scheduler->panic( PSTR("PANIC: AP_InertialSensor_MPU6000::_poll_data " "failed to take SPI semaphore synchronously")); } } } }
void AP_InertialSensor_ITG3200::_poll_data(uint32_t now) { if (now - _ins_timer > _micros_per_sample) { _ins_timer = now; if (hal.scheduler->in_timerprocess()) { _read_data_from_timerprocess(); } else { /* Synchronous read - take semaphore */ bool got = _i2c_sem->take(10); if (got) { _read_data_transaction(); _i2c_sem->give(); } else { hal.scheduler->panic( PSTR("PANIC: AP_InertialSensor_ITG3200::_poll_data " "failed to take I2C semaphore synchronously")); } } } }
void AP_InertialSensor_MPU6000_I2C::_poll_data(void) { hal.gpio->write(46,1); uint32_t now = hal.scheduler->micros(); if ( (now - _ins_timer > _micros_per_sample) || (_sens_stage == 1)) { // hal.gpio->write(46,1); if (hal.scheduler->in_timerprocess()) { bool _stage = _sens_stage; _read_data_from_timerprocess(); if (_stage != _sens_stage && _stage == 0) { _ins_timer = now; } } else { /* Synchronous read - take semaphore */ bool got = _i2c_sem->take(10); if (got) { if (_sens_stage == 0) { _ins_timer = now; } _read_data_transaction(); _i2c_sem->give(); } else { hal.scheduler->panic( PSTR("PANIC: AP_InertialSensor_MPU6000::_poll_data " "failed to take I2C semaphore synchronously")); } } } hal.gpio->write(46,0); }
uint16_t AP_InertialSensor_L3GD20::_init_sensor( Sample_rate sample_rate ) { if (_initialised) return _L3GD20_product_id; _initialised = true; _spi = hal.spi->device(AP_HAL::SPIDevice_L3GD20); _spi_sem = _spi->get_semaphore(); #ifdef L3GD20_DRDY_PIN _drdy_pin = hal.gpio->channel(L3GD20_DRDY_PIN); _drdy_pin->mode(HAL_GPIO_INPUT); #endif hal.scheduler->suspend_timer_procs(); // Test WHOAMI uint8_t whoami = _register_read(ADDR_WHO_AM_I); if (whoami != WHO_I_AM) { // TODO: we should probably accept multiple chip // revisions. This is the one on the PXF hal.console->printf("L3GD20: unexpected WHOAMI 0x%x\n", (unsigned)whoami); hal.scheduler->panic(PSTR("L3GD20: bad WHOAMI")); } uint8_t tries = 0; do { bool success = _hardware_init(sample_rate); if (success) { hal.scheduler->delay(5+2); if (!_spi_sem->take(100)) { hal.scheduler->panic(PSTR("L3GD20: Unable to get semaphore")); } if (_data_ready()) { _spi_sem->give(); break; } else { hal.console->println_P( PSTR("L3GD20 startup failed: no data ready")); } _spi_sem->give(); } if (tries++ > 5) { hal.scheduler->panic(PSTR("PANIC: failed to boot L3GD20 5 times")); } } while (1); hal.scheduler->resume_timer_procs(); /* read the first lot of data. * _read_data_transaction requires the spi semaphore to be taken by * its caller. */ _last_sample_time_micros = hal.scheduler->micros(); hal.scheduler->delay(10); if (_spi_sem->take(100)) { _read_data_transaction(); _spi_sem->give(); } // start the timer process to read samples hal.scheduler->register_timer_process(AP_HAL_MEMBERPROC(&AP_InertialSensor_L3GD20::_poll_data)); #if L3GD20_DEBUG _dump_registers(); #endif return _L3GD20_product_id; }
/* initialise the sensor */ uint16_t AP_InertialSensor_MPU9250::_init_sensor( Sample_rate sample_rate ) { if (_initialised) return _mpu9250_product_id; _initialised = true; _spi = hal.spi->device(AP_HAL::SPIDevice_MPU9250); _spi_sem = _spi->get_semaphore(); // we need to suspend timers to prevent other SPI drivers grabbing // the bus while we do the long initialisation hal.scheduler->suspend_timer_procs(); uint8_t whoami = _register_read(MPUREG_WHOAMI); if (whoami != 0x71) { // TODO: we should probably accept multiple chip // revisions. This is the one on the PXF hal.console->printf("MPU9250: unexpected WHOAMI 0x%x\n", (unsigned)whoami); hal.scheduler->panic("MPU9250: bad WHOAMI"); } uint8_t tries = 0; do { bool success = _hardware_init(sample_rate); if (success) { hal.scheduler->delay(10); if (!_spi_sem->take(100)) { hal.scheduler->panic(PSTR("MPU9250: Unable to get semaphore")); } uint8_t status = _register_read(MPUREG_INT_STATUS); if ((status & BIT_RAW_RDY_INT) != 0) { _spi_sem->give(); break; } else { hal.console->println_P( PSTR("MPU9250 startup failed: no data ready")); } _spi_sem->give(); } if (tries++ > 5) { hal.scheduler->panic(PSTR("PANIC: failed to boot MPU9250 5 times")); } } while (1); hal.scheduler->resume_timer_procs(); /* read the first lot of data. * _read_data_transaction requires the spi semaphore to be taken by * its caller. */ hal.scheduler->delay(10); if (_spi_sem->take(100)) { _read_data_transaction(); _spi_sem->give(); } // start the timer process to read samples hal.scheduler->register_timer_process(AP_HAL_MEMBERPROC(&AP_InertialSensor_MPU9250::_poll_data)); #if MPU9250_DEBUG _dump_registers(); #endif return _mpu9250_product_id; }