#include #include #define SD_CS 10 #define EM7180_QX 0x00 // this is a 32-bit normalized floating point number read from registers 0x00-03 #define EM7180_QY 0x04 // this is a 32-bit normalized floating point number read from registers 0x04-07 #define EM7180_QZ 0x08 // this is a 32-bit normalized floating point number read from registers 0x08-0B #define EM7180_QW 0x0C // this is a 32-bit normalized floating point number read from registers 0x0C-0F #define EM7180_QTIME 0x10 // this is a 16-bit unsigned integer read from registers 0x10-11 #define EM7180_MX 0x12 // int16_t from registers 0x12-13 #define EM7180_MY 0x14 // int16_t from registers 0x14-15 #define EM7180_MZ 0x16 // int16_t from registers 0x16-17 #define EM7180_MTIME 0x18 // uint16_t from registers 0x18-19 #define EM7180_AX 0x1A // int16_t from registers 0x1A-1B #define EM7180_AY 0x1C // int16_t from registers 0x1C-1D #define EM7180_AZ 0x1E // int16_t from registers 0x1E-1F #define EM7180_ATIME 0x20 // uint16_t from registers 0x20-21 #define EM7180_GX 0x22 // int16_t from registers 0x22-23 #define EM7180_GY 0x24 // int16_t from registers 0x24-25 #define EM7180_GZ 0x26 // int16_t from registers 0x26-27 #define EM7180_GTIME 0x28 // uint16_t from registers 0x28-29 #define EM7180_QRateDivisor 0x32 // uint8_t #define EM7180_EnableEvents 0x33 #define EM7180_HostControl 0x34 #define EM7180_EventStatus 0x35 #define EM7180_SensorStatus 0x36 #define EM7180_SentralStatus 0x37 #define EM7180_AlgorithmStatus 0x38 #define EM7180_FeatureFlags 0x39 #define EM7180_ParamAcknowledge 0x3A #define EM7180_SavedParamByte0 0x3B #define EM7180_SavedParamByte1 0x3C #define EM7180_SavedParamByte2 0x3D #define EM7180_SavedParamByte3 0x3E #define EM7180_ActualMagRate 0x45 #define EM7180_ActualAccelRate 0x46 #define EM7180_ActualGyroRate 0x47 #define EM7180_ErrorRegister 0x50 #define EM7180_AlgorithmControl 0x54 #define EM7180_MagRate 0x55 #define EM7180_AccelRate 0x56 #define EM7180_GyroRate 0x57 #define EM7180_LoadParamByte0 0x60 #define EM7180_LoadParamByte1 0x61 #define EM7180_LoadParamByte2 0x62 #define EM7180_LoadParamByte3 0x63 #define EM7180_ParamRequest 0x64 #define EM7180_ROMVersion1 0x70 #define EM7180_ROMVersion2 0x71 #define EM7180_RAMVersion1 0x72 #define EM7180_RAMVersion2 0x73 #define EM7180_ProductID 0x90 #define EM7180_RevisionID 0x91 #define EM7180_UploadAddress 0x94 // uint16_t registers 0x94 (MSB)-5(LSB) #define EM7180_UploadData 0x96 #define EM7180_CRCHost 0x97 // uint32_t from registers 0x97-9A #define EM7180_ResetRequest 0x9B #define EM7180_PassThruStatus 0x9E #define EM7180_PassThruControl 0xA0 // Using the Teensy Mini Add-On board, BMX055 SDO1 = SDO2 = CSB3 = GND as designed // Seven-bit BMX055 device addresses are ACC = 0x18, GYRO = 0x68, MAG = 0x10 #define BMX055_ACC_ADDRESS 0x18 // Address of BMX055 accelerometer #define BMX055_GYRO_ADDRESS 0x68 // Address of BMX055 gyroscope #define BMX055_MAG_ADDRESS 0x10 // Address of BMX055 magnetometer #define MS5637_ADDRESS 0x76 // Address of MS5637 altimeter #define EM7180_ADDRESS 0x28 // Address of the EM7180 SENtral sensor hub#define M24512DFM_DATA_ADDRESS 0x50 // Address of the 500 page M24512DFM EEPROM data buffer, 1024 bits (128 8-bit bytes) per page #define M24512DFM_DATA_ADDRESS 0x50 // Address of the 500 page M24512DFM EEPROM data buffer, 1024 bits (128 8-bit bytes) per page #define M24512DFM_IDPAGE_ADDRESS 0x58 // Address of the single M24512DFM lockable EEPROM ID page SdFat SD; SdFile sd_file; void setup() { // Setup for Master mode, pins 18/19, external pullups, 400kHz for Teensy 3.1 Wire.begin(I2C_MASTER, 0x00, I2C_PINS_16_17, I2C_PULLUP_EXT, I2C_RATE_400); Serial.begin(9600); delay(5000); while (!SD.begin(SD_CS, SPI_HALF_SPEED)) { Serial.println("failed to init sd"); Serial.printf("err: %02x\n", SD.card()->errorCode()); } Serial.println("sd init"); I2Cscan(); // Put EM7180 SENtral into pass-through mode SENtralPassThroughMode(); delay(1000); I2Cscan(); sd_file.open("/EM6500.fw", O_RDONLY); Serial.println("File Open!"); uint8_t buffer[128]; uint8_t numbytes= 0, MSadd = 0, totnum = 0; Serial.println("erasing EEPROM"); uint8_t eraseBuffer[128] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; for (MSadd = 0; MSadd < 256; MSadd++) { // MS address byte, 0 to 255 M24512DFMwriteBytes(M24512DFM_DATA_ADDRESS, MSadd, 0x00, 128, eraseBuffer); // write data starting at first byte of page MSadd delay(100); M24512DFMwriteBytes(M24512DFM_DATA_ADDRESS, MSadd, 0x80, 128, eraseBuffer); // write data starting at 128th byte of page MSadd delay(100); totnum++; if (MSadd = 255) { break; } Serial.print("totnum"); Serial.println(totnum); Serial.print("MSadd 0x"); Serial.println(MSadd, HEX); } // Verify EEPROM ihas been erased // Read first page of EEPROM uint8_t data[128]; M24512DFMreadBytes(M24512DFM_DATA_ADDRESS, 0x00, 0x00, 128, data); Serial.println("EEPROM first page"); for (int i = 0; i < 16; i++) { Serial.println(" "); for (int j = 0; j < 8; j++) { Serial.print(data[i*8 + j], HEX); Serial.print(" "); } } // Read second page of EEPROM M24512DFMreadBytes(M24512DFM_DATA_ADDRESS, 0x00, 0x80, 128, data); Serial.println("");Serial.println("EEPROM second page"); for (int i = 0; i < 16; i++) { Serial.println(" "); for (int j = 0; j < 8; j++) { Serial.print(data[i*8 + j], HEX); Serial.print(" "); } } // Read third page of EEPROM M24512DFMreadBytes(M24512DFM_DATA_ADDRESS, 0x01, 0x00, 128, data); Serial.println("");Serial.println("EEPROM third page"); for (int i = 0; i < 16; i++) { Serial.println(" "); for (int j = 0; j < 8; j++) { Serial.print(data[i*8 + j], HEX); Serial.print(" "); } } // write configuration file to EEPROM Serial.println("writing data to EEPROM"); for (MSadd = 0; MSadd < 256; MSadd++) { // MS address byte, 0 to 255 numbytes = sd_file.read(buffer, 128); // 128 bytes per page, 500 pages Serial.print("first two bytes: "); Serial.print("0x"); Serial.print(buffer[0], HEX); Serial.print("0x"); Serial.println(buffer[1], HEX); Serial.print("Number of bytes = "); Serial.println(numbytes); // print number of bytes read M24512DFMwriteBytes(M24512DFM_DATA_ADDRESS, MSadd, 0x00, 128, buffer); // write data starting at first byte of page MSadd delay(100); numbytes = sd_file.read(buffer, 128); // 128 bytes per page, 500 pages Serial.print("first two bytes: "); Serial.print("0x"); Serial.print(buffer[0], HEX); Serial.print("0x"); Serial.println(buffer[1], HEX); Serial.print("Number of bytes = "); Serial.println(numbytes); // print number of bytes read M24512DFMwriteBytes(M24512DFM_DATA_ADDRESS, MSadd, 0x80, 128, buffer); // write data starting at 128th byte of page MSadd delay(100); if (numbytes < 128) { break; } totnum++; Serial.print("totnum"); Serial.println(totnum); Serial.print("MSadd 0x"); Serial.println(MSadd, HEX); } // Read first page of EEPROM M24512DFMreadBytes(M24512DFM_DATA_ADDRESS, 0x00, 0x00, 128, data); Serial.println("EEPROM first page"); for (int i = 0; i < 16; i++) { Serial.println(" "); for (int j = 0; j < 8; j++) { Serial.print(data[i*8 + j], HEX); Serial.print(" "); } } // Read second page of EEPROM M24512DFMreadBytes(M24512DFM_DATA_ADDRESS, 0x00, 0x80, 128, data); Serial.println("");Serial.println("EEPROM second page"); for (int i = 0; i < 16; i++) { Serial.println(" "); for (int j = 0; j < 8; j++) { Serial.print(data[i*8 + j], HEX); Serial.print(" "); } } // Read third page of EEPROM M24512DFMreadBytes(M24512DFM_DATA_ADDRESS, 0x01, 0x00, 128, data); Serial.println("");Serial.println("EEPROM third page"); for (int i = 0; i < 16; i++) { Serial.println(" "); for (int j = 0; j < 8; j++) { Serial.print(data[i*8 + j], HEX); Serial.print(" "); } } } void loop() { } // I2C read/write functions for the MPU9250 and AK8963 sensors void writeByte(uint8_t address, uint8_t subAddress, uint8_t data) { Wire.beginTransmission(address); // Initialize the Tx buffer Wire.write(subAddress); // Put slave register address in Tx buffer Wire.write(data); // Put data in Tx buffer Wire.endTransmission(); // Send the Tx buffer } uint8_t readByte(uint8_t address, uint8_t subAddress) { uint8_t data; // `data` will store the register data Wire.beginTransmission(address); // Initialize the Tx buffer Wire.write(subAddress); // Put slave register address in Tx buffer Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive // Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive // Wire.requestFrom(address, 1); // Read one byte from slave register address Wire.requestFrom(address, (size_t) 1); // Read one byte from slave register address data = Wire.read(); // Fill Rx buffer with result return data; // Return data read from slave register } void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest) { Wire.beginTransmission(address); // Initialize the Tx buffer Wire.write(subAddress); // Put slave register address in Tx buffer Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive // Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive uint8_t i = 0; // Wire.requestFrom(address, count); // Read bytes from slave register address Wire.requestFrom(address, (size_t) count); // Read bytes from slave register address while (Wire.available()) { dest[i++] = Wire.read(); } // Put read results in the Rx buffer } void SENtralPassThroughMode() { // First put SENtral in standby mode uint8_t c = readByte(EM7180_ADDRESS, EM7180_AlgorithmControl); writeByte(EM7180_ADDRESS, EM7180_AlgorithmControl, c | 0x01); // c = readByte(EM7180_ADDRESS, EM7180_AlgorithmStatus); // Serial.print("c = "); Serial.println(c); // Verify standby status // if(readByte(EM7180_ADDRESS, EM7180_AlgorithmStatus) & 0x01) { Serial.println("SENtral in standby mode"); // Place SENtral in pass-through mode writeByte(EM7180_ADDRESS, EM7180_PassThruControl, 0x01); if(readByte(EM7180_ADDRESS, EM7180_PassThruStatus) & 0x01) { Serial.println("SENtral in pass-through mode"); } else { Serial.println("ERROR! SENtral not in pass-through mode!"); } } // I2C communication with the M24512DFM EEPROM is a little different from I2C communication with the usual motion sensor // since the address is defined by two bytes void M24512DFMwriteByte(uint8_t device_address, uint8_t data_address1, uint8_t data_address2, uint8_t data) { Wire.beginTransmission(device_address); // Initialize the Tx buffer Wire.write(data_address1); // Put slave register address in Tx buffer Wire.write(data_address2); // Put slave register address in Tx buffer Wire.write(data); // Put data in Tx buffer Wire.endTransmission(); // Send the Tx buffer } void M24512DFMwriteBytes(uint8_t device_address, uint8_t data_address1, uint8_t data_address2, uint8_t count, uint8_t * dest) { if(count > 128) { count = 128; Serial.print("Page count cannot be more than 128 bytes!"); } Wire.beginTransmission(device_address); // Initialize the Tx buffer Wire.write(data_address1); // Put slave register address in Tx buffer Wire.write(data_address2); // Put slave register address in Tx buffer for(uint8_t i=0; i < count; i++) { Wire.write(dest[i]); // Put data in Tx buffer } Wire.endTransmission(); // Send the Tx buffer } uint8_t M24512DFMreadByte(uint8_t device_address, uint8_t data_address1, uint8_t data_address2) { uint8_t data; // `data` will store the register data Wire.beginTransmission(device_address); // Initialize the Tx buffer Wire.write(data_address1); // Put slave register address in Tx buffer Wire.write(data_address2); // Put slave register address in Tx buffer Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive // Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive // Wire.requestFrom(address, 1); // Read one byte from slave register address Wire.requestFrom(device_address, (size_t) 1); // Read one byte from slave register address data = Wire.read(); // Fill Rx buffer with result return data; // Return data read from slave register } void M24512DFMreadBytes(uint8_t device_address, uint8_t data_address1, uint8_t data_address2, uint8_t count, uint8_t * dest) { Wire.beginTransmission(device_address); // Initialize the Tx buffer Wire.write(data_address1); // Put slave register address in Tx buffer Wire.write(data_address2); // Put slave register address in Tx buffer Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive // Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive uint8_t i = 0; // Wire.requestFrom(address, count); // Read bytes from slave register address Wire.requestFrom(device_address, (size_t) count); // Read bytes from slave register address while (Wire.available()) { dest[i++] = Wire.read(); } // Put read results in the Rx buffer } // simple function to scan for I2C devices on the bus void I2Cscan() { // scan for i2c devices byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknow error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); }