AnsweredAssumed Answered

STM32L Discovery I2C issue

Question asked by p.klemen on Dec 10, 2013
Latest reply on Dec 11, 2013 by p.klemen
Hello,

I have been searching online for some time now, but have been unable to find a solution to my problem:

I am using STM32L152 RC discovery board's I2C peripheral. I have found out that one combination of SCL and SDA is not working (the two LED's on the board go crazy for some reason). On the other pair I have successfully established (only partly) communication with the I2C device.
The I2C device is actually a device with 2 I2C addresses (0x50 and 0x60). One address is for the EEPROM of the device and the second addresses the RAM of the device (the measured data is deposited there).

The SCL and SDA lines have each a pullup resistor (4k7) and the VDD_I2C is connected to the VDD pin on the board (for some reason, this VDD is only round 3V instead of 3.3V? since I am using USB power. IS THE VOLTAGE TOO LOW?).

I will first post the relevant code and then explain what occurs when I try to communicate:

// INCLUDES
#include <stdio.h>
#include "stm32l1xx.h"
#include "main.h"
#include "stm32l_discovery_lcd.h"
#include "discover_functions.h"
#include "discover_board.h"
#include "stm32l1xx_i2c.h"
 
// DEFINITIONS
#define EEPROM_address_write    0xA0                                                                                    // I2C EEPROM address
#define EEPROM_address_read     0xA1
#define sensor_address_write    0xC0                                                                                    // I2C SENSOR address
#define sensor_address_read     0xC1
 
// DECLARATION OF FUNCTION PROTOTYPES
void Init_GPIO(void);                                                                                                           // Initialization of GPIO (general purpose IO)
void RCC_Configuration(void);                                                                                               // Initialization of RCC (real-time clock control)
void RTC_Configuration(void);                                                                                               // Initialization of RTC (real-time clock)
void RTC_TamperConfiguration(void);                                                
void Delay(__IO uint32_t nTime);                                                                                        // Delay function
void TimingDelay_Decrement(void);                                                                              
void Init_I2C2(void);                                                                                                               // I2C initialization and read
void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction);
void I2C_write(I2C_TypeDef* I2Cx, uint8_t data);
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx);
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx);
void I2C_stop(I2C_TypeDef* I2Cx);
 
// DECLARATION OF VARIABLES
RTC_InitTypeDef                 RTC_InitStructure;                                                                  // RTC Init TypeDef
RTC_TimeTypeDef                 RTC_TimeStruct;                                                                         // RTC Time Typedef        
static __IO uint32_t        TimingDelay;                                                                               
__IO uint16_t                   MillisecondTimer = 0;                                                               // Timing
extern uint8_t                  t_bar[2];                                                                                   // LCD bar graph
 
int16_t                                 iG;                                                                                                 // global loop index
uint8_t                                 *pD_g;                                                                                          // global uint8_t data pointer
uint8_t                                 EEPROM_[256];                                                                               // EEPROM calibration data
uint16_t                                REG_;                                                                                               // configuration register
 
// FUNCTION DECLARATION
 
// read EEPROM data
void EEPROM_read() {
    I2C_start(I2C2,EEPROM_address_write,I2C_Direction_Transmitter);
    I2C_write(I2C2,0x00);
    I2C_stop(I2C2);
    I2C_start(I2C2,EEPROM_address_read,I2C_Direction_Receiver);
    for(iG=0;iG<256;iG++) {
        EEPROM_[iG] = I2C_read_ack(I2C2);
    }
    I2C_stop(I2C2);
}
// write EEPROM data (one write per call)
void EEPROM_write(uint8_t address_, uint8_t value_) {
    I2C_start(I2C2,EEPROM_address_write,I2C_Direction_Transmitter);
    I2C_write(I2C2,address_);  
    I2C_write(I2C2,value_);
    I2C_stop(I2C2);
}
// read register
void REG_read() {  
    I2C_start(I2C2,sensor_address_write,I2C_Direction_Transmitter);
    I2C_write(I2C2,0x02);
    I2C_write(I2C2,0x92);
    I2C_write(I2C2,0x00);
    I2C_write(I2C2,0x01);
    I2C_stop(I2C2);
    I2C_start(I2C2,sensor_address_read,I2C_Direction_Receiver);
    // uint8_t pointer to REG_
    pD_g = (uint8_t*) REG_;
    (*pD_g) = I2C_read_ack(I2C2);
    pD_g++;
    (*pD_g) = I2C_read_ack(I2C2);
    I2C_stop(I2C2);
}
// set refresh rate of the sensor (returns refresh time in usec)
void REG_write(uint8_t sensor_refresh_rate_) {
    // address and command equal in all cases
    I2C_start(I2C2,sensor_address_write,I2C_Direction_Transmitter);
    I2C_write(I2C2,0x03);
    switch(sensor_refresh_rate_) {
    case 1:        
        I2C_write(I2C2,0x29);
        I2C_write(I2C2,0x7E);      
        break;
     
    case 8:    
        I2C_write(I2C2,0x26); 
        I2C_write(I2C2,0x7B);      
        break;
 
    case 16:           
        I2C_write(I2C2,0x25);
        I2C_write(I2C2,0x7A);      
        break;
     
    case 32:       
        I2C_write(I2C2,0x24); 
        I2C_write(I2C2,0x79);      
        break;
         
    case 64:                   
        I2C_write(I2C2,0x23); 
        I2C_write(I2C2,0x78);
        break;
 
    // 16Hz default
    default:                       
        I2C_write(I2C2,0x25);
        I2C_write(I2C2,0x7A);      
    }
    // MSB equal in all cases
    I2C_write(I2C2,0xAF); 
    I2C_write(I2C2,0x04);
    I2C_stop(I2C2);
}
 
// Get current time in seconds + second fraction (RTC_TimeStructure)
// pointer to a RTC_TimeTypeDef structure that contains the current time values
uint16_t RTC_MyTimer(RTC_TimeTypeDef *RTC_TimeStructure) {
    uint16_t SecondFraction = 0;
    uint16_t Second = 0;
    // Get seconds
    Second = (uint16_t) ((RTC_TimeStructure->RTC_Seconds)*1000);
    // Get second fraction
    SecondFraction = (uint16_t) (((256 - (uint32_t)RTC_GetSubSecond()) * 1000) / 256);
    // return time in milliseconds (seconds + second fraction) 
    return (Second + SecondFraction);
}
 
// i2c test
uint16_t received_data_Display[5];
 
//**********************************************************************************************//
                                                                                // MAIN
//**********************************************************************************************//                                 
/**
  * @brief   Main program
  * @param  None
  * @retval None
  */
int main(void)
{  
/*!< At this stage the microcontroller clock setting is already configured,
     this is done through SystemInit() function which is called from startup
     file (startup_stm32l1xx_md.s) before to branch to application main.
     To reconfigure the default setting of SystemInit() function, refer to
     system_stm32l1xx.c file
*/ 
    // RTC_TimeTypeDef structure
    RTC_TimeTypeDef  RTC_TimeStruct;
 
    // Configure Clocks for Application need
    RCC_Configuration();
    // Configure the RTC peripheral by selecting the clock source
    RTC_Configuration();
    // Configure the RTC tamper register : To Clear all the Backup data register
  RTC_TamperConfiguration();
     
    // SysTick 1 msec interrupts (1000 = 1ms, 100 = 10 ms ...)
  if(SysTick_Config(SystemCoreClock / 1000))
    {
        // capture error
        while(1);      
    }
     
    // Initialize I2C
    Init_I2C2();   
    REG_write(16);
    //EEPROM_write(0,209);
    // without delay, it does not work - why?????
    Delay(10);
    EEPROM_read();
    //REG_read();
             
    // Initialize GPIO
    Init_GPIO();   
    // Initialize LCD
    LCD_GLASS_Configure_GPIO();
    LCD_GLASS_Init();
    LCD_ContrastConfig(LCD_Contrast_Level_7);  
    // Initialize time Stucture
  RTC_TimeStructInit(&RTC_TimeStruct); 
 
    convert_into_char((uint32_t) REG_,received_data_Display);
    LCD_GLASS_DisplayStrDeci(received_data_Display);
    Delay(2000);
     
    // display I2C EEPROM data
    for(iG=0;iG<256;iG++) {
        convert_into_char((uint32_t) EEPROM_[iG],received_data_Display);
        LCD_GLASS_DisplayStrDeci(received_data_Display);
        Delay(10);
    }  
}
 
/**
  * @brief  Configures the different system clocks.
  * @param  None
  * @retval None
  */
void RCC_Configuration(void)
{  
    // Enable HSI Clock
  RCC_HSICmd(ENABLE);
   
    // Wait till HSI is ready
  while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) {}
 
    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
  
  RCC_MSIRangeConfig(RCC_MSIRange_6);
   
  // Enable the GPIOs Clock
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC| RCC_AHBPeriph_GPIOD| RCC_AHBPeriph_GPIOE| RCC_AHBPeriph_GPIOH, ENABLE);    
 
  // Enable comparator clock LCD and PWR mngt
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_COMP | RCC_APB1Periph_LCD | RCC_APB1Periph_PWR,ENABLE);
     
  // Enable ADC clock & SYSCFG
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_SYSCFG , ENABLE);
 
  // Allow access to the RTC
  PWR_RTCAccessCmd(ENABLE);
 
  // Reset Backup Domain
  RCC_RTCResetCmd(ENABLE);
  RCC_RTCResetCmd(DISABLE);
 
  // LSE Enable
  RCC_LSEConfig(RCC_LSE_ON);
 
  // Wait till LSE is ready
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {}
   
  RCC_RTCCLKCmd(ENABLE);
    
  // LCD Clock Source Selection
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
   
  RCC_HSEConfig(RCC_HSE_OFF);
   
  if(RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET )
  {
    while(1);
  }
}
 
/**
  * @brief  Configures the different RTC clocks.
  * @param  None
  * @retval None
  */
void RTC_Configuration(void)
    RTC_InitTypeDef RTC_InitStructure;
  RTC_TimeTypeDef  RTC_TimeStruct;
     
    // Enable the PWR clock
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
     
  // Allow access to the RTC
  PWR_RTCAccessCmd(ENABLE);
 
  // Reset Backup Domain
  RCC_RTCResetCmd(ENABLE);
  RCC_RTCResetCmd(DISABLE);
 
  // LSE Enable
  RCC_LSEConfig(RCC_LSE_ON);
 
  // Wait till LSE is ready
  while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  {
    
    
  // Select the RTC Clock Source
  RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
     
    // Configure the RTC data register and RTC prescaler
  RTC_InitStructure.RTC_AsynchPrediv = 0x7F;
  RTC_InitStructure.RTC_SynchPrediv  = 0xFF;
  RTC_InitStructure.RTC_HourFormat   = RTC_HourFormat_24;
  RTC_Init(&RTC_InitStructure);
   
  // Set the time to 00h 00mn 00s AM
  RTC_TimeStruct.RTC_H12     = RTC_H12_AM;
  RTC_TimeStruct.RTC_Hours   = 0x00;
  RTC_TimeStruct.RTC_Minutes = 0x00;
  RTC_TimeStruct.RTC_Seconds = 0x00
  RTC_SetTime(RTC_Format_BCD, &RTC_TimeStruct);
     
    // Enable the RTC Clock
    RCC_RTCCLKCmd(ENABLE);
     
    // Wait for RTC APB registers synchronisation
  RTC_WaitForSynchro();
}
 
/**
* @brief  RTC Tamper Configuration..
* @param  None
* @retval None
*/
void RTC_TamperConfiguration(void)
{
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
   
  // EXTI configuration
  EXTI_ClearITPendingBit(EXTI_Line19);
  EXTI_InitStructure.EXTI_Line = EXTI_Line19;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
   
  // Enable RTC_TAMP_STAMP_IRQn
  NVIC_InitStructure.NVIC_IRQChannel = TAMPER_STAMP_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
   
  // determines the number of active pulse for the specific level
  RTC_TamperFilterConfig(RTC_TamperFilter_2Sample);
   
  // Determines the frequency at which each of the tamper inputs are sampled
  RTC_TamperSamplingFreqConfig(RTC_TamperSamplingFreq_RTCCLK_Div32768);
   
  RTC_TamperPullUpCmd(DISABLE);
   
  // Select the tamper 1 with High level
  RTC_TamperTriggerConfig(RTC_Tamper_2, RTC_TamperTrigger_HighLevel );
   
  // Clear tamper 1 flag
  RTC_ClearFlag(RTC_FLAG_TAMP2F);
}
 
/**
  * @brief  To initialize the I/O ports
  * @caller main
  * @param None
  * @retval None
  */
void Init_GPIO(void)
{  
}
 
/**
  * @brief  To initialize the I2C ports
  * @caller main
  * @param None
  * @retval None
  */
void Init_I2C2(void){
     
    GPIO_InitTypeDef GPIO_InitStruct;
    I2C_InitTypeDef I2C_InitStruct;
     
    // Enable APB1 peripheral clock for I2C2
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);   
    // Enable clock for SCL and SDA pins
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
     
    // Setup SCL and SDA pins
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;                                   // using PB10 and PB11
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;                                                               // set pins to alternate function
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;                                                  // set GPIO speed
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;                                                         // set output to open drain --> the line has to be only pulled low, not driven high
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;                                                               // enable pull up resistors (disabled pullup = GPIO_PuPd_NOPULL, enabled pullup = GPIO_PuPd_UP)
    GPIO_Init(GPIOB, &GPIO_InitStruct);                                                                         // init GPIOB
     
    // Connect I2C2 pins to AF 
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);                                // SCL
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);                                // SDA
     
    // Configure I2C2
    I2C_InitStruct.I2C_ClockSpeed = 400000;                                                                 // 400kHz
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;                                                                 // I2C mode
    I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;                                                 // 50% duty cycle --> standard
    I2C_InitStruct.I2C_OwnAddress1 = 0x00;                                                                  // own address, not relevant in master mode
    I2C_InitStruct.I2C_Ack = I2C_Ack_Disable;                                                               // disable acknowledge when reading (can be changed later on)
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;  // set address length to 7 bit addresses
    I2C_Init(I2C2, &I2C_InitStruct);                                                                // init I2C2
     
    // Enable I2C2
    I2C_Cmd(I2C2, ENABLE); 
}
 
/**
  * @brief  To issue a start condition and transmit the slave address + R/W bit
  * @caller main
  * @param  I2C_TypeDef* I2Cx,
                        uint8_t address,
                        uint8_t direction
  * @retval None
  */
/* This function issues a start condition and
 * transmits the slave address + R/W bit
 *
 * Parameters:
 *      I2Cx --> the I2C peripheral e.g. I2C2
 *      address --> the 7 bit slave address
 *      direction --> the tranmission direction can be:
 *                      I2C_Direction_Tranmitter for Master transmitter mode
 *                      I2C_Direction_Receiver for Master receiver
 */
void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction){
     
    // Wait until I2C2 is not busy anymore
    while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
   
    // Send I2C2 START condition
    I2C_GenerateSTART(I2Cx, ENABLE);
       
    // Wait for I2C2 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 I2C2 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));
    }
}
 
/**
  * @brief  To transmit one byte to slave device
  * @caller main
  * @param  I2C_TypeDef* I2Cx,
                        uint8_t data                       
  * @retval None
  */
/* This function transmits one byte to the slave device
 * Parameters:
 *      I2Cx --> the I2C peripheral e.g. I2C2
 *      data --> the data byte to be transmitted
 */
void I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
{
    I2C_SendData(I2Cx, data);
    // wait for I2C2 EV8_2 --> byte has been transmitted
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
 
/**
  * @brief  To read one byte from slave device and Ack
  * @caller main
  * @param  I2C_TypeDef* I2Cx                                              
  * @retval data
  */
/* This function reads one byte from the slave device
 * and acknowledges the byte (requests another byte)
 */
uint8_t I2C_read_ack(I2C_TypeDef* I2Cx){
    // enable acknowledge of recieved data
    I2C_AcknowledgeConfig(I2Cx, ENABLE);
    // wait until one byte has been received
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));
    // read data from I2C data register and return data byte   
    return I2C_ReceiveData(I2Cx);  
}
 
/**
  * @brief  To read one byte from slave device and Nack
  * @caller main
  * @param  I2C_TypeDef* I2Cx                                              
  * @retval data
  */
/* This function reads one byte from the slave device
 * and doesn't acknowledge the recieved data
 */
uint8_t I2C_read_nack(I2C_TypeDef* I2Cx){
    // disabe acknowledge of received data
    // nack also generates stop condition after last byte received
    // see reference manual for more info
    I2C_AcknowledgeConfig(I2Cx, DISABLE);
    I2C_GenerateSTOP(I2Cx, ENABLE);
    // wait until one byte has been received
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));
    // read data from I2C data register and return data byte
    return I2C_ReceiveData(I2Cx);  
}
 
/**
  * @brief  To generate the stop condition and release the I2C bus
  * @caller main
  * @param  I2C_TypeDef* I2Cx                                              
  * @retval None
  */
/* This funtion issues a stop condition and therefore
 * releases the bus
 */
void I2C_stop(I2C_TypeDef* I2Cx){
    // Send I2C2 STOP Condition
    I2C_GenerateSTOP(I2Cx, ENABLE);
}
 
/**
  * @brief  Inserts a delay time.
  * @param  nTime: specifies the delay time length, in 1 ms.
  * @retval None
  */
void Delay(__IO uint32_t nTime)
{
    // delay 1000 ms introduces 2000 ms delay (don't know why)
    // to compensate for this, divide argument by 2
  TimingDelay = (uint32_t) nTime/2;
  while(TimingDelay != 0); 
}
 
/**
  * @brief  Decrements the TimingDelay variable.
  * @param  None
  * @retval None
  */
void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  {
    TimingDelay--;
  }
}
 
#ifdef  USE_FULL_ASSERT
 
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 
  // Infinite loop
  while (1)
  {
  }
}
 
#endif

First off, I have tested the device with an 8-bit AVR chip in the past and it worked.

In the code above I am trying to write and read some data to both slave devices on I2C.

Looking at the EEPROM_write function I am able to write the data to the EEPROM (address 0x50):

void EEPROM_write(uint8_t address_, uint8_t value_) {
    I2C_start(I2C2,EEPROM_address_write,I2C_Direction_Transmitter);
    I2C_write(I2C2,address_);  
    I2C_write(I2C2,value_);
    I2C_stop(I2C2);
}

and read it properly:

void EEPROM_read() {
    I2C_start(I2C2,EEPROM_address_write,I2C_Direction_Transmitter);
    I2C_write(I2C2,0x00);
    I2C_stop(I2C2);
    I2C_start(I2C2,EEPROM_address_read,I2C_Direction_Receiver);
    for(iG=0;iG<256;iG++) {
        EEPROM_[iG] = I2C_read_ack(I2C2);
    }
    I2C_stop(I2C2);
}

THE FIRST PROBLEM is that I have to stop the I2C bus in order to achieve repeated start. Removing theI2C_stop(I2C2); from the code above makes it unable to read from the device. Is this normal?

Looking at the REG_write function it seems I can also write to the device (this is the device with the other address, 0x60):

// set refresh rate of the sensor (returns refresh time in usec)
void REG_write(uint8_t sensor_refresh_rate_) {
    // address and command equal in all cases
    I2C_start(I2C2,sensor_address_write,I2C_Direction_Transmitter);
    I2C_write(I2C2,0x03);
    switch(sensor_refresh_rate_) {
    case 1:        
        I2C_write(I2C2,0x29);
        I2C_write(I2C2,0x7E);      
        break;
     
    case 8:    
        I2C_write(I2C2,0x26); 
        I2C_write(I2C2,0x7B);      
        break;
 
    case 16:           
        I2C_write(I2C2,0x25);
        I2C_write(I2C2,0x7A);      
        break;
     
    case 32:       
        I2C_write(I2C2,0x24); 
        I2C_write(I2C2,0x79);      
        break;
         
    case 64:                   
        I2C_write(I2C2,0x23); 
        I2C_write(I2C2,0x78);
        break;
 
    // 16Hz default
    default:                       
        I2C_write(I2C2,0x25);
        I2C_write(I2C2,0x7A);      
    }
    // MSB equal in all cases
    I2C_write(I2C2,0xAF); 
    I2C_write(I2C2,0x04);
    I2C_stop(I2C2);
}

but am unable to read the data:

void REG_read() {  
    I2C_start(I2C2,sensor_address_write,I2C_Direction_Transmitter);
    I2C_write(I2C2,0x02);
    I2C_write(I2C2,0x92);
    I2C_write(I2C2,0x00);
    I2C_write(I2C2,0x01);
    I2C_stop(I2C2);
    I2C_start(I2C2,sensor_address_read,I2C_Direction_Receiver);
    // uint8_t pointer to REG_
    pD_g = (uint8_t*) REG_;
    (*pD_g) = I2C_read_ack(I2C2);
    pD_g++;
    (*pD_g) = I2C_read_ack(I2C2);
    I2C_stop(I2C2);
}

Debugging gets me stuck at the repeated start (i2c stop, then i2c start), more precisely at:

while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

The communication schematics for the REG_read() is shown in the attached image.

Please offer some advice as I am getting really frustrated. Currently I do not have an oscilloscope available...

Thank you very much for your help and best regards,
K

P.S.: I tried posting to STM discovery forum, but have been receiving an error (due to site maintenance?)

Attachments

Outcomes