cancel
Showing results for 
Search instead for 
Did you mean: 

I2C on STM8S105

Posted on December 30, 2009 at 03:01

I2C on STM8S105

6 REPLIES 6
Posted on May 17, 2011 at 15:06

Dear all,

I'm trying to use the I2C device on my STM8S105. On this MCU I2C is implemented as alternative function. I've set the AF6 flag for I2C so that it should work. But when I send the start flag, the control of “I2C_CheckEvent(I2C_EVENT_MASTER_START_SENT)� fails and the program hangs. On the oscilloscope I can see that SDA is pulled down to low level, so only the flags are not set by hardware.

The same code works fine on STM8S208 and STM8S103. On this MCUs I2C can be used directly. Are there any other settings needed for using alternative functions?

Best regards!

simonl.li9
Associate
Posted on May 17, 2011 at 15:06

Hi,We also found sometime STM8S105 will not sent ACK when it received an address. IIC bus will be hold

mathieux
Associate
Posted on May 17, 2011 at 15:06

I also have an issue with it, I can't seem to use the I2C because the SR3 Busy bit always set.

Please let us know if someone is aware of the solution

Mat

Stm32User
Associate II
Posted on May 17, 2011 at 15:06

Hi 

This is a code segment that controls an external I2C multiplexer on my hardawre.  It works and seems reliable, it may help you.

There may be some minor differences in the library functions as the target is an stm8L151.

BYTE ee_SelectI2CMuxChannel(BYTE bChannel)

{

BYTE bI2CMuxAddr = I2CMUXADDR,bSelByte=0;

WORD wSelMuxErrorPollLoop;

// Selects the I2C channel using the PCA9540 I2C multiplexer

wSelMuxErrorPollLoop=I2CMUX_ERROR_TIMEOUT;

/* While the bus is busy */

do

{

WDG_RESET;

}

while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY) && (--wSelMuxErrorPollLoop) );

if(wSelMuxErrorPollLoop == 0 ) return 0;  // Timeout - bus busy

I2C_GenerateSTART(I2C1,ENABLE); // Send start

wSelMuxErrorPollLoop=I2CMUX_ERROR_TIMEOUT;

while ((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) && --wSelMuxErrorPollLoop) ;

  if(wSelMuxErrorPollLoop == 0) return 0;

// Send and wait for address to be transmitted

I2C_Send7bitAddress(I2C1,I2CMUXADDR, I2C_Direction_Transmitter);

wSelMuxErrorPollLoop=I2CMUX_ERROR_TIMEOUT;

while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))&&(--wSelMuxErrorPollLoop));

// Check correct ack and possible timeout condition

if ((I2C_GetFlagStatus(I2C1, I2C_FLAG_AF) != 0x00) || (wSelMuxErrorPollLoop == 0))

{

return 0;

}

// Decide on which bank of devices

if(bChannel == 1) bSelByte = I2CMUX_SEL_CH1; else bSelByte = I2CMUX_SEL_CH0;

// Send and wait for address to be transmitted

I2C_SendData(I2C1,bSelByte);

wSelMuxErrorPollLoop=I2CMUX_ERROR_TIMEOUT;

while ((!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED))&&(--wSelMuxErrorPollLoop));

// Check correct ack ( AF = ACK FAIL FLAG ) and possible timeout condition

if ((I2C_GetFlagStatus(I2C1, I2C_FLAG_AF) != 0x00) || (wSelMuxErrorPollLoop == 0))

{

return 0;

}

// Generate stop

  I2C_GenerateSTOP(I2C1,ENABLE);

return 1;

}

mozra272
Associate II
Posted on May 17, 2011 at 15:06

Hi Patrick;

After sending the address I2CMUXADDR you don't need to wait on the I2C_FLAG_AF, this check should be removed

if ((I2C_GetFlagStatus(I2C1, I2C_FLAG_AF) != 0x00) || (wSelMuxErrorPollLoop == 0))

{

return 0;

}

What is the frequency (Fcpu) used in your application and what is the timout value(I2CMUX_ERROR_TIMEOUT)?

Regards

mozra

Stm32User
Associate II
Posted on May 17, 2011 at 15:06

Hi Mozra

The Pollloop is a failsafe, its value is unimportant.  Under normal circumstances the polling will end quickly.  But if a straight while loop is used, if something goes wrong execution will hang .  At least if the function returns an error the error can be tracked down more easily.