using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace TinyFPGA_VisualProgrammer { public class JSON_BoardMeta { public string name { get; set; } public string fpga { get; set; } public string hver { get; set; } public string uuid { get; set; } } public class JSON_BootMeta { public string bootloader { get; set; } public string bver { get; set; } public string update { get; set; } public JSON_AddrMap addrmap { get; set; } } public class JSON_AddrMap { public string bootloader { get; set; } public string userimage { get; set; } public string userdata { get; set; } } public class TinyProg { SerialController pPort = null; byte SecurePage_bitOffset = 0x00; byte SecurePage_writeCmd = 0x00; byte SecurePage_readCmd = 0x00; byte SecurePage_eraseCmd = 0x00; TinyMeta tinyMeta = null; public bool TinyFPGAIsConnected { get; private set; } public TinyProg(SerialController p) { TinyFPGAIsConnected = false; if (p != null) pPort = p; } public void CheckTinyPresence() { WakeCmd(); byte[] flash_id = RetrieveFlashID(); if (flash_id.Length >= 3) { if (flash_id[0] == 0x9D && flash_id[2] == 0x60) { // ISSI SecurePage_bitOffset = 4; SecurePage_writeCmd = 0x62; SecurePage_readCmd = 0x68; SecurePage_eraseCmd = 0x64; } else { // Adesto SecurePage_bitOffset = 0; SecurePage_writeCmd = 0x42; SecurePage_readCmd = 0x48; SecurePage_eraseCmd = 0x44; } } tinyMeta = new TinyMeta(this); if (tinyMeta.BoardMeta != null) TinyFPGAIsConnected = true; else TinyFPGAIsConnected = false; } public JSON_BoardMeta GetBoardData() { return tinyMeta.BoardMeta; } public JSON_BootMeta GetBootData() { return tinyMeta.BootMeta; } byte[] SendCommand(byte opcode, byte[] addr, byte[] datas, uint read_len = 0) { if (addr == null) addr = new byte[] { }; if (datas == null) datas = new byte[] { }; byte[] _ret = new byte[read_len]; byte[] cmdSequence = new byte[sizeof(byte) + sizeof(ushort) + sizeof(ushort) + sizeof(byte) + addr.Length + datas.Length]; int i; /* * Prepare datas container */ cmdSequence[0] = 0x01; ushort seqSize = (ushort)(1 + addr.Length + datas.Length); cmdSequence[1] = (byte)(seqSize & 0xFF); // LSB cmdSequence[2] = (byte)((seqSize >> 8) & 0xFF); cmdSequence[3] = (byte)(read_len & 0xFF); // LSB cmdSequence[4] = (byte)((read_len >> 8) & 0xFF); cmdSequence[5] = opcode; i = 6; foreach (byte ab in addr) cmdSequence[i++] = ab; i = 6 + addr.Length; foreach (byte d in datas) cmdSequence[i++] = d; /* * Send datas container through serial line */ //pPort.clearBuffer(); pPort.SendBytes(cmdSequence, cmdSequence.Length); if (read_len > 0) _ret = pPort.WaitForBytes((int)read_len); return _ret; } public void WakeCmd() { SendCommand(0xab, null, null); } byte[] RetrieveFlashID() { return SendCommand(0x9f, null, null, 3); } void FlashWriteEnable() { SendCommand(0x06, null, null); } void FlashWriteDisable() { SendCommand(0x04, null, null); } byte RetrieveStatus() { return SendCommand(0x05, null, null, 1)[0]; } void WaitWhileBusy() { while ((RetrieveStatus() & 1) == 1) { } } void EraseSecureRegPage(uint page) { FlashWriteEnable(); SendCommand(SecurePage_eraseCmd, BitConverter.GetBytes((page & 0xFFFF) << 8 + SecurePage_bitOffset), null); WaitWhileBusy(); } void ProgramSecureRegPage(uint page, byte[] data) { FlashWriteEnable(); SendCommand(SecurePage_writeCmd, BitConverter.GetBytes((page & 0xFFFF) << 8 + SecurePage_bitOffset), data); WaitWhileBusy(); } public string ReadSecureRegPage(uint page) { return Encoding.UTF8.GetString(SendCommand(SecurePage_readCmd, BitConverter.GetBytes((page & 0xFFFF) << 8 + SecurePage_bitOffset), new byte[] { 0x00 }, 255)).Insert(0, "{"); } } public class TinyMeta { TinyProg tProg; //JSONRoot JSON_root; public JSON_BoardMeta BoardMeta { get; private set; } public JSON_BootMeta BootMeta { get; private set; } public TinyMeta(TinyProg tProg) { this.tProg = tProg; tProg.WakeCmd(); ReadMetadata(); } void ReadMetadata() { string rawJSON; rawJSON = tProg.ReadSecureRegPage(1).Substring(13, 107); BoardMeta = JsonConvert.DeserializeObject(rawJSON); // Read 1st register, contain boardmeta Thread.Sleep(200); rawJSON = tProg.ReadSecureRegPage(2).Substring(12, 209); BootMeta = JsonConvert.DeserializeObject(rawJSON); // Read 2nd register, contain bootmeta Thread.Sleep(200); //tProg.ReadSecureRegPage(3); // Read 3rd register, contain nothing } } }