Closed fmckeogh closed 3 years ago
Thanks! I have a logic analyser, just not sure I have one of those displays! I'll try and dig out an I2C device and give it go :)
I've been using https://github.com/reitermarkus/esp32-hello to try and help debug my implementation by swapping out parts with esp-idf
functions, no luck so far but I'll keep trying.
Just moved the latest i2c.rs, this was working on reitermarkus's template but I'm getting the LoadProhibited
errors again.
I've just pushed @arjanmels's changes from his branch, but it's failing to send commands on my device :/ I'll test again on the esp32-hello platform.
@chocol4te Checked out freshly and for me it still works. Does it still hang in the same loop on your device?
@arjanmels It does, what device are you using? I’ve only got the one esp32-based dev board unfortunately.
Hmm, I’m using one of these: https://heltec.org/project/wifi-lora-32/
I’ll try clearing everything on my machine and starting fresh I guess 😅
I'm unfortunately still getting the issue where commands don't ever send/sent register never set, but I'm happy to close this and merge @arjanmels I2C branch, if nobody else can replicate my issue then we shouldn't be blocked on it.
@chocol4te It looks like the helltec board has no pullup resistors on SCK and SDA, so it counts on the pullups of the esp32. It could be that the problem is due to errata "3.6 GPIO pull-up and pull-down resistors for pads with both GPIO and RTC_GPIO functionality can only be controlled via RTC_GPIO registers. (rev0, rev1 and rev3)". I will try to implement the suggested workaround one of the upcoming days.
@arjanmels Oh thank you so much! I'd never have spotted that, I'll try and confirm on my board :)
@arjanmels Oh thank you so much! I'd never have spotted that, I'll try and confirm on my board :)
@chocol4te Ok, I implemented the workaround. For me it still works (I haven't confirmed the actual pull down/up currents yet). Can you give it a spin? https://github.com/arjanmels/esp32-hal/tree/feature-i2c-am. You will need to use updated esp32 to avoid a version conflict: https://github.com/arjanmels/esp32/tree/update-cargo-xtensa-lx6-rt.
@arjanmels Same behaviour as before. I can't find any resistors I can use for manual pull-ups, and connecting the display to non-RTC pins (22 and 23) doesn't appear to work either, but it does work when using pins 22 and 23 to connect to an MPU6050. Reading still needs to be implemented so I'm gonna start on that today :)
@chocol4te The pull up/down were not disabled by default in the RTC. I fixed this now. Can you give it another try?
(I tested the pins with a multimeter now. On my board there are indeed 10kOhm pullups to 3.3V on pins 4 & 15. I also tested the functionality of the library. It now works properly. Pull up/down are capable to give ~ 75uA, which is ~ 45kOhm.)
@arjanmels It's working!! 🥳
Once the GPIO improvements get merged I can rebase and copy some of my changes onto feature-i2c-am
, like frequency and filter configuration?
Once the GPIO improvements get merged I can rebase and copy some of my changes onto
feature-i2c-am
, like frequency and filter configuration? Yes, please take ownership in any way you want for the i2c driver again. (I don't plan to drive this forward, I just used it as a vehicle to get the GPIO right.)
I've been trying and failing to implement reading/transfers, I've just pushed my work so far in the last commit. I'm again using the reference manual and esp-idf
source to understand how it needs to work and I am, again, stuck. When reading the RXFIFO buffer fills with 255. My guess would be that maybe the pull-up is too strong, but both sensors (MPU6050 and SGP30) work fine in an Arduino environment. I've checked and double-checked the ACK settings, even tried random combinations but no luck. Any advice/help would be greatly appreciated :/
According to the errata 3.18, the FIFO's cannot be reliably read via the AHB bus (address 0x600x_xxxx), but need to be read via the DPORT (0x3ffx_xxxx). Hope that helps, otherwise I can try to take a look later this week.
No rush, thank you so much for your help! I read through the errata but totally missed the last one. Just pushed a commit for using DPORT for FIFO reads and AHB for FIFO writes for compatibility across all versions, but still reading 255.
@chocol4te I didn't have too many I2C device at hand. I tried on a M5stickC board. I can get the AXP192 going (but not the SH200Q, may be some power gating on the board).
Which board do you use for the MPU6050 and SGP30?
Only thing different I noted between Arduino Lib & your rust code is a slight difference in timings, but for AXP192 both sets of timings work. To reproduce the Arduino timing you can use:
let period = ((80_000_000 / freq) / 2) as u16;
let half_period = period / 2;
let quarter_period = half_period / 2;
let scl_low = period;
let scl_high = period;
let sda_hold = quarter_period;
let sda_sample = quarter_period;
let setup = half_period;
let hold = half_period;
Regarding reading from I2C:
I'm currently experimenting with a HT16K33, when I try yo read the display buffer the first byte in the returned buffer seems to be the last byte in the actual buffer (I write the buffer and read it out again with changing data). Every other byte is 255 (default?).
Also I was wondering, if anyone is currently actively working on it? :)
I don't have enough knowledge yet into how exactly I2C works, so I'm a bit confused about the read from the exact same byte for rx_ncount times.
I think this is very exciting work and would love to actually see this merged as I'm trying to get a ssd1306 OLED display to work as well. Could somebody shed some light on where this currently sits at? Perhaps in this case, even incomplete work would be useful to get merged so that someone else may pick it up.
@chocol4te thanks for your hard work so far! If possible, could you briefly outline where this PR is stands so that someone else could take a stab at finishing it up?
@MabezDev I'm so sorry, university started back up in September and I didn't have much free time.
My general process to implement this was reading the esp-idf
source and trying to replicate register writes exactly, and once it was working, build up the layers of abstraction (expose clock and other configuration methods). Essentially the code as it stands should be a basic working I2C implementation, but has a bug where it reads in invalid data (0xFF
).
Anyone who wants to work on it should most likely start by running the code as is under a logic analyser to see if there is any explanation there, followed by testing different pull-up configurations to find if that could be the issue.
I was able to get this merged with the latest master (commit e8dd426) on my fork. I've verified that I can write to the SSD1306 using the same Heltec lora board mentioned above. Next up, I'm going to try to get reads working on an MPU6050 - I do have a logic analyzer so I'll start there.
A very rough initial suggestion for how I2C might look. There are several things that need to be added, including proper configuration during construction and possible an
nrf-hal
style GPIO Pin implementation to make peripherals that can work on any pins slightly more ergonomic.Currently this PR adds a new example of using the I2C interface with a display (as found on several
esp32
dev boards). The rest of the implementation attempts to mimic exactly what theesp32-idf-hal
I2C implementation does, and is commented with the respectiveesp-idf
functions.Currently there is a bug which is that it doesn't work. I don't have a working logic analyser, my multimeter's leads introduce too much capacitance to reliably measure if the clock signal is even enabled (tested by running an Arduino example which successfully draws on the display). I really wish I could give more details, but the only
esp32
board I have uses the JTAG pins for the SSD1306 display which makes debugging a program that writes to the display very tricky.Here is the serial output I see when I run the program.