-
Notifications
You must be signed in to change notification settings - Fork 40
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
I2C example software #76
Comments
Hi, There is for instance : Is it what you are looking for ? Regards |
Hi, I saw that, but it doesn't explain how to implement usual ш2с read/write sequence. I've tried the following code to read register reg (unisigned 8bit variable): i2c_masterStartBlocking(I2C_CTRL); Looking into i2c protocol exchange on oscilloscope I didn't see second START condition even I see second successful ACK And where I can find detailed timing register description (sample clock divider, Tlow, Thigh, Tsudat, Tbuf)? Not found it somewhere in the repository Thanks in advance |
Ahhh, Instead of Can you do a : Or you need specificaly a I2C restart sequance ?
Hmmm following : https://github.com/SpinalHDL/SaxonSoc/blob/dev-0.3/software/standalone/i2cMcp4725/src/main.c#L26 sample clock divider -1 = number of clocks between each io sample on the i2c bus (to avoid glitch issues) let's me know how it goes ^^ |
If I2C Master communicates with slave device that have a registers, exchange sequence usually performed the following way:
Most of the devices I've seen follow these steps. What should I do to implement this? Thanks in advance |
Hi, I reproduced the issue in simulation (no restart condition when the master issue a start in a frame) So, the issue i found was in the C driver, where the i2c_masterStartBlocking wasn't blocking at all in that specific condition. Here is my fix : static void i2c_masterStartBlocking(u32 reg){
i2c_masterStart(reg);
while(i2c_getMasterStatus(reg) & I2C_MASTER_START);
} Also, note that the driver i had in hand had some missnamed "gpio_" that should have been "i2c_" I got a good restart sequance doing that : (as an example) bsp_putString("Test 1\n");
i2c_masterStartBlocking(I2C_CTRL);
i2c_txByte(I2C_CTRL, 0xAA);
i2c_txAckBlocking(I2C_CTRL);
i2c_txByte(I2C_CTRL, 0x02);
i2c_txAckBlocking(I2C_CTRL);
i2c_masterStartBlocking(I2C_CTRL); //The driver fix will fix this call
i2c_txByte(I2C_CTRL, 0x04);
i2c_txAckBlocking(I2C_CTRL);
i2c_masterStopBlocking(I2C_CTRL);
bsp_putString("restart done\n"); Which give me in simulation (seems ok to me, the cursor is on the restart) : I updated the i2c driver with this commit : let's me know if anything isn't right. |
Why i2c_txAckBlocking after i2c_txByte? I understand it as "Transmitting ACK after sending data byte". But it violates the protocol! Slave sends Ack as a confirmation that the data byte has been successfully received, thus it should be like |
Hoo, the i2c_txAckBlocking of my example are just there for the sim. In my tests i wanted to check the impact of having the master driving the ACK low before the restart to ensure that the restart force the line release. You can use the i2c_listenAck(I2C_CTRL); This should not create any issue.
Yes ^^ |
The following code: static void efx_masterStartBlocking(u32 reg){ static void efx_waitAck(u32 reg) void i2c_soc_init()
} u8 i2c_soc_read(u8 reg)
} Thanks in advance |
Hi Igor, So i just tried in sim, there is a few issue with the code. Here is a version which works : static void efx_masterStartBlocking(u32 reg){
i2c_masterStart(reg);
while(i2c_getMasterStatus(reg) & I2C_MASTER_START);
}
static void efx_waitAck(u32 reg)
{
i2c_txNackBlocking(I2C_CTRL); //Sending a Nack will allow the slave to put his ack/nack
assert(i2c_rxAck(I2C_CTRL));
}
u8 i2c_soc_read(u8 reg)
{
u8 val;
val = (DEV_ADDR << 1) & 0xFE; // Addr shifted, LSB=0
efx_masterStartBlocking(I2C_CTRL);
i2c_txByte(I2C_CTRL,val);
efx_waitAck(I2C_CTRL);
i2c_txByte(I2C_CTRL,reg);
efx_waitAck(I2C_CTRL);
val |= 1; // LSB=1
efx_masterStartBlocking(I2C_CTRL);
i2c_txByte(I2C_CTRL,val);
efx_waitAck(I2C_CTRL);
i2c_txByte(I2C_CTRL, 0xFF); //Provide 0xFF to release the line (pull up)
efx_waitAck(I2C_CTRL);
val = i2c_rxData(I2C_CTRL);
i2c_masterStopBlocking(I2C_CTRL);
return val;
} The main thing was that i2c_txByte(I2C_CTRL, 0xFF) and i2c_txNackBlocking(I2C_CTRL); are required, they kind of say "Send something which will not interfer with SDA (pull up)" The rxListen stuff isn't required, it is mostly a way to specify : "block the i2c if there is something in that register that i haven't read yet". But as by default, the i2c bus is blocked until i2c_txByte i2c_txNackBlocking, it isn't that usefull. Let's me know how it goes ^^ |
Hello!
Using Efinix version of SaxonSoC (T120F324 devkit), trying to use i2c as master to communicate with plain slave peripheral. Is there an example to communicate SaxonSoC with plain i2c slave?
Thanks
Igor
The text was updated successfully, but these errors were encountered: