2016-04-20 11:51 PM
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}