fork of Sam Grove's library

Fork of ADIS16488 by Sam Grove

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;
+}
+