AnsweredAssumed Answered

STM32L152 I2C communication with LCD (NHD-C0220BiZ)

Question asked by dor.c on Feb 12, 2014
Latest reply on Feb 24, 2014 by sung.chen_chung
Hello,

I'm trying to interface the STM32L152 Discovery with an LCD display (NHD-C0220BiZ-FSW-FBW-3V3M) through I2C. I'm finding a problem when trying to write the first command to the LCD the code gets stuck on the EV6 check:
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

From the LCD I have SDA connected to PB7 and SCL connected to PB6. This lines have 4.7K pull up resistors connected to them. 

Any ideas why this is happening?

The I2C driver's code is the following:
void i2c_init(void)
{
   
    GPIO_InitTypeDef  GPIO_InitStructure;
    // NVIC_InitTypeDef NVIC_InitStructure;
  I2C_InitTypeDef  I2C_InitStructure;
 
        //I2C_DeInit(I2Cx);
         
    /*!< I2C Periph clock enable */
    RCC_APB1PeriphClockCmd(I2Cx_CLK, ENABLE);
     
    /*!< SDA GPIO clock enable */
    RCC_AHBPeriphClockCmd(I2Cx_SDA_GPIO_CLK, ENABLE);
     
    /*!< SCL GPIO clock enable */
    RCC_AHBPeriphClockCmd(I2Cx_SCL_GPIO_CLK, ENABLE);
     
    /* Connect PXx to I2C_SCL */
    GPIO_PinAFConfig(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_SOURCE, GPIO_AF_I2C1);
     
    /* Connect PXx to I2C_SDA */
    GPIO_PinAFConfig(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_SOURCE, GPIO_AF_I2C1);
     
    /*!< Configure I2C SCL pin */
    GPIO_InitStructure.GPIO_Pin = I2Cx_SCL_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStructure);
     
    /*!< Configure I2C SDA pin */
    GPIO_InitStructure.GPIO_Pin = I2Cx_SDA_PIN;
    GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStructure);
     
    // /* Configure the I2C event priority */
    // NVIC_InitStructure.NVIC_IRQChannel = I2Cx_EV_IRQn;
    // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    // NVIC_Init(&NVIC_InitStructure);
     
    // /* Configure I2C error interrupt to have the higher priority */
    // NVIC_InitStructure.NVIC_IRQChannel = I2Cx_ER_IRQn;
    // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    // NVIC_Init(&NVIC_InitStructure);
     
    I2C_DeInit(I2Cx);
     
    /*!< I2C Struct Initialize */
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DUTYCYCLE;
    I2C_InitStructure.I2C_OwnAddress1 = 0x60;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED1;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
   
    /*!< I2C Initialize */
    I2C_Init(I2Cx, &I2C_InitStructure);
     
    // /* Enable Error Interrupt */
    // I2C_ITConfig(I2Cx, I2C_IT_ERR , ENABLE);
     
    /* I2C ENABLE */
    I2C_Cmd(I2Cx, ENABLE);
}
 
 
/*******************************************************************************
* Function Name  : I2C_ByteWrite
* Description    : write a Byte to I2C Bus
* Input          : deviceAddr is the I2C address of the device
*                  WriteAddr is the register address you want to write to
*                  pBuffer contains bytes to write
* Output         : None
* Return         : None
*******************************************************************************/
void I2C_ByteWrite(uint8_t pBuffer, uint8_t deviceAddress, uint8_t WriteAddr) {   
 
  /* 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, deviceAddress, 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 write to : only one byte Address */
  I2C_SendData(I2Cx, WriteAddr);
   
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
 
  /* Send the byte to be written */
  I2C_SendData(I2Cx, pBuffer);
    
  /* Test on EV8 and clear it */
  while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
   
  /* Send STOP condition */
  I2C_GenerateSTOP(I2Cx, ENABLE);
}

I call i2c_init(); successfully, the problem arises in the first I2C_ByteWrite inside the call to init_lcd();
This looks as follows:
void init_lcd(void)
{
   RESET_RST;             //RST = 0, reset
   delay(2);
   SET_RST;             //RST = 1, end reset
   
   delay(20);
    
   I2C_ByteWrite(FUNC_SET_TBL0, LCD_ADDR, 0x00);
   delay(10);
   I2C_ByteWrite(FUNC_SET_TBL1, LCD_ADDR, 0x00);
   delay(10);
   I2C_ByteWrite(BIAS, LCD_ADDR, 0x00); // Set BIAS - 1/5
   I2C_ByteWrite(CONTRAST, LCD_ADDR, 0x00); // Set contrast low byte
   I2C_ByteWrite(BOOSTER, LCD_ADDR, 0x00); // ICON disp on, Booster on, Contrast high byte
   I2C_ByteWrite(FOLLOWER, LCD_ADDR, 0x00); // Follower circuit (internal), amp ratio (6)
   I2C_ByteWrite(DISPLAY_ON, LCD_ADDR, 0x00); // Display on
   I2C_ByteWrite(CLEAR_DISPLAY, LCD_ADDR, 0x00); // Clear display
   I2C_ByteWrite(ENTRY_MODE, LCD_ADDR, 0x00); //Entry mode set - increment
    
    delay(10);
}

I would really appreciate any help and suggestions.

Thank you.

Outcomes