Device driver

Files at this revision

API Documentation at this revision

Comitter:
sam_grove
Date:
Wed Apr 10 04:41:21 2013 +0000
Child:
1:18fe8829aa69
Commit message:
Initial commit - working in a basic way

Changed in this revision

Adis16488.cpp Show annotated file Show diff for this revision Revisions of this file
Adis16488.h Show annotated file Show diff for this revision Revisions of this file
--- /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;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Adis16488.h	Wed Apr 10 04:41:21 2013 +0000
@@ -0,0 +1,89 @@
+/**
+ * @file    Adis16488.h
+ * @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.
+ */
+ 
+#ifndef ADIS16488_H
+#define ADIS16488_H
+
+#include "LogUtil.h"
+#include "mbed.h"
+
+
+/** Using the Analog Devices ADIS16488/PCBZ
+ *
+ * Example:
+ * @code
+
+ * @endcode
+ */
+
+/**
+ *  @class Adis16488
+ *  @brief API abstraction for the ADIS16488 IMU
+ */ 
+class Adis16488
+{
+public:
+
+    struct{ uint16_t data[6]; } gyro, accel, magn, deltang, deltvel;
+    
+    /** Create the Adis16488 object
+     *  @param spi - A defined SPI object
+     *  @param cs - A defined DigitalOut object
+     *  @param rst - A defined DigitalOut object
+     *  @param dr - A defined InterruptIn object
+     */  
+    Adis16488(SPI &spi, DigitalOut &cs, DigitalOut &rst, InterruptIn &dr);
+    
+    /** Clear state vars and initilize the dependant objects
+     */
+    void init(void);
+    
+    /** Read from a register (exposed for debugging reasons)
+     *  @param reg - The register to be written
+     *  @param data - Data read from the device is stored here
+     */
+    void readRegister(uint16_t const reg, uint16_t &data);
+    
+    /** Write to a register (exposed for debugging reasons)
+     *  @param reg - The register to be written
+     */
+    void writeRegister(uint16_t const reg);
+    
+    /** Allow the IC to run and collect user input
+     */
+    void enable(void);
+   
+    /** Stop the IC and put into low power mode
+     */   
+    void disable(void);
+    
+private:
+    SPI         *_spi;
+    DigitalOut  *_cs;
+    DigitalOut  *_rst;
+    InterruptIn *_dr;
+    
+    void drHandler(void);
+};
+
+#endif
+