Would'nt it work without copying? The chip has a cache, and when running from RAM, a cache seems useless (?!)
I would have code in RAM and temporary data in cache
Would'nt it work without copying? The chip has a cache, and when running from RAM, a cache seems useless (?!)
I have also added a program to allow sensor fusion using the MPU-9250 9-axis motion sensor with the STM32F401 Nucleo board using the mbed compiler. The STM32F401 achieves a sensor fusion filter update rate using the Madgwick MARG fusion filter of 4800 Hz running the M4 Cortex ARM processor at 84 MHz; compare to the sensor fusion update rate of 2120 Hz achieved using the same filter with the Teensy 3.1 running its M4 Cortex ARM processor at 96 MHz.
************************************************
UDP Echo example
************************************************
IPv4 Address : 192.168.0.102
IPv4 Subnet mask : 255.255.255.0
IPv4 Gateway : 192.168.0.100
************************************************
T3.5 14,388.33 Hz
1050 22,005.26 Hz
Arduino version - polling:
tstart = micros();
// If intPin goes high, all data registers have new data
//if(newData == true) { // On interrupt, read data
if (readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) { // On interrupt, check if data ready interrupt
newData = false; // reset newData flag
readMPU9250Data(MPU9250Data); // INT cleared on any read
// Now we'll calculate the accleration value into actual g's
ax = (float)MPU9250Data[0]*aRes - accelBias[0]; // get actual g value, this depends on scale being set
ay = (float)MPU9250Data[1]*aRes - accelBias[1];
az = (float)MPU9250Data[2]*aRes - accelBias[2];
// Calculate the gyro value into actual degrees per second
gx = (float)MPU9250Data[4]*gRes; // get actual gyro value, this depends on scale being set
gy = (float)MPU9250Data[5]*gRes;
gz = (float)MPU9250Data[6]*gRes;
newMagData = (readByte(AK8963_ADDRESS, AK8963_ST1) & 0x01);
if(newMagData == true) { // wait for magnetometer data ready bit to be set
readMagData(magCount); // Read the x/y/z adc values
// Calculate the magnetometer values in milliGauss
// Include factory calibration per data sheet and user environmental corrections
mx = (float)magCount[0]*mRes*magCalibration[0] - magBias[0]; // get actual magnetometer value, this depends on scale being set
my = (float)magCount[1]*mRes*magCalibration[1] - magBias[1];
mz = (float)magCount[2]*mRes*magCalibration[2] - magBias[2];
mx *= magScale[0];
my *= magScale[1];
mz *= magScale[2];
}
for(uint8_t i = 0; i < 40; i++) { // iterate a fixed number of times per data read cycle
Now = micros();
deltat = ((Now - lastUpdate)/1000000.0f); // set integration time by time elapsed since last filter update
lastUpdate = Now;
sum += deltat; // sum for averaging filter update rate
sumCount++;
MadgwickQuaternionUpdate(-ax, ay, az, gx*pi/180.0f, -gy*pi/180.0f, -gz*pi/180.0f, my, -mx, mz);
}
tstop = micros();
deltat1 = ((tstop - tstart)); // set integration time by time elapsed since last filter update
sum1 += deltat1; // sum for averaging filter update rate
sumCount1++;
if(sumCount1 == 1000){
Serial.println("Filter Timing:");
Serial.print(sumCount1); Serial.print(", "); Serial.println(sum1);
Serial.println("Avg us: "); Serial.println(sum1/sumCount1);
Serial.println();
sum1 = 0;
sumCount1 = 0;
}
}
1050
Reg interrupt
400khz ----- 634 us
1000khz ----- 304 us
with interrupt pin
400khz ----- xxx us
1000khz ----- 124 us
T3.5
Reg interrupt
400khz ----- 1074 us
1000khz ----- 682 us
interrupt pin
400khz ==== 958 us
1000khz ==== 621 us
My GPS PPS test used pin interrupts (albeit only one tick per second), and it worked fine on EVKB.Interrupts just don't seem to work properly on the mbed side
mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS); //? need this with ISR
//if (mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS) & 0x01) {
if(isrPin.read() == 1) {
newData=false;
//mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS); //? need this with ISR
mpu9250.readMPU9250Data(MPU9250Data); // INT cleared on any read
Reg interrupt
400khz ----- 634 us
1000khz ----- 304 us
with interrupt pin
400khz ----- 572 us
1000khz ----- 247 us
1050
If I change the way the interrupt works by reading it directly I get at 400k
[CODE]average rate = 1751.004395
Error: "MPU9250::MPU9250(mbed::I2C &, std::uint8_t)" provides no initializer for in "MPU9250/MPU9250.cpp", Line: 28, Col: 2
class MPU9250{
public:
MPU9250(I2C &i2c, uint8_t addr);
~MPU9250(); …...
MPU9250::MPU9250(I2C &i2c, uint8_t addr)
{
_i2c = &i2c;
_address = addr << 1;
_useSPI = false; // set to use I2C
}
I2C with the MPU9250 still driving me a little on the crazy side but don't think its an i2c issue. Over the last day or so did a modification of the code to see how many times the interrupt fired per 1000 loop cycles and got some very strange and disturbing results:
1. For both 400k and 1000khz i2c frequency it was showing only 8 or 9 interrupt firings using the polling method
2. If I switched over to a pin interrupt it increased to 12 and 27 respectfully
3. If I did the same measurement on the T3.5 it was only showing about 2 hits for any method and frequency
4. On the Teensy 3.5 I used the same timing measurements but using Brian Taylors library and it showed that for every 1000 cycles the pin interrupt fired 1000 times and the update rates made a heck of a lot more sense to me.
I started the process of porting over the library to the mbed side but getting an error that I just can't figure out and can't seem to find anything on in a google search. Error message ==>Code:Error: "MPU9250::MPU9250(mbed::I2C &, std::uint8_t)" provides no initializer for in "MPU9250/MPU9250.cpp", Line: 28, Col: 2
In the .h file I have:
Code:class MPU9250{ public: MPU9250(I2C &i2c, uint8_t addr); ~MPU9250(); …...
on the .cpp file:
Code:MPU9250::MPU9250(I2C &i2c, uint8_t addr) { _i2c = &i2c; _address = addr << 1; _useSPI = false; // set to use I2C }
If you have an ideas please let me know.
Yep. This is the way I have it set up:Are you initializing the MBED I2C class that you're passing to the MPU9250 library
//Set up I2C, (SDA,SCL)
I2C i2c(A4, A5);
//MPU9250 Imu(A4, A5); // SDA, SCL
MPU9250 Imu(i2c, 0x68);
how is I2C defined as the private variable in the h file?
// i2c
I2C *_i2c;
uint8_t _address;
I think I got it set up correctly - going to put a couple of printf's to make sure of it later.Is it an issue getting the MPU-9250 interrupt setup to fire at the correct rate or an issue getting the NXP 1050 to recognize the interrupt?
Hmm. The difference in the version I am using is this single line when using the interrupt, I am also using d2 instead of D12:
Code:mpu9250.readByte(MPU9250_ADDRESS, INT_STATUS); //? need this with ISR
With running the filter 10x per Onehorse's recommendation:
I2C SRD Avg Rate
100k 200hz 1961hz
400k 200hz 1967hz
1000k 200hz 1971hz
1000k 500hz 4903hz
stack ext constant &fcn
ARM gcc 81dfe3b0 80000000 60007f18 60007ec1 mbed online
gnu gcc 2001ffb8 200014ac 600079dc 6000335d mcuxpresso
gnu gcc 2001ffb8 200077cc 200059bc 20001351 mcuxpresso with "link to RAM"
gnu gcc 81dfffec 80000ae0 6000ce48 60002ccd mbed export
ref ch 2
8000_0000 DFFF_FFFF 1.5GB RAM
6000_0000 7F7F_FFFF 504MB flexSPI ch 30 hyperflash boot
2000_0000 2007_FFFF 512KB DTCM flexRAM
TCM tightly coupled memory fast mode 1 cycle, else 2 cycle ch 29
SEMC SDRAM 32 bit Data Write and Read Compare Start!
SEMC SDRAM 32 bit Data Write and Read Compare Succeed!
32 bit Write Clock Cycles == > 14977467
SEMC SDRAM Memory 16 bit Write Start, Start Address 0x80000000, Data Length 4096 !
SEMC SDRAM Read 16 bit Data Start, Start Address 0x80000000, Data Length 4096 !
SEMC SDRAM 16 bit Data Write and Read Compare Start!
SEMC SDRAM 16 bit Data Write and Read Compare Succeed!
16 bit Write Clock Cycles == > 15011582
SEMC SDRAM Memory 8 bit Write Start, Start Address 0x80000000, Data Length 4096 !
SEMC SDRAM Read 8 bit Data Start, Start Address 0x80000000, Data Length 4096 !
SEMC SDRAM 8 bit Data Write and Read Compare Start!
SEMC SDRAM 8 bit Data Write and Read Compare Succeed!
8 bit Write Clock Cycles == > 14767014
SEMC SDRAM Example End.