mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-21 12:59:04 +00:00
nrf: add I2C error checking (#1392)
* machine/nrf: add I2C error checking
This commit is contained in:
@@ -258,12 +258,19 @@ func (i2c I2C) Configure(config I2CConfig) {
|
|||||||
// Tx does a single I2C transaction at the specified address.
|
// Tx does a single I2C transaction at the specified address.
|
||||||
// It clocks out the given address, writes the bytes in w, reads back len(r)
|
// It clocks out the given address, writes the bytes in w, reads back len(r)
|
||||||
// bytes and stores them in r, and generates a stop condition on the bus.
|
// bytes and stores them in r, and generates a stop condition on the bus.
|
||||||
func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
func (i2c I2C) Tx(addr uint16, w, r []byte) (err error) {
|
||||||
i2c.Bus.ADDRESS.Set(uint32(addr))
|
i2c.Bus.ADDRESS.Set(uint32(addr))
|
||||||
|
defer func() {
|
||||||
|
i2c.signalStop()
|
||||||
|
i2c.Bus.SHORTS.Set(nrf.TWI_SHORTS_BB_SUSPEND_Disabled)
|
||||||
|
}()
|
||||||
|
|
||||||
if len(w) != 0 {
|
if len(w) != 0 {
|
||||||
i2c.Bus.TASKS_STARTTX.Set(1) // start transmission for writing
|
i2c.Bus.TASKS_STARTTX.Set(1) // start transmission for writing
|
||||||
for _, b := range w {
|
for _, b := range w {
|
||||||
i2c.writeByte(b)
|
if err = i2c.writeByte(b); err != nil {
|
||||||
|
goto cleanUp
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(r) != 0 {
|
if len(r) != 0 {
|
||||||
@@ -276,12 +283,18 @@ func (i2c I2C) Tx(addr uint16, w, r []byte) error {
|
|||||||
i2c.Bus.SHORTS.Set(nrf.TWI_SHORTS_BB_STOP)
|
i2c.Bus.SHORTS.Set(nrf.TWI_SHORTS_BB_STOP)
|
||||||
}
|
}
|
||||||
i2c.Bus.TASKS_RESUME.Set(1) // re-start transmission for reading
|
i2c.Bus.TASKS_RESUME.Set(1) // re-start transmission for reading
|
||||||
r[i] = i2c.readByte()
|
if r[i], err = i2c.readByte(); err != nil {
|
||||||
|
// goto/break are practically equivalent here,
|
||||||
|
// but goto makes this more easily understandable for maintenance.
|
||||||
|
goto cleanUp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanUp:
|
||||||
i2c.signalStop()
|
i2c.signalStop()
|
||||||
i2c.Bus.SHORTS.Set(nrf.TWI_SHORTS_BB_SUSPEND_Disabled)
|
i2c.Bus.SHORTS.Set(nrf.TWI_SHORTS_BB_SUSPEND_Disabled)
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// signalStop sends a stop signal when writing or tells the I2C peripheral that
|
// signalStop sends a stop signal when writing or tells the I2C peripheral that
|
||||||
@@ -295,19 +308,28 @@ func (i2c I2C) signalStop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// writeByte writes a single byte to the I2C bus.
|
// writeByte writes a single byte to the I2C bus.
|
||||||
func (i2c I2C) writeByte(data byte) {
|
func (i2c I2C) writeByte(data byte) error {
|
||||||
i2c.Bus.TXD.Set(uint32(data))
|
i2c.Bus.TXD.Set(uint32(data))
|
||||||
for i2c.Bus.EVENTS_TXDSENT.Get() == 0 {
|
for i2c.Bus.EVENTS_TXDSENT.Get() == 0 {
|
||||||
|
if e := i2c.Bus.EVENTS_ERROR.Get(); e != 0 {
|
||||||
|
i2c.Bus.EVENTS_ERROR.Set(0)
|
||||||
|
return errI2CBusError
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i2c.Bus.EVENTS_TXDSENT.Set(0)
|
i2c.Bus.EVENTS_TXDSENT.Set(0)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// readByte reads a single byte from the I2C bus.
|
// readByte reads a single byte from the I2C bus.
|
||||||
func (i2c I2C) readByte() byte {
|
func (i2c I2C) readByte() (byte, error) {
|
||||||
for i2c.Bus.EVENTS_RXDREADY.Get() == 0 {
|
for i2c.Bus.EVENTS_RXDREADY.Get() == 0 {
|
||||||
|
if e := i2c.Bus.EVENTS_ERROR.Get(); e != 0 {
|
||||||
|
i2c.Bus.EVENTS_ERROR.Set(0)
|
||||||
|
return 0, errI2CBusError
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i2c.Bus.EVENTS_RXDREADY.Set(0)
|
i2c.Bus.EVENTS_RXDREADY.Set(0)
|
||||||
return byte(i2c.Bus.RXD.Get())
|
return byte(i2c.Bus.RXD.Get()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SPI on the NRF.
|
// SPI on the NRF.
|
||||||
|
|||||||
Reference in New Issue
Block a user