cancel
Showing results for 
Search instead for 
Did you mean: 

STR9 as I2C slave!

gyaum85
Associate
Posted on April 25, 2008 at 09:58

STR9 as I2C slave!

1 REPLY 1
gyaum85
Associate
Posted on May 17, 2011 at 09:52

Hi every body,

I have a issue with the I2C. I use a STR912FAW44 as a slave device on the I2C bus with the address 0xA0. When I try to read some bytes with an I2C master from the STR9, I have 2 problems: - first one seems to be similar of that one described in this post

http://www.st.com/mcu/forums-cat-5061-html

Quote:

On 01-03-2007 at 19:49, Anonymous wrote: Hi, I try to use the I2C interface of the STR912 in slave mode. The communication in the slave receiver mode looks like o.k. But the slave transmitter mode generate errors. The STR9 documentation describe the slave transmission procedere as followed: S ADRESS A DATA1 A DATA2 A DATA NA P EV1|EV3 EV3 EV3 EV3-1 EV4 EV1 : EVF = 1, ADSL = 1; cleared by reading I2Cn_SR1 register EV3 : EVF = 1, BTF = 1; cleared by reading I2Cn_SR1 register, following by writing DR EV3-1 : EVF = 1, AF = 1, BTF = 1; AF is cleared by reading SR2, BTF is cleared by releasing the line or writing DR = 0xff EV4 : EVF = 1, STOPF = 1; cleared by reading SR2 In my opinion the EV3-1 has to be detected by reading SR1 und SR2 registers and testing the AF and BTF bits. With other words the following code snipped have to do that work: if((I2C0_SR2 & I2C0_SR2_AF) && (I2C0_SR1 & I2C0_SR1_BTF)){ /* Not ACK -> EV3-1 */ I2C0_DR = 0xff; ..... This condition was never reached !!! Instead of the BTF the BUSY bit was set! That's why I changed the test to if(I2C0_SR1 & I2C0_SR2_AF){ /* EV3-1 */ I2C0_DR = 0xff; ..... Now I got the AF condition and I would expect that the EV4 (STOPF condition) was the next (last) event during I2C slave transmission. These condition fails sometimes. Note: sometimes !!! To verify the effect I wait into the interrupt service routine (very dirty I know) to the next event bit (I2C0_SR1 & 0x80). The event occurs but the STOPF bit in the SR2 was not set. The SR1 register contains 0xb8 -> EVF, TRA, BUSY and BTF is set. The EV3 is also upcoming? So I wait for the next event and now I found the EV4. In the result the slave transmission sequence has an addional event EV3 (look below): S ADRESS A DATA1 A DATA2 A DATA NA P EV1|EV3 EV3 EV3 EV3-1 EV3 EV4 Is this correct? Best regards, Jens - and a second one, more strange: when I set the frequency of 400kHz bus is OK but when I defines the frequency at 10KHz, the problems start: sometime the SDA line is not released and the BUSY flag is still set. When I say ''sometime'', in fact it seems to depend of the last data transmitted See attached some print screen of the frame with data 09 0A (which failed) and 7E 00 (which success). How can I resolve this issue? -------


#define GPIOIN2 0x3 
#define GPIOOUT2 0x000A 
#define GPIOTYPE2 0x03 
#define GPIO_DIR2 0x3 
----- 
void I2C_Initialization( tI2C_Comm *pCommStruct ) { 
 I2C_InitTypeDef I2C_Struct; 
 pI2C_Comm = pCommStruct; 
 I2C_Cmd(I2C0, ENABLE); 
 I2C_Struct.I2C_GeneralCall = I2C_GeneralCall_Disable; 
 I2C_Struct.I2C_Ack = I2C_Ack_Enable; 
 I2C_Struct.I2C_CLKSpeed = 400; 
 I2C_Struct.I2C_OwnAddress = 0xA0; 
 I2C_Init(I2C0, &I2C_Struct); 
 I2C_ITConfig(I2C0, ENABLE); 
} 
__irq void I2C0_IRQHandler(void) { 
 u16 event; 
 event = I2C_GetLastEvent(I2C0); 
 switch (event) { 
 case I2C_EVENT_SLAVE_ADDRESS_MATCHED: // EV1 
 pI2C_Comm->Direction = I2C_ReceiveData(I2C0) & 0x01; 
 print_dbg(''I2C : EV1 dir=%i
'', pI2C_Comm->Direction); 
 if ( pI2C_Comm->Direction == 0 ) { 
 // RX 
 I2C_AcknowledgeConfig(I2C0, ENABLE); 
 pI2C_Comm->RX_bufferSize = 0; 
 Rx_Idx = 0; 
 lastAcknowledge = TRUE; 
 } else { 
 // TX 
 Tx_Idx = 0; 
 } 
 break; 

 case I2C_EVENT_SLAVE_BYTE_RECEIVED: // EV2 
 //print_dbg(''I2C : EV2 data=%x
'', I2C_ReceiveData(I2C0)); 
 if ( pI2C_Comm->RX_bufferSize < MAX_FRAME_LENGTH ) { 
 pI2C_Comm->RX_buffer[Rx_Idx++] = I2C_ReceiveData(I2C0); 
 pI2C_Comm->RX_bufferSize++; 
 } 
 break; 

 case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: // EV3 
 //print_dbg(''I2C : EV3
''); 
 I2C_SendData(I2C0, pI2C_Comm->TX_buffer[Tx_Idx++]); 
 break; 

 case I2C_FLAG_BUSY | I2C_FLAG_AF : // EV3-2 
 //print_dbg(''I2C : EV3-2
''); 
 I2C_SendData(I2C0, 0xff); 
 break; 
 case I2C_EVENT_SLAVE_ACK_FAILURE : // EV3-1 
 //print_dbg(''I2C : EV3-1
''); 
 I2C_SendData(I2C0, 0xff); 
 break; 

 case I2C_EVENT_SLAVE_STOP_DETECTED: // EV4 
 print_dbg(''I2C : EV4
''); 
 if ( pI2C_Comm->Direction == 0 && lastAcknowledge==TRUE ) { 
 print_dbg(''I2C : nb byte=%i
'',Rx_Idx); 
 } 
 if ( pI2C_Comm->Direction == 1 ) { 
 print_dbg(''I2C : nb byte=%i
'',Tx_Idx); 
 } 
 break; 

 default: 
 print_dbg(''I2C : EV=%x
'', event); 
 print_dbg(''I2C : nb byte=%i
'',Tx_Idx); 
 break; 
 } 
} 

[ This message was edited by: gyaum85 on 30-04-2008 16:03 ]