@@ -142,129 +142,149 @@ public I2cDeviceConnection Connect(int deviceAddress)
142
142
143
143
#region Internal Methods
144
144
145
- internal void Write ( int deviceAddress , byte [ ] buffer )
145
+ /// <summary>
146
+ /// Executes the specified transaction.
147
+ /// </summary>
148
+ /// <param name="deviceAddress">The address of the device.</param>
149
+ /// <param name="transaction">The transaction.</param>
150
+ internal void Execute ( int deviceAddress , I2cTransaction transaction )
146
151
{
147
152
lock ( driverLock )
148
153
{
149
- EnsureDeviceAddress ( deviceAddress ) ;
154
+ var control = bscAddress + ( int ) Interop . BCM2835_BSC_C ;
155
+
156
+ foreach ( I2cAction action in transaction . Actions )
157
+ {
158
+ if ( action is I2cWriteAction )
159
+ {
160
+ Write ( deviceAddress , action . Buffer ) ;
161
+ }
162
+ else if ( action is I2cReadAction )
163
+ {
164
+ Read ( deviceAddress , action . Buffer ) ;
165
+ }
166
+ else
167
+ {
168
+ throw new InvalidOperationException ( "Only read and write transactions are allowed." ) ;
169
+ }
170
+ }
171
+
172
+ WriteUInt32Mask ( control , Interop . BCM2835_BSC_S_DONE , Interop . BCM2835_BSC_S_DONE ) ;
173
+ }
174
+ }
175
+
176
+ #endregion
150
177
151
- var len = ( uint ) buffer . Length ;
178
+ #region Private Helpers
179
+
180
+ private void Write ( int deviceAddress , byte [ ] buffer )
181
+ {
182
+ this . EnsureDeviceAddress ( deviceAddress ) ;
152
183
153
- var dlen = bscAddress + ( int ) Interop . BCM2835_BSC_DLEN ;
154
- var fifo = bscAddress + ( int ) Interop . BCM2835_BSC_FIFO ;
155
- var status = bscAddress + ( int ) Interop . BCM2835_BSC_S ;
156
- var control = bscAddress + ( int ) Interop . BCM2835_BSC_C ;
184
+ var len = ( uint ) buffer . Length ;
157
185
158
- var remaining = len ;
159
- var i = 0 ;
186
+ var dlen = this . bscAddress + ( int ) Interop . BCM2835_BSC_DLEN ;
187
+ var fifo = this . bscAddress + ( int ) Interop . BCM2835_BSC_FIFO ;
188
+ var status = this . bscAddress + ( int ) Interop . BCM2835_BSC_S ;
189
+ var control = this . bscAddress + ( int ) Interop . BCM2835_BSC_C ;
160
190
161
- // Clear FIFO
162
- WriteUInt32Mask ( control , Interop . BCM2835_BSC_C_CLEAR_1 , Interop . BCM2835_BSC_C_CLEAR_1 ) ;
191
+ var remaining = len ;
192
+ var i = 0 ;
163
193
164
- // Clear Status
165
- WriteUInt32 ( status , Interop . BCM2835_BSC_S_CLKT | Interop . BCM2835_BSC_S_ERR | Interop . BCM2835_BSC_S_DONE ) ;
194
+ // Clear FIFO
195
+ WriteUInt32Mask ( control , Interop . BCM2835_BSC_C_CLEAR_1 , Interop . BCM2835_BSC_C_CLEAR_1 ) ;
166
196
167
- // Set Data Length
168
- WriteUInt32 ( dlen , len ) ;
197
+ // Clear Status
198
+ WriteUInt32 ( status , Interop . BCM2835_BSC_S_CLKT | Interop . BCM2835_BSC_S_ERR | Interop . BCM2835_BSC_S_DONE ) ;
169
199
170
- while ( remaining != 0 && i < Interop . BCM2835_BSC_FIFO_SIZE )
200
+ // Set Data Length
201
+ WriteUInt32 ( dlen , len ) ;
202
+
203
+ while ( remaining != 0 && i < Interop . BCM2835_BSC_FIFO_SIZE )
204
+ {
205
+ WriteUInt32 ( fifo , buffer [ i ] ) ;
206
+ i ++ ;
207
+ remaining -- ;
208
+ }
209
+
210
+ // Enable device and start transfer
211
+ WriteUInt32 ( control , Interop . BCM2835_BSC_C_I2CEN | Interop . BCM2835_BSC_C_ST ) ;
212
+
213
+ while ( ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_DONE ) == 0 )
214
+ {
215
+ while ( remaining != 0 && ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_TXD ) != 0 )
171
216
{
217
+ // Write to FIFO, no barrier
172
218
WriteUInt32 ( fifo , buffer [ i ] ) ;
173
219
i ++ ;
174
220
remaining -- ;
175
221
}
176
222
177
- // Enable device and start transfer
178
- WriteUInt32 ( control , Interop . BCM2835_BSC_C_I2CEN | Interop . BCM2835_BSC_C_ST ) ;
179
-
180
- while ( ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_DONE ) == 0 )
181
- {
182
- while ( remaining != 0 && ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_TXD ) != 0 )
183
- {
184
- // Write to FIFO, no barrier
185
- WriteUInt32 ( fifo , buffer [ i ] ) ;
186
- i ++ ;
187
- remaining -- ;
188
- }
223
+ this . Wait ( remaining ) ;
224
+ }
189
225
190
- Wait ( remaining ) ;
191
- }
226
+ if ( ( SafeReadUInt32 ( status ) & Interop . BCM2835_BSC_S_ERR ) != 0 ) // Received a NACK
227
+ throw new InvalidOperationException ( "Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status" ) ;
228
+ if ( ( SafeReadUInt32 ( status ) & Interop . BCM2835_BSC_S_CLKT ) != 0 ) // Received Clock Stretch Timeout
229
+ throw new InvalidOperationException ( "Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status" ) ;
230
+ if ( remaining != 0 ) // Not all data is sent
231
+ throw new InvalidOperationException ( string . Format ( "Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes" , remaining ) ) ;
192
232
193
- if ( ( SafeReadUInt32 ( status ) & Interop . BCM2835_BSC_S_ERR ) != 0 ) // Received a NACK
194
- throw new InvalidOperationException ( "Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status" ) ;
195
- if ( ( SafeReadUInt32 ( status ) & Interop . BCM2835_BSC_S_CLKT ) != 0 ) // Received Clock Stretch Timeout
196
- throw new InvalidOperationException ( "Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status" ) ;
197
- if ( remaining != 0 ) // Not all data is sent
198
- throw new InvalidOperationException ( string . Format ( "Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes" , remaining ) ) ;
199
-
200
- WriteUInt32Mask ( control , Interop . BCM2835_BSC_S_DONE , Interop . BCM2835_BSC_S_DONE ) ;
201
- }
202
233
}
203
234
204
- internal byte [ ] Read ( int deviceAddress , int byteCount )
235
+ private void Read ( int deviceAddress , byte [ ] buffer )
205
236
{
206
- lock ( driverLock )
207
- {
208
- EnsureDeviceAddress ( deviceAddress ) ;
237
+ this . EnsureDeviceAddress ( deviceAddress ) ;
209
238
210
- var dlen = bscAddress + ( int ) Interop . BCM2835_BSC_DLEN ;
211
- var fifo = bscAddress + ( int ) Interop . BCM2835_BSC_FIFO ;
212
- var status = bscAddress + ( int ) Interop . BCM2835_BSC_S ;
213
- var control = bscAddress + ( int ) Interop . BCM2835_BSC_C ;
239
+ var dlen = this . bscAddress + ( int ) Interop . BCM2835_BSC_DLEN ;
240
+ var fifo = this . bscAddress + ( int ) Interop . BCM2835_BSC_FIFO ;
241
+ var status = this . bscAddress + ( int ) Interop . BCM2835_BSC_S ;
242
+ var control = this . bscAddress + ( int ) Interop . BCM2835_BSC_C ;
214
243
215
- var remaining = ( uint ) byteCount ;
216
- uint i = 0 ;
244
+ var remaining = ( uint ) buffer . Length ;
245
+ uint i = 0 ;
217
246
218
- // Clear FIFO
219
- WriteUInt32Mask ( control , Interop . BCM2835_BSC_C_CLEAR_1 , Interop . BCM2835_BSC_C_CLEAR_1 ) ;
247
+ // Clear FIFO
248
+ WriteUInt32Mask ( control , Interop . BCM2835_BSC_C_CLEAR_1 , Interop . BCM2835_BSC_C_CLEAR_1 ) ;
220
249
221
- // Clear Status
222
- WriteUInt32 ( status , Interop . BCM2835_BSC_S_CLKT | Interop . BCM2835_BSC_S_ERR | Interop . BCM2835_BSC_S_DONE ) ;
250
+ // Clear Status
251
+ WriteUInt32 ( status , Interop . BCM2835_BSC_S_CLKT | Interop . BCM2835_BSC_S_ERR | Interop . BCM2835_BSC_S_DONE ) ;
223
252
224
- // Set Data Length
225
- WriteUInt32 ( dlen , ( uint ) byteCount ) ;
253
+ // Set Data Length
254
+ WriteUInt32 ( dlen , ( uint ) buffer . Length ) ;
226
255
227
- // Start read
228
- WriteUInt32 ( control , Interop . BCM2835_BSC_C_I2CEN | Interop . BCM2835_BSC_C_ST | Interop . BCM2835_BSC_C_READ ) ;
256
+ // Start read
257
+ WriteUInt32 ( control , Interop . BCM2835_BSC_C_I2CEN | Interop . BCM2835_BSC_C_ST | Interop . BCM2835_BSC_C_READ ) ;
229
258
230
- var buffer = new byte [ byteCount ] ;
231
- while ( ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_DONE ) == 0 )
259
+ while ( ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_DONE ) == 0 )
260
+ {
261
+ while ( ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_RXD ) != 0 )
232
262
{
233
- while ( ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_RXD ) != 0 )
234
- {
235
- // Read from FIFO, no barrier
236
- buffer [ i ] = ( byte ) ReadUInt32 ( fifo ) ;
263
+ // Read from FIFO, no barrier
264
+ buffer [ i ] = ( byte ) ReadUInt32 ( fifo ) ;
237
265
238
- i ++ ;
239
- remaining -- ;
240
- }
241
-
242
- Wait ( remaining ) ;
243
- }
244
-
245
- while ( remaining != 0 && ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_RXD ) != 0 )
246
- {
247
- buffer [ i ] = ( byte ) ReadUInt32 ( fifo ) ;
248
266
i ++ ;
249
267
remaining -- ;
250
268
}
251
269
252
- if ( ( SafeReadUInt32 ( status ) & Interop . BCM2835_BSC_S_ERR ) != 0 ) // Received a NACK
253
- throw new InvalidOperationException ( "Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status" ) ;
254
- if ( ( SafeReadUInt32 ( status ) & Interop . BCM2835_BSC_S_CLKT ) != 0 ) // Received Clock Stretch Timeout
255
- throw new InvalidOperationException ( "Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status" ) ;
256
- if ( remaining != 0 ) // Not all data is received
257
- throw new InvalidOperationException ( string . Format ( "Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes" , remaining ) ) ;
258
-
259
- WriteUInt32Mask ( control , Interop . BCM2835_BSC_S_DONE , Interop . BCM2835_BSC_S_DONE ) ;
270
+ this . Wait ( remaining ) ;
271
+ }
260
272
261
- return buffer ;
273
+ while ( remaining != 0 && ( ReadUInt32 ( status ) & Interop . BCM2835_BSC_S_RXD ) != 0 )
274
+ {
275
+ buffer [ i ] = ( byte ) ReadUInt32 ( fifo ) ;
276
+ i ++ ;
277
+ remaining -- ;
262
278
}
263
- }
264
279
265
- #endregion
280
+ if ( ( SafeReadUInt32 ( status ) & Interop . BCM2835_BSC_S_ERR ) != 0 ) // Received a NACK
281
+ throw new InvalidOperationException ( "Read operation failed with BCM2835_I2C_REASON_ERROR_NACK status" ) ;
282
+ if ( ( SafeReadUInt32 ( status ) & Interop . BCM2835_BSC_S_CLKT ) != 0 ) // Received Clock Stretch Timeout
283
+ throw new InvalidOperationException ( "Read operation failed with BCM2835_I2C_REASON_ERROR_CLKT status" ) ;
284
+ if ( remaining != 0 ) // Not all data is received
285
+ throw new InvalidOperationException ( string . Format ( "Read operation failed with BCM2835_I2C_REASON_ERROR_DATA status, missing {0} bytes" , remaining ) ) ;
266
286
267
- #region Private Helpers
287
+ }
268
288
269
289
private static uint GetProcessorBscAddress ( Processor processor )
270
290
{
0 commit comments