I'm an engineering student and for my bachelor thesis I use a 16 channel IO expander which communicates with I2C with a STM8S microcontroller.
- IDE: STVD (I set the correct ARF6 byte)
- IO-ex: PCA8575 -> datasheet: https://www.mouser.be/datasheet/2/302/PCA8575-1127755.pdf
- µC: STM8S105K4 -> datasheet: https://www.st.com/en/microcontrollers-microprocessors/stm8s105k4.html
Now in previous projects I used SPI for communicating between modules (same µC), and it worked as I wanted.
The problem lies withing the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED
macro.
I found a similar post, but it seems very dead: "i2c stm8 issue with event"
I use the standard peripheral library of the controller. This is my main.c file. Now I pseudo'ed using the @-symbol my code to make this question more clean, you can assume these parts are well tested and work. Also the macros can be assumed to be correct. Hardware debugging is rather hard because everything is integrated on a PCB.
@inclusion of "stm8s.h", "stm8s_gpio.h", "stm8s_delay.h" and "stm8s_i2c.h"
@defining of C and D port
@defining P1,P2,... Pin macros
@defining I2C_SLAVE_ADDRESS, I2C_OUTPUT_CLK_FREQ, I2C_OWN_ADDRESS, I2C_INTERNAL_CLK_FREQ
@defining BLINK_LED_A,... macros
@defining I2C flag checking macros
#define wait ;
void I2C_Setup(void);
void main()
{
uint8_t rgbMSB, rgbLSB;
@initiating GPIO
I2C_DeInit();
I2C_Setup(); // see below this main function
while (1)
{
DEBUG_LED_B();
while (I2C_BUS_IS_BUSY) // ok
wait
DEBUG_LED_A();
I2C_GenerateSTART(ENABLE);
while (I2C_MASTER_MODE_NOT_SELECTED) // ok
wait
DEBUG_LED_B();
I2C_Send7bitAddress(I2C_SLAVE_ADDRESS, I2C_DIRECTION_TX);
while(I2C_CheckEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCES); // here the program goes into infinite loop
DEBUG_LED_A();
I2C_SendData(rgbLSB);
while (I2C_CheckEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS)
;
DEBUG_LED_B();
I2C_SendData(rgbMSB);
I2C_AcknowledgeConfig(I2C_ACK_NONE);
I2C_GenerateSTOP(ENABLE);
delay_ms(500);
}
}
void I2C_Setup(void)
{
u8 Input_Clock = 0;
Input_Clock = CLK_GetClockFreq() / 1000000;
I2C_Init(I2C_OUTPUT_CLK_FREQ, I2C_OWN_ADDRESS, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, Input_Clock);
}
Since I don't know what is wrong with my could I would politely ask you guys a) did you ever have a similar problem and how did you solve it, b) is it a possible software issue or a hardware one, c) provide a starting point on how to solve this issue.
I tried negating the events and flags, and obviously it doesn't work. I tried to immediately do the following and it didn't work.
// previous code
while(1){
I2C_GenerateSTART(ENABLE);
I2C_Send7bitAddress(I2C_SLAVE_ADDRESS, I2C_DIRECTION_TX);
I2C_SendData(rgbLSB);
I2C_SendData(rgbMSB);
I2C_AcknowledgeConfig(I2C_ACK_NONE);
I2C_GenerateSTOP(ENABLE);
delay_ms(500);
}