Device driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Adis16488.cpp Source File

Adis16488.cpp

Go to the documentation of this file.
00001 /**
00002  * @file    Adis16488.cpp
00003  * @brief   Device driver - ADIS16488 IMU
00004  * @author  sam grove
00005  * @version 1.0
00006  * @see     http://www.analog.com/static/imported-files/data_sheets/ADIS16488.pdf
00007  *
00008  * Copyright (c) 2013
00009  *
00010  * Licensed under the Apache License, Version 2.0 (the "License");
00011  * you may not use this file except in compliance with the License.
00012  * You may obtain a copy of the License at
00013  *
00014  *     http://www.apache.org/licenses/LICENSE-2.0
00015  *
00016  * Unless required by applicable law or agreed to in writing, software
00017  * distributed under the License is distributed on an "AS IS" BASIS,
00018  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00019  * See the License for the specific language governing permissions and
00020  * limitations under the License.
00021  */
00022  
00023 #include "Adis16488.h"
00024 
00025 uint16_t const GYRO_REGS[]    = {0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1A00};
00026 uint16_t const ACCL_REGS[]    = {0x1C00, 0x1E00, 0x2000, 0x2200, 0x2400, 0x2600};
00027 uint16_t const MAGN_REGS[]    = {0x2800, 0x2A00, 0x2C00};
00028 uint16_t const DELTANG_REGS[] = {0x4000, 0x4200, 0x4400, 0x4600, 0x4800, 0x4A00};
00029 uint16_t const DELTVEL_REGS[] = {0x4C00, 0x4E00, 0x5000, 0x5200, 0x5400, 0x5600};
00030 
00031 DigitalOut led_1(LED1);
00032 
00033 Adis16488::Adis16488(SPI &spi, DigitalOut &cs, DigitalOut &rst, InterruptIn &dr)
00034 {
00035     _spi = &spi;
00036     _cs = &cs;
00037     _rst = &rst;
00038     _dr = &dr;
00039     
00040     return;
00041 }
00042 
00043 void Adis16488::init(void)
00044 {
00045     _dr->mode(PullDown);
00046     _rst->write(0);
00047     _cs->write(0);
00048     
00049     _spi->format(16,3);
00050     _spi->frequency(10000000);
00051     
00052     return;
00053 }
00054 
00055 void Adis16488::enable(void)
00056 {
00057     LOG("Preparing the ADIS16488 IMU\n");
00058     
00059     _rst->write(1);
00060     wait(1.0);
00061     
00062     writeRegister(0x8000);
00063     writeRegister(0x7e00);
00064     uint16_t id;
00065     readRegister(0x7e00, id);
00066     if(id != 0x4068)
00067     {
00068         ERROR("Product ID doesn't match, %04X\n", id);
00069     }
00070     LOG("Product ID is %04X\n", id);
00071     
00072     //this result correctly returns 0x4068 as per the ADIS16488 specification
00073     //get the SERIAL_NUM (page 4, reg: 0x20)  
00074     writeRegister(0x8004);     //first change the page to page 4
00075     writeRegister(0x2000);     //send the register to get on the next write
00076     uint16_t serial_num;
00077     readRegister(0x2000, serial_num);
00078     LOG("IMU serial number is %04X\n", serial_num);
00079     
00080     writeRegister(0x8003);     //change to page 3
00081     writeRegister(0x7800);     //get FIRMWARE_REV
00082     uint16_t rev;
00083     readRegister(0x7800, rev);
00084     LOG("Firmware revision %04X\n", rev);
00085     
00086     writeRegister(0x7A00);     //get FIRMWARE_DM
00087     uint16_t rev_dm;
00088     readRegister(0x7A00, rev_dm);
00089     
00090     writeRegister(0x7C00);     //get FIRMWARE_YR
00091     uint16_t rev_yr;
00092     readRegister(0x7C00, rev_yr);
00093     LOG("Frimware date/month/year is %02X/%02X/%04X\n", ((rev_dm>>8)&0xff), (rev_dm&0xff), rev_yr);
00094     
00095     //change the DECRATE to 98.4 Hz (this is also in page 3)
00096     writeRegister(0x8C17);     //write high byte  (only page number can be written in a single byte)
00097     writeRegister(0x8D00);     //write the low byte of DECRATE
00098     
00099     // using varf...
00100 //    writeRegister(0x86CD);     //write high byte to register 0x06
00101 //    writeRegister(0x8700);     //write the low byte of 00 to registed 0x07
00102     writeRegister(0x8000);     //change to page 0
00103     
00104     // configred so IRQ is allowed
00105     _dr->rise(this, &Adis16488::drHandler);
00106     
00107     return;
00108 }
00109 
00110 void Adis16488::disable(void)
00111 {
00112     _dr->rise(NULL);
00113     _rst->write(0);
00114 }
00115 
00116 void Adis16488::readRegister(uint16_t const reg, uint16_t &data)
00117 {    
00118     _cs->write(0);
00119     _spi->write(reg);
00120     data = _spi->write(reg);
00121     _cs->write(1);
00122     
00123     return;
00124 }
00125 
00126 void Adis16488::writeRegister(uint16_t const reg)
00127 {
00128     _cs->write(0);
00129     _spi->write(reg);
00130     _cs->write(1);
00131     
00132     return;
00133 }
00134 
00135 void Adis16488::drHandler(void)
00136 {
00137     led_1 = !led_1;
00138     // read gyro
00139     for(int i=0; i<6; ++i)
00140     {
00141         readRegister(GYRO_REGS[i], gyro.data[i]);
00142     }
00143     // read accel data
00144     for(int i=0; i<6; ++i)
00145     {
00146         readRegister(ACCL_REGS[i], accel.data[i]);
00147     }
00148     // read mag data
00149     for(int i=0; i<3; ++i)
00150     {
00151         readRegister(MAGN_REGS[i], magn.data[i]);
00152     }
00153     // read delta angles
00154     for(int i=0; i<6; ++i)
00155     {
00156         readRegister(DELTANG_REGS[i], deltang.data[i]);
00157     }
00158     // read delta velocity
00159     for(int i=0; i<6; ++i)
00160     {
00161         readRegister(DELTVEL_REGS[i], deltvel.data[i]);
00162     }
00163     
00164     return;
00165 }
00166