cancel
Showing results for 
Search instead for 
Did you mean: 

Polled I2C breaks with other interrupts

ibarnes
Associate
Posted on November 24, 2009 at 18:44

Polled I2C breaks with other interrupts

1 REPLY 1
ibarnes
Associate
Posted on May 17, 2011 at 13:31

Hello,

Using the StdPeriph_Lib_V3.1.2 and STM32F105R8. Clocked at 4MHz throughout, no PLL. Cut down the example code to do continuous reads from a Microchip 24LC04B.

When there are no interrupts, the code runs fine and reads indefinitely. The moment I enable an unrelated interrupt (for example SysTick that does nothing but return) it falls over at ''test on EV7''. Looking at the bus with a scope, there are no differences between any of the reads and writes - even when it hangs the bus returns to the idle state.

I realise that the code is not optimal and should have timeouts/recovery but I would like to get this sorted before I add those. I have attached the code below, does anyone have any ideas?

-----

#include ''stm32f10x.h''

void Eeprom_Config(I2C_TypeDef* I2Cx);

void Eeprom_Byte_Read(I2C_TypeDef* I2Cx, uint8_t *Data, uint16_t ReadAddr);

int main(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

uint8_t Index;

uint8_t Data;

/* System Clocks Configuration */

SystemInit();

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

/* Configure the GPIO ports */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;

GPIO_Init(GPIOB, &GPIO_InitStructure);

SysTick_Config(SystemFrequency_AHBClk / 1000);

Eeprom_Config(I2C2);

while (1)

{

Eeprom_Byte_Read(I2C2, &Data, 0x0);

for (Index = 0; Index < 50; Index ++) {};

}

}

void Eeprom_Config(I2C_TypeDef* I2Cx)

{

I2C_InitTypeDef I2C_InitStructure;

/* I2C configuration */

I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

I2C_InitStructure.I2C_OwnAddress1 = 0xA0;

I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

I2C_InitStructure.I2C_ClockSpeed = 400000;

/* I2C Peripheral Enable */

I2C_Cmd(I2Cx, ENABLE);

/* Apply I2C configuration after enabling it */

I2C_Init(I2Cx, &I2C_InitStructure);

}

void Eeprom_Byte_Read(I2C_TypeDef* I2Cx, uint8_t *Data, uint16_t ReadAddr)

{

/* While the bus is busy */

while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));

/* Send START condition */

I2C_GenerateSTART(I2Cx, ENABLE);

/* Test on EV5 and clear it */

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

/* Send EEPROM address for write */

I2C_Send7bitAddress(I2Cx, 0xA0, I2C_Direction_Transmitter);

/* Test on EV6 and clear it */

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

/* Send the EEPROM's internal address to read from: Only one byte address */

I2C_SendData(I2Cx, ReadAddr);

/* Test on EV8 and clear it */

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

/* Send START condition a second time */

I2C_GenerateSTART(I2Cx, ENABLE);

/* Test on EV5 and clear it */

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

/* Send EEPROM address for read */

I2C_Send7bitAddress(I2Cx, 0xA0, I2C_Direction_Receiver);

/* Test on EV6 and clear it */

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

/* Disable Acknowledgement */

I2C_AcknowledgeConfig(I2Cx, DISABLE);

/* Send STOP Condition */

I2C_GenerateSTOP(I2Cx, ENABLE);

/* Test on EV7 and clear it */

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));

/* Read a byte from the EEPROM */

*Data = I2C_ReceiveData(I2Cx);

/* Enable Acknowledgement to be ready for another reception */

I2C_AcknowledgeConfig(I2Cx, ENABLE);

}

void SysTick_Handler(void)

{

}