-
Notifications
You must be signed in to change notification settings - Fork 221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lack of example of using I2C. Event interrupts not implemented? #143
Comments
Hi, I managed to make the MCP4725 work, I filtered an example of the AN3281 from ST, here are the routines that worked: (Note: My MCP4725 froze more than once (eventually) when trying out different settings in the I2C routines. Be aware that it may be necessary to use a MOSFET or relay to reset the MCP4725 via programming, or manually switch the power supply in the event of a communication failure) Usage (MCP4725) dac_test.ino: #include"stm8s.h"
#include "stm8s_i2c.h"
#define MCP4725_Addr 0x62
#define uC_Addr 0x1
#define I2C_Speed 100000
void setup (void);
void loop (void);
void I2C_WriteRegister2(u8 u8_regAddr, u8 u8_NumByteToWrite, u8 *u8_DataBuffer);
void I2C_Setup(u8 u8_regAddr);
void setup (void) {
I2C_Setup(uC_Addr); //
}
void loop (void) {
u8 buff[2];
while (1) {
for (int i = 0; i < 4095; i++) {
buff[0] = (i >> 8) & 0x0F;
buff[1] = i & 0xFF;
I2C_WriteRegister2(MCP4725_Addr, 2, buff);
}
}
}
/******************************************************************************
Function name : I2C_WriteRegister2
Description : write defined number bytes to slave memory starting with defined offset
Input param : offset in slave memory, number of bytes to write, starting address to send
Return : None.
See also : i2c_master_poll.c - STM8 optimized I2C examples (AN3281)
*******************************************************************************/
void I2C_WriteRegister2(u8 u8_regAddr, u8 u8_NumByteToWrite, u8 *u8_DataBuffer)
{
uint8_t I2C_Slave_Address = u8_regAddr << 1; // from 8 bits to 7 bits + R/W
I2C_GenerateSTART(ENABLE);
while ((I2C->SR1 & 1) == 0); // Wait for start bit detection (SB)
I2C_Send7bitAddress(I2C_Slave_Address, I2C_DIRECTION_TX);
while (!(I2C->SR1 & 2)); // Wait for address ack (ADDR)
(void)I2C->SR3; // ADDR=1, cleared by reading SR1 register followed by reading SR3
while (u8_NumByteToWrite--)
{ // write data loop start
while (!(I2C->SR1 & 0x80)); // test EV8 - wait for TxE
I2C_SendData(*u8_DataBuffer++); // send next data byte
}
while ((I2C->SR1 & 0x84) != 0x84); // Wait for TxE & BTF
I2C_GenerateSTOP(ENABLE);
while (I2C->CR2 & 2); // wait until stop is performed
}
void I2C_Setup(u8 u8_regAddr)
{
GPIO_DeInit(GPIOB);
GPIO_Init(GPIOB, GPIO_PIN_4, GPIO_MODE_OUT_OD_HIZ_FAST);
GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_OD_HIZ_FAST);
CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, ENABLE);
I2C_DeInit();
I2C_Init(I2C_Speed, u8_regAddr, I2C_DUTYCYCLE_2, I2C_ACK_CURR, I2C_ADDMODE_7BIT, (CLK_GetClockFreq() / 1000000));
// I2C->ITR = 1; // enable error interrupts
// I2C1_ITR_ITEVTEN = 1; //Event Enables : SB, ADDR, ADD10, STOPF, BTF, WUFH
// I2C1_ITR_ITBUFEN = 1; //Buffer Enables (if ITEVTEN) : RXNE, TXE
// I2C1_ITR_ITERREN = 1; //Error Enables : BERR, ARLO, AF, OVR
I2C_Cmd(ENABLE);
} Source code: https://github.com/rtek1000/RF_Magic_Controller_6803_IC/tree/main/Arduino_Modified_Hardware Note: People put the device address in the I2C init, but it's the address of the uC (Host) in slave mode, don't confuse it.
Sample code: |
Why not use the examples provided with the wire library port included in the sduino repo? |
Thanks for the feedback, actually I had only found a few examples for other compilers, and this document AN, but now that you mention Wire, I'll look for where it is and I'll try to use it, thanks again! |
Note: I tried adding the '#include <Wire.h>' declaration. Before adding the declaration, it had 91% of used program space, and after adding the instruction #include <Wire.h> the code started to occupy 105% of used program space (that is, it doesn't fit in memory in this case) we can see that using the Wire library takes up at least about 14% of the STM8S103F3's program space. Using this code with the I2C_WriteRegister2 routine (cited above) the code now occupies only 96%. That is, if it is only to write to the I2C port, it may be interesting to have the routine separate, to save the program memory of only 8kB. |
Hello,
I found some example usage codes on the Internet, but I couldn't get the MCP4725 to work, I tested it with Arduino Nano and it worked.
Test code for Arduino Nano:
Unfortunately I still couldn't get the I2C port to work correctly, there are some posts that say they had problems with I2C on these STM8S, and in my case the I2C_GetFlagStatus() function seems to be unable to read the register and so the routine freezes. The problem seems to be the lack of interrupt, because the initialization of the I2C module does not trigger interrupt events, so asking the code to wait for an interrupt, the code is stuck forever. Basically I found two initializations, one that activates the interrupt and one that does not activate.
This other file shows the activation of the interrupt on line 88, I've tried working with the interrupt, but it's a bit complex, and I believe you need to faithfully follow the steps outlined in ST's RM0016 document:
https://github.com/HomeSmartMesh/STM8_IoT_HelloWorld/blob/master/18_STM8L_HelloI2C/i2c.c
It would be interesting to have an example of functional usage for I2C in the folder:
https://github.com/tenbaht/sduino/tree/development/test
Or:
https://github.com/tenbaht/sduino/tree/development/examples
P.S.: Ref.:
https://www.st.com/en/embedded-software/stsw-stm8004.html
https://www.st.com/resource/en/application_note/an3281-stm8-8bit-mcus-ic-optimized-examples-stmicroelectronics.pdf
The text was updated successfully, but these errors were encountered: