โ02-22-2021 12:51 AM
Hello,
I use BMX 055 with 12MHz MCU (Lpc1343 Cortex-M3) and get data through I2C. I2C is set to 100kHz.
When I read first frame of data from gyroscope with FIFO queue data for X and Y axises seems reasonable (a sensor lies still on a desk), but data for Z axis sometimes is ok and sometimes has value -32768 (0x8000).
After first frame data for all axises has value -32768. What is the reason?
#include "LPC13xx.h"
#include <cr_section_macros.h>
#define POWER_ON_IOCON (0x1 << 16)
#define DEASSERT_I2C_RESET (0x1 << 1)
#define POWER_ON_I2C (0x1 << 5)
#define PIO0_4_FUNC_I2C_SCL (0x1 << 0)
#define PIO0_5_FUNC_I2C_SDA (0x1 << 0)
#define I2C_ENABLE (0x1 << 6)
#define I2C_SCL_HIGH_TIME (60 << 0)
#define I2C_SCL_LOW_TIME (60 << 0)
#define I2C_START_BIT (0x1 << 5)
#define I2C_STOP_BIT (0x1 << 4)
#define I2C_ACK_BIT (0x1 << 2)
#define I2C_SI_BIT (0x1 << 3)
#define I2C_SIC_BIT I2C_SI_BIT
#define ACC_BUFFER_SIZE 6
int16_t x,y,z;
float fx, fy, fz;
unsigned char i = 0;
int stop = 1, idx;
char buffer[ACC_BUFFER_SIZE];
int main(void) {
LPC_SYSCON->PRESETCTRL |= DEASSERT_I2C_RESET;
LPC_SYSCON->SYSAHBCLKCTRL |= POWER_ON_I2C | POWER_ON_IOCON;
LPC_IOCON->PIO0_4 |= PIO0_4_FUNC_I2C_SCL;
LPC_IOCON->PIO0_5 |= PIO0_5_FUNC_I2C_SDA;
NVIC_EnableIRQ(I2C_IRQn);
LPC_I2C->CONSET |= I2C_ENABLE;
LPC_I2C->SCLH = I2C_SCL_HIGH_TIME;
LPC_I2C->SCLL = I2C_SCL_LOW_TIME;
// Enter an infinite loop, just incrementing a counter
while(1) {
if (stop == 1) {
stop = 0;
// answer with ACK
LPC_I2C->CONSET |= I2C_ACK_BIT;
LPC_I2C->CONSET |= I2C_START_BIT;
}
// "Dummy" NOP to allow source level single
// stepping of tight while() loop
__asm volatile ("nop");
}
return 0 ;
}
void processGyroData() {
x = (int16_t) (((int16_t)buffer[1] << ๐ | buffer[0]);
y = (int16_t) (((int16_t)buffer[3] << ๐ | buffer[2]);
z = (int16_t) (((int16_t)buffer[5] << ๐ | buffer[4]);
}
void I2C_IRQHandler(void) {
volatile unsigned int statusCode = LPC_I2C->STAT;
switch(statusCode) {
case 0x08:
//address of gyro
LPC_I2C->DAT = 0x68 << 1;
// start condition on bus
LPC_I2C->CONCLR = I2C_START_BIT;
break;
case 0x18: //SLA+W has been transmitted; ACK has been received.
// read register at address 0x3F (FIFO)
LPC_I2C->DAT = 0x3F;
break;
case 0x20: // SLA+W has been transmitted; NOT ACK has been received.
case 0x28: // Data byte in I2DAT has been transmitted; ACK has been received.
LPC_I2C->CONSET = I2C_START_BIT;
break;
case 0x10: // A Repeated START condition has been transmitted.
LPC_I2C->CONCLR = I2C_START_BIT;
LPC_I2C->DAT = (0x68 << 1) | 1;
break;
case 0x40:
break;
case 0x50:
idx = i % ACC_BUFFER_SIZE;
buffer[idx] = LPC_I2C->DAT;
if (idx == ACC_BUFFER_SIZE - 1) {
processGyroData();
__asm volatile ("nop");
}
i++;
break;
case 0x58:
LPC_I2C->CONSET = I2C_STOP_BIT;
stop = 1;
break;
default:
break;
}
LPC_I2C->CONCLR = I2C_SIC_BIT;
}
โ03-13-2021 10:47 PM
The IC was broken. After replacing corrupted sensor with the new one I do not have to do any additional configuration or clearing FIFO buffer first in order to read data from FIFO buffer. FIFO reading works by default after power up. The only thing that needs to be changed (in order to read data from gyro in a FIFO way) is to set FIFO register address as the one that you want to read from.
โ03-18-2021 07:16 AM
Hi,
Thanks for your feedback. I'm glad that you find the issue.
Recommend you read BMI160-FIFO-Advanced-Usage . It's usefull for you use FIFO.
Best regards.