fork of Sam Grove's library
Fork of ADIS16488 by
Diff: Adis16488.cpp
- Revision:
- 0:e9a81060a092
- Child:
- 1:18fe8829aa69
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adis16488.cpp Wed Apr 10 04:41:21 2013 +0000 @@ -0,0 +1,166 @@ +/** + * @file Adis16488.cpp + * @brief Device driver - ADIS16488 IMU + * @author sam grove + * @version 1.0 + * @see http://www.analog.com/static/imported-files/data_sheets/ADIS16488.pdf + * + * Copyright (c) 2013 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Adis16488.h" + +uint16_t const GYRO_REGS[] = {0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1A00}; +uint16_t const ACCL_REGS[] = {0x1C00, 0x1E00, 0x2000, 0x2200, 0x2400, 0x2600}; +uint16_t const MAGN_REGS[] = {0x2800, 0x2A00, 0x2C00}; +uint16_t const DELTANG_REGS[] = {0x4000, 0x4200, 0x4400, 0x4600, 0x4800, 0x4A00}; +uint16_t const DELTVEL_REGS[] = {0x4C00, 0x4E00, 0x5000, 0x5200, 0x5400, 0x5600}; + +DigitalOut led_1(LED1); + +Adis16488::Adis16488(SPI &spi, DigitalOut &cs, DigitalOut &rst, InterruptIn &dr) +{ + _spi = &spi; + _cs = &cs; + _rst = &rst; + _dr = &dr; + + return; +} + +void Adis16488::init(void) +{ + _dr->mode(PullDown); + _rst->write(0); + _cs->write(0); + + _spi->format(16,3); + _spi->frequency(10000000); + + return; +} + +void Adis16488::enable(void) +{ + LOG("Preparing the ADIS16488 IMU\n"); + + _rst->write(1); + wait(1.0); + + writeRegister(0x8000); + writeRegister(0x7e00); + uint16_t id; + readRegister(0x7e00, id); + if(id != 0x4068) + { + ERROR("Product ID doesn't match, %04X\n", id); + } + LOG("Product ID is %04X\n", id); + + //this result correctly returns 0x4068 as per the ADIS16488 specification + //get the SERIAL_NUM (page 4, reg: 0x20) + writeRegister(0x8004); //first change the page to page 4 + writeRegister(0x2000); //send the register to get on the next write + uint16_t serial_num; + readRegister(0x2000, serial_num); + LOG("IMU serial number is %04X\n", serial_num); + + writeRegister(0x8003); //change to page 3 + writeRegister(0x7800); //get FIRMWARE_REV + uint16_t rev; + readRegister(0x7800, rev); + LOG("Firmware revision %04X\n", rev); + + writeRegister(0x7A00); //get FIRMWARE_DM + uint16_t rev_dm; + readRegister(0x7A00, rev_dm); + + writeRegister(0x7C00); //get FIRMWARE_YR + uint16_t rev_yr; + readRegister(0x7C00, rev_yr); + LOG("Frimware date/month/year is %02X/%02X/%04X\n", ((rev_dm>>8)&0xff), (rev_dm&0xff), rev_yr); + + //change the DECRATE to 98.4 Hz (this is also in page 3) + writeRegister(0x8C17); //write high byte (only page number can be written in a single byte) + writeRegister(0x8D00); //write the low byte of DECRATE + + // using varf... + writeRegister(0x86CD); //write high byte to register 0x06 + writeRegister(0x8700); //write the low byte of 00 to registed 0x07 + writeRegister(0x8000); //change to page 0 + + // configred so IRQ is allowed + _dr->rise(this, &Adis16488::drHandler); + + return; +} + +void Adis16488::disable(void) +{ + _dr->rise(NULL); + _rst->write(0); +} + +void Adis16488::readRegister(uint16_t const reg, uint16_t &data) +{ + _cs->write(0); + _spi->write(reg); + data = _spi->write(reg); + _cs->write(1); + + return; +} + +void Adis16488::writeRegister(uint16_t const reg) +{ + _cs->write(0); + _spi->write(reg); + _cs->write(1); + + return; +} + +void Adis16488::drHandler(void) +{ + led_1 = !led_1; + // read gyro + for(int i=0; i<6; ++i) + { + readRegister(GYRO_REGS[i], gyro.data[i]); + } + // read accel data + for(int i=0; i<6; ++i) + { + readRegister(ACCL_REGS[i], accel.data[i]); + } + // read mag data + for(int i=0; i<3; ++i) + { + readRegister(MAGN_REGS[i], magn.data[i]); + } + // read delta angles + for(int i=0; i<6; ++i) + { + readRegister(DELTANG_REGS[i], deltang.data[i]); + } + // read delta velocity + for(int i=0; i<6; ++i) + { + readRegister(DELTVEL_REGS[i], deltvel.data[i]); + } + + return; +} +