217 lines
6.2 KiB
C#
217 lines
6.2 KiB
C#
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<JSON_BoardMeta>(rawJSON); // Read 1st register, contain boardmeta
|
|
Thread.Sleep(200);
|
|
|
|
rawJSON = tProg.ReadSecureRegPage(2).Substring(12, 209);
|
|
BootMeta = JsonConvert.DeserializeObject<JSON_BootMeta>(rawJSON); // Read 2nd register, contain bootmeta
|
|
Thread.Sleep(200);
|
|
//tProg.ReadSecureRegPage(3); // Read 3rd register, contain nothing
|
|
}
|
|
}
|
|
}
|