Hi,
I'm using a MPU9250 and porting the Sensor fusion on a Corex M0.
I used SPI to read and write in MPU9250 registers.
I have an error when I load the dmp firmware.
At the starting address 0x6F, I write the first 16 unsigned char : 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00.
Just after writting, I read and I get : 0x00, 0x00, 0x70, 0x2, 0x00, 0x0B, 0x71, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00.
I suppose I am not writting in dmp memory_r_w correctly.
Is there any specific configuration to do before writting in this memory?
Best regards
- Log in to post comments
phpbb Topic ID
16455
Re: Re: DMP load
Hi,
Please find the attached code snippet for loading DMP firmware.
/**
* @brief Load and verify DMP image.
* @param[in] length Length of DMP image.
* @param[in] firmware DMP code.
* @param[in] start_addr Starting address of DMP code memory.
* @param[in] sample_rate Fixed sampling rate used when DMP is enabled.
* @return 0 if successful.
*/
int mpu_load_firmware(unsigned short length, const unsigned char *firmware,
unsigned short start_addr, unsigned short sample_rate)
{
unsigned short ii;
unsigned short this_write;
/* Must divide evenly into st.hw->bank_size to avoid bank crossings. */
#define LOAD_CHUNK (16)
unsigned char cur[LOAD_CHUNK], tmp[2];
if (st.chip_cfg.dmp_loaded)
/* DMP should only be loaded once. */
return -1;
if (!firmware)
return -1;
for (ii = 0; ii < length; ii += this_write) {
this_write = min(LOAD_CHUNK, length - ii);
if (mpu_write_mem(ii, this_write, (unsigned char*)&firmware[ii]))
return -1;
if (mpu_read_mem(ii, this_write, cur))
return -1;
if (memcmp(firmware+ii, cur, this_write))
return -2;
}
/* Set program start address. */
tmp[0] = start_addr >> 8;
tmp[1] = start_addr & 0xFF;
if (i2c_write(st.hw->addr, st.reg->prgm_start_h, 2, tmp))
return -1;
st.chip_cfg.dmp_loaded = 1;
st.chip_cfg.dmp_sample_rate = sample_rate;
return 0;
}
/**
* @brief Write to the DMP memory.
* This function prevents I2C writes past the bank boundaries. The DMP memory
* is only accessible when the chip is awake.
* @param[in] mem_addr Memory location (bank << 8 | start address)
* @param[in] length Number of bytes to write.
* @param[in] data Bytes to write to memory.
* @return 0 if successful.
*/
int mpu_write_mem(unsigned short mem_addr, unsigned short length,
unsigned char *data)
{
unsigned char tmp[2];
if (!data)
return -1;
if (!st.chip_cfg.sensors)
return -1;
tmp[0] = (unsigned char)(mem_addr >> 8);
tmp[1] = (unsigned char)(mem_addr & 0xFF);
/* Check bank boundaries. */
if (tmp[1] + length > st.hw->bank_size)
return -1;
if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp))
return -1;
if (i2c_write(st.hw->addr, st.reg->mem_r_w, length, data))
return -1;
return 0;
}
/**
* @brief Read from the DMP memory.
* This function prevents I2C reads past the bank boundaries. The DMP memory
* is only accessible when the chip is awake.
* @param[in] mem_addr Memory location (bank << 8 | start address)
* @param[in] length Number of bytes to read.
* @param[out] data Bytes read from memory.
* @return 0 if successful.
*/
int mpu_read_mem(unsigned short mem_addr, unsigned short length,
unsigned char *data)
{
unsigned char tmp[2];
if (!data)
return -1;
if (!st.chip_cfg.sensors)
return -1;
tmp[0] = (unsigned char)(mem_addr >> 8);
tmp[1] = (unsigned char)(mem_addr & 0xFF);
/* Check bank boundaries. */
if (tmp[1] + length > st.hw->bank_size)
return -1;
if (i2c_write(st.hw->addr, st.reg->bank_sel, 2, tmp))
return -1;
if (i2c_read(st.hw->addr, st.reg->mem_r_w, length, data))
return -1;
return 0;
}
Re: Re: DMP load
I use SPI to write and read in mpu registers.
Here is my mpu_write_mem function
int mpu_write_mem(unsigned short mem_addr, unsigned short length,unsigned char *data)
{
unsigned char tmp[2];
int i;
if (!data)
return -1;
if (!st.chip_cfg.sensors)
return -1;
tmp[0] = (unsigned char)(mem_addr >> 8);
tmp[1] = (unsigned char)(mem_addr & 0xFF);
/* Check bank boundaries. */
if (tmp[1] + length > st.hw->bank_size)
return -1;
MPU9250writeRegister(BANK_SEL,tmp[0]);
MPU9250writeRegister(BANK_SEL+1,tmp[1]);
for(i=0;i<length;i++)
{
MPU9250writeRegister(MEM_R_W,data);
}
return 0;
}
I get no error when I load dmp. But when I read back features I get feature_mask=0 and fifo is empty. I guess there is a configuration issue.
Is my write memory function OK?
Thanks in advance.
Re: Re: DMP load
Function looks OK. Below is the code snippet to initialize and setup DMP, please refer to motion driver for more.
result = mpu_init(&int_param);
if (result)
msp430_reset();
/* If you're not using an MPU9150 AND you're not using DMP features, this
* function will place all slaves on the primary bus.
* mpu_set_bypass(1);
*/
/* Get/set hardware configuration. Start gyro. */
/* Wake up all sensors. */
mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL);
/* Push both gyro and accel data into the FIFO. */
mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL);
mpu_set_sample_rate(DEFAULT_MPU_HZ);
/* Read back configuration in case it was set improperly. */
mpu_get_sample_rate(&gyro_rate);
mpu_get_gyro_fsr(&gyro_fsr);
mpu_get_accel_fsr(&accel_fsr);
/* Initialize HAL state variables. */
memset(&hal, 0, sizeof(hal));
hal.sensors = ACCEL_ON | GYRO_ON;
hal.report = PRINT_QUAT;
/* To initialize the DMP:
* 1. Call dmp_load_motion_driver_firmware(). This pushes the DMP image in
* inv_mpu_dmp_motion_driver.h into the MPU memory.
* 2. Push the gyro and accel orientation matrix to the DMP.
* 3. Register gesture callbacks. Don't worry, these callbacks won't be
* executed unless the corresponding feature is enabled.
* 4. Call dmp_enable_feature(mask) to enable different features.
* 5. Call dmp_set_fifo_rate(freq) to select a DMP output rate.
* 6. Call any feature-specific control functions.
*
* To enable the DMP, just call mpu_set_dmp_state(1). This function can
* be called repeatedly to enable and disable the DMP at runtime.
*
* The following is a short summary of the features supported in the DMP
* image provided in inv_mpu_dmp_motion_driver.c:
* DMP_FEATURE_LP_QUAT: Generate a gyro-only quaternion on the DMP at
* 200Hz. Integrating the gyro data at higher rates reduces numerical
* errors (compared to integration on the MCU at a lower sampling rate).
* DMP_FEATURE_6X_LP_QUAT: Generate a gyro/accel quaternion on the DMP at
* 200Hz. Cannot be used in combination with DMP_FEATURE_LP_QUAT.
* DMP_FEATURE_TAP: Detect taps along the X, Y, and Z axes.
* DMP_FEATURE_ANDROID_ORIENT: Google's screen rotation algorithm. Triggers
* an event at the four orientations where the screen should rotate.
* DMP_FEATURE_GYRO_CAL: Calibrates the gyro data after eight seconds of
* no motion.
* DMP_FEATURE_SEND_RAW_ACCEL: Add raw accelerometer data to the FIFO.
* DMP_FEATURE_SEND_RAW_GYRO: Add raw gyro data to the FIFO.
* DMP_FEATURE_SEND_CAL_GYRO: Add calibrated gyro data to the FIFO. Cannot
* be used in combination with DMP_FEATURE_SEND_RAW_GYRO.
*/
dmp_load_motion_driver_firmware();
dmp_set_orientation(
inv_orientation_matrix_to_scalar(gyro_orientation));
dmp_register_tap_cb(tap_cb);
dmp_register_android_orient_cb(android_orient_cb);
hal.dmp_features = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
DMP_FEATURE_GYRO_CAL;
dmp_enable_feature(hal.dmp_features);
dmp_set_fifo_rate(DEFAULT_MPU_HZ);
mpu_set_dmp_state(1);
hal.dmp_on = 1;
__enable_interrupt();
Hi,
I'm using dmp with Intel Edison MCU SDK !
I follow your steps to setting the DMP !
However, the
dmp_set_orientation(~)seem to no effect on "accelerometer" ! I setgyro_orientation ={1,0,0 ,0,-1,0 ,0,0,-1}Its "accelerometer" result is same as that I set
gyro_orientation={1,0,0,0,1,0,0,0,1}I also refer the doc
Has dmp_set_orientation() function effect on "accelerometer"?
Would you have any idea?
Thank you very much!
please has anyone a Response to the orientation Matrix???
thanks.
Daniel.