add SOLT/E-Resp calibration and command

This commit is contained in:
TT 2016-10-16 08:11:16 +09:00
parent 16c09799a1
commit 86fae97c9b
4 changed files with 222 additions and 64 deletions

2
dsp.c
View file

@ -117,7 +117,7 @@ void calclate_gamma(float *gamma)
acc_i += (float)(s0 * ri); acc_i += (float)(s0 * ri);
acc_ref += (float)rr*rr + (float)ri*ri; acc_ref += (float)rr*rr + (float)ri*ri;
} }
rn = sqrtf(acc_ref / len) * 1e3 * len; rn = sqrtf(acc_ref / len) * 2e3 * len;
gamma[0] = -acc_r / rn; gamma[0] = -acc_r / rn;
gamma[1] = acc_i / rn; gamma[1] = acc_i / rn;
} }

View file

@ -596,6 +596,7 @@ float phase(float *v)
return 4 + 2 * atan2f(v[1], v[0]) / M_PI; return 4 + 2 * atan2f(v[1], v[0]) / M_PI;
} }
#if 0
void sweep_plot(int32_t freq, int first, float *measured) void sweep_plot(int32_t freq, int first, float *measured)
{ {
int curr_x = ((float)WIDTH * (freq - fstart) / fspan); int curr_x = ((float)WIDTH * (freq - fstart) / fspan);
@ -646,6 +647,7 @@ void sweep_tail()
prev_x++; prev_x++;
} }
} }
#endif
#define RADIUS ((HEIGHT-1)/2) #define RADIUS ((HEIGHT-1)/2)
void void
@ -663,6 +665,7 @@ cartesian_scale(float re, float im, int *xp, int *yp)
*yp = HEIGHT/2 - y; *yp = HEIGHT/2 - y;
} }
#if 0
void polar_plot(float measured[101][4]) void polar_plot(float measured[101][4])
{ {
int x0, y0; int x0, y0;
@ -676,7 +679,7 @@ void polar_plot(float measured[101][4])
y0 = y1; y0 = y1;
} }
} }
#endif
#define INDEX(x, y, n) \ #define INDEX(x, y, n) \
((((x)&0x03e0UL)<<22) | (((y)&0x03e0UL)<<17) | (((n)&0x0fffUL)<<10) \ ((((x)&0x03e0UL)<<22) | (((y)&0x03e0UL)<<17) | (((n)&0x0fffUL)<<10) \
@ -788,7 +791,7 @@ force_set_markmap(void)
memset(markmap[current_mappage], 0xff, sizeof markmap[current_mappage]); memset(markmap[current_mappage], 0xff, sizeof markmap[current_mappage]);
} }
void plot_into_index(float measured[101][2][2]) void plot_into_index(float measured[2][101][2])
{ {
int i, t; int i, t;
float coeff[2]; float coeff[2];
@ -799,38 +802,39 @@ void plot_into_index(float measured[101][2][2])
if (!trace[t].enabled) if (!trace[t].enabled)
continue; continue;
coeff[0] = measured[i][n][0]; coeff[0] = measured[n][i][0];
coeff[1] = measured[i][n][1]; coeff[1] = measured[n][i][1];
#if 0
if (cal_status & CALSTAT_APPLY) { if (cal_status & CALSTAT_APPLY) {
if (n == 0) { if (n == 0) {
float sq = cal_data[i][CAL_OPEN][0] * cal_data[i][CAL_OPEN][0] float sq = cal_data[CAL_OPEN][i][0] * cal_data[CAL_OPEN][i][0]
+ cal_data[i][CAL_OPEN][1] * cal_data[i][CAL_OPEN][1]; + cal_data[CAL_OPEN][i][1] * cal_data[CAL_OPEN][i][1];
float m0 = measured[i][n][0]; float m0 = measured[n][i][0];
float m1 = measured[i][n][1]; float m1 = measured[n][i][1];
if (cal_status & CALSTAT_LOAD) { if (cal_status & CALSTAT_LOAD) {
m0 -= cal_data[i][CAL_LOAD][0]; m0 -= cal_data[CAL_LOAD][i][0];
m1 -= cal_data[i][CAL_LOAD][1]; m1 -= cal_data[CAL_LOAD][i][1];
} }
coeff[0] = (m0 * cal_data[i][CAL_OPEN][0] coeff[0] = (m0 * cal_data[CAL_OPEN][i][0]
+ m1 * cal_data[i][CAL_OPEN][1]) / sq; + m1 * cal_data[CAL_OPEN][i][1]) / sq;
coeff[1] = (m1 * cal_data[i][CAL_OPEN][0] coeff[1] = (m1 * cal_data[CAL_OPEN][i][0]
- m0 * cal_data[i][CAL_OPEN][1]) / sq; - m0 * cal_data[CAL_OPEN][i][1]) / sq;
} else { } else {
float sq = cal_data[i][CAL_THRU][0] * cal_data[i][CAL_THRU][0] float sq = cal_data[CAL_THRU][i][0] * cal_data[CAL_THRU][i][0]
+ cal_data[i][CAL_THRU][1] * cal_data[i][CAL_THRU][1]; + cal_data[CAL_THRU][i][1] * cal_data[CAL_THRU][i][1];
float m0 = measured[i][n][0]; float m0 = measured[n][i][0];
float m1 = measured[i][n][1]; float m1 = measured[n][i][1];
if (cal_status & CALSTAT_ISOLN) { if (cal_status & CALSTAT_ISOLN) {
m0 -= cal_data[i][CAL_ISOLN][0]; m0 -= cal_data[CAL_ISOLN][i][0];
m1 -= cal_data[i][CAL_ISOLN][1]; m1 -= cal_data[CAL_ISOLN][i][1];
} }
coeff[0] = (m0 * cal_data[i][CAL_THRU][0] coeff[0] = (m0 * cal_data[CAL_THRU][i][0]
+ m1 * cal_data[i][CAL_THRU][1]) / sq; + m1 * cal_data[CAL_THRU][i][1]) / sq;
coeff[1] = (m1 * cal_data[i][CAL_THRU][0] coeff[1] = (m1 * cal_data[CAL_THRU][i][0]
- m0 * cal_data[i][CAL_THRU][1]) / sq; - m0 * cal_data[CAL_THRU][i][1]) / sq;
} }
} }
#endif
if (trace[t].polar) { if (trace[t].polar) {
int x1, y1; int x1, y1;
cartesian_scale(coeff[0], coeff[1], &x1, &y1); cartesian_scale(coeff[0], coeff[1], &x1, &y1);

207
main.c
View file

@ -12,6 +12,8 @@
RTCDateTime timespec; RTCDateTime timespec;
static void apply_error_term(void);
static const I2CConfig i2ccfg = { static const I2CConfig i2ccfg = {
0x00300506, //voodoo magic 400kHz @ HSI 8MHz 0x00300506, //voodoo magic 400kHz @ HSI 8MHz
@ -44,7 +46,7 @@ static MUTEX_DECL(mutex);
static THD_WORKING_AREA(waThread1, 384); static THD_WORKING_AREA(waThread1, 400);
static THD_FUNCTION(Thread1, arg) static THD_FUNCTION(Thread1, arg)
{ {
(void)arg; (void)arg;
@ -213,11 +215,11 @@ volatile int16_t wait_count = 0;
int16_t dump_selection = 0; int16_t dump_selection = 0;
int16_t dsp_disabled = FALSE; int16_t dsp_disabled = FALSE;
float measured[101][2][2]; float measured[2][101][2];
uint32_t frequencies[101]; uint32_t frequencies[101];
uint16_t cal_status; uint16_t cal_status;
float cal_data[101][5][2]; float cal_data[5][101][2];
@ -349,7 +351,7 @@ void scan_lcd(void)
{ {
int i; int i;
int delay; int delay;
int first = TRUE; //int first = TRUE;
delay = set_frequency(frequencies[0]); delay = set_frequency(frequencies[0]);
delay += 2; delay += 2;
@ -360,7 +362,7 @@ void scan_lcd(void)
; ;
palClearPad(GPIOC, GPIOC_LED); palClearPad(GPIOC, GPIOC_LED);
__disable_irq(); __disable_irq();
calclate_gamma(&measured[i][0]); calclate_gamma(measured[0][i]);
__enable_irq(); __enable_irq();
tlv320aic3204_select_in1(); tlv320aic3204_select_in1();
@ -368,19 +370,19 @@ void scan_lcd(void)
while (wait_count) while (wait_count)
; ;
__disable_irq(); __disable_irq();
calclate_gamma(&measured[i][1]); calclate_gamma(measured[1][i]);
__enable_irq(); __enable_irq();
delay = set_frequency(frequencies[(i+1)%sweep_points]); delay = set_frequency(frequencies[(i+1)%sweep_points]);
#if 0 #if 0
sweep_plot(frequencies[i], first, measured[i]); sweep_plot(frequencies[i], first, measured[0][i], measured[1][i]);
first = FALSE; first = FALSE;
#endif #endif
palSetPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);
} }
#if 0 #if 0
for (i = 0; i < sweep_points; i++) { for (i = 0; i < sweep_points; i++) {
sweep_plot(frequencies[i], first, measured[i]); sweep_plot(frequencies[i], first, measured[0][i], measured[1][i]);
first = FALSE; first = FALSE;
} }
#endif #endif
@ -388,6 +390,8 @@ void scan_lcd(void)
sweep_tail(); sweep_tail();
polar_plot(measured); polar_plot(measured);
#endif #endif
if (cal_status & CALSTAT_APPLY)
apply_error_term();
plot_into_index(measured); plot_into_index(measured);
draw_cell_all(); draw_cell_all();
} }
@ -450,66 +454,203 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[])
} }
static void
eterm_set(int term, float re, float im)
{
int i;
for (i = 0; i < 101; i++) {
cal_data[term][i][0] = re;
cal_data[term][i][1] = im;
}
}
static void
eterm_copy(int dst, int src)
{
memcpy(cal_data[dst], cal_data[src], sizeof cal_data[dst]);
}
static void
eterm_calc_es(void)
{
int i;
for (i = 0; i < 101; i++) {
// S11mo= S11mo - Ed
// S11ms= S11ms - Ed
float s11or = cal_data[CAL_OPEN][i][0] - cal_data[ETERM_ED][i][0];
float s11oi = cal_data[CAL_OPEN][i][1] - cal_data[ETERM_ED][i][1];
float s11sr = cal_data[CAL_SHORT][i][0] - cal_data[ETERM_ED][i][0];
float s11si = cal_data[CAL_SHORT][i][1] - cal_data[ETERM_ED][i][1];
// Es = (S11mo' + S11ms)/(S11mo' - S11ms)
float numr = s11or + s11sr;
float numi = s11oi + s11si;
float denomr = s11or - s11sr;
float denomi = s11oi - s11si;
float sq = denomr*denomr+denomi*denomi;
cal_data[ETERM_ES][i][0] = (numr*denomr + numi*denomi)/sq;
cal_data[ETERM_ES][i][1] = (numi*denomr - numr*denomi)/sq;
}
cal_status &= ~CALSTAT_SHORT;
cal_status |= CALSTAT_ES;
}
static void
eterm_calc_er(int sign)
{
int i;
for (i = 0; i < 101; i++) {
// Er = sign*(1-Es)S11mo'
float esr = 1 - cal_data[ETERM_ES][i][0];
float esi = -cal_data[ETERM_ES][i][1];
float err = esr * cal_data[CAL_OPEN][i][0] - esi * cal_data[CAL_OPEN][i][1];
float eri = esr * cal_data[CAL_OPEN][i][1] + esi * cal_data[CAL_OPEN][i][0];
if (sign < 0) {
err = -err;
eri = -eri;
}
cal_data[ETERM_ER][i][0] = err;
cal_data[ETERM_ER][i][1] = eri;
}
cal_status &= ~CALSTAT_OPEN;
cal_status |= CALSTAT_ER;
}
// CAUTION: Et is inversed for efficiency
static void
eterm_calc_et(void)
{
int i;
for (i = 0; i < 101; i++) {
// Et = 1/(S21mt - Ex)(1 - Es)
float esr = 1 - cal_data[ETERM_ES][i][0];
float esi = -cal_data[ETERM_ES][i][1];
float s21mr = cal_data[CAL_THRU][i][0] - cal_data[CAL_ISOLN][i][0];
float s21mi = cal_data[CAL_THRU][i][1] - cal_data[CAL_ISOLN][i][1];
float etr = esr * s21mr - esi * s21mi;
float eti = esr * s21mi + esi * s21mr;
float sq = etr*etr + eti*eti;
float invr = etr / sq;
float invi = -eti / sq;
cal_data[ETERM_ET][i][0] = invr;
cal_data[ETERM_ET][i][1] = invi;
}
cal_status &= ~CALSTAT_THRU;
cal_status |= CALSTAT_ET;
}
void apply_error_term(void)
{
int i;
for (i = 0; i < 101; i++) {
// S11m' = S11m - Ed
// S11a = S11m' / (Er + Es S11m')
float s11mr = measured[0][i][0] - cal_data[ETERM_ED][i][0];
float s11mi = measured[0][i][1] - cal_data[ETERM_ED][i][1];
float err = cal_data[ETERM_ER][i][0] + s11mr * cal_data[ETERM_ES][i][0] - s11mi * cal_data[ETERM_ES][i][1];
float eri = cal_data[ETERM_ER][i][1] + s11mr * cal_data[ETERM_ES][i][1] + s11mi * cal_data[ETERM_ES][i][0];
float sq = err*err + eri*eri;
float s11ar = (s11mr * err + s11mi * eri) / sq;
float s11ai = (s11mi * err - s11mr * eri) / sq;
measured[0][i][0] = s11ar;
measured[0][i][1] = s11ai;
// CAUTION: Et is inversed for efficiency
// S21m' = S21m - Ex
// S21a = S21m' (1-EsS11a)Et
float s21mr = measured[1][i][0] - cal_data[ETERM_EX][i][0];
float s21mi = measured[1][i][1] - cal_data[ETERM_EX][i][1];
float esr = 1 - (cal_data[ETERM_ES][i][0] * s11ar - cal_data[ETERM_ES][i][1] * s11ai);
float esi = - (cal_data[ETERM_ES][i][1] * s11ar + cal_data[ETERM_ES][i][0] * s11ai);
float etr = esr * cal_data[ETERM_ET][i][0] - esi * cal_data[ETERM_ET][i][1];
float eti = esr * cal_data[ETERM_ET][i][1] + esi * cal_data[ETERM_ET][i][0];
float s21ar = s21mr * etr - s21mi * eti;
float s21ai = s21mi * etr + s21mr * eti;
measured[1][i][0] = s21ar;
measured[1][i][1] = s21ai;
}
}
static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[])
{ {
const char *items[] = { "load", "open", "short", "thru", "isoln", "Es", "Er", "Et", "cal'ed" };
if (argc == 0) { if (argc == 0) {
chprintf(chp, "%d\r\n", cal_status); int i;
for (i = 0; i < 9; i++) {
if (cal_status & (1<<i))
chprintf(chp, "%s ", items[i]);
}
chprintf(chp, "\r\n");
return; return;
} }
char *cmd = argv[0]; char *cmd = argv[0];
int s, d, i;
if (strcmp(cmd, "load") == 0) { if (strcmp(cmd, "load") == 0) {
cal_status |= CALSTAT_LOAD; cal_status |= CALSTAT_LOAD;
s = 0; memcpy(cal_data[CAL_LOAD], measured[0], sizeof measured[0]);
d = CAL_LOAD;
} else if (strcmp(cmd, "open") == 0) { } else if (strcmp(cmd, "open") == 0) {
cal_status |= CALSTAT_OPEN; cal_status |= CALSTAT_OPEN;
s = 0; memcpy(cal_data[CAL_OPEN], measured[0], sizeof measured[0]);
d = CAL_OPEN;
} else if (strcmp(cmd, "short") == 0) { } else if (strcmp(cmd, "short") == 0) {
cal_status |= CALSTAT_SHORT; cal_status |= CALSTAT_SHORT;
s = 0; memcpy(cal_data[CAL_SHORT], measured[0], sizeof measured[0]);
d = CAL_SHORT;
} else if (strcmp(cmd, "thru") == 0) { } else if (strcmp(cmd, "thru") == 0) {
cal_status |= CALSTAT_THRU; cal_status |= CALSTAT_THRU;
s = 1; memcpy(cal_data[CAL_THRU], measured[1], sizeof measured[0]);
d = CAL_THRU;
} else if (strcmp(cmd, "isoln") == 0) { } else if (strcmp(cmd, "isoln") == 0) {
cal_status |= CALSTAT_ISOLN; cal_status |= CALSTAT_ISOLN;
s = 1; memcpy(cal_data[CAL_ISOLN], measured[1], sizeof measured[0]);
d = CAL_ISOLN;
} else if (strcmp(cmd, "done") == 0) { } else if (strcmp(cmd, "done") == 0) {
if (!(cal_status & CALSTAT_LOAD))
eterm_set(ETERM_ED, 0.0, 0.0);
if ((cal_status & CALSTAT_SHORT) && (cal_status & CALSTAT_OPEN)) {
eterm_calc_es();
eterm_calc_er(1);
} else if (cal_status & CALSTAT_OPEN) {
eterm_set(ETERM_ES, 0.0, 0.0);
eterm_calc_er(1);
} else if (cal_status & CALSTAT_SHORT) {
eterm_copy(CAL_OPEN, CAL_SHORT);
eterm_set(ETERM_ES, 0.0, 0.0);
cal_status &= ~CALSTAT_SHORT;
eterm_calc_er(-1);
} else {
eterm_set(ETERM_ER, 1.0, 0.0);
eterm_set(ETERM_ES, 0.0, 0.0);
}
if (!(cal_status & CALSTAT_ISOLN))
eterm_set(ETERM_EX, 0.0, 0.0);
if (cal_status & CALSTAT_THRU) {
eterm_calc_et();
} else {
eterm_set(ETERM_ET, 1.0, 0.0);
}
cal_status |= CALSTAT_APPLY; cal_status |= CALSTAT_APPLY;
return; return;
} else if (strcmp(cmd, "on") == 0) {
cal_status |= CALSTAT_APPLY;
return;
} else if (strcmp(cmd, "off") == 0) {
cal_status &= ~CALSTAT_APPLY;
return;
} else if (strcmp(cmd, "reset") == 0) { } else if (strcmp(cmd, "reset") == 0) {
cal_status = 0; cal_status = 0;
return; return;
} else if (strcmp(cmd, "data") == 0) { } else if (strcmp(cmd, "data") == 0) {
chprintf(chp, "%d %d\r\n", cal_data[0][CAL_LOAD][0], cal_data[0][CAL_LOAD][1]); chprintf(chp, "%d %d\r\n", (int)cal_data[CAL_LOAD][0][0], (int)cal_data[CAL_LOAD][0][1]);
chprintf(chp, "%d %d\r\n", cal_data[0][CAL_OPEN][0], cal_data[0][CAL_OPEN][1]); chprintf(chp, "%d %d\r\n", (int)cal_data[CAL_OPEN][0][0], (int)cal_data[CAL_OPEN][0][1]);
chprintf(chp, "%d %d\r\n", cal_data[0][CAL_SHORT][0], cal_data[0][CAL_SHORT][1]); chprintf(chp, "%d %d\r\n", (int)cal_data[CAL_SHORT][0][0], (int)cal_data[CAL_SHORT][0][1]);
chprintf(chp, "%d %d\r\n", cal_data[0][CAL_THRU][0], cal_data[0][CAL_THRU][1]); chprintf(chp, "%d %d\r\n", (int)cal_data[CAL_THRU][0][0], (int)cal_data[CAL_THRU][0][1]);
chprintf(chp, "%d %d\r\n", cal_data[0][CAL_ISOLN][0], cal_data[0][CAL_ISOLN][1]); chprintf(chp, "%d %d\r\n", (int)cal_data[CAL_ISOLN][0][0], (int)cal_data[CAL_ISOLN][0][1]);
return; return;
} else { } else {
chprintf(chp, "usage: cal {load|open|short|thru|isoln|done}\r\n"); chprintf(chp, "usage: cal {load|open|short|thru|isoln|done}\r\n");
return; return;
} }
for (i = 0; i < 101; i++) {
cal_data[i][d][0] = measured[i][s][0];
cal_data[i][d][1] = measured[i][s][1];
}
} }
static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[])
{ {
int i; int i;
@ -612,7 +753,7 @@ static void cmd_stat(BaseSequentialStream *chp, int argc, char *argv[])
#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(384) #define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(400)
static const ShellCommand commands[] = static const ShellCommand commands[] =
{ {

View file

@ -46,13 +46,15 @@ void ili9341_init(void);
void ili9341_test(int mode); void ili9341_test(int mode);
void set_sweep(int32_t start, int stop); void set_sweep(int32_t start, int stop);
void sweep_plot(int32_t freq, int first, float measured[4]); #if 0
void sweep_plot(int32_t freq, int first, float port0[2], float port1[2]);
void sweep_tail(void); void sweep_tail(void);
#endif
void redraw(void); void redraw(void);
void polar_plot(float measured[101][4]); void polar_plot(float measured[101][4]);
extern uint16_t cal_status; extern uint16_t cal_status;
extern float cal_data[101][5][2]; extern float cal_data[5][101][2];
#define CAL_LOAD 0 #define CAL_LOAD 0
#define CAL_OPEN 1 #define CAL_OPEN 1
@ -65,10 +67,21 @@ extern float cal_data[101][5][2];
#define CALSTAT_SHORT (1<<2) #define CALSTAT_SHORT (1<<2)
#define CALSTAT_THRU (1<<3) #define CALSTAT_THRU (1<<3)
#define CALSTAT_ISOLN (1<<4) #define CALSTAT_ISOLN (1<<4)
#define CALSTAT_APPLY (1<<5) #define CALSTAT_ES (1<<5)
#define CALSTAT_ER (1<<6)
#define CALSTAT_ET (1<<7)
#define CALSTAT_ED CALSTAT_LOAD
#define CALSTAT_EX CALSTAT_ISOLN
#define CALSTAT_APPLY (1<<8)
#define ETERM_ED 0 /* error term directivity */
#define ETERM_ER 1 /* error term refrection tracking */
#define ETERM_ES 2 /* error term source match */
#define ETERM_ET 3 /* error term transmission tracking */
#define ETERM_EX 4 /* error term isolation */
void plot_into_index(float measured[101][2][2]); void plot_into_index(float measured[2][101][2]);
void draw_cell_all(void); void draw_cell_all(void);
extern const uint16_t x5x7_bits []; extern const uint16_t x5x7_bits [];