📄 veriphy.c
字号:
else { /*- Link-up mode VeriPHY now completed, read valid bit! */
delay_1(3 + 1); /* Wait valid flag to complete. 3msec required, so add 1 to be sure */
if ((phy_read_ext(port_no, 24) & ((ushort) 1 << 14)) != 0) {
tsk_valid_flag = TRUE;
}
}
/* Re-enable RClk125 gating */
write_rclk125_gating(port_no, 0);
if ( (tsk_stat[0] == 4 || tsk_stat[0] == 1) && tsk_loc[0] <= NO_CABLE__MAX_TAP &&
(tsk_stat[1] == 4 || tsk_stat[1] == 1) && tsk_loc[1] <= NO_CABLE__MAX_TAP &&
(tsk_stat[2] == 4 || tsk_stat[2] == 1) && tsk_loc[2] <= NO_CABLE__MAX_TAP &&
(tsk_stat[3] == 4 || tsk_stat[3] == 1) && tsk_loc[3] <= NO_CABLE__MAX_TAP )
{
result = VERIPHY_DONE_UNPLUGGED; /* Nothing plugged into jack */
}
else
{
// Pairs A & B will have to be used to decide the status
result = (tsk_stat[0] != 0 || tsk_stat[1] != 0);
// Check if we should ignore pairs C & D
if ( ( (tsk_loc[2] == tsk_loc[3] ) ||
(tsk_loc[2] < tsk_loc[3] && (tsk_loc[2] + SAME_LOC__TAP_TOLERANCE) >= tsk_loc[3]) ||
(tsk_loc[3] < tsk_loc[2] && (tsk_loc[3] + SAME_LOC__TAP_TOLERANCE) >= tsk_loc[2]) )
&& ( (tsk_stat[2] <= 4 && tsk_stat[3] == tsk_stat[2]) ||
(tsk_stat[2] <= 2 && tsk_stat[3] == 4 ) ||
(tsk_stat[3] <= 2 && tsk_stat[2] == 4 ) ) )
{
// Pairs C & D have compatible anomalies (or lack of anomalies) near
// the same location. This may occur when plugged into a 10/100
// Ethernet PHY (or a gigabit National PHY). As a result, we cannot
// declare the cable bad based on this configuration of C/D status
}
else // Use pairs C & D status to determine good/bad
{
result = (result || tsk_stat[2] != 0 || tsk_stat[3] != 0);
}
result |= VERIPHY_DONE_MASK;
}
#if 0
print_str("port = 0x");
print_hex_b(port_no);
print_str(" stat = ");
print_hex_b(tsk_stat[0]);
print_str(", ");
print_hex_b(tsk_stat[1]);
print_str(", ");
print_hex_b(tsk_stat[2]);
print_str(", ");
print_hex_b(tsk_stat[3]);
print_str(" loc = ");
print_hex_b(tsk_loc[0]);
print_str(", ");
print_hex_b(tsk_loc[1]);
print_str(", ");
print_hex_b(tsk_loc[2]);
print_str(", ");
print_hex_b(tsk_loc[3]);
if (tsk_valid_flag) {
print_str(" valid");
}
else {
print_str(" not valid");
}
print_str(" result = 0x");
print_hex_b(result);
print_cr_lf();
#endif
break;
default:
result = VERIPHY_DONE_ANOMALY;
break;
}
veriphy_parms_ptr->state = tsk_state;
veriphy_parms_ptr->aux_delay = tsk_aux_delay;
veriphy_parms_ptr->ecAllZerosCount = tsk_ecAllZerosCount;
veriphy_parms_ptr->ecAllZerosCountPrev = tsk_ecAllZerosCountPrev;
veriphy_parms_ptr->ecAllZerosAccum = tsk_ecAllZerosAccum;
memcpy(&veriphy_parms_ptr->stat, &tsk_stat, sizeof(tsk_stat));
memcpy(&veriphy_parms_ptr->loc, &tsk_loc, sizeof(tsk_loc));
memcpy(&veriphy_parms_ptr->strength, &tsk_strength, sizeof(tsk_strength));
veriphy_parms_ptr->log2VGAx256 = tsk_log2VGAx256;
veriphy_parms_ptr->thresh[0] = tsk_thresh[0];
veriphy_parms_ptr->thresh[1] = tsk_thresh[1];
if (tsk_linkup_flag) {
veriphy_parms_ptr->flags |= 0x01;
}
else {
veriphy_parms_ptr->flags &= ~0x01;
}
if (tsk_valid_flag) {
veriphy_parms_ptr->flags |= 0x02;
}
else {
veriphy_parms_ptr->flags &= ~0x02;
}
veriphy_parms_ptr->signFlip = tsk_signFlip;
return result;
}
static void checkValidity(uchar port_no, uchar subchan)
{
uchar retry;
ushort maxAbsCoeff;
#define RETRY_MAX_ABS_COEFF_LT (ushort) 1
//#define MAX_RETRIES 4
#define MAX_RETRIES 70
if (tsk_linkup_flag) {
return;
}
/* EcVarForceDelayVal = 232 - 72, EcVarForceDelay = 1 */
// tr_raw_write_reg_0_3_4(((ushort) (232 - 72) << 1) | 1);
tr_raw_data[0] = 0;
tr_raw_data[1] = (232 - 72) >> 7;
tr_raw_data[2] = ((232 - 72) << 1) | 1;
phy_write_tr(port_no, 0x188);
set_EcVarForceIdle(port_no, 0x02 << subchan); /* EcVar<subchan>ForceIdle = 1 */
set_EcVarForceIdle(port_no, 0); /* EcVar<subchan>ForceIdle = 0 */
delay_1(1 + 1);
// tr_raw_write_reg_0_3_4(0); /* remove forced delay */
tr_raw_data[0] = 0;
tr_raw_data[1] = 0;
tr_raw_data[2] = 0;
phy_write_tr(port_no, 0x188);
for (retry = 0; retry < 100; retry++) {
if ((maxAbsCoeff = readAvgECNCECVar(port_no, subchan, 72, 8, EXCL_COEFFS)) >=
RETRY_MAX_ABS_COEFF_LT) {
break;
}
delay_1(2 + 1);
}
set_EcVarForceIdle(port_no, 0x02 << subchan); /* EcVar<subchan>ForceIdle = 1 */
set_EcVarForceIdle(port_no, 0); /* EcVar<subchan>ForceIdle = 0 */
if ((retry > MAX_RETRIES) ||
(maxAbsCoeff > MAX_ABS_COEFF_ANOM_INVALID_NOISE)) {
tsk_stat[subchan] = 0;
tsk_loc[subchan] = 0;
tsk_strength[subchan] = 0;
}
}
static void xc_search(uchar port_no, uchar subchan, uchar firstCoeff, uchar numCoeffs, uchar locFirst, uchar prefix)
{
uchar idx;
short strength_tmp;
short coeff_tmp;
short s;
uchar locAbs;
bit loc_crit;
(void) readAvgECNCECVar(port_no, subchan, firstCoeff, numCoeffs, INCL_COEFFS);
while (numCoeffs-- != 0) {
idx = numCoeffs;
locAbs = locFirst + idx;
coeff_tmp = coeff_tab[idx];
if (abs_w(coeff_tmp) > tsk_thresh[1]) {
s = (short)(32L*(long)coeff_tmp/(long)tsk_thresh[1]);
strength_tmp = tsk_strength[subchan];
loc_crit = (tsk_loc[subchan] <= (locAbs + 3));
if ((abs_w(s) <= abs_w(strength_tmp) || (locAbs < prefix))) {
if ((tsk_signFlip < 0) && (tsk_stat[subchan] < 4) && loc_crit) {
if ((coeff_tmp > 0) && (strength_tmp < 0)) {
tsk_stat[subchan] = 2;
tsk_signFlip = 2;
if (locAbs < prefix) {
tsk_loc[subchan] = locAbs;
}
}
else if ((coeff_tmp < 0) && (strength_tmp > 0)) {
tsk_stat[subchan] = 1;
tsk_signFlip = 2;
if (locAbs < prefix) {
tsk_loc[subchan] = locAbs;
}
}
}
}
else { /* magnitude is largest seen so far & not in prefix taps */
if (coeff_tmp < -tsk_thresh[0]) {
if (loc_crit && (tsk_strength[subchan] > 0)) {
tsk_signFlip = 2;
}
tsk_stat[subchan] = 1;
}
else if (coeff_tmp > tsk_thresh[0]) {
if (loc_crit && (tsk_strength[subchan] < 0)) {
tsk_signFlip = 2;
}
tsk_stat[subchan] = 2;
}
else {
tsk_stat[subchan] = 4;
}
tsk_loc[subchan] = locAbs;
tsk_strength[subchan] = s;
}
}
tsk_signFlip = tsk_signFlip - 1;
}
}
static void get_anom_thresh(uchar tap)
{
short log2ThreshX256;
schar sh;
uchar j;
log2ThreshX256 = 542 - (8 * (short) tap) + tsk_log2VGAx256;
tsk_thresh[0] = 256 + LOW_BYTE(log2ThreshX256);
sh = (schar) (log2ThreshX256 >> 8);
if (sh >= 0) {
tsk_thresh[0] <<= sh;
}
else {
tsk_thresh[0] >>= -sh;
if (tsk_thresh[0] < 23) {
tsk_thresh[0] = 23;
}
}
if (tsk_linkup_flag) {
tsk_thresh[1] = tsk_thresh[0] >> 1; /* anomaly = 1/2 open/short when link up */
}
else {
tsk_thresh[1] = 0;
for (j = 0; j < 5; ++j) { /* anomaly = 1/3 open/short when link down */
tsk_thresh[1] = (tsk_thresh[1] + tsk_thresh[0] + 2) >> 2;
}
}
if (tsk_thresh[1] < 15) {
tsk_thresh[1] = 15;
}
/* Limit anomaly threshold to 12 lsbs less than tap range for each EC tap */
if ((tsk_thresh[1] > 1012) && (tap >= 32)) {
tsk_thresh[1] = 1012;
}
else if ((tsk_thresh[1] > 4084) && (tap >= 16)) {
tsk_thresh[1] = 4084;
}
else if (tsk_thresh[1] > 8180) {
tsk_thresh[1] = 8180;
}
}
static void set_EcVarForceIdle (uchar port_no, uchar value)
{
// TrRawWrite(0, 3, 2, value);
tr_raw_data[0] = 0;
tr_raw_data[1] = 0;
tr_raw_data[2] = value;
phy_write_tr(port_no, 0x0184);
}
static ushort readAvgECNCECVar(uchar port_no, uchar subchan, uchar firstCoeff, uchar numCoeffs, uchar incl_coeffs)
{
uchar i;
uchar j;
short cur_coeff;
ushort maxAbsC;
ushort reg_val;
#define NUM_REPEAT 4
#define SCALE_FACTOR 2
maxAbsC = 0;
if (incl_coeffs != 0) {
/* Normal read & store coefficients */
/* Clear coefficients to be averaged */
memset(coeff_tab, 0, 16);
}
/* Accumulate coefficients (pre-scaling when necessay for dynamic range) */
phy_page_tr(port_no);
for (i = 0; i < NUM_REPEAT; ++i) {
reg_val = (5 << 13) | ((ushort) subchan << 11) | ((ushort) firstCoeff << 1);
for (j = 0; j < numCoeffs; ++j) {
// phy_write(port_no, 16, (5 << 13) | ((ushort) subchan << 11) | ((ushort) (j & 0xc0) << 1) | ((j & 0x3f) << 1));
// phy_write(port_no, 16, (5 << 13) | ((ushort) subchan << 11) | ((ushort) j << 1));
phy_write(port_no, 16, reg_val);
reg_val += 2;
cur_coeff = phy_read(port_no, 17); /* low part only */
if ( cur_coeff & 0x2000 ) {
cur_coeff -= 0x4000;
}
if (incl_coeffs) {
coeff_tab[j] += cur_coeff;
}
else {
if (abs_w(cur_coeff) > maxAbsC) {
maxAbsC = abs_w(cur_coeff);
}
}
}
}
phy_page_std(port_no);
if (incl_coeffs) {
#if NUM_REPEAT == 3
/* Complete averaging by scaling coefficients */
for (j = 0; j < 8; ++j) {
cur_coeff = 0;
for (i = 0; i < 5; ++i) {
cur_coeff = (cur_coeff >> 2) + coeff_tab[j];
}
coeff_tab[j] = (cur_coeff + 2) >> 2;
}
#else
for (j = 0; j < 8; ++j) {
coeff_tab[j] >>= SCALE_FACTOR;
}
#endif
}
/* Return max(ABS(all coeffs. Read)) */
return maxAbsC;
}
static void ffe_init (uchar port_no)
{
/* FFE settings for anomaly search */
schar code ffe_settings_anomsea [16] = {
0, 0, 0, 0,
1, 3, -3, -1,
0, 0, 0, 0,
0, 0, 0, 0
};
uchar j;
#define ffe_settings ffe_settings_anomsea
// TrRawWrite(0, 4, 0x20, 0x0100); /* Set FfeWriteAllSubchans */
tr_raw_data[0] = 0;
tr_raw_data[1] = 0x01;
tr_raw_data[2] = 0;
phy_write_tr(port_no, 0x0240);
for (j = 0; j < 16; ++j) {
// TrRawWrite(0, 4, j, (unsigned long)((long)ffe_settings[j] << 9));
tr_raw_data[0] = (uchar) (ffe_settings[j] >> 7);
tr_raw_data[1] = (uchar) (ffe_settings[j] << 1);
tr_raw_data[2] = 0;
phy_write_tr(port_no, 0x0200 | (j << 1));
}
// TrRawWrite(0, 4, 0x20, 0x0000); /* Clear FfeWriteAllSubchans */
tr_raw_data[0] = 0;
tr_raw_data[1] = 0;
tr_raw_data[2] = 0;
phy_write_tr(port_no, 0x0240);
}
static void enable_EC_var_delay_force_val (uchar port_no, uchar status)
{
phy_read_tr(port_no, 0x0f86);
if (status) {
/* Set EnableECvarDelayForce/Val */
tr_raw_data[0] |= 0x30;
// TrRawWrite(1, 15, 0x03, TrRawRead(1, 15, 0x03) | 0x300000L);
}
else {
tr_raw_data[0] &= ~0x30;
/* Clear EnableECvarDelayForce/Val */
// TrRawWrite(1, 15, 0x03, TrRawRead(1, 15, 0x03) & ~0x300000L);
}
phy_write_tr(port_no, 0x0f86);
}
static void write_rclk125_gating (uchar port_no, uchar value)
{
phy_write_tp_bit(port_no, 8, 9, value);
}
static void set_blip_search (uchar port_no, ushort reg_val)
{
// TrRawWrite(0, 3, 8, reg_val);
tr_raw_data[0] = 0;
tr_raw_data[1] = HIGH_BYTE(reg_val);
tr_raw_data[2] = LOW_BYTE(reg_val);
phy_write_tr(port_no, 0x0190);
}
static ushort abs_w (short x)
{
if (x < 0) {
return (-x);
}
else {
return x;
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -