Last active
October 21, 2024 15:23
-
-
Save MarsTechHAN/caf6bdf7b8356d9e55dd9aa929739b96 to your computer and use it in GitHub Desktop.
Program Gowin from ESP32
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import struct | |
import sys | |
if __name__ == '__main__': | |
fs = open(sys.argv[1], 'rb') | |
with open('fs.c', 'w+') as f: | |
print('const unsigned char fs_bitstream[] __attribute__((aligned(128))) ={', file=f) | |
counter = 0 | |
while 1: | |
counter = counter + 1 | |
fs_byte = fs.read(2) | |
if not fs_byte: | |
break | |
struct.unpack('>H', fs_byte) | |
print(', '.join([str(i) for i in fs_byte]) + ', ',end='', file=f) | |
if counter % 8 == 0: | |
print(file=f) | |
print(file=f) | |
print('};', file=f) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "fs.c" //fs_bitstream | |
#define TMS_SET digitalWrite(TMS_PIN, HIGH) | |
#define TMS_RESET digitalWrite(TMS_PIN, LOW) | |
#define TCK_SET digitalWrite(TCK_PIN, HIGH) | |
#define TCK_RESET digitalWrite(TCK_PIN, LOW) | |
#define TDI_SET digitalWrite(TDI_PIN, HIGH) | |
#define TDI_RESET digitalWrite(TDI_PIN, LOW) | |
#define TDO_VALUE digitalRead(TDO_PIN) | |
const uint8_t TCK_PIN = 22; | |
const uint8_t TDI_PIN = 19; | |
const uint8_t TDO_PIN = 23; | |
const uint8_t TMS_PIN = 33; | |
const uint8_t DELAY_LEN = 3; | |
const uint32_t BUFFER_SIZE = 0xff; | |
const uint32_t ID_GW1N9 = 0x1100581B; | |
typedef enum{ | |
TAP_RESET, | |
TAP_IDLE, | |
TAP_DRSELECT, | |
TAP_DRCAPTURE, | |
TAP_DRSHIFT, | |
TAP_DREXIT1, | |
TAP_DRPAUSE, | |
TAP_DREXIT2, | |
TAP_DRUPDATE, | |
TAP_IRSELECT, | |
TAP_IRCAPTURE, | |
TAP_IRSHIFT, | |
TAP_IREXIT1, | |
TAP_IRPAUSE, | |
TAP_IREXIT2, | |
TAP_IRUPDATE, | |
TAP_UNKNOWN | |
} TAP_TypeDef; | |
typedef enum{ | |
ISC_NOOP = 0x02, | |
ISC_ERASE = 0x05, | |
ERASE_DONE = 0x09, | |
READ_ID_CODE = 0x11, | |
ISC_ENABLE = 0x15, | |
FAST_PROGRAM = 0x17, | |
STATUS_CODE = 0x41, | |
JTAG_EF_PROGRAM = 0x71, | |
JTAG_EF_READ = 0x73, | |
JTAG_EF_ERASE = 0x75, | |
ISC_DISABLE = 0x3A, | |
REPROGRAM = 0x3C, | |
Bypass = 0xFF | |
} GWFPGA_Inst_Def; | |
typedef enum{ | |
STATUS_CRC_ERROR = (1<<0), | |
STATUS_BAD_COMMAND = (1<<1), | |
STATUS_ID_VERIFY_FAILED = (1<<2), | |
STATUS_TIMEOUT = (1<<3), | |
STATUS_MEMORY_ERASE = (1<<5), | |
STATUS_PREAMBLE = (1<<6), | |
STATUS_SYSTEM_EDIT_MODE = (1<<7), | |
STATUS_PRG_SPIFLASH_DIRECT = (1<<8), | |
STATUS_NON_JTAG_CNF_ACTIVE = (1<<10), | |
STATUS_BYPASS = (1<<11), | |
STATUS_GOWIN_VLD = (1<<12), | |
STATUS_DONE_FINAL = (1<<13), | |
STATUS_SECURITY_FINAL = (1<<14), | |
STATUS_READY = (1<<15), | |
STATUS_POR = (1<<16), | |
STATUS_FLASH_LOCK = (1<<17) | |
} GWFPGA_StatusReg_Def; | |
void JTAG_Io_Init(){ | |
pinMode(TCK_PIN, OUTPUT); | |
pinMode(TDI_PIN, OUTPUT); | |
pinMode(TMS_PIN, OUTPUT); | |
pinMode(TDO_PIN, INPUT); | |
} | |
void JTAG_TapMove_OneClock(uint8_t tms_value) | |
{ | |
if(tms_value){ | |
TMS_SET; | |
}else{ | |
TMS_RESET; | |
} | |
TCK_RESET; | |
TCK_SET; | |
} | |
void JTAG_MoveTap(TAP_TypeDef TAP_From, TAP_TypeDef TAP_To) | |
{ | |
if ((TAP_From == TAP_UNKNOWN) && (TAP_To==TAP_IDLE) ) | |
{ | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(0); | |
JTAG_TapMove_OneClock(0); | |
} | |
else if ((TAP_From == TAP_IDLE) && (TAP_To==TAP_IDLE) ) | |
{ | |
JTAG_TapMove_OneClock(0); | |
JTAG_TapMove_OneClock(0); | |
JTAG_TapMove_OneClock(0); | |
} | |
else if ((TAP_From == TAP_IDLE) && (TAP_To==TAP_IRSHIFT) ) | |
{ | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(0); | |
JTAG_TapMove_OneClock(0); | |
} | |
else if ((TAP_From == TAP_IDLE) && (TAP_To==TAP_DRSHIFT) ) | |
{ | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(0); | |
JTAG_TapMove_OneClock(0); | |
} | |
else if ((TAP_From == TAP_IREXIT1) && (TAP_To==TAP_IDLE) ) | |
{ | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(0); | |
JTAG_TapMove_OneClock(0); | |
} | |
else if ((TAP_From == TAP_DREXIT1) && (TAP_To==TAP_IDLE) ) | |
{ | |
JTAG_TapMove_OneClock(1); | |
JTAG_TapMove_OneClock(0); | |
JTAG_TapMove_OneClock(0); | |
} | |
else | |
{ | |
Serial.printf("error tap walking."); | |
} | |
} | |
uint8_t JTAG_Write(uint8_t din, uint8_t dout, uint8_t tms, bool LSB) | |
{ | |
uint8_t tmp = 0; | |
uint8_t dout_new = 0; | |
if (LSB==false) | |
{ | |
uint8_t _tmp_din=0; | |
uint8_t sign = 1; | |
for (uint8_t i=0;i<=7;i++) | |
{ | |
_tmp_din |=((din&(sign<<i))>>i)<<(7-i); | |
} | |
din = _tmp_din; | |
} | |
TMS_RESET; | |
for (uint8_t i=0; i<8; i++) // LSB | |
{ | |
if (i == 7){ | |
if((tms & 1) == 1) | |
TMS_SET; | |
} | |
tmp = din>>i ; | |
if((1&tmp) == 0) | |
TDI_RESET; | |
else | |
TDI_SET; | |
TCK_RESET; | |
TCK_SET; | |
dout_new <<= 1; | |
dout_new |= (TDO_VALUE & 1); | |
} | |
return dout_new; | |
} | |
void JTAG_WriteInst(uint8_t inst) | |
{ | |
JTAG_MoveTap(TAP_IDLE, TAP_IRSHIFT); | |
JTAG_Write(inst, 0x0, 0x1,true); | |
JTAG_MoveTap(TAP_IREXIT1, TAP_IDLE); | |
JTAG_MoveTap(TAP_IDLE, TAP_IDLE); | |
JTAG_MoveTap(TAP_IDLE, TAP_IDLE); | |
JTAG_MoveTap(TAP_IDLE, TAP_IDLE); | |
} | |
void JTAG_RunTest(uint8_t cycles) | |
{ | |
for (uint8_t i=0; i<cycles; i++) | |
{ | |
JTAG_TapMove_OneClock(0); | |
} | |
} | |
uint32_t JTAG_ReadCode() | |
{ | |
uint32_t out=0; | |
JTAG_WriteInst(READ_ID_CODE); | |
JTAG_MoveTap(TAP_IDLE, TAP_DRSHIFT); | |
TMS_RESET; | |
for (uint8_t i=0; i<32; i++) | |
{ | |
if (i == 31) TMS_SET; | |
TCK_RESET; | |
TCK_SET; | |
out |= (TDO_VALUE) ? (1 << i) : 0; | |
}; | |
JTAG_MoveTap(TAP_DREXIT1, TAP_IDLE); | |
return out; | |
} | |
uint32_t JTAG_ReadStatus() | |
{ | |
uint32_t out=0; | |
JTAG_WriteInst(STATUS_CODE); | |
JTAG_MoveTap(TAP_IDLE, TAP_DRSHIFT); | |
TMS_RESET; | |
for (uint8_t i=0; i<32; i++) | |
{ | |
if (i == 31) TMS_SET; | |
TCK_RESET; | |
TCK_SET; | |
out |= (TDO_VALUE) ? (1 << i) : 0; | |
}; | |
JTAG_MoveTap(TAP_DREXIT1, TAP_IDLE); | |
return out; | |
} | |
void displayReadReg(uint32_t dev) | |
{ | |
Serial.printf("STATUS_REG: %08x\n", dev); | |
if (dev & STATUS_CRC_ERROR) | |
Serial.printf("\tCRC Error\n"); | |
if (dev & STATUS_BAD_COMMAND) | |
Serial.printf("\tBad Command\n"); | |
if (dev & STATUS_ID_VERIFY_FAILED) | |
Serial.printf("\tID Verify Failed\n"); | |
if (dev & STATUS_TIMEOUT) | |
Serial.printf("\tTimeout\n"); | |
if (dev & STATUS_MEMORY_ERASE) | |
Serial.printf("\tMemory Erase\n"); | |
if (dev & STATUS_PREAMBLE) | |
Serial.printf("\tPreamble\n"); | |
if (dev & STATUS_SYSTEM_EDIT_MODE) | |
Serial.printf("\tSystem Edit Mode\n"); | |
if (dev & STATUS_PRG_SPIFLASH_DIRECT) | |
Serial.printf("\tProgram spi flash directly\n"); | |
if (dev & STATUS_NON_JTAG_CNF_ACTIVE) | |
Serial.printf("\tNon-jtag is active\n"); | |
if (dev & STATUS_BYPASS) | |
Serial.printf("\tBypass\n"); | |
if (dev & STATUS_GOWIN_VLD) | |
Serial.printf("\tGowin VLD\n"); | |
if (dev & STATUS_DONE_FINAL) | |
Serial.printf("\tDone Final\n"); | |
if (dev & STATUS_SECURITY_FINAL) | |
Serial.printf("\tSecurity Final\n"); | |
if (dev & STATUS_READY) | |
Serial.printf("\tReady\n"); | |
if (dev & STATUS_POR) | |
Serial.printf("\tPOR\n"); | |
if (dev & STATUS_FLASH_LOCK) | |
Serial.printf("\tFlash Lock\n"); | |
} | |
void setup() { | |
Serial.begin(115200); | |
Serial.println("Starting JTAG Chain..."); | |
uint32_t debug_timming = millis(); | |
JTAG_Io_Init(); | |
Serial.println("---------------------------"); | |
Serial.println("Reading IDCODE..."); | |
uint32_t ID_CODE = JTAG_ReadCode(); | |
Serial.printf("IDCODE: 0x%X\n", ID_CODE); | |
Serial.println("---------------------------"); | |
Serial.println("Reading Status Reg..."); | |
uint32_t STATUS_REG = JTAG_ReadStatus(); | |
displayReadReg(STATUS_REG); | |
Serial.println("---------------------------"); | |
Serial.println("Starting Writing to SRAM..."); | |
JTAG_WriteInst(ISC_ENABLE); | |
JTAG_WriteInst(ISC_ERASE); | |
JTAG_WriteInst(ISC_NOOP); | |
uint32_t erase_time = millis(); | |
while(millis() - erase_time < 4){ //TN653 | |
TCK_RESET; | |
TCK_SET; | |
} | |
JTAG_WriteInst(ERASE_DONE); | |
JTAG_WriteInst(ISC_NOOP); | |
JTAG_WriteInst(ISC_DISABLE); | |
JTAG_WriteInst(ISC_NOOP); | |
erase_time = millis(); | |
while(millis() - erase_time < 4){ | |
TCK_RESET; | |
TCK_SET; | |
} | |
JTAG_WriteInst(ISC_ENABLE); | |
JTAG_WriteInst(FAST_PROGRAM); | |
JTAG_MoveTap(TAP_IDLE, TAP_DRSHIFT); | |
uint8_t tx_end = 0; | |
for (uint32_t i=0; i < sizeof(fs_bitstream); i+=1) { | |
if (i == sizeof(fs_bitstream) - 1) | |
tx_end = 1; // to move in EXIT1_DR | |
JTAG_Write(fs_bitstream[i], 0x00, tx_end, 0x00); | |
} | |
JTAG_MoveTap(TAP_DREXIT1, TAP_IDLE); | |
JTAG_WriteInst(ISC_DISABLE); | |
JTAG_WriteInst(ISC_NOOP); | |
Serial.println("SRAM Prog Finish..."); | |
Serial.println("---------------------------"); | |
Serial.println("Waiting for DONE..."); | |
while(!(JTAG_ReadStatus() & STATUS_DONE_FINAL)) | |
delay(1); | |
Serial.println("Done!"); | |
Serial.println("---------------------------"); | |
Serial.printf("Total Time: %ums", (millis() - debug_timming)); | |
} | |
void loop() { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#From @ciniml https://gist.github.com/ciniml/e02f4cc9b00f30d950cd2a787a1ea8d3 | |
import sys | |
input_path = sys.argv[1] | |
output_path = sys.argv[1].replace('.fs', '.bin') | |
with open(input_path, 'r') as input_file: | |
with open(output_path, 'wb') as output_file: | |
for line in iter(input_file.readline, ''): #type: str | |
line = line.strip() | |
if line.startswith('//'): | |
continue | |
buffer = bytearray(1) | |
for byte_index in range(0, len(line), 8): | |
value = 0 | |
for bit_index in range(8): | |
bit = line[byte_index + bit_index] | |
value = (value << 1) | (1 if bit == '1' else 0) | |
buffer[0] = value | |
output_file.write(buffer) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment