Skip to content

Instantly share code, notes, and snippets.

@kazu1995
Created November 19, 2017 00:49
Show Gist options
  • Save kazu1995/c9b2551540cff6c8110f3283d0dbc5b5 to your computer and use it in GitHub Desktop.
Save kazu1995/c9b2551540cff6c8110f3283d0dbc5b5 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using VirtualJtag.Constant;
using VirtualJtag.Instruction;
namespace VirtualJtag.Communicate
{
public unsafe class TmsControl
{
// https://msdn.microsoft.com/ja-jp/library/k7137bfe.aspx
// プラットフォームターゲットを常にx86(32bit)にしてビルドすること
const string DLL_PATH = "ftd2xx.dll";
[DllImport(DLL_PATH)]
unsafe private static extern UInt32 FT_Open( Int16 DeviceNumber, UInt32* ftHandle );
[DllImport(DLL_PATH)]
private static extern UInt32 FT_Close( UInt32 ftHandle );
[DllImport(DLL_PATH)]
unsafe private static extern UInt32 FT_Write( UInt32 ftHandle,
[MarshalAs(UnmanagedType.LPArray)] short[] bdata, UInt32 BufferSize, UInt32* BytesWriten );
[DllImport(DLL_PATH)]
unsafe private static extern UInt32 FT_Read( UInt32 lngHandle,
[MarshalAs(UnmanagedType.LPArray)] byte[] bdata, UInt32 lngBufferSize, UInt32* lngBytesReturned );
const short L = 0x2D2C;
const short H = (short)(L | 0x1010);
const short TMS = (short)(L | 0x0202);
const short TMS_H = (short)(TMS | H);
const short WR = 0x81;
const short RD = 0xC0;
const short OFF = 0x0D0C;
private UInt32 ftHandle;
DataByteLength DataByteLength = new DataByteLength();
private uint MoveIdle()
{
uint size;
var memory = new List<short> { TMS, TMS, TMS, TMS, TMS, L };
return FT_Write(ftHandle, memory.ToArray(), (UInt32)memory.Count << 1, &size);
}
private uint MoveIdleToShiftir()
{
uint size;
var memory = new List<short> { TMS, TMS, L, L };
return FT_Write(ftHandle, memory.ToArray(), (UInt32)memory.Count << 1, &size);
}
private uint MoveShiftirToShiftdr()
{
uint size;
var memory = new List<short> { TMS, TMS, TMS, L, L };
return FT_Write(ftHandle, memory.ToArray(), (UInt32)memory.Count << 1, &size);
}
private uint MoveShiftdrToShiftir()
{
uint size;
var memory = new List<short> { TMS_H, TMS, TMS, TMS, L, L };
return FT_Write(ftHandle, memory.ToArray(), (UInt32)memory.Count << 1, &size);
}
private List<byte> ReadShiftdr( short drCodeByteLength )
{
uint size;
// jtag.read
var memory = new List<short> { (short)((0 << 8) | (RD | drCodeByteLength)), TMS_H, TMS, TMS, L, L };
FT_Write(ftHandle, memory.ToArray(), (UInt32)memory.Count << 1, &size);
var rxDataBuf = new List<byte>();
for (var i = 0; i < drCodeByteLength; i++)
{
byte[] rxData = new byte[64];
FT_Read(ftHandle, rxData, 1, &size);
rxDataBuf.Add(rxData[0]);
}
return rxDataBuf;
}
private uint WriteShiftir( byte irCodeValue )
{
uint size;
var memory = new List<short> { (short)((irCodeValue << 8) | WR), L };
return FT_Write(ftHandle, memory.ToArray(), (UInt32)memory.Count << 1, &size);
}
private uint WriteShiftdr( byte drCodeValue )
{
uint size;
var memory = new List<short> { (short)((drCodeValue << 8) | WR)};
return FT_Write(ftHandle, memory.ToArray(), (UInt32)memory.Count << 1, &size);
}
/*
private uint LoopShiftdr()
{
uint size;
var memory = new List<short> { TMS_H, TMS, TMS, L, L };
return FT_Write(ftHandle, memory.ToArray(), (UInt32)memory.Count << 1, &size);
}
*/
// FT_GetDeviceInfoList or FT_ListDevices → FT_OpenEx
protected uint DeviceOpen()
{
UInt32 ftStatus;
UInt32 ftHandle_;
ftStatus = FT_Open(0, &ftHandle_);
ftHandle = ftHandle_;
return ftStatus;
}
protected uint DeviceClose()
{
uint size;
var memory = new List<short> { TMS_H, TMS, OFF };
FT_Write(ftHandle, memory.ToArray(), (UInt32)memory.Count << 1, &size);
return FT_Close(ftHandle);
}
protected List<byte> GetBasicInformation( byte basicInstructionCode )
{
MoveIdle();
MoveIdleToShiftir();
WriteShiftir(basicInstructionCode);
MoveShiftirToShiftdr();
return ReadShiftdr(DataByteLength.Basic(basicInstructionCode));
}
private void VirtualInstruction( int virtualInstructionCode )
{
MoveIdle();
MoveIdleToShiftir();
WriteShiftir((byte)BasicInstruction.User1);
MoveShiftirToShiftdr();
WriteShiftdr((byte)(virtualInstructionCode));
MoveShiftdrToShiftir();
WriteShiftir((byte)BasicInstruction.User0);
MoveShiftirToShiftdr();
}
public void VirtualInstructionForMultipleBytes( List<byte> virtualInstructionCode )
{
MoveIdle();
MoveIdleToShiftir();
foreach (byte tx in virtualInstructionCode)
{
WriteShiftir((byte)BasicInstruction.User1);
MoveShiftirToShiftdr();
WriteShiftdr(tx);
MoveShiftdrToShiftir();
}
WriteShiftir((byte)BasicInstruction.User0);
MoveShiftirToShiftdr();
WriteShiftdr(0);
}
protected void SetVirtualInstruction( int virtualInstructionCode, List<byte> virtualInstructionData )
{
VirtualInstruction(virtualInstructionCode);
foreach(var x in virtualInstructionData)
{
WriteShiftdr(x);
}
}
protected List<byte> GetVirtualInstruction( byte virtualInstructionCode )
{
VirtualInstruction(virtualInstructionCode);
var rx = new List<byte>(ReadShiftdr((short)(DataByteLength.User(virtualInstructionCode)+1)));
for (var i = 0; i < rx.Count; i++)
{
rx[i] = (byte)(rx[i] >> 1);
if((i < rx.Count - 1) && ((rx[i+1] & 0x01) == 1))
{
rx[i] = (byte)(rx[i] + 0x80);
}
}
rx.RemoveAt(rx.Count - 1);
return rx;
}
}
public class De0Control : TmsControl
{
public uint Connection => DeviceOpen();
public uint DisConnection => DeviceClose();
public int Idcode
{
get
{
var rx = GetBasicInformation((byte)BasicInstruction.IdCode);
return BitConverter.ToInt32(rx.ToArray(), 0);
}
}
public void MultipleBytesSendingTest()
{
var tx = new List<byte>{(byte)LedSegment.Zero, (byte)LedSegment.One, (byte)LedSegment.Two, (byte)LedSegment.Three};
VirtualInstructionForMultipleBytes(tx);
}
}
}
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
entity Cyclone is
port (
HEX0_D : out std_logic_vector( 6 downto 0);
HEX1_D : out std_logic_vector( 6 downto 0);
HEX2_D : out std_logic_vector( 6 downto 0);
HEX3_D : out std_logic_vector( 6 downto 0);
LEDG : out std_logic_vector( 9 downto 0)
);
end Cyclone;
architecture RTL of Cyclone is
signal cnt : integer := 0;
signal tck : std_logic;
signal tdi : std_logic;
signal tdo : std_logic;
signal ir_in : std_logic_vector( 7 downto 0);
signal ir_out : std_logic_vector( 7 downto 0);
signal virtual_state_uir : std_logic;
signal virtual_state_sdr : std_logic;
signal r_ir : std_logic_vector( 7 downto 0);
constant build_number : std_logic_vector( 31 downto 0)
:= (conv_std_logic_vector(20171117, 32));
begin
top_connection : entity work.virtualjtag
port map(
tck => tck,
tdi => tdi,
tdo => tdo,
ir_in => ir_in,
ir_out => ir_out,
virtual_state_uir => virtual_state_uir,
virtual_state_sdr => virtual_state_sdr
);
process(tck)
begin
if(tck'event and tck='1') then
if(virtual_state_uir = '1') then
LEDG <= conv_std_logic_vector(cnt, 10);
case cnt is
when 0 => HEX3_D( 6 downto 0) <= ir_in( 6 downto 0);
when 1 => HEX2_D( 6 downto 0) <= ir_in( 6 downto 0);
when 2 => HEX1_D( 6 downto 0) <= ir_in( 6 downto 0);
when 3 => HEX0_D( 6 downto 0) <= ir_in( 6 downto 0);
when others => null;
end case;
cnt <= cnt + 1;
elsif(virtual_state_sdr='1') then
cnt <= 0;
end if;
end if;
end process;
end RTL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment