@@ -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 (& w [0 ]))))
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 (& r [0 ]))))
6262		i2c .Bus .RXD .MAXCNT .Set (uint32 (len (r )))
6363
6464		// Auto-start Rx after Tx and Stop after Rx 
@@ -89,6 +89,15 @@ 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+ 	if  len (w ) >  0  {
95+ 		keepAliveNoEscape (unsafe .Pointer (& w [0 ]))
96+ 	}
97+ 	if  len (r ) >  0  {
98+ 		keepAliveNoEscape (unsafe .Pointer (& r [0 ]))
99+ 	}
100+ 
92101	return 
93102}
94103
@@ -117,7 +126,7 @@ func (i2c *I2C) Listen(addr uint8) error {
117126// 
118127// For request events, the caller MUST call `Reply` to avoid hanging the i2c bus indefinitely. 
119128func  (i2c  * I2C ) WaitForEvent (buf  []byte ) (evt  I2CTargetEvent , count  int , err  error ) {
120- 	i2c .BusT .RXD .PTR .Set (uint32 (uintptr (unsafe .Pointer (& buf [0 ]))))
129+ 	i2c .BusT .RXD .PTR .Set (uint32 (unsafeNoEscape (unsafe .Pointer (& buf [0 ]))))
121130	i2c .BusT .RXD .MAXCNT .Set (uint32 (len (buf )))
122131
123132	i2c .BusT .TASKS_PREPARERX .Set (nrf .TWIS_TASKS_PREPARERX_TASKS_PREPARERX_Trigger )
@@ -134,6 +143,10 @@ func (i2c *I2C) WaitForEvent(buf []byte) (evt I2CTargetEvent, count int, err err
134143		}
135144	}
136145
146+ 	// Make sure buf stays alive until this point, so it won't be garbage 
147+ 	// collected while it is used by the hardware. 
148+ 	keepAliveNoEscape (unsafe .Pointer (& buf [0 ]))
149+ 
137150	count  =  0 
138151	evt  =  I2CFinish 
139152	err  =  nil 
@@ -163,7 +176,7 @@ func (i2c *I2C) WaitForEvent(buf []byte) (evt I2CTargetEvent, count int, err err
163176
164177// Reply supplies the response data the controller. 
165178func  (i2c  * I2C ) Reply (buf  []byte ) error  {
166- 	i2c .BusT .TXD .PTR .Set (uint32 (uintptr (unsafe .Pointer (& buf [0 ]))))
179+ 	i2c .BusT .TXD .PTR .Set (uint32 (unsafeNoEscape (unsafe .Pointer (& buf [0 ]))))
167180	i2c .BusT .TXD .MAXCNT .Set (uint32 (len (buf )))
168181
169182	i2c .BusT .EVENTS_STOPPED .Set (0 )
@@ -180,6 +193,10 @@ func (i2c *I2C) Reply(buf []byte) error {
180193		}
181194	}
182195
196+ 	// Make sure the buffer stays alive until this point, so it won't be garbage 
197+ 	// collected while it is used by the hardware. 
198+ 	keepAliveNoEscape (unsafe .Pointer (& buf [0 ]))
199+ 
183200	i2c .BusT .EVENTS_STOPPED .Set (0 )
184201
185202	return  nil 
0 commit comments