@@ -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 (& w [0 ]))))
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 (& r [0 ]))))
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,15 @@ 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
+ if len (w ) > 0 {
95
+ keepAliveNoEscape (unsafe .Pointer (& w [0 ]))
96
+ }
97
+ if len (r ) > 0 {
98
+ keepAliveNoEscape (unsafe .Pointer (& r [0 ]))
99
+ }
100
+
92
101
return
93
102
}
94
103
@@ -117,7 +126,7 @@ func (i2c *I2C) Listen(addr uint8) error {
117
126
//
118
127
// For request events, the caller MUST call `Reply` to avoid hanging the i2c bus indefinitely.
119
128
func (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 ]))))
121
130
i2c .BusT .RXD .MAXCNT .Set (uint32 (len (buf )))
122
131
123
132
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
134
143
}
135
144
}
136
145
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
+
137
150
count = 0
138
151
evt = I2CFinish
139
152
err = nil
@@ -163,7 +176,7 @@ func (i2c *I2C) WaitForEvent(buf []byte) (evt I2CTargetEvent, count int, err err
163
176
164
177
// Reply supplies the response data the controller.
165
178
func (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 ]))))
167
180
i2c .BusT .TXD .MAXCNT .Set (uint32 (len (buf )))
168
181
169
182
i2c .BusT .EVENTS_STOPPED .Set (0 )
@@ -180,6 +193,10 @@ func (i2c *I2C) Reply(buf []byte) error {
180
193
}
181
194
}
182
195
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
+
183
200
i2c .BusT .EVENTS_STOPPED .Set (0 )
184
201
185
202
return nil
0 commit comments