FEZ Domino with MI0283QT-2 touch LCD

@ Andreas
I thought so too, but your code showed that to be false, as long as the buffer of bytes/words is as large as possible. I also thought that I would get into trouble with large buffers that got interrupted by task switching, but that doesn’t seem to be the case with .NETMF, so apparently I can send many small buffers between DrawStart and DrawStop.
I also changed the xx = new byte[] { LCD_DATA } to a constant to reduce the allocation and freeing of small memory blocks, but I don’t know enough about the GHI implementation to know if that even happens - maybe a register is used for that sort of thing.
I’m just soldering up my other MI0293QT panels to use for user-input and display on my Panda II’s. I was afraid they weren’t going to be responsive enough - but that’s definitely not the case.

New Version now uploaded.
Update Rev 2
-Calibration Data can be stored on SD or InternalFlashStorage

  • BMP can now be loaded (Format only 24bit no compression) Example files in folder SD in Zip
  • Circles now correctly filled
  • Code optimized

cu
Andreas

@ Andreas
Thanks. Some good ideas there. I decided to stick with my old one for the moment

1.) The DrawCircle always wants to make a black square as background, which isn’t quite what my current one does (I often use YELLOW or LIGHTCYAN as background, DrawCircle makes a black box around the circle). I’ll post the version I use in a later post.

  1. The SD routines are nice, as far as correct programming goes. The calibration will work fine, but the bitmap routines will crash my system with larger bitmaps due to the width*height ushort allocation. I found using smaller buffers (i.e. reading several smaller amounts from the SDCard and sending them to the TFT in between) to be healthier with the bitmaps I want to use.
    The code is not as nice, but for what it’s worth …
   public class SD_Storage 
   {
      // Hold a static reference in case the GC kicks in and disposes it automatically
      static PersistentStorage sdCard;
      // Hold a filestream if the file is open, so that byte[] chunks can be read
      static FileStream fsPtr;

      public static bool SDCardLoaded
      {
         get;
         set;
      }
      
      public bool Check_SDCardLoaded
      {
         get { return (SDCardLoaded); }
      }

      public void initSDCard()
      {
         if (sdCard == null)
         {
            // Subscribe to RemovableMedia events
            RemovableMedia.Insert += RemovableMedia_Insert;
            RemovableMedia.Eject += RemovableMedia_Eject;

            // Assume SD card is inserted
            // Create a new storage device
            try
            {
               sdCard = new PersistentStorage("SD");
               sdCard.MountFileSystem();
               SDCardLoaded = true;
            }
            catch (Exception ex)
            {
               Debug.Print("Failed to mount SD card: " + ex.Message);
               SDCardLoaded = false;
            }

         }
      }

      public bool OpenFile(string filename)
      {
         if (sdCard == null)
            initSDCard();

         if (SDCardLoaded)
         {
            //filename = filename.Replace("/", "\\");
            if (filename[0] == '\\')
               filename = filename.Substring(1);

            var path = Path.Combine("\\SD", filename);
            if (File.Exists(path))
            {
               fsPtr = File.OpenRead(path);
               return (true);
            }
         }
         return (false);
      }

      public int ReadFile(byte[] buff, int offset, int count)
      {
         int g;

         if (fsPtr == null)
            return 0;

         fsPtr.Seek((long)offset, SeekOrigin.Begin);
         g = fsPtr.Read(buff, 0, count);

         Debug.Print("Read Count " + g.ToString());
         return (g);
      }

      public bool CloseFile()
      {
         if (fsPtr == null)
            return false;
         fsPtr.Close();
         return true;
      }

      public void UnmountSDCard()
      {
         if (SDCardLoaded)
         {
            Debug.Print("Storage unmouted.");
            sdCard.UnmountFileSystem();
            SDCardLoaded = false;
            Thread.Sleep(200);
            sdCard.Dispose();
         }
      }

      static void RemovableMedia_Insert(object sender, MediaEventArgs e)
      {
         Debug.Print("Storage \"" + e.Volume.RootDirectory + "\" is inserted.");
         SDCardLoaded = true;

         // We do not need the old instance any more
         //UnmountSDCard();
      }

      static void RemovableMedia_Eject(object sender, MediaEventArgs e)
      {
         Debug.Print("Storage \"" + e.Volume.RootDirectory + "\" is ejected.");
         SDCardLoaded = false;
      }

   }

The call then looks like this (this is a 176x132 bitmap from a cell phone, where the first 6 bytes are display size info I don’t need)

      public bool DisplayPicture(string filename, ushort x1, ushort y1, ushort x2, ushort y2)
      {
         byte[] buff = new byte[512];
         int start;
         int n;

         SD_Storage sdc = new SD_Storage();
         sdc.initSDCard();

         if (sdc.Check_SDCardLoaded == true)
         {
            if (sdc.OpenFile(filename) == true)
            {
               start = 6;	// Skip the first 6 bytes
               // Start picture, transfer data from SDCard
               SetArea(x1, y1, x2, y2);    // Define Window	
               StartDrawing();
               while ((n = sdc.ReadFile(buff, start, 512)) > 0)
               {
                  start += n;
                  _SPI.Write(buff);
               }
               StopDrawing();

               sdc.CloseFile();
               sdc.UnmountSDCard();
               return (true);
            }

         }
         return (false);
      }

This is wobbly if you don’t know the size beforehand, I guess. But usually I do, or I could get it without reading in the whole blob.
Tips for decent C# code writing are always appreciated.

@ Lurch
Black Box in the drawcircle routine is a mistake, i have to take a look at this.

You are right, smaller buffers are the solution for the bitmaps. I want to build this in the next rev.

I think, we are a good Team and at the end we have a perfect Display :smiley: