* machine/nrf: add I2C error checking
Этот коммит содержится в:
Daniel M. Lambea 2020-09-26 08:20:43 +01:00 коммит произвёл GitHub
родитель d1f90ef59c
коммит 9e61e6fe4d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23

Просмотреть файл

@ -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.