/******************************************************************************* * Outline : Accel_SelfTest * Description : This function reads the acceleromter's X axis * Argument : none * Return value : bool true - pass, false - fail *******************************************************************************/ bool Accel_SelfTest( void ) { bool err =true; uint8_t target_reg_data[2]; uint16_t i; // set the data format + self test mode target_reg_data[0] = ADXL345_DATA_FORMAT_REG; target_reg_data[1] = 0x83; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg_data[0], 2, PDL_NO_FUNC, 0 ); // Wait for self-test forces to act for (i = 0; i < 1000; i++); Accel_X = 0; Accel_Y = 0; Accel_Z = 0; for (i = 0; i < 8; i++) { Accel_X += Accel_AxisRd(ADXL345_DATAX0_REG); Accel_Y += Accel_AxisRd(ADXL345_DATAY0_REG); Accel_Z += Accel_AxisRd(ADXL345_DATAZ0_REG); } Accel_X = Accel_X / 8; Accel_Y = Accel_Y / 8; Accel_Z = Accel_Z / 8; // normalize the self test values Accel_X = SCALE_X(Accel_X) - Accel_X_Zero; Accel_Y = SCALE_Y(Accel_Y) - Accel_Y_Zero; Accel_Z = SCALE_Z(Accel_Z) - Accel_Z_Zero; // Range check self-test values err &= ((Accel_X > 6) && (Accel_X < 67)) ? true : false; err &= ((Accel_Y > -67) && (Accel_Y < -6)) ? true : false; err &= ((Accel_Z > 10) && (Accel_Z < 110)) ? true : false; // turn off self test mode target_reg_data[0] = ADXL345_DATA_FORMAT_REG; target_reg_data[1] = 0x03; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg_data[0], 2, PDL_NO_FUNC, 0 ); return err; }
/******************************************************************************* * Outline : CB_CMT_Thermal * Description : CMT interrupt callback function. This callback function is * executed after every period of the CMT timer. The function * fetches the thermal temperature and displays it on the LCD. * Argument : none * Return value : none *******************************************************************************/ void CB_CMT_Thermal(void) { bool err = true; uint8_t target_reg, target_data[2]; uint16_t temp; uint8_t temp_int[2]; /* Declare display buffer */ uint8_t lcd_buffer[13]; /* Read the temperature */ target_reg = ADT7420_TEMP_MSB_REG; err = R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADT7420_ADDR, &target_reg, 1, PDL_NO_FUNC, 0 ); err = R_IIC_MasterReceive( IIC_CHANNEL, PDL_NO_DATA, ADT7420_ADDR, &target_data[0], 2, PDL_NO_FUNC, 0 ); /* Convert the device measurement into a decimal number and insert into a temporary string to be displayed */ temp = (target_data[0]<<8)+target_data[1]; temp = temp >> 3; temp_int[0] = (int16_t)temp/16; temp_int[1] = (int16_t)((temp&0x000F)*10)/16; sprintf((char *)lcd_buffer, " %d.%d C" , temp_int[0], temp_int[1] ); /* Display the contents of lcd_buffer onto the debug LCD */ DisplayLCD(LCD_LINE6, lcd_buffer); /* Halt in while loop when RPDL errors detected */ while (!err); }
/******************************************************************************* * Outline : Init_Thermal_Sensor * Description : This function configures the ADT7420 thermal device and starts * a timer to periodically read the temperature. * Argument : none * Return value : none *******************************************************************************/ void Init_Thermal_Sensor(void) { /* Declare error flag */ bool err = true; uint8_t target_reg, target_data; DisplayLCD(LCD_LINE5, "Temp:"); /* Configure the ADT7420 */ target_reg = ADT7420_CONFIG_REG; err = R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADT7420_ADDR, &target_reg, 1, PDL_NO_FUNC, 0 ); target_data = 0x00; err = R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADT7420_ADDR, &target_data, 1, PDL_NO_FUNC, 0 ); /* Configure CMT1 to execute callback function every 250ms */ err &= R_CMT_Create( 1, PDL_CMT_PERIOD, 250E-3, CB_CMT_Thermal, 3 ); /* Halt in while loop when RPDL errors detected */ while (!err); }
/******************************************************************************* * Outline : Accel_AxisRd * Description : This function reads the acceleromter's X, Y or Z axis * Argument : uint8_t axis -- axis registers to read * Return value : short value of axis *******************************************************************************/ short Accel_AxisRd (uint8_t axis) { uint16_t axis_val; uint8_t accel_reg, accel_data[2]; accel_reg = axis; R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &accel_reg, 1, PDL_NO_FUNC, 0 ); R_IIC_MasterReceive( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &accel_data[0], 2, PDL_NO_FUNC, 0 ); axis_val = accel_data[1] << 8; axis_val += accel_data[0]; return((short)axis_val); }
/******************************************************************************* * Outline : Init_Accelerometer * Description : This function configures the ADXL345 accelerometer and starts * a timer to periodically read it. * Argument : none * Return value : none *******************************************************************************/ void Init_Accelerometer(void) { /* Declare error flag */ bool err = true; uint8_t target_reg, target_data; uint16_t i; uint8_t target_reg_data[2]; // Read the DEVID register and verify the device target_reg = 0x00; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg, 1, PDL_NO_FUNC, 0 ); err &= R_IIC_MasterReceive( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_data, 1, PDL_NO_FUNC, 0 ); if ( target_data != 0xE5 ) return; // set the data format #if 0 // example of writing slave address and data as separate function calls target_reg = ADXL345_DATA_FORMAT_REG; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_IIC_STOP_DISABLE, ADXL345_ADDR, &target_reg, 1, PDL_NO_FUNC, 0 ); target_data = 3; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_IIC_START_DISABLE, ADXL345_ADDR, &target_data, 1, PDL_NO_FUNC, 0 ); #else // example of writing slave address and data in same function call target_reg_data[0] = ADXL345_DATA_FORMAT_REG; target_reg_data[1] = 3; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg_data[0], 2, PDL_NO_FUNC, 0 ); #endif // put FIFO into bypass mode target_reg_data[0] = ADXL345_FIFO_CTL_REG; target_reg_data[1] = 0; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg_data[0], 2, PDL_NO_FUNC, 0 ); // set the measure bit in the power control register target_reg_data[0] = ADXL345_POWER_CTL_REG; target_reg_data[1] = 8; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg_data[0], 2, PDL_NO_FUNC, 0 ); // get baseline readings to calibrate accelerometer Accel_X_Zero = 0; Accel_Y_Zero = 0; Accel_Z_Zero = 0; for (i = 0; i < 8; i++) { Accel_X_Zero += Accel_AxisRd(0x32); Accel_Y_Zero += Accel_AxisRd(0x34); Accel_Z_Zero += Accel_AxisRd(0x36); } // determine the average reading Accel_X_Zero = Accel_X_Zero / 8; Accel_Y_Zero = Accel_Y_Zero / 8; Accel_Z_Zero = Accel_Z_Zero / 8; // run self test err &= Accel_SelfTest(); // Activate X, Y Z to detect activity target_reg_data[0] = ADXL345_ACT_INACT_CTL_REG; target_reg_data[1] = 0x70; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg_data[0], 2, PDL_NO_FUNC, 0 ); #ifdef ACCELEROMETER_DEBUG // read all the registers for debug target_reg = ADXL345_THRESH_TAP_REG; err &= R_IIC_MasterSend( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_reg, 1, PDL_NO_FUNC, 0 ); err &= R_IIC_MasterReceive( IIC_CHANNEL, PDL_NO_DATA, ADXL345_ADDR, &target_string[0], 29, PDL_NO_FUNC, 0 ); #endif /* Configure CMT2 to execute callback function every 100ms */ err &= R_CMT_Create( 2, PDL_CMT_PERIOD, 100E-3, CB_CMT_Accelerometer, 3 ); /* Halt in while loop when RPDL errors detected */ while (!err); }