@@ -242,6 +242,7 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
242242 timeoutNS := int64 (timeoutMS ) * 1000000
243243 needAddress := true
244244 needRestart := false
245+ isRead := false
245246 var readTo []byte
246247 for cmdIdx , reg := 0 , & i2c .Bus .COMD0 ; cmdIdx < len (cmd ); {
247248 c := & cmd [cmdIdx ]
@@ -253,6 +254,7 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
253254 cmdIdx ++
254255
255256 case i2cCMD_WRITE :
257+ isRead = false
256258 count := 32
257259 if needAddress {
258260 needAddress = false
@@ -266,15 +268,17 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
266268 reg .Set (i2cCMD_WRITE | uint32 (32 - count ))
267269 reg = nextAddress (reg )
268270
269- if c .head < len (c .data ) {
270- reg .Set (i2cCMD_END )
271- reg = nil
272- } else {
271+ // Always end a write segment with END, so STOP goes out alone
272+ // in its own segment (ref: ESP32 TRM v5.8, section 21.3.5).
273+ reg .Set (i2cCMD_END )
274+ reg = nil
275+ if c .head >= len (c .data ) {
273276 cmdIdx ++
274277 }
275278 needRestart = true
276279
277280 case i2cCMD_READ :
281+ isRead = true
278282 if needAddress {
279283 needAddress = false
280284 i2c .Bus .SetDATA_FIFO_RDATA ((uint32 (addr )& 0x7f )<< 1 | 1 )
@@ -308,10 +312,16 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
308312 reg = nextAddress (reg )
309313 }
310314
311- if split {
315+ if split && bytes > 0 {
316+ reg .Set (i2cCMD_END )
317+ readTo = c .data [c .head : c .head + bytes ]
318+ reg = nil
319+ } else if split {
312320 reg .Set (i2cCMD_READLAST | 1 )
313321 reg = nextAddress (reg )
314- readTo = c .data [c .head : c .head + bytes + 1 ] // read bytes + 1 last byte
322+ reg .Set (i2cCMD_END )
323+ readTo = c .data [c .head : c .head + 1 ]
324+ reg = nil
315325 cmdIdx ++
316326 } else {
317327 reg .Set (i2cCMD_END )
@@ -333,7 +343,7 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
333343 if nanotime () > end {
334344 // timeout leaves the bus in an undefined state, reset
335345 i2c .resetBus ()
336- if readTo != nil {
346+ if isRead {
337347 return errI2CReadTimeout
338348 }
339349 return errI2CWriteTimeout
@@ -345,7 +355,7 @@ func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
345355 case mask & esp .I2C_INT_STATUS_TIME_OUT_INT_ST_Msk != 0 :
346356 // timeout leaves the bus in an undefined state, reset
347357 i2c .resetBus ()
348- if readTo != nil {
358+ if isRead {
349359 return errI2CReadTimeout
350360 }
351361 return errI2CWriteTimeout
0 commit comments