@@ -21,6 +21,8 @@ public class I2cDriver : IDisposable
21
21
22
22
private readonly ProcessorPin sdaPin ;
23
23
private readonly ProcessorPin sclPin ;
24
+ private readonly bool wasSdaPinSet ;
25
+ private readonly bool wasSclPinSet ;
24
26
25
27
private readonly IntPtr gpioAddress ;
26
28
private readonly IntPtr bscAddress ;
@@ -72,8 +74,9 @@ public I2cDriver(ProcessorPin sdaPin, ProcessorPin sclPin)
72
74
throw new InvalidOperationException ( "Unable to access device memory" ) ;
73
75
74
76
// Set the I2C pins to the Alt 0 function to enable I2C access on them
75
- SetPinMode ( ( uint ) ( int ) sdaPin , Interop . BCM2835_GPIO_FSEL_ALT0 ) ; // SDA
76
- SetPinMode ( ( uint ) ( int ) sclPin , Interop . BCM2835_GPIO_FSEL_ALT0 ) ; // SCL
77
+ // remembers if the values were actually changed to clear them or not upon dispose
78
+ wasSdaPinSet = SetPinMode ( ( uint ) ( int ) sdaPin , Interop . BCM2835_GPIO_FSEL_ALT0 ) ; // SDA
79
+ wasSclPinSet = SetPinMode ( ( uint ) ( int ) sclPin , Interop . BCM2835_GPIO_FSEL_ALT0 ) ; // SCL
77
80
78
81
// Read the clock divider register
79
82
var dividerAddress = bscAddress + ( int ) Interop . BCM2835_BSC_DIV ;
@@ -89,9 +92,15 @@ public I2cDriver(ProcessorPin sdaPin, ProcessorPin sclPin)
89
92
/// </summary>
90
93
public void Dispose ( )
91
94
{
92
- // Set all the I2C/BSC1 pins back to input
93
- SetPinMode ( ( uint ) ( int ) sdaPin , Interop . BCM2835_GPIO_FSEL_INPT ) ; // SDA
94
- SetPinMode ( ( uint ) ( int ) sclPin , Interop . BCM2835_GPIO_FSEL_INPT ) ; // SCL
95
+ // Set all the I2C/BSC1 pins back to original values if changed
96
+ if ( wasSdaPinSet )
97
+ {
98
+ SetPinMode ( ( uint ) ( int ) sdaPin , Interop . BCM2835_GPIO_FSEL_INPT ) ; // SDA
99
+ }
100
+ if ( wasSclPinSet )
101
+ {
102
+ SetPinMode ( ( uint ) ( int ) sclPin , Interop . BCM2835_GPIO_FSEL_INPT ) ; // SCL
103
+ }
95
104
96
105
Interop . munmap ( gpioAddress , Interop . BCM2835_BLOCK_SIZE ) ;
97
106
Interop . munmap ( bscAddress , Interop . BCM2835_BLOCK_SIZE ) ;
@@ -369,15 +378,31 @@ private static uint GetBscBase(ProcessorPin sdaPin, ProcessorPin sclPin)
369
378
}
370
379
}
371
380
372
- private void SetPinMode ( uint pin , uint mode )
381
+ /// <summary>
382
+ ///
383
+ /// </summary>
384
+ /// <param name="pin"></param>
385
+ /// <param name="mode"></param>
386
+ /// <returns>True when value was changed, false otherwise.</returns>
387
+ private bool SetPinMode ( uint pin , uint mode )
373
388
{
374
389
// Function selects are 10 pins per 32 bit word, 3 bits per pin
375
390
var paddr = gpioAddress + ( int ) ( Interop . BCM2835_GPFSEL0 + 4 * ( pin / 10 ) ) ;
376
391
var shift = ( pin % 10 ) * 3 ;
377
392
var mask = Interop . BCM2835_GPIO_FSEL_MASK << ( int ) shift ;
378
393
var value = mode << ( int ) shift ;
379
394
380
- WriteUInt32Mask ( paddr , value , mask ) ;
395
+ var existing = ReadUInt32 ( paddr ) & mask ;
396
+ if ( existing != value )
397
+ {
398
+ //Console.WriteLine($"existing is {x} masked:{x & mask} vs mask:{mask} value:{value}");
399
+ WriteUInt32Mask ( paddr , value , mask ) ;
400
+ return true ;
401
+ }
402
+ else
403
+ {
404
+ return false ;
405
+ }
381
406
}
382
407
383
408
private static void WriteUInt32Mask ( IntPtr address , uint value , uint mask )
0 commit comments