mirror of
https://github.com/ttrftech/NanoVNA.git
synced 2025-12-06 03:31:59 +01:00
change menu name to 'TRANSFORM'
This commit is contained in:
parent
b17ecfa533
commit
6bad9de606
45
fft.h
45
fft.h
|
|
@ -33,16 +33,38 @@ static uint8_t reverse_bits(uint8_t x, int n) {
|
|||
return result;
|
||||
}
|
||||
|
||||
static const float sin_table[] = {
|
||||
/*
|
||||
* float has about 7.2 digits of precision
|
||||
for (uint8_t i = 0; i < 96; i++) {
|
||||
printf("% .8f,%c", sin(2 * M_PI * i / n), i % 8 == 7 ? '\n' : ' ');
|
||||
}
|
||||
*/
|
||||
0.00000000, 0.04906767, 0.09801714, 0.14673047, 0.19509032, 0.24298018, 0.29028468, 0.33688985,
|
||||
0.38268343, 0.42755509, 0.47139674, 0.51410274, 0.55557023, 0.59569930, 0.63439328, 0.67155895,
|
||||
0.70710678, 0.74095113, 0.77301045, 0.80320753, 0.83146961, 0.85772861, 0.88192126, 0.90398929,
|
||||
0.92387953, 0.94154407, 0.95694034, 0.97003125, 0.98078528, 0.98917651, 0.99518473, 0.99879546,
|
||||
1.00000000, 0.99879546, 0.99518473, 0.98917651, 0.98078528, 0.97003125, 0.95694034, 0.94154407,
|
||||
0.92387953, 0.90398929, 0.88192126, 0.85772861, 0.83146961, 0.80320753, 0.77301045, 0.74095113,
|
||||
0.70710678, 0.67155895, 0.63439328, 0.59569930, 0.55557023, 0.51410274, 0.47139674, 0.42755509,
|
||||
0.38268343, 0.33688985, 0.29028468, 0.24298018, 0.19509032, 0.14673047, 0.09801714, 0.04906767,
|
||||
0.00000000, -0.04906767, -0.09801714, -0.14673047, -0.19509032, -0.24298018, -0.29028468, -0.33688985,
|
||||
-0.38268343, -0.42755509, -0.47139674, -0.51410274, -0.55557023, -0.59569930, -0.63439328, -0.67155895,
|
||||
-0.70710678, -0.74095113, -0.77301045, -0.80320753, -0.83146961, -0.85772861, -0.88192126, -0.90398929,
|
||||
-0.92387953, -0.94154407, -0.95694034, -0.97003125, -0.98078528, -0.98917651, -0.99518473, -0.99879546,
|
||||
};
|
||||
|
||||
/***
|
||||
* dir = forward: 0, inverse: 1
|
||||
* https://www.nayuki.io/res/free-small-fft-in-multiple-languages/fft.c
|
||||
*/
|
||||
void fft(float array[][2], uint8_t n, uint8_t dir) {
|
||||
int levels = 0; // Compute levels = floor(log2(n))
|
||||
for (uint8_t temp = n; temp > 1U; temp >>= 1)
|
||||
levels++;
|
||||
static void fft128(float array[][2], const uint8_t dir) {
|
||||
const uint8_t n = 128;
|
||||
const uint8_t levels = 7; // log2(n)
|
||||
const float* const cos_table = &sin_table[32];
|
||||
|
||||
uint8_t real = dir & 1;
|
||||
uint8_t imag = ~real & 1;
|
||||
const uint8_t real = dir & 1;
|
||||
const uint8_t imag = ~real & 1;
|
||||
|
||||
for (uint8_t i = 0; i < n; i++) {
|
||||
uint8_t j = reverse_bits(i, levels);
|
||||
|
|
@ -63,8 +85,8 @@ void fft(float array[][2], uint8_t n, uint8_t dir) {
|
|||
for (uint8_t i = 0; i < n; i += size) {
|
||||
for (uint8_t j = i, k = 0; j < i + halfsize; j++, k += tablestep) {
|
||||
uint8_t l = j + halfsize;
|
||||
float tpre = array[l][real] * cos(2 * M_PI * k / n) + array[l][imag] * sin(2 * M_PI * k / n);
|
||||
float tpim = -array[l][real] * sin(2 * M_PI * k / n) + array[l][imag] * cos(2 * M_PI * k / n);
|
||||
float tpre = array[l][real] * cos_table[k] + array[l][imag] * sin_table[k];
|
||||
float tpim = -array[l][real] * sin_table[k] + array[l][imag] * cos_table[k] ;
|
||||
array[l][real] = array[j][real] - tpre;
|
||||
array[l][imag] = array[j][imag] - tpim;
|
||||
array[j][real] += tpre;
|
||||
|
|
@ -76,3 +98,10 @@ void fft(float array[][2], uint8_t n, uint8_t dir) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline void fft128_forward(float array[][2]) {
|
||||
fft128(array, 0);
|
||||
}
|
||||
|
||||
static inline void fft128_inverse(float array[][2]) {
|
||||
fft128(array, 1);
|
||||
}
|
||||
|
|
|
|||
4
main.c
4
main.c
|
|
@ -122,13 +122,13 @@ transform_domain(void)
|
|||
tmp[i*2+0] = 0.0;
|
||||
tmp[i*2+1] = 0.0;
|
||||
}
|
||||
fft((float(*)[2])tmp, 128, 1);
|
||||
fft128_inverse((float(*)[2])tmp);
|
||||
memcpy(measured[ch], tmp, sizeof(measured[0]));
|
||||
for (int i = 0; i < 101; i++) {
|
||||
measured[ch][i][0] /= 128.0;
|
||||
measured[ch][i][1] /= 128.0;
|
||||
}
|
||||
if ( (domain_mode & TDR_FUNC_STEP) == TDR_FUNC_STEP ) {
|
||||
if ( (domain_mode & TDR_FUNC) == TDR_FUNC_LOWPASS_STEP ) {
|
||||
for (int i = 1; i < 101; i++) {
|
||||
measured[ch][i][0] += measured[ch][i-1][0];
|
||||
measured[ch][i][1] += measured[ch][i-1][1];
|
||||
|
|
|
|||
13
nanovna.h
13
nanovna.h
|
|
@ -61,9 +61,14 @@ enum {
|
|||
#define DOMAIN_MODE (1<<0)
|
||||
#define DOMAIN_FREQ (0<<0)
|
||||
#define DOMAIN_TIME (1<<0)
|
||||
#define TDR_FUNC (1<<1)
|
||||
#define TDR_FUNC_IMPULSE (0<<1)
|
||||
#define TDR_FUNC_STEP (1<<1)
|
||||
#define TDR_FUNC (0b11<<1)
|
||||
#define TDR_FUNC_BANDPASS (0b00<<1)
|
||||
#define TDR_FUNC_LOWPASS_IMPULSE (0b01<<1)
|
||||
#define TDR_FUNC_LOWPASS_STEP (0b10<<1)
|
||||
#define TDR_WINDOW (0b11<<3)
|
||||
#define TDR_WINDOW_NORMAL (0b00<<3)
|
||||
#define TDR_WINDOW_MINIMUM (0b01<<3)
|
||||
#define TDR_WINDOW_MAXIMUM (0b10<<3)
|
||||
|
||||
void cal_collect(int type);
|
||||
void cal_done(void);
|
||||
|
|
@ -298,7 +303,7 @@ typedef struct {
|
|||
trace_t _trace[TRACES_MAX];
|
||||
marker_t _markers[4];
|
||||
int _active_marker;
|
||||
uint8_t _domain_mode;
|
||||
uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TDR_FUNC m: DOMAIN_MODE */
|
||||
uint8_t _velocity_factor; // %
|
||||
|
||||
int32_t checksum;
|
||||
|
|
|
|||
69
ui.c
69
ui.c
|
|
@ -665,7 +665,27 @@ menu_channel_cb(int item)
|
|||
}
|
||||
|
||||
static void
|
||||
menu_tdr_cb(int item)
|
||||
menu_transform_window_cb(int item)
|
||||
{
|
||||
// TODO
|
||||
switch (item) {
|
||||
case 0:
|
||||
domain_mode = (domain_mode & ~TDR_WINDOW) | TDR_WINDOW_MINIMUM;
|
||||
ui_mode_normal();
|
||||
break;
|
||||
case 1:
|
||||
domain_mode = (domain_mode & ~TDR_WINDOW) | TDR_WINDOW_NORMAL;
|
||||
ui_mode_normal();
|
||||
break;
|
||||
case 2:
|
||||
domain_mode = (domain_mode & ~TDR_WINDOW) | TDR_WINDOW_MAXIMUM;
|
||||
ui_mode_normal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
menu_transform_cb(int item)
|
||||
{
|
||||
int status;
|
||||
switch (item) {
|
||||
|
|
@ -678,14 +698,18 @@ menu_tdr_cb(int item)
|
|||
ui_mode_normal();
|
||||
break;
|
||||
case 1:
|
||||
domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_IMPULSE;
|
||||
domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_LOWPASS_IMPULSE;
|
||||
ui_mode_normal();
|
||||
break;
|
||||
case 2:
|
||||
domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_STEP;
|
||||
domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_LOWPASS_STEP;
|
||||
ui_mode_normal();
|
||||
break;
|
||||
case 3:
|
||||
domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_BANDPASS;
|
||||
ui_mode_normal();
|
||||
break;
|
||||
case 5:
|
||||
status = btn_wait_release();
|
||||
if (status & EVT_BUTTON_DOWN_LONG) {
|
||||
ui_mode_numeric(KM_VELOCITY_FACTOR);
|
||||
|
|
@ -908,11 +932,21 @@ const menuitem_t menu_channel[] = {
|
|||
{ MT_NONE, NULL, NULL } // sentinel
|
||||
};
|
||||
|
||||
const menuitem_t menu_tdr[] = {
|
||||
{ MT_CALLBACK, "TDR MODE", menu_tdr_cb },
|
||||
{ MT_CALLBACK, "IMPULSE", menu_tdr_cb },
|
||||
{ MT_CALLBACK, "STEP", menu_tdr_cb },
|
||||
{ MT_CALLBACK, "\2VELOCITY\0FACTOR", menu_tdr_cb },
|
||||
const menuitem_t menu_transform_window[] = {
|
||||
{ MT_CALLBACK, "MINIMUM", menu_transform_window_cb },
|
||||
{ MT_CALLBACK, "NORMAL", menu_transform_window_cb },
|
||||
{ MT_CALLBACK, "MAXIMUM", menu_transform_window_cb },
|
||||
{ MT_CANCEL, S_LARROW" BACK", NULL },
|
||||
{ MT_NONE, NULL, NULL } // sentinel
|
||||
};
|
||||
|
||||
const menuitem_t menu_transform[] = {
|
||||
{ MT_CALLBACK, "\2TRANSFORM\0ON", menu_transform_cb },
|
||||
{ MT_CALLBACK, "\2LOW PASS\0IMPULSE", menu_transform_cb },
|
||||
{ MT_CALLBACK, "\2LOW PASS\0STEP", menu_transform_cb },
|
||||
{ MT_CALLBACK, "BANDPASS", menu_transform_cb },
|
||||
{ MT_SUBMENU, "WINDOW", menu_transform_window },
|
||||
{ MT_CALLBACK, "\2VELOCITY\0FACTOR", menu_transform_cb },
|
||||
{ MT_CANCEL, S_LARROW" BACK", NULL },
|
||||
{ MT_NONE, NULL, NULL } // sentinel
|
||||
};
|
||||
|
|
@ -922,7 +956,7 @@ const menuitem_t menu_display[] = {
|
|||
{ MT_SUBMENU, "FORMAT", menu_format },
|
||||
{ MT_SUBMENU, "SCALE", menu_scale },
|
||||
{ MT_SUBMENU, "CHANNEL", menu_channel },
|
||||
{ MT_SUBMENU, "TDR", menu_tdr },
|
||||
{ MT_SUBMENU, "TRANSFORM", menu_transform },
|
||||
{ MT_CANCEL, S_LARROW" BACK", NULL },
|
||||
{ MT_NONE, NULL, NULL } // sentinel
|
||||
};
|
||||
|
|
@ -1168,7 +1202,7 @@ const keypads_t * const keypads_mode_tbl[] = {
|
|||
};
|
||||
|
||||
const char * const keypad_mode_label[] = {
|
||||
"START", "STOP", "CENTER", "SPAN", "CW FREQ", "SCALE", "REFPOS", "EDELAY", "VELOCITY"
|
||||
"START", "STOP", "CENTER", "SPAN", "CW FREQ", "SCALE", "REFPOS", "EDELAY", "VELOCITY%"
|
||||
};
|
||||
|
||||
void
|
||||
|
|
@ -1281,10 +1315,19 @@ menu_item_modify_attribute(const menuitem_t *menu, int item,
|
|||
*bg = 0x0000;
|
||||
*fg = 0xffff;
|
||||
}
|
||||
} else if (menu == menu_tdr) {
|
||||
} else if (menu == menu_transform) {
|
||||
if ((item == 0 && (domain_mode & DOMAIN_MODE) == DOMAIN_TIME)
|
||||
|| (item == 1 && (domain_mode & TDR_FUNC) == TDR_FUNC_IMPULSE)
|
||||
|| (item == 2 && (domain_mode & TDR_FUNC) == TDR_FUNC_STEP)
|
||||
|| (item == 1 && (domain_mode & TDR_FUNC) == TDR_FUNC_LOWPASS_IMPULSE)
|
||||
|| (item == 2 && (domain_mode & TDR_FUNC) == TDR_FUNC_LOWPASS_STEP)
|
||||
|| (item == 3 && (domain_mode & TDR_FUNC) == TDR_FUNC_BANDPASS)
|
||||
) {
|
||||
*bg = 0x0000;
|
||||
*fg = 0xffff;
|
||||
}
|
||||
} else if (menu == menu_transform_window) {
|
||||
if ((item == 0 && (domain_mode & TDR_WINDOW) == TDR_WINDOW_MINIMUM)
|
||||
|| (item == 1 && (domain_mode & TDR_WINDOW) == TDR_WINDOW_NORMAL)
|
||||
|| (item == 2 && (domain_mode & TDR_WINDOW) == TDR_WINDOW_MAXIMUM)
|
||||
) {
|
||||
*bg = 0x0000;
|
||||
*fg = 0xffff;
|
||||
|
|
|
|||
Loading…
Reference in a new issue