tinygo icon indicating copy to clipboard operation
tinygo copied to clipboard

i2c for esp32-c3

Open zdima opened this issue 3 years ago • 15 comments

Added support for I2C with 7-bit addressing for ESP32C3. Tested with bh1750 (reads) and SSD1306 (writes).

zdima avatar Feb 11 '22 14:02 zdima

@zdima I tried with the ADT7410 example. However, m5stamp-c3 did not produce the expected waveform. feather-m4-can (atsamd51) is working correctly. Can you think of any possible causes?

m5stamp-c3 image

feather-m4-can image

package main

import (
	"fmt"
	"machine"
	"time"

	"tinygo.org/x/drivers/adt7410"
)

var (
	i2c    = machine.I2C0
	sensor = adt7410.New(i2c)
)

func main() {
	i2c.Configure(machine.I2CConfig{Frequency: machine.TWI_FREQ_400KHZ, SCL: machine.IO6, SDA: machine.IO7})
	//i2c.Configure(machine.I2CConfig{Frequency: machine.TWI_FREQ_400KHZ})
	sensor.Configure()

	for {
		temp := sensor.ReadTempC()
		fmt.Printf("temperature: %f\r\n", temp)
		time.Sleep(time.Second)
	}

}

sago35 avatar Feb 19 '22 06:02 sago35

I rewrote it as follows, and it works a little better. But it still doesn't work well.

m5stamp-c3 image

func main() {

	i2c := machine.I2C0
	i2c.Configure(machine.I2CConfig{Frequency: machine.TWI_FREQ_400KHZ, SCL: machine.IO6, SDA: machine.IO7})
	//i2c.Configure(machine.I2CConfig{Frequency: machine.TWI_FREQ_400KHZ})
	sensor := adt7410.New(i2c)
	sensor.Configure()

	for {
		temp := sensor.ReadTempC()
		fmt.Printf("temperature: %f\r\n", temp)
		time.Sleep(time.Second)
	}

}

sago35 avatar Feb 19 '22 06:02 sago35

I have confirmed that the SSD1306 does work.

sago35 avatar Feb 19 '22 06:02 sago35

@sago35

@zdima I tried with the ADT7410 example. However, m5stamp-c3 did not produce the expected waveform. feather-m4-can (atsamd51) is working correctly. Can you think of any possible causes?

From the wave form it look like the signal capture is partial. The signal with address is not captured and only data portion shown.

I rewrote it as follows, and it works a little better.

I think this is because sensor is initialized with i2c interface before i2c get initialized. This is only thing that may provide unexpected result. In case you need to keep sensor as a global variable, you could add function that return configured i2c interface and use it to initialize sensor while program is loading.

zdima avatar Feb 19 '22 14:02 zdima

@zdima I did some more research.


The following source code cannot be loaded by m5stamp-c3. It looks like there is no address transmission on read.

		i2c.Tx(0x48, []byte{0x00}, buf[:2])

m5stamp-c3 image

feather-m4-can image


In the case of the following source code, m5stamp-c3 can also read the data of ADT7410.

		i2c.Tx(0x48, []byte{0x00}, []byte{})
		i2c.Tx(0x48, []byte{}, buf[:2])

m5stamp-c3 image

feather-m4-can image

sago35 avatar Feb 20 '22 01:02 sago35

@zdima can you please rebase this branch against dev?

sago35 avatar Feb 20 '22 01:02 sago35

@sago35 I don't have I2C device with registers. Can you try new code and let me know if this fix the issue?

zdima avatar Feb 20 '22 14:02 zdima

@zdima

The waveform is now good enough to communicate.

image

However, there are some waveform changes that are too fast, perhaps due to timing issues with register operations.

image

image

In addition, this process reads 2 bytes, but the second byte is always 0xFF. I don't understand what the following source code is doing, but it seems to me that only one byte is being processed.

https://github.com/zdima/tinygo/blob/2bfdd894e76138efca8b3738cc22a9bd1a85d089/src/machine/machine_esp32c3.go#L409-L411

sago35 avatar Feb 21 '22 13:02 sago35

However, there are some waveform changes that are too fast,

The registry operations are all complete before it start sending the entire sequence. I don't think I can do anything with this.

I don't understand what the following source code is doing

The reason for this code is to set for last byte NACK.

this process reads 2 bytes, but the second byte is always 0xFF.

Yes, looks like because of this twist with the last byte, the last byte was not getting read from the controller. Please try the last changes.

zdima avatar Feb 21 '22 15:02 zdima

ADT7410 is now working. Thank you for the quick response.

sago35 avatar Feb 22 '22 00:02 sago35

@zdima Now, it looks like it is failing to read a single byte. Here, we want to read only one byte from address==0xA1, but it keeps reading until timeout.

https://github.com/tinygo-org/drivers/blob/a15f2167cc7e46864d82e08904a3ddaa3e610d5e/bme280/bme280.go#L65-L69

image

sago35 avatar Feb 22 '22 00:02 sago35

Hi @zdima! is there any news about this PR? I just tested it with a Lolin C3 Mini v1 and an SSD1306 OLED display and it works perfectly. The test program is visible here if it can help: https://gist.github.com/osechet/d6d3e2d3bc8ad33435705c3a94dc85af.

The program is flashed using the esp32c3 target: tinygo flash -port COM3 -target esp32c3 .\ssd1306 tinygo version: 0.27.0 windows/amd64 go version: 1.19.4

osechet avatar Feb 20 '23 15:02 osechet

I am also very interested in finding out the status of this PR and helping out however needed. :smile_cat:

deadprogram avatar Apr 03 '23 21:04 deadprogram

Just submitted PR https://github.com/tinygo-org/tinygo/pull/4011

What do we think is needed if anything to get this PR completed?

deadprogram avatar Nov 27 '23 16:11 deadprogram

I did some testing last night.

The good news is that with a couple small changes this branch worked to read/write data. The not as good news is that as @sago35 reported the PR does not work correctly when writing a single byte. I will look into that this evening to see if I can resolve.

deadprogram avatar Nov 28 '23 10:11 deadprogram

Looks like the code here has been merged already in #4014 .

aykevl avatar Feb 25 '24 14:02 aykevl