1 changed files with 320 additions and 0 deletions
@ -0,0 +1,320 @@ |
|||||||
|
#include <SdFat.h> |
||||||
|
#include <i2c_t3.h> |
||||||
|
|
||||||
|
#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); |
||||||
|
|
||||||
|
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(); |
||||||
|
|
||||||
|
I2Cscan(); |
||||||
|
|
||||||
|
sd_file.open("/SENTRA~1.FW", O_RDONLY);
|
||||||
|
Serial.println("File Open!"); |
||||||
|
|
||||||
|
uint8_t buffer[128]; |
||||||
|
uint8_t numbytes, MSadd = 0, totnum = 0; |
||||||
|
|
||||||
|
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(50); |
||||||
|
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(50); |
||||||
|
|
||||||
|
if (numbytes < 128) { break; } |
||||||
|
totnum++; |
||||||
|
Serial.print("totnum"); Serial.println(totnum); |
||||||
|
Serial.print("MSadd 0x"); Serial.println(MSadd, HEX); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
// 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(" "); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
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"); |
||||||
|
} |
Loading…
Reference in new issue