Looking for the source code for the Official Demo for the SC13048 Dev board.
I see “SC20100S Dev” and “SCM2060D Dev” on GitHub TinyClr-Samples.
But cannot find the SC13048 Dev Board code ?
Is it missing, or should I look someplace else ?
Looking for the source code for the Official Demo for the SC13048 Dev board.
I see “SC20100S Dev” and “SCM2060D Dev” on GitHub TinyClr-Samples.
But cannot find the SC13048 Dev Board code ?
Is it missing, or should I look someplace else ?
The SC13 is quite simple so no Demo, you can find example code in our doc.
And we are here to help, just let us know.
Thanks.
Hmmm … maybe I wasn’t clear.
The SC13408 Dev Board comes preloaded with a Demo App.
I’m looking for the source code to that App as an example to get the screen working.
Where would I find the source code for the preloaded Demo App ?
it maybe the tester application use for testing.
This is not demo, but if you want we can share the testing application.
Yes please … some example code would be great !
I’m trying to figure out to use the display.
The limited documentation is … a schematic. Nowhere in the schematic does it include the model of the display. Is there some other documentation I’m missing ?
I found the GHIElectronics.TinyCLR.Drivers.Sitronix.ST7735 NUGet package.
The display looks similar … maybe that’s it? Not sure which size though.
Also, there doesn’t seem to be any documentation on GHIElectronics.TinyCLR.Drivers.Sitronix.ST7735 either. Not sure how to use it or what the various commands do.
If … this is even the correct display.
Thanks for your help !
I can share here:
make new project, add these two files below and add needed nugets
Program.cs
using System;
using System.Collections;
using System.Diagnostics;
using System.Text;
using System.Threading;
using GHIElectronics.TinyCLR.Cryptography;
using GHIElectronics.TinyCLR.Devices.Can;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.Pwm;
using GHIElectronics.TinyCLR.Devices.Rtc;
using GHIElectronics.TinyCLR.Devices.Storage;
using GHIElectronics.TinyCLR.Devices.Uart;
using GHIElectronics.TinyCLR.Drivers.BasicGraphics;
using GHIElectronics.TinyCLR.Pins;
namespace SC13048QDev {
class Program {
const int Ldr1 = SC13048.GpioPin.PC13;
const int App = SC13048.GpioPin.PB7;
const int Mod = SC13048.GpioPin.PA15;
static GpioPin ldr;
static GpioPin app;
static GpioPin mod;
static GpioController gpioController = GpioController.GetDefault();
static Thread printStarThread;
static void Main() {
ldr = gpioController.OpenPin(Ldr1);
app = gpioController.OpenPin(App);
mod = gpioController.OpenPin(Mod);
ldr.SetDriveMode(GpioPinDriveMode.InputPullUp);
app.SetDriveMode(GpioPinDriveMode.InputPullUp);
mod.SetDriveMode(GpioPinDriveMode.InputPullUp);
DoTest();
}
static Graphics gfx;
static uint colorWhite = BasicGraphics.ColorFromRgb(255, 255, 255);
static uint colorRed = BasicGraphics.ColorFromRgb(255, 0, 0);
static uint colorBlue = BasicGraphics.ColorFromRgb(0, 0, 255);
static uint colorYellow = BasicGraphics.ColorFromRgb(255, 255, 0);
static uint colorGreen = BasicGraphics.ColorFromRgb(0, 255, 0);
static void DoTest() {
gfx = new Graphics();
gfx.DrawString("Tester (07132021)", colorWhite, MenuStartX, MenuStartY);
//Display
gfx.FillRect(colorRed, 0, currentY, 40, ItemOffsetY);
gfx.FillRect(colorGreen, 40, currentY, 40, ItemOffsetY);
gfx.FillRect(colorBlue, 80, currentY, 40, ItemOffsetY);
gfx.FillRect(colorWhite, 120, currentY, 40, ItemOffsetY);
currentY += ItemOffsetY;
gfx.DrawString("Red?", colorRed, 0, currentY);
gfx.DrawString("Green?", colorGreen, 40, currentY);
gfx.DrawString("Blue?", colorBlue, 80, currentY);
gfx.DrawString("White?", colorWhite, 120, currentY);
currentY += ItemOffsetY;
// RTC
gfx.DrawString("Rtc...", colorWhite, currentX, currentY);
if (DoTestRtc() == true) {
gfx.DrawString("OK", colorGreen, currentX + 6 * 6, currentY);
}
else {
gfx.DrawString("Failed", colorRed, currentX + 6 * 6, currentY);
return;
}
currentY += ItemOffsetY;
// QSPI
gfx.DrawString("Qspi...", colorWhite, currentX, currentY);
if (DoTestQspi() == true) {
gfx.DrawString("OK", colorGreen, currentX + 7 * 6, currentY);
}
else {
gfx.DrawString("Failed", colorRed, currentX + 7 * 6, currentY);
return;
}
currentY += ItemOffsetY;
// Buttons
gfx.DrawString("ldr...", colorWhite, currentX, currentY);
while (ldr.Read() == GpioPinValue.High) ;
gfx.DrawString("OK", colorGreen, currentX + 6 * 6, currentY); currentY += ItemOffsetY;
gfx.DrawString("app...", colorWhite, currentX, currentY);
while (app.Read() == GpioPinValue.High) ;
gfx.DrawString("OK", colorGreen, currentX + 6 * 6, currentY); currentY += ItemOffsetY;
gfx.DrawString("mod...", colorWhite, currentX, currentY);
while (mod.Read() == GpioPinValue.High) ;
gfx.DrawString("OK", colorGreen, currentX + 6 * 6, currentY); currentY += ItemOffsetY;
//Sound
gfx.DrawString("Sound...", colorWhite, currentX, currentY);
DoTestSound();
gfx.DrawString("beep ???", colorRed, currentX + 8 * 6, currentY); currentY += ItemOffsetY;
// Leds
gfx.DrawString("Led...", colorWhite, currentX, currentY);
new Thread(ThreadToggleLed).Start();
gfx.DrawString("toggle ???", colorRed, currentX + 8 * 6, currentY); currentY += ItemOffsetY;
gfx.DrawString("External power ???", colorRed, currentX, currentY); currentY += ItemOffsetY;
// Uart
gfx.DrawString("Quick test done!", colorGreen, currentX, currentY); currentY += ItemOffsetY;
gfx.DrawString("Any button for Uart test!", colorGreen, currentX, currentY); currentY += ItemOffsetY;
while (ldr.Read() == GpioPinValue.High && app.Read() == GpioPinValue.High && mod.Read() == GpioPinValue.High) ;
runToggleLedThread = false;
gfx.Clear();
gfx.Flush();
currentY = 0;
gfx.DrawString("Uart...", colorWhite, currentX, currentY); currentY += ItemOffsetY;
gfx.DrawString("Connect to Tera Term, 9600", colorWhite, currentX, currentY); currentY += ItemOffsetY;
gfx.DrawString("Type the character on Tera", colorWhite, currentX, currentY); currentY += ItemOffsetY;
gfx.DrawString("Term screen.", colorWhite, currentX, currentY); currentY += ItemOffsetY;
starY = currentY;
currentStarX = 0;
doPrintStar = true;
printStarThread = new Thread(TheadPrintStar);
printStarThread.Start();
DoTestUart();
// CAN
doPrintStar = false;
gfx.Clear();
gfx.Flush();
currentY = 0;
gfx.DrawString("Can...", colorWhite, currentX, currentY); currentY += ItemOffsetY;
gfx.DrawString("Use CanTester Board, connect:", colorWhite, currentX, currentY); currentY += ItemOffsetY;
gfx.DrawString("High <-> High", colorWhite, currentX, currentY); currentY += ItemOffsetY;
gfx.DrawString("Low <-> Low", colorWhite, currentX, currentY); currentY += ItemOffsetY;
gfx.DrawString("GND <-> GND", colorWhite, currentX, currentY); currentY += ItemOffsetY;
starY = currentY;
currentStarX = 0;
doPrintStar = true;
var canTest = DoTestCan();
doPrintStar = false;
currentY += ItemOffsetY;
if (canTest) {
gfx.DrawString("Full test passed...", colorGreen, currentX, currentY); currentY += ItemOffsetY;
}
else {
gfx.DrawString("Can test failed...", colorRed, currentX, currentY); currentY += ItemOffsetY;
}
//gfx.Flush();
}
static bool DoTestRtc() {
var rtc = RtcController.GetDefault();
return !rtc.InternalRC;
}
static bool DoTestQspi() {
var storeController = StorageController.FromName("GHIElectronics.TinyCLR.NativeApis.STM32L4.QspiStorageController\\0");
var drive = storeController.Provider;
drive.Open();
var size = 8 * 1024;
var rd = new Random();
var sectorSize = 4 * 1024;
var dataWrite = new byte[sectorSize];
rd.NextBytes(dataWrite);
var crc16 = new Crc16();
var crcVal = crc16.ComputeHash(dataWrite);
var offset = 0;
while (offset < size) {
drive.Erase(offset, dataWrite.Length, TimeSpan.FromSeconds(1));
drive.Write(offset, dataWrite.Length, dataWrite, 0, TimeSpan.FromSeconds(1));
var dataRead = new byte[sectorSize];
drive.Read(offset, dataRead.Length, dataRead, 0, TimeSpan.FromSeconds(10));
if (crc16.ComputeHash(dataRead) != crcVal) {
return false;
}
offset += sectorSize;
}
drive.Close();
return true;
}
static bool DoTestUart() {
var serial = GHIElectronics.TinyCLR.Devices.Uart.UartController.FromName(SC13048.UartPort.Uart1);
var pass = false;
var uartSetting = new UartSetting() {
BaudRate = 9600,
DataBits = 8,
Parity = UartParity.None,
StopBits = UartStopBitCount.One,
};
serial.SetActiveSettings(uartSetting);
serial.ReadBufferSize = 1 * 1024;
serial.WriteBufferSize = 1 * 1024;
serial.Enable();
serial.DataReceived += (a, b) => {
var b2r = a.BytesToRead;
var data = new byte[b2r];
a.Read(data);
for (var i = 0; i < b2r; i++) {
if (data[i] == (byte)('A') || data[i] == (byte)('a')) {
pass = true;
break;
}
}
};
serial.ClearReadBuffer();
serial.ClearWriteBuffer();
while (pass == false) {
serial.Write(new byte[] { (byte)('a') });
Thread.Sleep(1000);
}
return pass;
}
const int MenuStartX = 25;
const int MenuStartY = 0;
const int MenuOffsetY = 10;
const int ItemStartX = 0;
const int ItemStartY = MenuStartY + MenuOffsetY;
const int ItemOffsetY = 10;
static int currentY = ItemStartY;
static int currentX = ItemStartX;
static void DoTestSound() {
var pwmController = PwmController.FromName(SC13048.Timer.Pwm.Controller2.Id);
var pwmChannel = pwmController.OpenChannel(SC13048.Timer.Pwm.Controller2.PA5);
pwmController.SetDesiredFrequency(1000);
pwmChannel.SetActiveDutyCyclePercentage(0.50);
pwmChannel.Start();
Thread.Sleep(250);
pwmChannel.Stop();
}
static bool DoTestCan() {
var controller = CanController.FromName(SC13048.CanBus.Can1);
controller.SetNominalBitTiming(new GHIElectronics.TinyCLR.Devices.Can.CanBitTiming(5, 4, 16, 1, false)); // 250Kb at 40MHz
var data = new byte[8];
var msg0 = new GHIElectronics.TinyCLR.Devices.Can.CanMessage() { Data = data, ArbitrationId = (0x260413), Length = data.Length, RemoteTransmissionRequest = false, ExtendedId = true, FdCan = false, BitRateSwitch = false };
controller.Enable();
var pass = false;
var cnt = 0;
while (!pass) {
cnt++;
try {
if (cnt % 10 == 0) {
controller.WriteMessages(new GHIElectronics.TinyCLR.Devices.Can.CanMessage[] { msg0 }, 0, 1);
}
if (controller.MessagesToRead > 0) {
var msgCnt = controller.MessagesToRead;
var msg = new CanMessage[msgCnt];
for (var i = 0; i < msg.Length; i++) {
msg[i] = new CanMessage();
}
controller.ReadMessages(msg, 0, msg.Length);
for (var i = 0; i < msg.Length; i++) {
if (msg[i].ArbitrationId == 0x260413) {
pass = true;
break;
}
}
}
}
catch {
return false;
}
Thread.Sleep(100);
}
return pass;
}
static bool runToggleLedThread = true;
static void ThreadToggleLed() {
var led = GpioController.GetDefault().OpenPin(SC13048.GpioPin.PA8);
led.SetDriveMode(GpioPinDriveMode.Output);
while (runToggleLedThread) {
led.Write(led.Read() == GpioPinValue.High ? GpioPinValue.Low : GpioPinValue.High);
Thread.Sleep(100);
}
}
static int starY = 0;
static int currentStarX = 0;
static bool doPrintStar = false;
static void TheadPrintStar() {
while (true) {
if (doPrintStar) {
gfx.DrawString("*", colorWhite, currentStarX, starY);
currentStarX += 1 * 6;
if (currentStarX >= 160) {
currentStarX = 0;
gfx.FillRect(0, currentStarX, starY, 160, 10);
}
}
Thread.Sleep(1000);
}
}
}
}
Graphics.cs
using System;
using System.Collections;
using System.Text;
using System.Threading;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.Spi;
using GHIElectronics.TinyCLR.Drivers.BasicGraphics;
using GHIElectronics.TinyCLR.Drivers.Sitronix.ST7735;
using GHIElectronics.TinyCLR.Pins;
namespace SC13048QDev {
public class Graphics : BasicGraphics {
private readonly ST7735Controller st7735;
const int Width = 160;
const int Height = 128;
public Graphics() : base(Width, Height, ColorFormat.Rgb565) {
var spi = SpiController.FromName("GHIElectronics.TinyCLR.NativeApis.STM32L4.SpiController\\0");
var gpio = GpioController.GetDefault();
var customConfig = ST7735Controller.GetConnectionSettings(SpiChipSelectType.Gpio, GpioController.GetDefault().OpenPin(SC13048.GpioPin.PB14));
customConfig.ClockFrequency = 12_000_000;
this.st7735 = new ST7735Controller(
spi.GetDevice(customConfig), // ChipSelect
gpio.OpenPin(SC13048.GpioPin.PA14), // Pin RS
gpio.OpenPin(SC13048.GpioPin.PA13)// Pin RESET
);
var bl = gpio.OpenPin(STM32H7.GpioPin.PB13); // back light
bl.SetDriveMode(GpioPinDriveMode.Output);
bl.Write(GpioPinValue.High);
this.st7735.SetDataAccessControl(true, true, false, false); // rotate the screen
this.st7735.SetDrawWindow(0, 0, Width, Height);
this.st7735.Enable();
}
public void Flush() => this.st7735.DrawBuffer(this.Buffer, 0, 0, Width, Height, Width, 1, 1);
public new void DrawString(string s, uint color, int x, int y) {
base.DrawString(s, color, x, y);
this.Flush();
}
public void FillRect(uint color, int x, int y, int w, int h) {
h += y;
w += x;
for (var y1 = y; y1<h; y1++) {
for (var x1 = x; x1 < w; x1++) {
this.SetPixel(x1, y1, color);
}
}
}
}
}
And those nugets needed:
<package id="GHIElectronics.TinyCLR.Core" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Cryptography" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Devices.Can" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Devices.Gpio" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Devices.Pwm" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Devices.Rtc" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Devices.Spi" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Devices.Storage" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Devices.Uart" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Drivers.BasicGraphics" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Drivers.Sitronix.ST7735" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Native" version="2.2.0.5000" targetFramework="net48" />
<package id="GHIElectronics.TinyCLR.Pins" version="2.2.0.5000" targetFramework="net48" />
Thanks !
Great example.
Looks like I was on the right track for the display.
This code helps a bunch.