Device driver
Adis16488.cpp
- Committer:
- sam_grove
- Date:
- 2013-04-27
- Revision:
- 2:e2e5e40668bf
- Parent:
- 1:18fe8829aa69
File content as of revision 2:e2e5e40668bf:
/**
* @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;
}
Sam Grove