@@ -49,7 +49,7 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
49
49
50
50
// Configure for a single shot to perform both write and read (as applicable)
51
51
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 ) ))))
53
53
i2c .Bus .TXD .MAXCNT .Set (uint32 (len (w )))
54
54
55
55
// If no read, immediately signal stop after TX
@@ -58,7 +58,7 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
58
58
}
59
59
}
60
60
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 ) ))))
62
62
i2c .Bus .RXD .MAXCNT .Set (uint32 (len (r )))
63
63
64
64
// Auto-start Rx after Tx and Stop after Rx
@@ -89,6 +89,11 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
89
89
}
90
90
}
91
91
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
+
92
97
return
93
98
}
94
99
@@ -117,7 +122,7 @@ func (i2c *I2C) Listen(addr uint8) error {
117
122
//
118
123
// For request events, the caller MUST call `Reply` to avoid hanging the i2c bus indefinitely.
119
124
func (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 ) ))))
121
126
i2c .BusT .RXD .MAXCNT .Set (uint32 (len (buf )))
122
127
123
128
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
134
139
}
135
140
}
136
141
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
+
137
146
count = 0
138
147
evt = I2CFinish
139
148
err = nil
@@ -163,7 +172,7 @@ func (i2c *I2C) WaitForEvent(buf []byte) (evt I2CTargetEvent, count int, err err
163
172
164
173
// Reply supplies the response data the controller.
165
174
func (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 ) ))))
167
176
i2c .BusT .TXD .MAXCNT .Set (uint32 (len (buf )))
168
177
169
178
i2c .BusT .EVENTS_STOPPED .Set (0 )
@@ -180,6 +189,10 @@ func (i2c *I2C) Reply(buf []byte) error {
180
189
}
181
190
}
182
191
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
+
183
196
i2c .BusT .EVENTS_STOPPED .Set (0 )
184
197
185
198
return nil
0 commit comments