SC20100S SPI Display Exception

I have a problem with a spi display on a developpment board SC20100S Dev Rev C…

At a random time after I start the program an exception is generated for no apparent reason.
It may run for 5 seconds or it may make it to 200 seconds - I havent had it run for grater than 200 seconds.

I feel I must be doing something basically wrong but for the life of me cant find the problem.

Firmware Version is 2.1.0.6000
VS TinyCLR OS Project System is Version 2.1.700
All Nugets are 2.1.0
Board is powered by an external power supply

The complete output of the debugger is

Create TS.

Loading Deployment Assemblies.

Attaching deployed file.

Assembly: mscorlib (2.1.0.0) Attaching deployed file.

Assembly: GHIElectronics.TinyCLR.Drawing (2.1.0.0) Attaching deployed file.

Assembly: GHIElectronics.TinyCLR.Devices.Spi (2.1.0.0) Attaching deployed file.

Assembly: GHIElectronics.TinyCLR.Native (2.1.0.0) Attaching deployed file.

Assembly: Display_Test (1.0.0.0) Attaching deployed file.

Assembly: GHIElectronics.TinyCLR.Devices.Gpio (2.1.0.0) Attaching deployed file.

Assembly: GHIElectronics.TinyCLR.Drivers.Sitronix.ST7735 (2.1.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\TinyCLR_ST7735_Test\Display_Test\bin\Debug\pe…\GHIElectronics.TinyCLR.Drawing.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\TinyCLR_ST7735_Test\Display_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\TinyCLR_ST7735_Test\Display_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\TinyCLR_ST7735_Test\Display_Test\bin\Debug\pe…\GHIElectronics.TinyCLR.Devices.Spi.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\TinyCLR_ST7735_Test\Display_Test\bin\Debug\pe…\GHIElectronics.TinyCLR.Drivers.Sitronix.ST7735.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\TinyCLR_ST7735_Test\Display_Test\bin\Debug\pe…\Display_Test.exe’, Symbols loaded.
The thread ‘’ (0x2) has exited with code 0 (0x0).
#### Exception System.InvalidOperationException - CLR_E_INVALID_OPERATION (1) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.Spi.Provider.SpiControllerApiWrapper::WriteRead [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.Spi.SpiDevice::WriteRead [IP: 001d] ####
#### GHIElectronics.TinyCLR.Devices.Spi.SpiDevice::Write [IP: 000b] ####
#### GHIElectronics.TinyCLR.Devices.Spi.SpiDevice::Write [IP: 0009] ####
#### GHIElectronics.TinyCLR.Drivers.Sitronix.ST7735.ST7735Controller::DrawBuffer [IP: 0019] ####
#### System.Drawing.Graphics::Flush [IP: 0051] ####
#### Display_Test.Program::Main [IP: 00f1] ####
Exception thrown: ‘System.InvalidOperationException’ in GHIElectronics.TinyCLR.Devices.Spi.dll
Exception was thrown: System.InvalidOperationException
The thread ‘’ (0x1) has exited with code 0 (0x0).
Done.
Waiting for debug commands…
The program ‘[13] TinyCLR application: Managed’ has exited with code 0 (0x0).

The program is

using System.Diagnostics;
using System.Threading;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.Spi;
using GHIElectronics.TinyCLR.Drivers.Sitronix.ST7735;
using GHIElectronics.TinyCLR.Pins;
using System.Drawing;

namespace Display_Test
{
class Program
{
private static ST7735Controller DisplayController = null;
private const int Width = 160;
private const int Height = 128;

static void Main()
{

  try
  {
    int Screen_Display_Counter = 0;
    string update_string = "---";

    var spi = SpiController.FromName(SC20100.SpiBus.Spi4);
    var gpio = GpioController.GetDefault();

   DisplayController = new ST7735Controller(
             spi.GetDevice(ST7735Controller.GetConnectionSettings(SpiChipSelectType.Gpio, gpio.OpenPin(SC20100.GpioPin.PD10))), // ChipSelect 
             gpio.OpenPin(SC20100.GpioPin.PC4), // Pin RS
             gpio.OpenPin(SC20100.GpioPin.PE15) // Pin RESET
   );
           
    DisplayController.SetDataAccessControl(true, true, false, false); //Rotate the screen.
    DisplayController.SetDrawWindow(0, 0, Width, Height);
    DisplayController.Enable();
  
    var bl = gpio.OpenPin(SC20100.GpioPin.PA15); // back light

    bl.Write(GpioPinValue.High);
    bl.SetDriveMode(GpioPinDriveMode.Output);
    bl.Write(GpioPinValue.High);
   
    
    Graphics.OnFlushEvent += Graphics_OnFlushEvent;

    var font = Display_Test.Properties.Resources.GetFont(Display_Test.Properties.Resources.FontResources.droid_reg10);

    var whitePen = new System.Drawing.Pen(System.Drawing.Color.White);
    var blackPen = new System.Drawing.Pen(System.Drawing.Color.Black);

    var screen = Graphics.FromImage(new Bitmap(DisplayController.Width, DisplayController.Height));

    while (true)
    {

      {
        Screen_Display_Counter++;

        update_string = Screen_Display_Counter.ToString();
      
        screen.FillRectangle(blackPen.Brush, 0, 0, Width, Height);

        screen.DrawString(update_string, font, whitePen.Brush, 130, 10);
                    
        screen.Flush();
         
        Thread.Sleep(500);

      }
    }
  }
  catch (System.Exception error)
  {
    
    Debug.WriteLine(error.Message);
  }
  

}
private static void Graphics_OnFlushEvent(Graphics sender, byte[] data, int x, int y, int width, int height, int originalWidth) => DisplayController.DrawBuffer(data);

}
}

Using 2.1?

We can reproduce with your code but not sure why yet.

The workaround is, according your code, try catch and resend the frame

private static void Graphics_OnFlushEvent(Graphics sender, byte[] data, int x, int y, int width, int height, int originalWidth) {
            for (; ; )
                try {
                    DisplayController.DrawBuffer(data);

                    break;
                }
                catch {}
        }
1 Like

Thanks @Dat_Tran