cancel
Showing results for 
Search instead for 
Did you mean: 

I2C checkevent hang

luke2
Associate II
Posted on April 21, 2016 at 08:51

Hi all,

I am writing a program on the STM32F446 in which I am trying to talk with a PCM sound module via I2C. I am attempting to read its registers, which involves sending the register number and then reading the value back. Unfortunately my program cannot get past the sending of the register request as it seems to be hanging whilst waiting for I2C_EVENT_MASTER_BYTE_TRANSMITTED event to occur. Looking at the scope everything appears to be fine - the module acknowledges its address, my program sends the byte to indicate the register to read, then the module holds data low to acknowledge the byte, however my program does not seem to pick up the successful transfer of the byte and hangs on the while condition. My code is below... when calling I2C_readreg() we successfully start the transaction and then call I2C_write(), in which we hang on

  while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

So apparently byte transmission event is never being acknowledge, even though the scope shows that it has been put onto the line. Does anybody have any ideas what could be going wrong here?

void I2C_init(void) {

I2C_InitTypeDef  I2C_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // I2C CLK

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//NOPULL;

GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // I2C DATA

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//NOPULL;

GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C_CLK);

GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_I2C_DATA);

    //Reset

    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);

    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);

I2C_InitStructure.I2C_ClockSpeed = 250000;

I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

    I2C_InitStructure.I2C_OwnAddress1 = 0x00;

    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_Init(I2C2, &I2C_InitStructure);

    I2C_Cmd(I2C2, ENABLE);

}

void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction) {

// wait until I2C1 is not busy anymore

while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));

// Send I2C1 START condition

I2C_GenerateSTART(I2Cx, ENABLE);

// wait for I2C1 EV5 --> Slave has acknowledged start condition

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

// Send slave Address for write

I2C_Send7bitAddress(I2Cx, address, direction);

/* wait for I2C1 EV6, check if

* either Slave has acknowledged Master transmitter or

* Master receiver mode, depending on the transmission

* direction

*/

if(direction == I2C_Direction_Transmitter){

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

}

else if(direction == I2C_Direction_Receiver){

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

}

}

void I2C_write(I2C_TypeDef* I2Cx, uint8_t data)

{

I2C_SendData(I2Cx, data);

// wait for I2C1 EV8_2 --> byte has been transmitted

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

//while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));

}

void I2C_readreg() {

uint8_t received_data[2];

I2C_start(I2C2, RTC_address, I2C_Direction_Transmitter); 

I2C_write(I2C2, 0x12); // register

//PROGRAM HANGS IN THIS WRITE

I2C_start(I2C2, RTC_address, I2C_Direction_Receiver); // start a transmission in Master receiver mode

//received_data[0] = I2C_read_ack(I2C2); // read one byte and request another byte

received_data[0] = I2C_read_nack(I2C2); // read one byte and don't request another byte, stop transmission

I2C_stop(I2C2); // stop the transmission

}

0 REPLIES 0