2013-04-23 03:38 AM
Hi all,
Im taking my first steps in trying to get a STM32F103 I2C slave working... Not easy considering what seems to be the complete lack of simple known working examples :( Polling for I2C events/data works perfectly. Using the interrupt has issues though. The int will get the first start/data-byte/stop sequence OK, but after that it fails to work. The int gets fired, but I2C_GetLastEvent() returns an odd code that doesnt match anything in stm32f10x_i2c.h. So far ihaven'tbeen able to find out where the flags are listed?? Below is the polled & int-driven code...void
I2C_SlaveTest(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
lBYTE Data;
//enable clocks
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// I2C1 SDA and SCL configuration
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_DeInit(I2C1);
I2C_Cmd(I2C1, ENABLE);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 10000;
I2C_Init(I2C1, &I2C_InitStructure);
#ifndef POLLED
// I2C1 interrupts
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
I2C_ITConfig(I2C1, I2C_IT_EVT
/*| I2C_IT_ERR*/
, ENABLE);
#endif
while
(1)
{
#ifdef POLLED
if
(!I2C_CheckFlag(I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED, LED1_RED_PIN))
continue
;
if
(!I2C_CheckFlag(I2C_EVENT_SLAVE_BYTE_RECEIVED, LED2_RED_PIN))
continue
;
Data = I2C_ReceiveData(I2C1);
if
(!I2C_CheckFlag(I2C_EVENT_SLAVE_STOP_DETECTED, LED3_RED_PIN))
continue
;
GPIO_WriteBit(LED4_GRN_PIN, 1);
GPIO_Delay(100);
GPIO_WriteBit(LED4_GRN_PIN, 0);
#endif
}
}
#ifndef POLLED
void
I2C_Interrupt(
void
)
{
lBYTE Data;
switch
(Last = I2C_GetLastEvent(I2C1))
{
case
I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
GPIO_WriteBit(LED2_RED_PIN, 1);
break
;
case
I2C_EVENT_SLAVE_BYTE_RECEIVED:
GPIO_WriteBit(LED3_RED_PIN, 1);
Data = I2C_ReceiveData(I2C1);
break
;
case
I2C_EVENT_SLAVE_STOP_DETECTED:
GPIO_WriteBit(LED4_RED_PIN, 1);
break
;
default
:
break
;
}
}
#endif
#forum-says-no
2013-04-24 08:25 AM
Anyone??
Im yet to solve this problem.Are there any flags that need to be cleared on entering/leaving the int on any of the events?Thanks in advance!2013-04-24 08:44 AM
Anyone??
Clearly not.2013-04-30 02:59 AM
Well that wasnt quite the response i was hoping for from you clive1 :(
I dont understand why there is so little information around about using I2C on STM32's.Its pretty easy to find information on everything else.2013-04-30 09:15 AM
when I look at the source code for I2C_GetLastEvent I see that SR1 and SR2 are combined into a 32bit value.
You say that the code returned is not in the list of Event Codes. So what, in hex, is returned?one should be able to look at 25.6.6 and 25.6.7 to see what has error occurred on the bus simply by looking at the bits. Whoops! I use the F407 but I suspect that many of the bits are the same. Use your target Reference manual to decode the bits2013-05-02 01:59 AM
Thanks rocketdawg.
I was just about to go digging for the SR1/2 values when i came across this:https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Attachments/20502/i2c_int.c
It's helped me get it working to some degree.