I have a problem where a I2C timeout appears to block other threads.
I am using:
SC20100S Dev Rev C with
Firmware 2.1.0.6400
VS2019
TinyCLR OS Project System V 1.0.5139.0
'TinyCLR.Devices.I2c V2.1.0
I have created the smallest project that demonstrates the apparent problem.
There are two very simple threads:
Thread_1 - I2C thread
while true
Prints "Before Write"
Writes a byte to I2C device
Prints "After Write"
Sleep 1000 mS
Thread 2
While true
Prints "Print Thread - " + date and time
Sleep 250 mS
With an I2C device connected (PCF8574T) this all works as expected. debug printout looking like
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:26
Print_Thread - 01/01/2021 00:00:26
Print_Thread - 01/01/2021 00:00:26
Print_Thread - 01/01/2021 00:00:26
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:27
Print_Thread - 01/01/2021 00:00:27
Print_Thread - 01/01/2021 00:00:27
Print_Thread - 01/01/2021 00:00:27
I2C Before Write
I2C After Write ..................
If I disconnect the I2C device then the print sequence looks like below with the "Print Thread now only printing every two seconds.
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:09
Print_Thread - 01/01/2021 00:00:09
Print_Thread - 01/01/2021 00:00:09
Print_Thread - 01/01/2021 00:00:09
I2C Before Write
#### Exception System.Exception - CLR_E_TIMEOUT (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.I2c.Provider.I2cControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::WriteRead [IP: 0027] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::Write [IP: 000c] ####
#### TinyCLR_I2C_Test.Program::I2C_Write_Byte [IP: 000f] ####
#### TinyCLR_I2C_Test.Program::I2C_Thread [IP: 002c] ####
I2C After Write
Print_Thread - 01/01/2021 00:00:11
Print_Thread - 01/01/2021 00:00:11
Print_Thread - 01/01/2021 00:00:11
Print_Thread - 01/01/2021 00:00:11
I2C Before Write
#### Exception System.Exception - CLR_E_TIMEOUT (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.I2c.Provider.I2cControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::WriteRead [IP: 0027] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::Write [IP: 000c] ####
#### TinyCLR_I2C_Test.Program::I2C_Write_Byte [IP: 000f] ####
#### TinyCLR_I2C_Test.Program::I2C_Thread [IP: 002c] ####
I2C After Write
Print_Thread - 01/01/2021 00:00:13
Print_Thread - 01/01/2021 00:00:13
Print_Thread - 01/01/2021 00:00:13
Print_Thread - 01/01/2021 00:00:13
I2C Before Write
#### Exception System.Exception - CLR_E_TIMEOUT (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.I2c.Provider.I2cControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::WriteRead [IP: 0027] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::Write [IP: 000c] ####
#### TinyCLR_I2C_Test.Program::I2C_Write_Byte [IP: 000f] ####
#### TinyCLR_I2C_Test.Program::I2C_Thread [IP: 002c] ####
I2C After Write
Print_Thread - 01/01/2021 00:00:15
Print_Thread - 01/01/2021 00:00:15
Print_Thread - 01/01/2021 00:00:15
Print_Thread - 01/01/2021 00:00:15
What appears to be happenning is the I2C blocks the “Print Thread” for the timeout period.
The code for the project is
using System;
using System.Diagnostics;
using System.Threading;
using GHIElectronics.TinyCLR.Devices.I2c;
using GHIElectronics.TinyCLR.Devices.Rtc;
using GHIElectronics.TinyCLR.Native;
namespace TinyCLR_I2C_Test
{
class Program
{
static void Main()
{
//Setup Real Time Clock
var rtc = RtcController.GetDefault();
var MyTime = new DateTime(2021, 01, 01, 00, 0, 00);
rtc.Now = MyTime;
SystemTime.SetTime(MyTime);
Thread Thread_1 = new Thread(I2C_Thread);
Thread_1.Start();
Thread Thread_2 = new Thread(Print_Thread);
Thread_2.Start();
}
static void Print_Thread()
{
while (true)
{
Debug.WriteLine("Print_Thread - " + DateTime.Now);
Thread.Sleep(250);
}
}
static void I2C_Thread()
{
try
{
byte device_address = 39;
I2cDevice i2cDevice;
I2cController i2cController = I2cController.FromName(GHIElectronics.TinyCLR.Pins.SC20100.I2cBus.I2c1);
I2cConnectionSettings i2cConnectionSettings = new I2cConnectionSettings(device_address, 100_000); // bus speed was 1_000
i2cDevice = i2cController.GetDevice(i2cConnectionSettings);
while (true)
{
Debug.WriteLine("I2C Before Write ");
//write byte
I2C_Write_Byte(ref i2cDevice, 0);
Debug.WriteLine("I2C After Write ");
Thread.Sleep(1000);
}
}
catch (System.Exception error)
{
Debug.WriteLine(error.Message);
}
}
private static void I2C_Write_Byte(ref I2cDevice wb_i2c, byte byte_to_write)
{
try
{
//send byte
wb_i2c.Write(new byte[] { byte_to_write });
}
catch
{
}
}
}
}
The complete debug output is
Create TS.
Loading Deployment Assemblies.
Attaching deployed file.
Assembly: mscorlib (2.1.0.0) Attaching deployed file.
Assembly: GHIElectronics.TinyCLR.Native (2.1.0.0) Attaching deployed file.
Assembly: GHIElectronics.TinyCLR.Devices.I2c (2.1.0.0) Attaching deployed file.
Assembly: GHIElectronics.TinyCLR.Devices.Gpio (2.1.0.0) Attaching deployed file.
Assembly: GHIElectronics.TinyCLR.Devices.Rtc (2.1.0.0) Attaching deployed file.
Assembly: TinyCLR_I2C_Test (1.0.0.0) Resolving.
The debugging target runtime is loading the application assemblies and starting execution.
Ready.
'GHIElectronics.TinyCLR.VisualStudio.ProjectSystem.dll' (Managed): Loaded 'C:\Projects TinyCLR\I2C_Test\TinyCLR_I2C_Test\bin\Debug\pe\..\GHIElectronics.TinyCLR.Native.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'GHIElectronics.TinyCLR.VisualStudio.ProjectSystem.dll' (Managed): Loaded 'C:\Projects TinyCLR\I2C_Test\TinyCLR_I2C_Test\bin\Debug\pe\..\GHIElectronics.TinyCLR.Devices.Gpio.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'GHIElectronics.TinyCLR.VisualStudio.ProjectSystem.dll' (Managed): Loaded 'C:\Projects TinyCLR\I2C_Test\TinyCLR_I2C_Test\bin\Debug\pe\..\GHIElectronics.TinyCLR.Devices.I2c.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'GHIElectronics.TinyCLR.VisualStudio.ProjectSystem.dll' (Managed): Loaded 'C:\Projects TinyCLR\I2C_Test\TinyCLR_I2C_Test\bin\Debug\pe\..\GHIElectronics.TinyCLR.Devices.Rtc.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'GHIElectronics.TinyCLR.VisualStudio.ProjectSystem.dll' (Managed): Loaded 'C:\Projects TinyCLR\I2C_Test\TinyCLR_I2C_Test\bin\Debug\pe\..\TinyCLR_I2C_Test.exe', Symbols loaded.
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:00
The thread '<No Name>' (0x1) has exited with code 0 (0x0).
Print_Thread - 01/01/2021 00:00:00
Print_Thread - 01/01/2021 00:00:00
Print_Thread - 01/01/2021 00:00:00
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:01
Print_Thread - 01/01/2021 00:00:01
Print_Thread - 01/01/2021 00:00:01
Print_Thread - 01/01/2021 00:00:01
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:02
Print_Thread - 01/01/2021 00:00:02
Print_Thread - 01/01/2021 00:00:02
Print_Thread - 01/01/2021 00:00:02
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:03
Print_Thread - 01/01/2021 00:00:03
Print_Thread - 01/01/2021 00:00:03
Print_Thread - 01/01/2021 00:00:03
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:04
Print_Thread - 01/01/2021 00:00:04
Print_Thread - 01/01/2021 00:00:04
Print_Thread - 01/01/2021 00:00:04
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:05
Print_Thread - 01/01/2021 00:00:05
Print_Thread - 01/01/2021 00:00:05
Print_Thread - 01/01/2021 00:00:05
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:06
Print_Thread - 01/01/2021 00:00:06
Print_Thread - 01/01/2021 00:00:06
Print_Thread - 01/01/2021 00:00:06
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:07
Print_Thread - 01/01/2021 00:00:07
Print_Thread - 01/01/2021 00:00:07
Print_Thread - 01/01/2021 00:00:07
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:08
Print_Thread - 01/01/2021 00:00:08
Print_Thread - 01/01/2021 00:00:08
Print_Thread - 01/01/2021 00:00:08
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:09
Print_Thread - 01/01/2021 00:00:09
Print_Thread - 01/01/2021 00:00:09
Print_Thread - 01/01/2021 00:00:09
I2C Before Write
#### Exception System.Exception - CLR_E_TIMEOUT (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.I2c.Provider.I2cControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::WriteRead [IP: 0027] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::Write [IP: 000c] ####
#### TinyCLR_I2C_Test.Program::I2C_Write_Byte [IP: 000f] ####
#### TinyCLR_I2C_Test.Program::I2C_Thread [IP: 002c] ####
I2C After Write
Print_Thread - 01/01/2021 00:00:11
Print_Thread - 01/01/2021 00:00:11
Print_Thread - 01/01/2021 00:00:11
Print_Thread - 01/01/2021 00:00:11
I2C Before Write
#### Exception System.Exception - CLR_E_TIMEOUT (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.I2c.Provider.I2cControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::WriteRead [IP: 0027] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::Write [IP: 000c] ####
#### TinyCLR_I2C_Test.Program::I2C_Write_Byte [IP: 000f] ####
#### TinyCLR_I2C_Test.Program::I2C_Thread [IP: 002c] ####
I2C After Write
Print_Thread - 01/01/2021 00:00:13
Print_Thread - 01/01/2021 00:00:13
Print_Thread - 01/01/2021 00:00:13
Print_Thread - 01/01/2021 00:00:13
I2C Before Write
#### Exception System.Exception - CLR_E_TIMEOUT (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.I2c.Provider.I2cControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::WriteRead [IP: 0027] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::Write [IP: 000c] ####
#### TinyCLR_I2C_Test.Program::I2C_Write_Byte [IP: 000f] ####
#### TinyCLR_I2C_Test.Program::I2C_Thread [IP: 002c] ####
I2C After Write
Print_Thread - 01/01/2021 00:00:15
Print_Thread - 01/01/2021 00:00:15
Print_Thread - 01/01/2021 00:00:15
Print_Thread - 01/01/2021 00:00:15
I2C Before Write
#### Exception System.Exception - CLR_E_TIMEOUT (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.I2c.Provider.I2cControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::WriteRead [IP: 0027] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::Write [IP: 000c] ####
#### TinyCLR_I2C_Test.Program::I2C_Write_Byte [IP: 000f] ####
#### TinyCLR_I2C_Test.Program::I2C_Thread [IP: 002c] ####
I2C After Write
Print_Thread - 01/01/2021 00:00:17
Print_Thread - 01/01/2021 00:00:17
Print_Thread - 01/01/2021 00:00:17
Print_Thread - 01/01/2021 00:00:17
I2C Before Write
#### Exception System.Exception - CLR_E_TIMEOUT (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.I2c.Provider.I2cControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::WriteRead [IP: 0027] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::Write [IP: 000c] ####
#### TinyCLR_I2C_Test.Program::I2C_Write_Byte [IP: 000f] ####
#### TinyCLR_I2C_Test.Program::I2C_Thread [IP: 002c] ####
I2C After Write
Print_Thread - 01/01/2021 00:00:19
Print_Thread - 01/01/2021 00:00:19
Print_Thread - 01/01/2021 00:00:19
Print_Thread - 01/01/2021 00:00:19
I2C Before Write
#### Exception System.Exception - CLR_E_TIMEOUT (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.I2c.Provider.I2cControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::WriteRead [IP: 0027] ####
#### GHIElectronics.TinyCLR.Devices.I2c.I2cDevice::Write [IP: 000c] ####
#### TinyCLR_I2C_Test.Program::I2C_Write_Byte [IP: 000f] ####
#### TinyCLR_I2C_Test.Program::I2C_Thread [IP: 002c] ####
I2C After Write
Print_Thread - 01/01/2021 00:00:21
Print_Thread - 01/01/2021 00:00:21
Print_Thread - 01/01/2021 00:00:21
Print_Thread - 01/01/2021 00:00:21
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:22
Print_Thread - 01/01/2021 00:00:22
Print_Thread - 01/01/2021 00:00:22
Print_Thread - 01/01/2021 00:00:22
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:23
Print_Thread - 01/01/2021 00:00:23
Print_Thread - 01/01/2021 00:00:23
Print_Thread - 01/01/2021 00:00:23
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:24
Print_Thread - 01/01/2021 00:00:24
Print_Thread - 01/01/2021 00:00:24
Print_Thread - 01/01/2021 00:00:24
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:25
Print_Thread - 01/01/2021 00:00:25
Print_Thread - 01/01/2021 00:00:25
Print_Thread - 01/01/2021 00:00:25
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:26
Print_Thread - 01/01/2021 00:00:26
Print_Thread - 01/01/2021 00:00:26
Print_Thread - 01/01/2021 00:00:26
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:27
Print_Thread - 01/01/2021 00:00:27
Print_Thread - 01/01/2021 00:00:27
Print_Thread - 01/01/2021 00:00:27
I2C Before Write
I2C After Write
Print_Thread - 01/01/2021 00:00:28
Print_Thread - 01/01/2021 00:00:28
The program '[5] TinyCLR application: Managed' has exited with code 0 (0x0).