tinygo-org / drivers

TinyGo drivers for sensors, displays, wireless adaptors, and other devices that use I2C, SPI, GPIO, ADC, and UART interfaces.
https://tinygo.org
BSD 3-Clause "New" or "Revised" License
607 stars 192 forks source link

feat(as7262): init driver for new device #592

Open JohnTrunix opened 1 year ago

JohnTrunix commented 1 year ago

Hey guys!

This is my first time contributing to an open source project. I have implemented a driver for the AS7262 according to the data sheet.

Note

adt7410 uses "tinygo.org/x/drivers/internal/legacy" so does as7262 but should work later in release with "tinygo.org/x/drivers"

Example: adt7410.go on dev branch line 56-60

func (d *Device) Connected() bool {
    data := []byte{0}
    legacy.ReadRegister(d.bus, uint8(d.Address), RegID, data)
    return data[0]&0xF8 == 0xC8
}

adt7410.go on release branch line 55-59

func (d *Device) Connected() bool {
    data := []byte{0}
    d.bus.ReadRegister(uint8(d.Address), RegID, data)
    return data[0]&0xF8 == 0xC8
}

If you have any questions or feedback, please contact me! Thanks

deadprogram commented 1 year ago

@JohnTrunix can you please make sure to add both an example for use and smoke test for this new device? Thank you!

JohnTrunix commented 1 year ago

Well, I added an example and the smoketest. Workflow passes but without success:

2023-08-26T10:59:52.1111675Z tinygo build -size short -o ./build/test.hex -target=arduino ./examples/as7262/main.go
2023-08-26T10:59:52.1126374Z tinygo:ld.lld: error: section '.text' will not fit in region 'FLASH_TEXT': overflowed by 4042 byte

As I contribute first time and also first time to some hardware related stuff can someone point out my problem(s):

Would be verry happy to get some insights on that issue, thanks!

deadprogram commented 1 year ago

It is probably too large to work on an Arduino Uno. Try switching to a different board for the smoke test.

deadprogram commented 1 year ago

Or just avoid using fmt package and use simpler println() function to avoid needed to use reflection.

JohnTrunix commented 1 year ago

It is probably too large to work on an Arduino Uno. Try switching to a different board for the smoke test.

But this would mean, that in prod this feature wouldn't work with an arduino uno?

deadprogram commented 1 year ago

The Arduino Uno has so little RAM that reflection is too big for it. Solution: don't use fmt.

deadprogram commented 1 year ago

@JohnTrunix have you received the physical sensor for testing yet?

JohnTrunix commented 1 year ago

@JohnTrunix have you received the physical sensor for testing yet?

No unfortunately not, hopefully in the middle of this week. Otherwise, I can test the driver at the end of September because I will be on vacation for two weeks.

JohnTrunix commented 1 year ago

d18a337 fixes smoketest for arduino uno

JohnTrunix commented 1 year ago

Short update: I have the sensor, but currently it's not working. I might have some bugs/errors in my drivers code. Will try to fix it in the next few days, but it will probably be end of September (holidays).

deadprogram commented 1 year ago

Thanks @JohnTrunix looking forward to when you get this working.

JohnTrunix commented 1 year ago

Well, after 10h+ I have gained a comprehensive understanding of the virtual registers and functionality of the sensor. I am now working on implementing all other features and configurations, this will probably take a while. If there is an urgency for a release, feel free to prioritize other PRs for the upcoming release cycle.

JohnTrunix commented 1 year ago

@deadprogram or someone else, I'm hard stuck and would appreciate some help:

Status: everything is implemented, config, led setup and one time read of a virtual byte register works Problem: after two times reading a byte from a virtual register the driver gets stuck by writing the virtual register for the next read.

Context:

Reading a byte from the virtual register (implemented according to the pseudocode in the datasheet):

  1. Wait until sensor is ready to write
  2. Write virutal register to WriteReg
  3. Wait until read is ready
  4. Read virtual register value from ReadReg
func (d *Device) readByte(reg byte) byte {
    d.buf[0] = 0b00000000
    for {
        if d.writeReady() {
            break
        }
    }

    legacy.WriteRegister(d.bus, d.Address, WriteReg, []byte{reg})

    for {
        if d.readReady() {
            break
        }
    }

    legacy.ReadRegister(d.bus, d.Address, ReadReg, d.buf)
    return d.buf[0]
}

My test code reads the temperature register because it is only 1 byte in size (not like the light value registers which are 4 bytes long and have to be read 4 bytes ascending). This shows the error better, because otherwise the sensor gets stuck when reading the second byte of a light value.

Test Code:

...

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

func main() {
    i2c.Configure(machine.I2CConfig{Frequency: machine.KHz * 100})
    sensor.Configure(true, 64, 17.857, 2)
    //sensor.ConfigureLed(12.5, true, 8, true)

    println("Starting ...")

    for {
        println("Value: ", sensor.Temperature())
        time.Sleep(time.Millisecond * 800)
    }
}

So sensor.Configure(...) does one read, and the first time in the for loop sensor.Temperature() does the second read. When starting the next read in the for loop, the sensor gets stuck writing the virtual register to the WriteReg (tested with println functions where it gets stuck).

I have been debugging for the past week and have not been able to figure out why this error is occurring. As I mentioned earlier, my experience is very limited. Perhaps you guys have a better understanding or know where the problem might be. My guess is that this sensor is using a different I2C "style/flavour".