From 629b0248502b894285153c5f372394d9ad045d37 Mon Sep 17 00:00:00 2001 From: Kris Winer Date: Sat, 27 Dec 2014 00:54:35 -0800 Subject: [PATCH] Create FirmwareUpload.ino --- FirmwareUpload.ino | 320 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 FirmwareUpload.ino diff --git a/FirmwareUpload.ino b/FirmwareUpload.ino new file mode 100644 index 0000000..ec7d942 --- /dev/null +++ b/FirmwareUpload.ino @@ -0,0 +1,320 @@ +#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); + + 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"); +}