interface class for an inertial measurement unit that uses a serial protocol.

Dependencies:   mbed

Committer:
Blaze513
Date:
Tue Aug 31 04:38:14 2010 +0000
Revision:
0:fd1fce2347d9

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Blaze513 0:fd1fce2347d9 1 #include "3DM-GX2.h"
Blaze513 0:fd1fce2347d9 2
Blaze513 0:fd1fce2347d9 3 MS3DMGX2::MS3DMGX2(PinName tx, PinName rx) : DataLines(tx, rx),
Blaze513 0:fd1fce2347d9 4 ModeCommand(0xCF), ModeLength(6), ModeSync(0), InterruptBuffer((float*)Workspace)
Blaze513 0:fd1fce2347d9 5 {
Blaze513 0:fd1fce2347d9 6 DataLines.baud(115200);
Blaze513 0:fd1fce2347d9 7 DataLines.format(8, Serial::None, 1);
Blaze513 0:fd1fce2347d9 8 DataLines.attach(NULL, Serial::RxIrq);
Blaze513 0:fd1fce2347d9 9 }
Blaze513 0:fd1fce2347d9 10
Blaze513 0:fd1fce2347d9 11 unsigned char MS3DMGX2::Mode(unsigned char Selection)
Blaze513 0:fd1fce2347d9 12 {
Blaze513 0:fd1fce2347d9 13 switch (Selection & 0x03)
Blaze513 0:fd1fce2347d9 14 {
Blaze513 0:fd1fce2347d9 15 case 0x00:
Blaze513 0:fd1fce2347d9 16 ModeCommand = 0xCF;
Blaze513 0:fd1fce2347d9 17 ModeLength = 6;
Blaze513 0:fd1fce2347d9 18 break;
Blaze513 0:fd1fce2347d9 19 case 0x01:
Blaze513 0:fd1fce2347d9 20 ModeCommand = 0xD2;
Blaze513 0:fd1fce2347d9 21 ModeLength = 9;
Blaze513 0:fd1fce2347d9 22 break;
Blaze513 0:fd1fce2347d9 23 case 0x02:
Blaze513 0:fd1fce2347d9 24 ModeCommand = 0xC8;
Blaze513 0:fd1fce2347d9 25 ModeLength = 15;
Blaze513 0:fd1fce2347d9 26 break;
Blaze513 0:fd1fce2347d9 27 case 0x03:
Blaze513 0:fd1fce2347d9 28 ModeCommand = 0xCC;
Blaze513 0:fd1fce2347d9 29 ModeLength = 18;
Blaze513 0:fd1fce2347d9 30 break;
Blaze513 0:fd1fce2347d9 31 }
Blaze513 0:fd1fce2347d9 32 if (Selection & 0x04)
Blaze513 0:fd1fce2347d9 33 {
Blaze513 0:fd1fce2347d9 34 DiscardSerialBuffer();
Blaze513 0:fd1fce2347d9 35 DataLines.putc(0xC4);
Blaze513 0:fd1fce2347d9 36 DataLines.putc(0xC1);
Blaze513 0:fd1fce2347d9 37 DataLines.putc(0x29);
Blaze513 0:fd1fce2347d9 38 DataLines.putc(ModeCommand);
Blaze513 0:fd1fce2347d9 39 ModeSync = 1;
Blaze513 0:fd1fce2347d9 40 wait_ms(10);
Blaze513 0:fd1fce2347d9 41 Workspace[0] = DataLines.getc();
Blaze513 0:fd1fce2347d9 42 Workspace[1] = DataLines.getc();
Blaze513 0:fd1fce2347d9 43 while (DataLines.readable() && ((Workspace[0] != 0xC4) || (Workspace[1] != ModeCommand)))
Blaze513 0:fd1fce2347d9 44 {
Blaze513 0:fd1fce2347d9 45 Workspace[0] = Workspace[1];
Blaze513 0:fd1fce2347d9 46 Workspace[1] = DataLines.getc();
Blaze513 0:fd1fce2347d9 47 }
Blaze513 0:fd1fce2347d9 48 unsigned char i = 7;
Blaze513 0:fd1fce2347d9 49 while (DataLines.readable() && (i > 1))
Blaze513 0:fd1fce2347d9 50 {
Blaze513 0:fd1fce2347d9 51 Workspace[i] = DataLines.getc();
Blaze513 0:fd1fce2347d9 52 i--;
Blaze513 0:fd1fce2347d9 53 }
Blaze513 0:fd1fce2347d9 54 CheckSum(0xC4, 1, &ModeCommand, &Workspace[4], Workspace);
Blaze513 0:fd1fce2347d9 55 Workspace[0] = (Workspace[0] != Workspace[2]) || (Workspace[1] != Workspace[3]);
Blaze513 0:fd1fce2347d9 56 }
Blaze513 0:fd1fce2347d9 57 else
Blaze513 0:fd1fce2347d9 58 {
Blaze513 0:fd1fce2347d9 59 DataLines.putc(0xFA);
Blaze513 0:fd1fce2347d9 60 ModeSync = 0;
Blaze513 0:fd1fce2347d9 61 }
Blaze513 0:fd1fce2347d9 62 if (Selection & 0x08)
Blaze513 0:fd1fce2347d9 63 {
Blaze513 0:fd1fce2347d9 64 DataLines.attach(this, &MS3DMGX2::Interrupt, Serial::RxIrq);
Blaze513 0:fd1fce2347d9 65 }
Blaze513 0:fd1fce2347d9 66 else
Blaze513 0:fd1fce2347d9 67 {
Blaze513 0:fd1fce2347d9 68 DataLines.attach(NULL, Serial::RxIrq);
Blaze513 0:fd1fce2347d9 69 }
Blaze513 0:fd1fce2347d9 70 if (Workspace[0])
Blaze513 0:fd1fce2347d9 71 {
Blaze513 0:fd1fce2347d9 72 return 0x01;
Blaze513 0:fd1fce2347d9 73 }
Blaze513 0:fd1fce2347d9 74 else
Blaze513 0:fd1fce2347d9 75 {
Blaze513 0:fd1fce2347d9 76 return 0x00;
Blaze513 0:fd1fce2347d9 77 }
Blaze513 0:fd1fce2347d9 78 }
Blaze513 0:fd1fce2347d9 79
Blaze513 0:fd1fce2347d9 80 void MS3DMGX2::AttachInterruptBuffer(float* Buffer)
Blaze513 0:fd1fce2347d9 81 {
Blaze513 0:fd1fce2347d9 82 InterruptBuffer = Buffer;
Blaze513 0:fd1fce2347d9 83 }
Blaze513 0:fd1fce2347d9 84 //store user's data pointer for use in interrupt modes
Blaze513 0:fd1fce2347d9 85
Blaze513 0:fd1fce2347d9 86 void MS3DMGX2::RequestSyncRead()
Blaze513 0:fd1fce2347d9 87 {
Blaze513 0:fd1fce2347d9 88 if (ModeSync)
Blaze513 0:fd1fce2347d9 89 {
Blaze513 0:fd1fce2347d9 90 DataLines.putc(0xFA);
Blaze513 0:fd1fce2347d9 91 ModeSync = 0x00;
Blaze513 0:fd1fce2347d9 92 }
Blaze513 0:fd1fce2347d9 93 //if operating in an asynchronous mode, switch to the synchronous equivalent
Blaze513 0:fd1fce2347d9 94 DataLines.putc(ModeCommand);
Blaze513 0:fd1fce2347d9 95 //send polled mode command byte
Blaze513 0:fd1fce2347d9 96 }
Blaze513 0:fd1fce2347d9 97 //lazy switches to synchronous mode and sends polled mode command byte
Blaze513 0:fd1fce2347d9 98
Blaze513 0:fd1fce2347d9 99 void MS3DMGX2::DiscardSerialBuffer()
Blaze513 0:fd1fce2347d9 100 {
Blaze513 0:fd1fce2347d9 101 while (DataLines.readable())
Blaze513 0:fd1fce2347d9 102 {
Blaze513 0:fd1fce2347d9 103 DataLines.getc();
Blaze513 0:fd1fce2347d9 104 }
Blaze513 0:fd1fce2347d9 105 }
Blaze513 0:fd1fce2347d9 106 //empty buffer of all data
Blaze513 0:fd1fce2347d9 107
Blaze513 0:fd1fce2347d9 108 unsigned char MS3DMGX2::Read(float* Data)
Blaze513 0:fd1fce2347d9 109 {
Blaze513 0:fd1fce2347d9 110 unsigned char j = 0;
Blaze513 0:fd1fce2347d9 111 do
Blaze513 0:fd1fce2347d9 112 {
Blaze513 0:fd1fce2347d9 113 j++;
Blaze513 0:fd1fce2347d9 114 } while (DataLines.readable() && (DataLines.getc() != ModeCommand) && (j < (ModeLength << 2)));
Blaze513 0:fd1fce2347d9 115 //find the header byte for synchronization
Blaze513 0:fd1fce2347d9 116 for (unsigned char i = 0; i < ModeLength; i++)
Blaze513 0:fd1fce2347d9 117 {
Blaze513 0:fd1fce2347d9 118 j = 3;
Blaze513 0:fd1fce2347d9 119 while (DataLines.readable() && (j < 4))
Blaze513 0:fd1fce2347d9 120 {
Blaze513 0:fd1fce2347d9 121 ((unsigned char*)&Data[i])[j] = DataLines.getc();
Blaze513 0:fd1fce2347d9 122 j--;
Blaze513 0:fd1fce2347d9 123 }
Blaze513 0:fd1fce2347d9 124 }
Blaze513 0:fd1fce2347d9 125 //change endianness and fill user buffer
Blaze513 0:fd1fce2347d9 126 j = 7;
Blaze513 0:fd1fce2347d9 127 while (DataLines.readable() && (j > 1))
Blaze513 0:fd1fce2347d9 128 {
Blaze513 0:fd1fce2347d9 129 Workspace[j] = DataLines.getc();
Blaze513 0:fd1fce2347d9 130 j--;
Blaze513 0:fd1fce2347d9 131 }
Blaze513 0:fd1fce2347d9 132 //change endianness and gather timer and checksum (bytes 2 and 3)
Blaze513 0:fd1fce2347d9 133 CheckSum(ModeCommand, ModeLength << 2, (unsigned char*)Data, &Workspace[4], Workspace);
Blaze513 0:fd1fce2347d9 134 //compute checksum and store in bytes 0 and 1
Blaze513 0:fd1fce2347d9 135 if ((Workspace[0] != Workspace[2]) || (Workspace[1] != Workspace[3]))
Blaze513 0:fd1fce2347d9 136 {
Blaze513 0:fd1fce2347d9 137 return 0x01;
Blaze513 0:fd1fce2347d9 138 }
Blaze513 0:fd1fce2347d9 139 else
Blaze513 0:fd1fce2347d9 140 {
Blaze513 0:fd1fce2347d9 141 return 0x00;
Blaze513 0:fd1fce2347d9 142 }
Blaze513 0:fd1fce2347d9 143 //verify checksum and return result
Blaze513 0:fd1fce2347d9 144 }
Blaze513 0:fd1fce2347d9 145 //this method reads a measurement from the serial port, assuming one is waiting there
Blaze513 0:fd1fce2347d9 146
Blaze513 0:fd1fce2347d9 147 void MS3DMGX2::Interrupt()
Blaze513 0:fd1fce2347d9 148 {
Blaze513 0:fd1fce2347d9 149 Read(InterruptBuffer);
Blaze513 0:fd1fce2347d9 150 DiscardSerialBuffer();
Blaze513 0:fd1fce2347d9 151 }
Blaze513 0:fd1fce2347d9 152 //this will be called when in an interrupt mode and a serial interrupt is generated
Blaze513 0:fd1fce2347d9 153
Blaze513 0:fd1fce2347d9 154 void MS3DMGX2::CheckSum(unsigned char Header, unsigned char Length,
Blaze513 0:fd1fce2347d9 155 unsigned char* Data, unsigned char* Timer, unsigned char* Result)
Blaze513 0:fd1fce2347d9 156 {
Blaze513 0:fd1fce2347d9 157 unsigned short Sum = Header;
Blaze513 0:fd1fce2347d9 158 for (unsigned char i = 0; i < Length; i++)
Blaze513 0:fd1fce2347d9 159 {
Blaze513 0:fd1fce2347d9 160 Sum += Data[i];
Blaze513 0:fd1fce2347d9 161 }
Blaze513 0:fd1fce2347d9 162 for (unsigned char i = 0; i < 4; i++)
Blaze513 0:fd1fce2347d9 163 {
Blaze513 0:fd1fce2347d9 164 Sum += Timer[i];
Blaze513 0:fd1fce2347d9 165 }
Blaze513 0:fd1fce2347d9 166 Result[0] = ((char*)&Sum)[0];
Blaze513 0:fd1fce2347d9 167 Result[1] = ((char*)&Sum)[1];
Blaze513 0:fd1fce2347d9 168 }
Blaze513 0:fd1fce2347d9 169 //compute the checksum of a data packet and store the result in the first two bytes of "Result"