cancel
Showing results for 
Search instead for 
Did you mean: 

M24LR16E and STM32L Discovery

jesperhede
Associate II
Posted on November 18, 2014 at 06:02

Hey guys,

http://www.bdtic.com/DataSheet/ST/M24LR16E-R.pdf

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();
PWR_PVDCmd(DISABLE);
RCC_Configuration();
PWR_VoltageScalingConfig(PWR_VoltageScaling_Range1);
/* Wait Until the Voltage Regulator is ready */
while
(PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET) ;
/* Init I/O ports */
Init_GPIOs ();
/* Initializes ADC */
ADC_Icc_Init();
enableInterrupts(); 
/* Warning ! in TSL Init the sysTick interrupt is setted to:
SysTick_Config(RCC_Clocks.HCLK_Frequency / 2000 ---> 500 µs*/
/* Init Touch Sensing configuration */
TSL_Init();
sMCKeyInfo[0].Setting.b.IMPLEMENTED = 1;
sMCKeyInfo[0].Setting.b.ENABLED = 1;
sMCKeyInfo[0].DxSGroup = 0x00; 
/* Initializes the LCD glass */
LCD_GLASS_Init();
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_DeInit(I2C1);
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStruct.I2C_OwnAddress1 = 0xC; 
//0b1 
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);
while
(1)
{
/* Turn on M24LR16E */
GPIO_HIGH(GPIOD, GPIO_Pin_2);
Delay(100);
/* 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 = 0b10100 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);
Delay(100);
/* Shut down M24LR16E */
GPIO_LOW(GPIOD, GPIO_Pin_2);
Delay(100);
}
} 

#stm32-m24lr16e-i2c
1 REPLY 1
jesperhede
Associate II
Posted on November 18, 2014 at 20:19

UPDATE:

The error described was because I didn't initialize my GPIO port to Open Drain. Now I'm facing another issue. The M24LR16 replies with a NACK when trying to establish a connection. My code:

1.
/* Generate start condition */
2.
I2C_GenerateSTART(I2C1, ENABLE);
3.
while
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); 
//Wait until bus is free
4.
5.
/* Send device select+read/write cmd and wait for ACK */
6.
I2C_Send7bitAddress(I2C1, 0xA6, I2C_Direction_Transmitter); 
//0xA6 = 0b10100 Page 18 datasheet
7.
Delay(5);

Am I accessing the M24LR16 in a wrong any? Any ideas?