Question
STM32F103 - I2C Slave - Polled works, Int fails
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