AnsweredAssumed Answered

M24LR16E and STM32L Discovery

Question asked by hede.jesper on Nov 18, 2014
Latest reply on Nov 18, 2014 by hede.jesper
Hey guys,

M24LR16E datasheet

I'm trying to write to the M24LR16E with my STM32L1 discovery board, to the RF Block 1 / I2C address 4.

It seems that the STM takes over the bus just fine, sends the address data but then doesn't receive an ACK from the M24LR16E. They might be fighting over the bus since it's not a high or low on the last clock? (see attached). I do not know how to solve this issue..

I'm coding on top of their demo code, but I'm initializing everything I use some I don't believe that is an issue.
int main(void)
        GPIO_InitTypeDef GPIO_InitStruct;
        I2C_InitTypeDef I2C_InitStruct;
        uint8_t i = 0;
 /*!< 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
  Int_CurrentSTBY = Current_Measurement();
  /* Wait Until the Voltage Regulator is ready */
  while (PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET) ;
  /* Init I/O ports */
  Init_GPIOs ();
  /* Initializes ADC */
  /* Warning ! in TSL Init the sysTick interrupt is setted to:
  SysTick_Config(RCC_Clocks.HCLK_Frequency / 2000 ---> 500 µs*/
  /* Init Touch Sensing configuration */ 
  sMCKeyInfo[0].Setting.b.IMPLEMENTED = 1;
  sMCKeyInfo[0].Setting.b.ENABLED = 1;
  sMCKeyInfo[0].DxSGroup = 0x00;
  /* Initializes the LCD glass */
  LCD_GLASS_ScrollSentence("      ** TEST PROGRAM **",1,SCROLL_SPEED);
    /*  INITIALIZE */
    /**     I2C bus
        *   Used as communication bus between STM32Lxxx and M24LR16E
        1       Initialize RCC clock containing I2C bus and GPIO port B
        2       Initialize PB6 and PB7 in alternate function
        3       Initialize I2C bus
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;           // Alternate function
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
        GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;           // Pull up for I2C
        GPIO_Init(GPIOB, &GPIO_InitStruct);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);     //Assign pin to I2C
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);     //Assign pin to I2C
        RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
        RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
        I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
        I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
        I2C_InitStruct.I2C_OwnAddress1 = 0xC;           //0b1100.
        I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStruct.I2C_ClockSpeed = IS_I2C_CLOCK_SPEED(40000);      //correct?
        I2C_Init(I2C1, &I2C_InitStruct);
        I2C_Cmd(I2C1, ENABLE);
        /**     PD2
        *           Used as VCC for M24LR16E
        1       Set as output with no pull-up or down
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOD, &GPIO_InitStruct);
        I2C_AcknowledgeConfig(I2C1, ENABLE);
                /* Turn on M24LR16E */
                GPIO_HIGH(GPIOD, GPIO_Pin_2);
                /* Generate start condition */
                I2C_GenerateSTART(I2C1, ENABLE);
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));     //Wait until bus is free
                /* Send device select+read/write cmd and wait for ACK */
                I2C_SendData(I2C1, 0xA6);                          
                //I2C_Send7bitAddress(I2C1,0xA6, I2C_Direction_Transmitter);                                //0xA6 = 0b10100110. Page 18 datasheet
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_BYTE_RECEIVED));        //Wait for ACK on address from slave
                /* Send address byte 1 and 2. Wait until data has been received */
                I2C_SendData(I2C1, 0x0);
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_BYTE_RECEIVED));        // Wait for ACK from slave
                I2C_SendData(I2C1, 0x4);
                while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_BYTE_RECEIVED));        // Wait for ACK from slave
                /* Write data and wait for ACK  x4*/
                for(i = 0; i < 4; i++)
                    I2C_SendData(I2C1,0x2A); // 0b00101010 = 42
                    while(!I2C_CheckEvent(I2C1, I2C_EVENT_SLAVE_BYTE_RECEIVED));
                /* Generate Stop condition */
                I2C_GenerateSTOP(I2C1, ENABLE);
                /* Shut down M24LR16E */
                GPIO_LOW(GPIOD, GPIO_Pin_2);