tx-gxx-linux/device/gxx-linux/motorboard/vec.cpp

522 lines
15 KiB
C++
Raw Permalink Normal View History

2023-05-02 01:50:55 +00:00
/*******************************************************************
* Copyright (c) 2011 -2021 Anlogic Inc.
* This file is strictly confidential. All rights reserved.
*******************************************************************/
/***********************************************************************
Filename: vec.c
Description: generate vec
Log: initial version, July 2019
***********************************************************************/
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include "Jtag.h"
#include "opcode.h"
/* global variables about hdr/hir/tdr/tir */
unsigned int g_hdr_size = 0;
unsigned int g_hir_size = 0;
unsigned int g_tdr_size = 0;
unsigned int g_tir_size = 0;
unsigned char* g_hdr_data = NULL;
unsigned char* g_hir_data = NULL;
unsigned char* g_tdr_data = NULL;
unsigned char* g_tir_data = NULL;
static Jtag jtag_burning;
/* function declared in ajeutil.c */
extern int Anlogic_GetBit(unsigned char* data, int id);
extern void Anlogic_SetBit(unsigned char* data, int id, int val);
extern unsigned char Anlogic_ReverseChar(unsigned char byte);
/* Function forward declaration */
void Anlogic_WritePulseTck(void);
/* Tap Opcode To TAP_STATE */
enum TAP_STATE Anlogic_TapState(unsigned char opcode) {
enum TAP_STATE state = TAP_RESET;
switch (opcode) {
case RESET: state = TAP_RESET; break;
case IDLE: state = TAP_IDLE; break;
case DRSELECT: state = TAP_DRSELECT; break;
case DRCAPTURE: state = TAP_DRCAPTURE; break;
case DRSHIFT: state = TAP_DRSHIFT; break;
case DREXIT1: state = TAP_DREXIT1; break;
case DRPAUSE: state = TAP_DRPAUSE; break;
case DREXIT2: state = TAP_DREXIT2; break;
case DRUPDATE: state = TAP_DRUPDATE; break;
case IRSELECT: state = TAP_IRSELECT; break;
case IRCAPTURE: state = TAP_IRCAPTURE; break;
case IRSHIFT: state = TAP_IRSHIFT; break;
case IREXIT1: state = TAP_IREXIT1; break;
case IRPAUSE: state = TAP_IRPAUSE; break;
case IREXIT2: state = TAP_IREXIT2; break;
case IRUPDATE: state = TAP_IRUPDATE; break;
default:
printf("Error: Illegal tap state opcode %u\n", (unsigned int)opcode);
}
return state;
}
/* TAP_STATE to TapState String */
const char* Anlogic_TapState2Str(enum TAP_STATE tap_state) {
#define X(_w) if (tap_state == TAP_ ## _w) return #_w
X(RESET);
X(IDLE);
X(DRSELECT);
X(DRCAPTURE);
X(DRSHIFT);
X(DREXIT1);
X(DRPAUSE);
X(DREXIT2);
X(DRUPDATE);
X(IRSELECT);
X(IRCAPTURE);
X(IRSHIFT);
X(IREXIT1);
X(IRPAUSE);
X(IREXIT2);
X(IRUPDATE);
#undef X
return "TapState2Str: unkown state";
}
static enum TAP_STATE cur_tap_state = TAP_RESET; /* current tap state */
static enum TAP_STATE end_dr_state = TAP_IDLE; /* the tap state that device goes after sdr */
static enum TAP_STATE end_ir_state = TAP_IDLE; /* the tap state that device goes after sir */
/* Tap State Transistions */
int Anlogic_TapTransist(enum TAP_STATE state) {
int id = 0;
int count = 0;
// printf("Anlogic_TapTransist start...\n");
if (cur_tap_state == state && state == TAP_RESET) {
for (id = 0; id < 6; ++id) {
jtag_burning.TMS_Wr(1);
Anlogic_WritePulseTck();
}
// printf("Anlogic_TapTransist 107 end...\n");
return 0;
}
while (cur_tap_state != state) {
switch (cur_tap_state) {
case TAP_RESET:
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_IDLE;
break;
case TAP_IDLE:
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_DRSELECT;
break;
/* DR STATE Transistion */
case TAP_DRSELECT:
if (state >= TAP_IRSELECT || state == TAP_RESET) {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_IRSELECT;
} else {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_DRCAPTURE;
}
break;
case TAP_DRCAPTURE:
if (state == TAP_DRSHIFT) {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_DRSHIFT;
} else {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_DREXIT1;
}
break;
case TAP_DRSHIFT:
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_DREXIT1;
break;
case TAP_DREXIT1:
if (state == TAP_DRPAUSE) {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_DRPAUSE;
} else {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_DRUPDATE;
}
break;
case TAP_DRPAUSE:
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_DREXIT2;
break;
case TAP_DREXIT2:
if (state == TAP_DRSHIFT) {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_DRSHIFT;
} else {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_DRUPDATE;
}
break;
case TAP_DRUPDATE:
if (state == TAP_IDLE) {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_IDLE;
} else {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_DRSELECT;
}
break;
/* IR STATE Transistion */
case TAP_IRSELECT:
if (state == TAP_RESET) {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_RESET;
} else {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_IRCAPTURE;
}
break;
case TAP_IRCAPTURE:
if (state == TAP_IRSHIFT) {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_IRSHIFT;
} else {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_IREXIT1;
}
break;
case TAP_IRSHIFT:
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_IREXIT1;
break;
case TAP_IREXIT1:
if (state == TAP_IRPAUSE) {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_IRPAUSE;
} else {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_IRUPDATE;
}
break;
case TAP_IRPAUSE:
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_IREXIT2;
break;
case TAP_IREXIT2:
if (state == TAP_IRSHIFT) {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_IRSHIFT;
} else {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_IRUPDATE;
}
break;
case TAP_IRUPDATE:
if (state == TAP_IDLE) {
jtag_burning.TMS_Wr(0);
cur_tap_state = TAP_IDLE;
} else {
jtag_burning.TMS_Wr(1);
cur_tap_state = TAP_IRSELECT;
}
break;
default:
printf("Error: invalid tap sate.\n");
return -1;
}
Anlogic_WritePulseTck();
if (++count > 10) {
printf("Error: Loop in Tap Transistion.");
return -1;
}
}
jtag_burning.TDI_Wr(0);
// printf("Anlogic_TapTransist 240 end...\n");
return 0;
}
/* Init function, set current tap state to reset */
void Anlogic_Init(void) {
cur_tap_state = TAP_RESET;
Anlogic_TapTransist(TAP_RESET);
}
/* set the tap state that deevice goes after sdr */
void Anlogic_SetEndDRState(enum TAP_STATE end_st) {
end_dr_state = end_st;
#ifdef AJE_DEBUG
printf("ENDDR %s;\n", Anlogic_TapState2Str(end_st));
#endif
}
/* set the tap state that deevice goes after sir */
void Anlogic_SetEndIRState(enum TAP_STATE end_st) {
end_ir_state = end_st;
#ifdef AJE_DEBUG
printf("ENDIR %s;\n", Anlogic_TapState2Str(end_st));
#endif
}
/* Send HIR/HDR/TIR/TDR data to device */
void Anlogic_SendBypassData(unsigned int op_code) {
unsigned char* data = NULL;
unsigned int size = 0;
unsigned int index = 0;
unsigned int bit = 0;
switch (op_code) {
case HIR: size = g_hir_size; data = g_hir_data; break;
case HDR: size = g_hdr_size; data = g_hdr_data; break;
case TIR: size = g_tir_size; data = g_tir_data; break;
case TDR: size = g_tdr_size; data = g_tdr_data; break;
default: break;
}
/* no value set, use default */
if (data == NULL) {
bit = (op_code == HIR || op_code == TIR) ? 1 : 0;
}
for (index = 0; index < size-1; ++index) {
if (data != NULL) {
bit = Anlogic_GetBit(data, index);
}
jtag_burning.TDI_Wr(bit);
Anlogic_WritePulseTck();
}
bit = Anlogic_GetBit(data, index);
jtag_burning.TDI_Wr(bit);
}
/* Send TDI data to device */
int Anlogic_SendData(unsigned char* tdi_data, unsigned int bin_size, int cascade) {
unsigned int index = 0;
unsigned int bit = 0;
for (index = 0; index < bin_size-1; ++index) {
bit = Anlogic_GetBit(tdi_data, index);
jtag_burning.TDI_Wr(bit);
Anlogic_WritePulseTck();
}
bit = Anlogic_GetBit(tdi_data, index);
jtag_burning.TDI_Wr(bit);
if (cascade == 1) {
Anlogic_WritePulseTck();
}
return 0;
}
/* Send TDI data and read TDO, Verify */
int Anlogic_ReadData(unsigned char* tdi_data, unsigned char* tdo_data, unsigned char* mask, unsigned int data_size, int cascade) {
unsigned int index = 0;
int tdi_bit = 0;
int tdo_bit = 0;
int mask_bit = 0;
for (index = 0; index < data_size-1; ++index) {
tdi_bit = Anlogic_GetBit(tdi_data, index);
tdo_bit = Anlogic_GetBit(tdo_data, index);
mask_bit = Anlogic_GetBit(mask, index);
if (mask_bit == 1 && tdo_bit != jtag_burning.TDO_RD()) {
return AJE_VERIFY_FAIL;
}
jtag_burning.TDI_Wr(tdi_bit);
Anlogic_WritePulseTck();
}
tdi_bit = Anlogic_GetBit(tdi_data, index);
tdo_bit = Anlogic_GetBit(tdo_data, index);
mask_bit = Anlogic_GetBit(mask, index);
if (mask_bit == 1 && tdo_bit != jtag_burning.TDO_RD()) {
return AJE_VERIFY_FAIL;
}
jtag_burning.TDI_Wr(tdi_bit);
if (cascade == 1) {
Anlogic_WritePulseTck();
}
return AJE_OK;
}
/* Send TDI Data and Save TDO */
int Anlogic_SaveData(unsigned char* tdi_data, unsigned int data_size, unsigned char** tdo_data) {
unsigned int index = 0;
unsigned int tdi_bit = 0;
unsigned int tdo_bit = 0;
for (index = 0; index < data_size-1; ++index) {
tdo_bit = jtag_burning.TDO_RD();
Anlogic_SetBit(*tdo_data, index, tdo_bit);
tdi_bit = Anlogic_GetBit(tdi_data, index);
jtag_burning.TDI_Wr(tdi_bit);
Anlogic_WritePulseTck();
}
tdo_bit = jtag_burning.TDO_RD();
Anlogic_SetBit(*tdo_data, index, tdo_bit);
tdi_bit = Anlogic_GetBit(tdi_data, index);
jtag_burning.TDI_Wr(tdi_bit);
return AJE_OK;
}
/* Process SIR/SDR */
int Anlogic_ProcessShiftCmd(unsigned int op_code, unsigned int cascade, unsigned int read, unsigned int data_size,
unsigned char* tdi_data, unsigned char* tdo_data, unsigned char* mask) {
int rtn_val = AJE_OK;
// process header data
switch (op_code) {
case SIR:
if (cascade != 1) {
Anlogic_TapTransist(TAP_IRSHIFT);
if (g_hir_size > 0) {
Anlogic_SendBypassData(HIR);
Anlogic_WritePulseTck();
}
}
break;
case SDR:
if (cascade != 1) {
Anlogic_TapTransist(TAP_DRSHIFT);
if (g_hdr_size > 0) {
Anlogic_SendBypassData(HDR);
Anlogic_WritePulseTck();
}
}
break;
default:
break;
}
if (read == 1) {
rtn_val =Anlogic_SaveData(tdi_data, data_size, &tdo_data);
} else if (mask == NULL) {
rtn_val =Anlogic_SendData(tdi_data, data_size, cascade);
} else {
rtn_val =Anlogic_ReadData(tdi_data, tdo_data, mask, data_size, cascade);
}
// process tailer data
switch (op_code) {
case SIR:
if (cascade != 1) {
if (g_tir_size > 0) {
Anlogic_WritePulseTck();
Anlogic_SendBypassData(TIR);
}
Anlogic_TapTransist(end_ir_state);
}
break;
case SDR:
if (cascade != 1) {
if (g_tdr_size > 0) {
Anlogic_WritePulseTck();
Anlogic_SendBypassData(TDR);
}
Anlogic_TapTransist(end_dr_state);
}
break;
default:
break;
}
return rtn_val;
}
/* process single sir command, do not use bypass data (hir/tir) */
int Anlogic_ExeSirCommand(unsigned char command, int cur_lvl, int total_lvl) {
int rtn_val = AJE_OK;
unsigned char* tdi_data = NULL;
int id = 0;
Anlogic_TapTransist(TAP_IRSHIFT);
tdi_data = (unsigned char*)calloc((total_lvl*8+1), sizeof(unsigned char));
for(id = 0; id < total_lvl; ++id) {
if (id == (total_lvl - cur_lvl)) {
tdi_data[id] = Anlogic_ReverseChar(command);
} else {
tdi_data[id] = 0xFF;
}
}
rtn_val = Anlogic_SendData(tdi_data, total_lvl*8, 0 /*cascade*/);
Anlogic_TapTransist(end_ir_state);
return rtn_val;
}
/* process sdr command, do not use bypass data (hdr/tdr) */
int Anlogic_ExeSdrCommand(unsigned int bit_size, int cur_lvl, int total_lvl,
unsigned char* tdi_data, unsigned char* tdo_data) {
int rtn_val = AJE_OK;
int head_num = total_lvl - cur_lvl;
int tailer_num = cur_lvl-1;
int id = 0;
unsigned int byte_size = (bit_size + 7)/8;
Anlogic_TapTransist(TAP_DRSHIFT);
if (head_num > 0) {
for (id = 0; id < head_num; ++id) {
jtag_burning.TDI_Wr(0);
Anlogic_WritePulseTck();
}
}
if (tdi_data == NULL) {
tdi_data = (unsigned char*)calloc((byte_size+1), sizeof(unsigned char));
}
if (tdo_data == NULL) {
rtn_val = Anlogic_SendData(tdi_data, bit_size, 0 /*cascade*/);
} else { /* read and save tdo readback data */
rtn_val = Anlogic_SaveData(tdi_data, bit_size, &tdo_data /*cascade*/);
}
if (tailer_num > 0) {
for (id = 0; id < tailer_num; ++id) {
Anlogic_WritePulseTck();
jtag_burning.TDI_Wr(0);
}
}
Anlogic_TapTransist(end_dr_state);
return rtn_val;
}
/* process runtest num tck */
void Anlogic_ProcessRunTestTck(int num) {
volatile int i = 0;
jtag_burning.TDI_Wr(0);
jtag_burning.TMS_Wr(0);
for(i = 0; i < num; ++i) {
jtag_burning.TCK_Wr(1);
jtag_burning.TCK_Wr(0);
}
#ifdef AJE_DEBUG
printf("RUNTEST %d TCK;\n", num);
#endif
}
void Anlogic_WritePulseTck(void) {
static unsigned int i = 0;
jtag_burning.TCK_Wr(1);
jtag_burning.TCK_Wr(0);
}