@@ -49,7 +49,7 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
4949
5050	// Configure for a single shot to perform both write and read (as applicable) 
5151	if  len (w ) !=  0  {
52- 		i2c .Bus .TXD .PTR .Set (uint32 (uintptr (unsafe .Pointer (& w [ 0 ] ))))
52+ 		i2c .Bus .TXD .PTR .Set (uint32 (unsafeNoEscape (unsafe .Pointer (unsafe . SliceData ( w ) ))))
5353		i2c .Bus .TXD .MAXCNT .Set (uint32 (len (w )))
5454
5555		// If no read, immediately signal stop after TX 
@@ -58,7 +58,7 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
5858		}
5959	}
6060	if  len (r ) !=  0  {
61- 		i2c .Bus .RXD .PTR .Set (uint32 (uintptr (unsafe .Pointer (& r [ 0 ] ))))
61+ 		i2c .Bus .RXD .PTR .Set (uint32 (unsafeNoEscape (unsafe .Pointer (unsafe . SliceData ( r ) ))))
6262		i2c .Bus .RXD .MAXCNT .Set (uint32 (len (r )))
6363
6464		// Auto-start Rx after Tx and Stop after Rx 
@@ -89,6 +89,11 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
8989		}
9090	}
9191
92+ 	// Make sure the w and r buffers stay alive until this point, so they won't 
93+ 	// be garbage collected while the buffers are used by the hardware. 
94+ 	keepAliveNoEscape (unsafe .Pointer (unsafe .SliceData (w )))
95+ 	keepAliveNoEscape (unsafe .Pointer (unsafe .SliceData (r )))
96+ 
9297	return 
9398}
9499
@@ -117,7 +122,7 @@ func (i2c *I2C) Listen(addr uint8) error {
117122// 
118123// For request events, the caller MUST call `Reply` to avoid hanging the i2c bus indefinitely. 
119124func  (i2c  * I2C ) WaitForEvent (buf  []byte ) (evt  I2CTargetEvent , count  int , err  error ) {
120- 	i2c .BusT .RXD .PTR .Set (uint32 (uintptr (unsafe .Pointer (& buf [ 0 ] ))))
125+ 	i2c .BusT .RXD .PTR .Set (uint32 (unsafeNoEscape (unsafe .Pointer (unsafe . SliceData ( buf ) ))))
121126	i2c .BusT .RXD .MAXCNT .Set (uint32 (len (buf )))
122127
123128	i2c .BusT .TASKS_PREPARERX .Set (nrf .TWIS_TASKS_PREPARERX_TASKS_PREPARERX_Trigger )
@@ -134,6 +139,10 @@ func (i2c *I2C) WaitForEvent(buf []byte) (evt I2CTargetEvent, count int, err err
134139		}
135140	}
136141
142+ 	// Make sure buf stays alive until this point, so it won't be garbage 
143+ 	// collected while it is used by the hardware. 
144+ 	keepAliveNoEscape (unsafe .Pointer (unsafe .SliceData (buf )))
145+ 
137146	count  =  0 
138147	evt  =  I2CFinish 
139148	err  =  nil 
@@ -163,7 +172,7 @@ func (i2c *I2C) WaitForEvent(buf []byte) (evt I2CTargetEvent, count int, err err
163172
164173// Reply supplies the response data the controller. 
165174func  (i2c  * I2C ) Reply (buf  []byte ) error  {
166- 	i2c .BusT .TXD .PTR .Set (uint32 (uintptr (unsafe .Pointer (& buf [ 0 ] ))))
175+ 	i2c .BusT .TXD .PTR .Set (uint32 (unsafeNoEscape (unsafe .Pointer (unsafe . SliceData ( buf ) ))))
167176	i2c .BusT .TXD .MAXCNT .Set (uint32 (len (buf )))
168177
169178	i2c .BusT .EVENTS_STOPPED .Set (0 )
@@ -180,6 +189,10 @@ func (i2c *I2C) Reply(buf []byte) error {
180189		}
181190	}
182191
192+ 	// Make sure the buffer stays alive until this point, so it won't be garbage 
193+ 	// collected while it is used by the hardware. 
194+ 	keepAliveNoEscape (unsafe .Pointer (unsafe .SliceData (buf )))
195+ 
183196	i2c .BusT .EVENTS_STOPPED .Set (0 )
184197
185198	return  nil 
0 commit comments