These are commands that are not (yet) explicitly exposed in the C# and C++ library (they are constants define / enum: SPI_Command in a .h firmware file ?????).
The SPI Command can be dispatched through
In particular, SPI Flash Commands could be used:
First case pseudocode example:
Command[0] = (byte) FX2_Commands.CMD_FX2_FLASH_WRITE_COMMAND;
Command[1] = (byte) 1; //Numeber of SPI commands used by spi_command() : putcSPI(SPI_RDID);
Command[2] = (byte) 3; //Number of SPI bytes as reply: mid == 0xEF && did == 0x40 && uid == 0x17
Command[3] = (byte) 0x9F;//(byte)SPI_Commands.CMD_SPI_RDID; // SPI_RDID 0x9F ≡ get ID command
Command[4] = (byte)0;
Command[5] = (byte)0;
Command[6] = (byte)0;
case CMD_FLASH_WRITE_COMMAND:
EP1INBUF[0] = 0x55;
spi_command(EP1OUTBUF[1], &EP1OUTBUF[3], EP1OUTBUF[2], &EP1INBUF[1]);
new_data = 1;
break;
void spi_command(BYTE CmdLen, unsigned char *CmdData, BYTE RdLen, unsigned char *RdData)
aka
Command[0] = CMD_FLASH_WRITE_COMMAND; used by TE_USB_FX2_SendCommand () Command[1] = CmdLen = 1; used by spi_command() Command[2] = RdLen = 3; // if((mid == 0xEF) && (did == 0x40) && (uid == 0x17)) //used by spi_command() Command[3] = CMD_SPI_RDID = 0x9F; //used by spi_command() Reply[0] = EP1INBUF[0] = 0x55; Reply[1] = EP1INBUF[1] = 0xEF; Reply[2] = EP1INBUF[2] = 0x40; Reply[3] = EP1INBUF[3] = 0x17;
byte[] Command1 = new byte[64];
byte[] Reply1 = new byte[64];
int CmdLength1 = 4;
int ReplyLength1 = 64;
byte[] Command2 = new byte[64];
byte[] Reply2 = new byte[64];
int CmdLength2 = 64;
int ReplyLength2 = 64;
//To use the firmware function spi_command() you need to use a double indirection
Command2[0] = (byte)FX2_Commands.CMD_FX2_FLASH_WRITE_COMMAND;
Command2[1] = (byte)0x01;//(byte)FX2_Commands.CMD_SPI_RDID;
Command2[2] = (byte)0x03;
Command2[3] = (byte)0x9F;
//To use the firmware function spi_command() you need to use a double indirection
Command1[0] = Command2[0];
Command1[1] = Command2[1];
Command1[2] = Command2[2];
Command1[3] = Command2[3];
Command1[4] = (byte)0;
Command1[5] = (byte)0;
Command1[6] = (byte)0;
if (TE_USB_FX2.TE_USB_FX2.TE_USB_FX2_SendCommand(ref TE_USB_FX2_USBDevice, ref Command1, ref CmdLength1, ref Reply1, ref ReplyLength1, 5000) == true)
{
LogTextLine += "SPI Flash IDCODE 0x" + Reply1[1].ToString("x") + " 0x"
+ Reply1[2].ToString("x") + " 0x" + Reply1[3].ToString("x") + "\r\n";
}
else
{
LogTextLine += "SPI Flash IDCODE 0x" + Reply1[1].ToString("x") + " 0x"
+ Reply1[2].ToString("x") + " 0x" + Reply1[3].ToString("x") + "\r\n";
}
-------------------------------------------------
// SPI Flash commands #define SPI_READ 0x03 #define SPI_WREN 0x06 #define SPI_WRDI 0x04 #define SPI_RDSR1 0x05 #define SPI_RDSR2 0x35 #define SPI_WRSR 0x01 #define SPI_READ 0x03 #define SPI_FAST_READ 0x0b #define SPI_WRITE 0x02 #define SPI_SE 0xD8 #define SPI_BE 0xC7 #define SPI_DP 0xb9 #define SPI_RES 0xab #define SPI_RDID 0x9F |
The SPI Command can be dispatched through
In particular, SPI Flash Commands could be used:
First case example (reads the ID of the SPI Flash):
// This is pseudocode close to the real one byte[] Command = new byte[64]; byte[] Reply = new byte[64]; Command[0] = (byte) FX2_Commands.CMD_FX2_FLASH_WRITE_COMMAND; Command[1] = (byte) 1; //Numeber of SPI commands used by spi_command() : putcSPI(SPI_RDID); Command[2] = (byte) 3; //Number of SPI bytes as reply: mid == 0xEF && did == 0x40 && uid == 0x17 Command[3] = (byte) 0x9F; //(byte)SPI_Commands.CMD_SPI_RDID; // SPI_RDID 0x9F ≡ get ID command Command[4] = (byte)0; Command[5] = (byte)0; Command[6] = (byte)0; /* TE_USB_FX2_SendCommand (Command[0] = (byte) FX2_Commands.CMD_FX2_FLASH_WRITE_COMMAND) calls "case CMD_FLASH_WRITE_COMMAND" "case CMD_FLASH_WRITE_COMMAND" calls spi_command(EP1OUTBUF[1], &EP1OUTBUF[3], EP1OUTBUF[2], &EP1INBUF[1]) with EP1OUTBUF[3]= SPI_RDID SPI Flash Command EP1OUTBUF = Command Reply = EP1INBUF */ if (TE_USB_FX2_SendCommand(..., Command, CmdLength, Reply, ReplyLength, 5000) == true) { LogTextLine += "SPI Flash IDCODE " + "uid = 0x" + Reply1[1].ToString("x") + "mid = 0x "+ Reply1[2].ToString("x") + " did = 0x" + Reply1[3].ToString("x") + "\r\n"; } | |
//This is a piece of real code (FW running on USB FX2 microcontroller) case CMD_FLASH_WRITE_COMMAND: EP1INBUF[0] = 0x55; //void spi_command(BYTE CmdLen, unsigned char *CmdData, BYTE RdLen, unsigned char *RdData) spi_command(EP1OUTBUF[1], &EP1OUTBUF[3], EP1OUTBUF[2], &EP1INBUF[1]); new_data = 1; break; /* Command[0] = CMD_FLASH_WRITE_COMMAND; used by TE_USB_FX2_SendCommand () to call "case CMD_FLASH_WRITE_COMMAND" and then spi_command() EP1OUTBUF[1] = CmdLen = Command[1]= CmdLength = 1; // used by spi_command(), MD_SPI_RDID = 0x9F is a single byte EP1OUTBUF[2] = RdLen = Command[2]= ReplyLength = 3; // used by spi_command(), SPI Flash ID should be 3 byte EP1OUTBUF[3] = Command[3] = CMD_SPI_RDID = 0x9F; //used by spi_command() Reply[0] = EP1INBUF[0] = 0x55; Reply[1] = EP1INBUF[1] = 0xEF; // for example Reply[2] = EP1INBUF[2] = 0x40; // for example Reply[3] = EP1INBUF[3] = 0x17; // for example */ | |
byte[] Command1 = new byte[64];
byte[] Reply1 = new byte[64];
int CmdLength1 = 4;
int ReplyLength1 = 64;
byte[] Command2 = new byte[64];
byte[] Reply2 = new byte[64];
int CmdLength2 = 64;
int ReplyLength2 = 64;
//To use the firmware function spi_command() you need to use a double indirection
Command2[0] = (byte)FX2_Commands.CMD_FX2_FLASH_WRITE_COMMAND;
Command2[1] = (byte)0x01;//(byte)FX2_Commands.CMD_SPI_RDID;
Command2[2] = (byte)0x03;
Command2[3] = (byte)0x9F;
//To use the firmware function spi_command() you need to use a double indirection
Command1[0] = Command2[0];
Command1[1] = Command2[1];
Command1[2] = Command2[2];
Command1[3] = Command2[3];
Command1[4] = (byte)0;
Command1[5] = (byte)0;
Command1[6] = (byte)0;
if (TE_USB_FX2.TE_USB_FX2.TE_USB_FX2_SendCommand(ref TE_USB_FX2_USBDevice, ref Command1, ref CmdLength1, ref Reply1, ref ReplyLength1, 5000) == true)
{
LogTextLine += "SPI Flash IDCODE 0x" + Reply1[1].ToString("x") + " 0x"
+ Reply1[2].ToString("x") + " 0x" + Reply1[3].ToString("x") + "\r\n";
}
else
{
LogTextLine += "SPI Flash IDCODE 0x" + Reply1[1].ToString("x") + " 0x"
+ Reply1[2].ToString("x") + " 0x" + Reply1[3].ToString("x") + "\r\n";
}
if (TE_USB_FX2.TE_USB_FX2.TE_USB_FX2_SendCommand(ref TE_USB_FX2_USBDevice, ref Command, ref CmdLength, ref Reply, ref ReplyLength, 20000) == false) LogTextLine += "Doesn't work" + "\r\n"; else { LogTextLine += "Doesn't work" + "\r\n" } As explained bellow the problems seems some unmatched settings. There is a problem with SPI_RDID command used in process_flash_id(): it requires two "settings" not normally present (FPGA_PROG= 0; and busy_polling();) in spi_command () function and spi_command () has a setting in not equired (FPGA_POWER=0;) for SPI_RDID used in process_flash_id(). -----------------------------------
FX2_Commands.CMD_FX2_FLASH_WRITE_COMMAND call spi_command(), in spi_command 0x9F SPI command (CMD_SPI_RDID) is used
------------------------------
// SPI Flash commands
#define SPI_READ 0x03
#define SPI_WREN 0x06
#define SPI_WRDI 0x04
#define SPI_RDSR1 0x05
#define SPI_RDSR2 0x35
#define SPI_WRSR 0x01
#define SPI_READ 0x03
#define SPI_FAST_READ 0x0b
#define SPI_WRITE 0x02
#define SPI_SE 0xD8
#define SPI_BE 0xC7
#define SPI_DP 0xb9
#define SPI_RES 0xab
-----------------------
#define SPI_RDID 0x9F
...