L3G4200D SPI driver. Runs at 10mhz vs I2C 400khz. High pass filtered data sets a INT1 pin high when a reference threshold is reached on an axis. Returns the axis that reached the threshold and the DPS of that threshold. Threshold levels can be tweaked by editing void setupL3G4200D()
L3G4200D.h
- Committer:
- Spilly
- Date:
- 2014-11-25
- Revision:
- 0:66fe7a32bd59
File content as of revision 0:66fe7a32bd59:
#include "mbed.h" /************************* L3G4200D Registers *************************/ #define WHO_AM_I 0x0F #define CTRL_REG1 0x20 #define CTRL_REG2 0x21 #define CTRL_REG3 0x22 #define CTRL_REG4 0x23 #define CTRL_REG5 0x24 #define REFERENCE 0x25 #define OUT_TEMP 0x26 #define STATUS_REG 0x27 #define OUT_X_L 0x28 #define OUT_X_H 0x29 #define OUT_Y_L 0x2A #define OUT_Y_H 0x2B #define OUT_Z_L 0x2C #define OUT_Z_H 0x2D #define FIFO_CTRL_REG 0x2E #define FIFO_SRC_REG 0x2F #define INT1_CFG 0x30 #define INT1_SRC 0x31 #define INT1_TSH_XH 0x32 #define INT1_TSH_XL 0x33 #define INT1_TSH_YH 0x34 #define INT1_TSH_YL 0x35 #define INT1_TSH_ZH 0x36 #define INT1_TSH_ZL 0x37 #define INT1_DURATION 0x38 #define xHigh 2 //axis x 0b00000010 #define yHigh 8 //axis y 0b00001000 #define zHigh 32 //axis z 0b00100000 #define GYRO_CALIBRATION_COUNT 64 //how many samples to take for calibration #define GYRO_SAMPLE_PERIOD .001f //differnece of ODR period and time required to read registers #define GYRO_SAMPLE_COUNT 1 //number of samples to average DigitalOut chipSelect(PTD4); DigitalIn INT1(D0); Serial pc(USBTX, USBRX); SPI L3G4200D(PTD6, PTD7, PTD5); // 16-bit two's comp gyro readings int16_t gyro[3] = {0,0,0}, gyroBias[3] = {0,0,0}; int readRegister(int address) { int toRead; address |= 0x80; // This tells the L3G4200D we're reading; chipSelect.write(0); L3G4200D.write(address); toRead = L3G4200D.write(0x00); chipSelect.write(1); return toRead; } void writeRegister(int address, int data) { address &= 0x7F; // This to tell the L3G4200D we're writing chipSelect.write(0); L3G4200D.write(address); L3G4200D.write(data); chipSelect.write(1); } void setRef() { readRegister(REFERENCE); writeRegister(INT1_CFG, 0x6A); //Enable XH, YH and ZH interrupt generation //Interrupt latched //Gyro.writeReg(L3G_INT1_CFG, 0x80); } void getGyroValues() { gyro[0] = (readRegister(0x29)&0xFF)<<8; gyro[0] |= (readRegister(0x28)&0xFF); //gyro[0] = gyro[0] - gyroBias[0]; gyro[1] = (readRegister(0x2B)&0xFF)<<8; gyro[1] |= (readRegister(0x2A)&0xFF); //gyro[1] = gyro[1] - gyroBias[1]; gyro[2] = (readRegister(0x2D)&0xFF)<<8; gyro[2] |= (readRegister(0x2C)&0xFF); //gyro[2] = gyro[2] - gyroBias[2]; } void getGyroBias() { float accumulator[3] = {0,0,0}, tempStore[3]; int sampleCount = 0; //Summation of 64 readings while (sampleCount < GYRO_CALIBRATION_COUNT) { //Make sure the accelerometer has had enough time //to take a new sample. wait(GYRO_SAMPLE_PERIOD); //get accelerometer data getGyroValues(); for(int i = 0; i < 3; i++) { //add current sample to previous samples accumulator[i] += tempStore[i]; } sampleCount++; } for(int i = 0; i < 3; i++) { //divide by number of samples tempStore[i] = accumulator[i] / GYRO_CALIBRATION_COUNT; gyroBias[i] = (int16_t)tempStore[i]; } } void getGyroAvg() { float accumulator[3] = {0,0,0}, tempStore[3]; int sampleCount = 0; //Summation of 64 readings while (sampleCount < GYRO_SAMPLE_COUNT) { //Make sure the accelerometer has had enough time //to take a new sample. wait(GYRO_SAMPLE_PERIOD); //get accelerometer data getGyroValues(); for(int i = 0; i < 3; i++) { //add current sample to previous samples accumulator[i] += tempStore[i]; } sampleCount++; } for(int i = 0; i < 3; i++) { //divide by number of samples tempStore[i] = accumulator[i] / GYRO_CALIBRATION_COUNT; gyro[i] = (int16_t)tempStore[i]; } } void setupL3G4200D() { L3G4200D.format(8, 3); //Set SPI mode to CPOL = 1 and CPHA = 1 //8-bit transmissions L3G4200D.frequency(10000000); //10MHz SPI frequency chipSelect.write(1); wait(.1); chipSelect.write(0); L3G4200D.write(0); //Work around for clock not being set high when initiating SPI chipSelect.write(1); //writeRegister(CTRL_REG1, 0xCF); //normal power mode, all axes enabled, 800 Hz writeRegister(CTRL_REG1, 0xCF); //normal power mode, all axes enabled, 100 Hz writeRegister(CTRL_REG2, 0x00); //High-pass filter disabled writeRegister(CTRL_REG3, 0x80); //Interrupt driven to INT1 pad writeRegister(CTRL_REG4, 0x00); //250 dps full scale writeRegister(CTRL_REG5, 0x05); //Data in DataReg and FIFO are high-pass filtered //High-pass-filtered data are used for interrupt //generation writeRegister(INT1_TSH_XH, 0x00); //X HIGH threshold writeRegister(INT1_TSH_XL, 0x60); //X LOW threshold writeRegister(INT1_TSH_YH, 0x00); //Y HIGH threshold writeRegister(INT1_TSH_YL, 0x60); //Y LOW threshold writeRegister(INT1_TSH_ZH, 0x00); //Z HIGH threshold writeRegister(INT1_TSH_ZL, 0x60); //Z LOW threshold writeRegister(INT1_DURATION, 0x01); //Duration = 10ms setRef(); //Device must remain stationary while setting the gyro reference level //getGyroBias(); } void checkGyro() { int interrSource = readRegister(INT1_SRC); int compare = interrSource&xHigh; //X-Axis if(compare == 2) { //getGyroAvg(); getGyroValues(); pc.printf("X: %i\n", gyro[0]); compare = interrSource&yHigh; //Y-Axis if(compare == 8) { pc.printf("Y: %i\n", gyro[1]); } compare = interrSource&zHigh; //Z-Axis if(compare == 32) { pc.printf("Z: %i\n", gyro[2]); } } else { compare = interrSource&yHigh; //Y-Axis if(compare == 8) { //getGyroAvg(); getGyroValues(); pc.printf("Y: %i\n", gyro[1]); //Z-Axis compare = interrSource&zHigh; if(compare == 32) { pc.printf("Z: %i\n", gyro[2]); } } else { //Z-Axis compare = interrSource&zHigh; if(compare == 32) { //getGyroAvg(); getGyroValues(); pc.printf("Z: %i\n", gyro[2]); } } } }