BOOL Accel_Init(const TAccelSetup* const accelSetup) { TAccelMode CurrentMode; DataCallback = accelSetup->dataReadyCallbackFunction; DataCallbackArgument = accelSetup->dataReadyCallbackArguments; ReadCallback = accelSetup->readCompleteCallbackFunction; ReadCallbackArgument = accelSetup->readCompleteCallbackArguments; //Let there be clocks! SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK; /*portb GPIO, clear interrupt, interrupt on falling edge.*/ PORTB_PCR7 = (PORT_PCR_MUX(0x01) | PORT_PCR_ISF_MASK | PORT_PCR_IRQC(0x0A)); /* NVICIP88: PRI88=0x80 */ NVICIP88 = NVIC_IP_PRI88(0x80); /* NVICISER2: SETENA|=0x01000000 */ NVICISER2 |= NVIC_ISER_SETENA(0x01000000); //Check if we are connected to the correct device uint8_t whoAmI; I2C_SelectSlaveDevice(MMA8451Q_ADDR_SA0_HIGH); //TODO: uncomment /* I2C_PollRead(MMA8451Q_WHO_AM_I, &whoAmI, 1); if (whoAmI != MMA8451Q_WHO_AM_I_VALUE) { //This is not the i2c device we are looking for return bFALSE; } */ //Reset the accelerometer //TODO: uncomment /*I2C_Write(MMA8451Q_CTRL_REG2, MMA8451Q_CTRL_REG2_RST_MASK, bFALSE); uint8_t reg2 = MMA8451Q_CTRL_REG2_RST_MASK; while (reg2 & MMA8451Q_CTRL_REG2_RST_MASK) { I2C_PollRead(MMA8451Q_CTRL_REG2, ®2, 1); }*/ /* * activate * enable fast read * low noise * data rate 1.56Hz (0x38) * */ I2C_Write(MMA8451Q_CTRL_REG1, (0x38 | MMA8451Q_CTRL_REG1_ACTIVE_MASK | MMA8451Q_CTRL_REG1_F_READ_MASK | MMA8451Q_CTRL_REG1_LNOISE_MASK), bFALSE); return bTRUE; }
// read MMA8652 accelerometer and magnetometer data over I2C void mma8652ReadData (LDD_TDeviceData *DeviceDataPtr, struct AccelSensor *pthisAccel) { LDD_I2C_TBusState BusState; // I2C bus state // set up the MMA8652 I2C address I2C_SelectSlaveDevice (DeviceDataPtr, LDD_I2C_ADDRTYPE_7BITS, MMA8652_I2C_ADDR); // set up the address of the first output register I2C_Buf[0] = MMA8652_OUT_X_MSB; mqxglobals.I2C_Status &= ~I2C_SENT_FLAG; I2C_MasterSendBlock (DeviceDataPtr, I2C_Buf, 1, LDD_I2C_NO_SEND_STOP); // wait until the I2C sent callback function sets the sent flag while ((mqxglobals.I2C_Status & I2C_SENT_FLAG) == 0) ; // read the 6 bytes of sequential sensor data mqxglobals.I2C_Status &= ~I2C_RCVD_FLAG; I2C_MasterReceiveBlock (DeviceDataPtr, I2C_Buf, 6, LDD_I2C_SEND_STOP); // wait until the I2C received callback function sets the received flag while ((mqxglobals.I2C_Status & I2C_RCVD_FLAG) == 0) ; // wait until the I2C bus is idle do { I2C_CheckBus (DeviceDataPtr, &BusState); } while (BusState != LDD_I2C_IDLE); // place the 12 bytes read into the 16 bit accelerometer structure pthisAccel->iGpFast[X] = (I2C_Buf[0] << 8) | I2C_Buf[1]; pthisAccel->iGpFast[Y] = (I2C_Buf[2] << 8) | I2C_Buf[3]; pthisAccel->iGpFast[Z] = (I2C_Buf[4] << 8) | I2C_Buf[5]; // finally check for -32768 in the accelerometer since // this value cannot be negated in a later HAL operation if (pthisAccel->iGpFast[X] == -32768) pthisAccel->iGpFast[X]++; if (pthisAccel->iGpFast[Y] == -32768) pthisAccel->iGpFast[Y]++; if (pthisAccel->iGpFast[Z] == -32768) pthisAccel->iGpFast[Z]++; return; }
void Accel_ReadXYZ(uint8_t data[3]) { I2C_SelectSlaveDevice(MMA8451Q_ADDR_SA0_HIGH); I2C_IntRead(MMA8451Q_OUT_X_MSB, data, 3, ReadCallback, ReadCallbackArgument); }
// initialize MMA8652 accelerometer sensor void mma8652Init (LDD_TDeviceData *DeviceDataPtr, struct AccelSensor *pthisAccel) { LDD_I2C_TBusState BusState; // I2C bus state // set up the MMA8652 I2C address I2C_SelectSlaveDevice (DeviceDataPtr, LDD_I2C_ADDRTYPE_7BITS, MMA8652_I2C_ADDR); // write 0000 0000 = 0x00 to CTRL_REG1 to place MMA8652 into standby // [7-1] = 0000 000 // [0]: active=0 I2C_Buf[0] = MMA8652_CTRL_REG1; I2C_Buf[1] = 0x00; mqxglobals.I2C_Status &= ~I2C_SENT_FLAG; I2C_MasterSendBlock (DeviceDataPtr, I2C_Buf, 2, LDD_I2C_SEND_STOP); // wait until the I2C sent callback function sets the sent flag while ((mqxglobals.I2C_Status & I2C_SENT_FLAG) == 0) ; // wait until the I2C bus is idle do { I2C_CheckBus (DeviceDataPtr, &BusState); } while (BusState != LDD_I2C_IDLE); // write 0000 0001 = 0x01 to XYZ_DATA_CFG register to set g range // [7-5]: reserved=000 // [4]: HPF_OUT=0 // [3-2]: reserved=00 // [1-0]: FS=01 for +/-4g: 512 counts / g = 8192 counts / g after 4 bit left shift I2C_Buf[0] = MMA8652_XYZ_DATA_CFG; I2C_Buf[1] = 0x01; mqxglobals.I2C_Status &= ~I2C_SENT_FLAG; I2C_MasterSendBlock (DeviceDataPtr, I2C_Buf, 2, LDD_I2C_SEND_STOP); // wait until the I2C sent callback function sets the sent flag while ((mqxglobals.I2C_Status & I2C_SENT_FLAG) == 0) ; // wait until the I2C bus is idle do { I2C_CheckBus (DeviceDataPtr, &BusState); } while (BusState != LDD_I2C_IDLE); // write 0000 0010 = 0x02 to CTRL_REG2 to set MODS bits // [7]: ST=0: self test disabled // [6]: RST=0: reset disabled // [5]: unused // [4-3]: SMODS=00 // [2]: SLPE=0: auto sleep disabled // [1-0]: mods=10 for high resolution (maximum over sampling) I2C_Buf[0] = MMA8652_CTRL_REG2; I2C_Buf[1] = 0x02; mqxglobals.I2C_Status &= ~I2C_SENT_FLAG; I2C_MasterSendBlock (DeviceDataPtr, I2C_Buf, 2, LDD_I2C_SEND_STOP); // wait until the I2C sent callback function sets the sent flag while ((mqxglobals.I2C_Status & I2C_SENT_FLAG) == 0) ; // wait until the I2C bus is idle do { I2C_CheckBus (DeviceDataPtr, &BusState); } while (BusState != LDD_I2C_IDLE); // write 0001 0001 = 0x11 to CTRL_REG1 // [7-6]: aslp_rate=00 // [5-3]: dr=010 for 200Hz data rate // [2]: unused=0 // [1]: f_read=0 for normal 16 bit reads // [0]: active=1 to take the part out of standby and enable sampling I2C_Buf[0] = MMA8652_CTRL_REG1; I2C_Buf[1] = 0x11; mqxglobals.I2C_Status &= ~I2C_SENT_FLAG; I2C_MasterSendBlock (DeviceDataPtr, I2C_Buf, 2, LDD_I2C_SEND_STOP); // wait until the I2C sent callback function sets the sent flag while ((mqxglobals.I2C_Status & I2C_SENT_FLAG) == 0) ; // wait until the I2C bus is idle do { I2C_CheckBus (DeviceDataPtr, &BusState); } while (BusState != LDD_I2C_IDLE); // store the gain terms in the accelerometer and magnetometer sensor structures #define MMA8652_GPERCOUNT 0.0001220703125F // equal to 1/8192 pthisAccel->fgPerCount = MMA8652_GPERCOUNT; return; }