cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f103 I2C_EVENT_MASTER_BYTE_RECEIVED IRQ problem

Posted on November 18, 2012 at 08:16

Hi,

I try to use IRQ to read data from MPU 6050, but eventI2C_EVENT_MASTER_BYTE_RECEIVED is never trigered. The interrupt code looks like following

void
I2C1_EV_IRQHandler(
void
)
{
volatile
static
uint8_t first_I2C_EVENT_MASTER_BYTE_TRANSMITTED = 1;
uint32_t event = ( (uint32_t)(I2C1->SR1) | (uint32_t)(I2C1->SR2)<<16 ) & 0x00FFFFFF;
if
(gv_evlog_pointer < 63)
{
gv_evlog[gv_evlog_pointer++] = event;
}
switch
(event)
{
case
I2C_EVENT_MASTER_MODE_SELECT: 
// EV5
first_I2C_EVENT_MASTER_BYTE_TRANSMITTED = 1;
if
( gv_i2c1_phase == I2C_PHASE_REG_NUMBER_SENT )
{
// sending addres and set reciver mode
I2C_Send7bitAddress(MPU6050_I2C_DEV, MPU6050_I2C_ADDRESS, I2C_Direction_Receiver);
}
else
{
// sending addres and set transmiter mode
I2C_Send7bitAddress(MPU6050_I2C_DEV, MPU6050_I2C_ADDRESS, I2C_Direction_Transmitter);
}
break
;
case
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED: 
// EV6
/* Clear EV6 by setting again the PE bit */
I2C_Cmd(MPU6050_I2C_DEV, ENABLE);
// sending register number
I2C_SendData(MPU6050_I2C_DEV, gv_i2c1_reg);
gv_i2c1_phase = I2C_PHASE_REG_NUMBER_SENT;
break
;
case
I2C_EVENT_MASTER_BYTE_TRANSMITTED: 
// EV8
if
(first_I2C_EVENT_MASTER_BYTE_TRANSMITTED == 1)
// restart for slave transmistion
I2C_GenerateSTART(MPU6050_I2C_DEV, ENABLE);
first_I2C_EVENT_MASTER_BYTE_TRANSMITTED = 0;
break
;
case
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED: 
// EV 6
// disable acknowledge
I2C_AcknowledgeConfig(MPU6050_I2C_DEV, DISABLE);
/* Send STOP Condition */
I2C_GenerateSTOP(MPU6050_I2C_DEV, ENABLE);
break
;
case
I2C_EVENT_MASTER_BYTE_RECEIVED: 
// EV 7
gv_i2c1_reg_val = I2C_ReceiveData(MPU6050_I2C_DEV);
// generate stop
I2C_GenerateSTOP(MPU6050_I2C_DEV, ENABLE);
// turn on acknowlage
I2C_AcknowledgeConfig(MPU6050_I2C_DEV, ENABLE);
gv_i2c1_phase = I2C_PHASE_BYTE_RECIVED;
I2C_ITConfig(MPU6050_I2C_DEV, I2C_IT_EVT, DISABLE);
break
;
default
:
// test
qconsole_led_blink(QCONSOLE_LED_B1, QCONSOLE_LED_SPEED_FAST, 10);
break
;
}
}

The read register function is

uint8_t qmpu6050_read_register_irq(uint8_t reg, uint8_t * val)
{
uint32_t event;
printf
(
''qmpu6050_read_register_irq\n\r''
);
// wait for i2c device
//while (I2C_GetFlagStatus(MPU6050_I2C_DEV, I2C_FLAG_BUSY));
while
( ( event = qmpu6050_get_event_flags() ) & I2C_FLAG_BUSY )
{
printf
(
''I2C_FLAG_BUSY %x\n\r''
, event);
}
// store data to global variables
gv_i2c1_reg = reg;
gv_i2c1_phase = I2C_PHASE_DEVICE_READY;
gv_evlog_pointer = 0;
memset
(gv_evlog, 0, 64);
I2C_ITConfig(MPU6050_I2C_DEV, I2C_IT_EVT, ENABLE);
//transmision start
I2C_GenerateSTART(MPU6050_I2C_DEV, ENABLE);
delay_ms(500);
for
(
int
i=0; i < 64; i++)
{
printf
(
''Event no %d = %x\n\r''
, i, gv_evlog[i]);
}
while
(gv_i2c1_phase != I2C_PHASE_BYTE_RECIVED)
{
// printf(''Wait for BYTE_RECIVED_PHASE %x Event=%x\n\r'', gv_i2c1_phase, gv_event);
}
* val = gv_i2c1_reg_val;
return
QMPU6050_RET_OK;
}

Thegv_evlog variable contains following entries Event no 0 = 30001 I2C_EVENT_MASTER_MODE_SELECT Event no 1 = 70082 I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED Event no 2 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 3 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 4 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 5 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 6 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 7 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 8 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 9 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 10 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 11 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 12 = 70084 I2C_EVENT_MASTER_BYTE_TRANSMITTED Event no 13 = 30001 I2C_EVENT_MASTER_MODE_SELECT Event no 14 = 30002 I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED so, theI2C_EVENT_MASTER_BYTE_RECEIVED is never trigered :( Similar code using pooling working ok (except limitation described in errata).

uint8_t qmpu6050_read_register(uint8_t reg, uint8_t * val)
{
uint32_t event;
//while (I2C_GetFlagStatus(MPU6050_I2C_DEV, I2C_FLAG_BUSY));
while
( ( event = qmpu6050_get_event_flags() ) & I2C_FLAG_BUSY )
{
//printf(''I2C_FLAG_BUSY'');
}
//transmision start
I2C_GenerateSTART(MPU6050_I2C_DEV, ENABLE);
//wait for ev5
//while( !I2C_CheckEvent(MPU6050_I2C_DEV, I2C_EVENT_MASTER_MODE_SELECT))
while
( ( ( event = qmpu6050_get_event_flags() ) & I2C_EVENT_MASTER_MODE_SELECT ) != I2C_EVENT_MASTER_MODE_SELECT )
{
//printf(''I2C_EVENT_MASTER_MODE_SELECT %x\n\r'', event);
}
// send mpu6050 address
I2C_Send7bitAddress(MPU6050_I2C_DEV, MPU6050_I2C_ADDRESS, I2C_Direction_Transmitter);
// wait for ev6
//while( !I2C_CheckEvent(MPU6050_I2C_DEV, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
while
( ( ( event = qmpu6050_get_event_flags() ) & I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) != I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED )
{
//printf(''I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED %x\n\r'', event);
}
/* Clear EV6 by setting again the PE bit */
I2C_Cmd(MPU6050_I2C_DEV, ENABLE);
// send register no
I2C_SendData(MPU6050_I2C_DEV, reg);
// wait for ev8
//while( !I2C_CheckEvent(MPU6050_I2C_DEV, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
while
( ( ( event = qmpu6050_get_event_flags() ) & I2C_EVENT_MASTER_BYTE_TRANSMITTED ) != I2C_EVENT_MASTER_BYTE_TRANSMITTED )
{
//printf(''I2C_EVENT_MASTER_BYTE_TRANSMITTED %x\n\r'', event);
}
// send restart for starting slave transmision
I2C_GenerateSTART(MPU6050_I2C_DEV, ENABLE);
//wait for ev5
//while( !I2C_CheckEvent(MPU6050_I2C_DEV, I2C_EVENT_MASTER_MODE_SELECT))
while
( ( ( event = qmpu6050_get_event_flags() ) & I2C_EVENT_MASTER_MODE_SELECT) != I2C_EVENT_MASTER_MODE_SELECT)
{
//printf('' I2C_EVENT_MASTER_MODE_SELECT %x\n\r'', event);
}
// send mpu6050 address
I2C_Send7bitAddress(MPU6050_I2C_DEV, MPU6050_I2C_ADDRESS, I2C_Direction_Receiver);
// wait for ev6
//while( !I2C_CheckEvent(MPU6050_I2C_DEV, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
while
( ( ( event = qmpu6050_get_event_flags() ) & I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) != I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED )
{
//printf(''I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED %x\n\r'', event);
}
// disable acknowledge
I2C_AcknowledgeConfig(MPU6050_I2C_DEV, DISABLE);
/* Send STOP Condition */
I2C_GenerateSTOP(MPU6050_I2C_DEV, ENABLE);
//wait for ev7
//while( !I2C_CheckEvent(MPU6050_I2C_DEV, I2C_EVENT_MASTER_BYTE_RECEIVED))
while
( ( ( event = qmpu6050_get_event_flags() ) & I2C_EVENT_MASTER_BYTE_RECEIVED ) != I2C_EVENT_MASTER_BYTE_RECEIVED )
{
//printf(''I2C_EVENT_MASTER_BYTE_RECEIVED %x\n\r'', event);
}
// get byte
* val = I2C_ReceiveData(MPU6050_I2C_DEV);
// generate stop
I2C_GenerateSTOP(MPU6050_I2C_DEV, ENABLE);
// turn on acknowlage
I2C_AcknowledgeConfig(MPU6050_I2C_DEV, ENABLE);
return
QMPU6050_RET_OK;
}

What am i doing wrong? 🙂 Thank you in advance Krzysiek PS This is i2c transfer, and it looks quite good 0690X000006052BQAQ.png #i2c #stm32-irq-i2c-problem #i2c
3 REPLIES 3
jpeacock2399
Associate II
Posted on November 19, 2012 at 15:58

It looks like the only problem you have in your code is following the ST polled example, trying to move it to IRQ.  The trick is that is on EV7 and EV8 events you need to take the BTF flag into consideration.  After getting the event you need to mask the BTF flag in the event code.  In effect there are two EV7 and EV8 events, with or without BTF flag set.

  Jack Peacock
Posted on November 19, 2012 at 16:16

Hi Jack,

Thanks for replay.

Do you mean i should simply clear BTF bit in case of  I2C_EVENT_MASTER_BYTE_TRANSMITTED ?

The next question is why i got several times I2C_EVENT_MASTER_BYTE_TRANSMITTED 0x00070084(BTF = 1)  instead of I2C_EVENT_MASTER_BYTE_TRANSMITTING  0x00070080(BTF = 0

Regards

Krzysiek

Posted on November 19, 2012 at 22:22

Hi,

Problem solved, i forgot to enable buf interrupt in cr2. Now i need to play with irq routine to limit nubers of interrupts....

thank kyou again

krzysiek