cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 - I2C Slave - Polled works, Int fails

mwp
Senior
Posted on April 23, 2013 at 12:38

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
5 REPLIES 5
mwp
Senior
Posted on April 24, 2013 at 17:25

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!
Posted on April 24, 2013 at 17:44

Anyone??

Clearly not.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mwp
Senior
Posted on April 30, 2013 at 11:59

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.
dthedens23
Associate II
Posted on April 30, 2013 at 18:15

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 bits

mwp
Senior
Posted on May 02, 2013 at 10:59

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.