change menu name to 'TRANSFORM'

scan_delay_optimize
cho45 6 years ago
parent b17ecfa533
commit 6bad9de606

45
fft.h

@ -33,16 +33,38 @@ static uint8_t reverse_bits(uint8_t x, int n) {
return result; 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 * 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) { static void fft128(float array[][2], const uint8_t dir) {
int levels = 0; // Compute levels = floor(log2(n)) const uint8_t n = 128;
for (uint8_t temp = n; temp > 1U; temp >>= 1) const uint8_t levels = 7; // log2(n)
levels++; const float* const cos_table = &sin_table[32];
uint8_t real = dir & 1; const uint8_t real = dir & 1;
uint8_t imag = ~real & 1; const uint8_t imag = ~real & 1;
for (uint8_t i = 0; i < n; i++) { for (uint8_t i = 0; i < n; i++) {
uint8_t j = reverse_bits(i, levels); 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 i = 0; i < n; i += size) {
for (uint8_t j = i, k = 0; j < i + halfsize; j++, k += tablestep) { for (uint8_t j = i, k = 0; j < i + halfsize; j++, k += tablestep) {
uint8_t l = j + halfsize; 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 tpre = array[l][real] * cos_table[k] + array[l][imag] * sin_table[k];
float tpim = -array[l][real] * sin(2 * M_PI * k / n) + array[l][imag] * cos(2 * M_PI * k / n); float tpim = -array[l][real] * sin_table[k] + array[l][imag] * cos_table[k] ;
array[l][real] = array[j][real] - tpre; array[l][real] = array[j][real] - tpre;
array[l][imag] = array[j][imag] - tpim; array[l][imag] = array[j][imag] - tpim;
array[j][real] += tpre; 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);
}

@ -122,13 +122,13 @@ transform_domain(void)
tmp[i*2+0] = 0.0; tmp[i*2+0] = 0.0;
tmp[i*2+1] = 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])); memcpy(measured[ch], tmp, sizeof(measured[0]));
for (int i = 0; i < 101; i++) { for (int i = 0; i < 101; i++) {
measured[ch][i][0] /= 128.0; measured[ch][i][0] /= 128.0;
measured[ch][i][1] /= 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++) { for (int i = 1; i < 101; i++) {
measured[ch][i][0] += measured[ch][i-1][0]; measured[ch][i][0] += measured[ch][i-1][0];
measured[ch][i][1] += measured[ch][i-1][1]; measured[ch][i][1] += measured[ch][i-1][1];

@ -61,9 +61,14 @@ enum {
#define DOMAIN_MODE (1<<0) #define DOMAIN_MODE (1<<0)
#define DOMAIN_FREQ (0<<0) #define DOMAIN_FREQ (0<<0)
#define DOMAIN_TIME (1<<0) #define DOMAIN_TIME (1<<0)
#define TDR_FUNC (1<<1) #define TDR_FUNC (0b11<<1)
#define TDR_FUNC_IMPULSE (0<<1) #define TDR_FUNC_BANDPASS (0b00<<1)
#define TDR_FUNC_STEP (1<<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_collect(int type);
void cal_done(void); void cal_done(void);
@ -298,7 +303,7 @@ typedef struct {
trace_t _trace[TRACES_MAX]; trace_t _trace[TRACES_MAX];
marker_t _markers[4]; marker_t _markers[4];
int _active_marker; int _active_marker;
uint8_t _domain_mode; uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TDR_FUNC m: DOMAIN_MODE */
uint8_t _velocity_factor; // % uint8_t _velocity_factor; // %
int32_t checksum; int32_t checksum;

69
ui.c

@ -665,7 +665,27 @@ menu_channel_cb(int item)
} }
static void 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; int status;
switch (item) { switch (item) {
@ -678,14 +698,18 @@ menu_tdr_cb(int item)
ui_mode_normal(); ui_mode_normal();
break; break;
case 1: case 1:
domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_IMPULSE; domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_LOWPASS_IMPULSE;
ui_mode_normal(); ui_mode_normal();
break; break;
case 2: case 2:
domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_STEP; domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_LOWPASS_STEP;
ui_mode_normal(); ui_mode_normal();
break; break;
case 3: case 3:
domain_mode = (domain_mode & ~TDR_FUNC) | TDR_FUNC_BANDPASS;
ui_mode_normal();
break;
case 5:
status = btn_wait_release(); status = btn_wait_release();
if (status & EVT_BUTTON_DOWN_LONG) { if (status & EVT_BUTTON_DOWN_LONG) {
ui_mode_numeric(KM_VELOCITY_FACTOR); ui_mode_numeric(KM_VELOCITY_FACTOR);
@ -908,11 +932,21 @@ const menuitem_t menu_channel[] = {
{ MT_NONE, NULL, NULL } // sentinel { MT_NONE, NULL, NULL } // sentinel
}; };
const menuitem_t menu_tdr[] = { const menuitem_t menu_transform_window[] = {
{ MT_CALLBACK, "TDR MODE", menu_tdr_cb }, { MT_CALLBACK, "MINIMUM", menu_transform_window_cb },
{ MT_CALLBACK, "IMPULSE", menu_tdr_cb }, { MT_CALLBACK, "NORMAL", menu_transform_window_cb },
{ MT_CALLBACK, "STEP", menu_tdr_cb }, { MT_CALLBACK, "MAXIMUM", menu_transform_window_cb },
{ MT_CALLBACK, "\2VELOCITY\0FACTOR", menu_tdr_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_CANCEL, S_LARROW" BACK", NULL },
{ MT_NONE, NULL, NULL } // sentinel { MT_NONE, NULL, NULL } // sentinel
}; };
@ -922,7 +956,7 @@ const menuitem_t menu_display[] = {
{ MT_SUBMENU, "FORMAT", menu_format }, { MT_SUBMENU, "FORMAT", menu_format },
{ MT_SUBMENU, "SCALE", menu_scale }, { MT_SUBMENU, "SCALE", menu_scale },
{ MT_SUBMENU, "CHANNEL", menu_channel }, { MT_SUBMENU, "CHANNEL", menu_channel },
{ MT_SUBMENU, "TDR", menu_tdr }, { MT_SUBMENU, "TRANSFORM", menu_transform },
{ MT_CANCEL, S_LARROW" BACK", NULL }, { MT_CANCEL, S_LARROW" BACK", NULL },
{ MT_NONE, NULL, NULL } // sentinel { MT_NONE, NULL, NULL } // sentinel
}; };
@ -1168,7 +1202,7 @@ const keypads_t * const keypads_mode_tbl[] = {
}; };
const char * const keypad_mode_label[] = { 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 void
@ -1281,10 +1315,19 @@ menu_item_modify_attribute(const menuitem_t *menu, int item,
*bg = 0x0000; *bg = 0x0000;
*fg = 0xffff; *fg = 0xffff;
} }
} else if (menu == menu_tdr) { } else if (menu == menu_transform) {
if ((item == 0 && (domain_mode & DOMAIN_MODE) == DOMAIN_TIME) if ((item == 0 && (domain_mode & DOMAIN_MODE) == DOMAIN_TIME)
|| (item == 1 && (domain_mode & TDR_FUNC) == TDR_FUNC_IMPULSE) || (item == 1 && (domain_mode & TDR_FUNC) == TDR_FUNC_LOWPASS_IMPULSE)
|| (item == 2 && (domain_mode & TDR_FUNC) == TDR_FUNC_STEP) || (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; *bg = 0x0000;
*fg = 0xffff; *fg = 0xffff;

Loading…
Cancel
Save

Powered by TurnKey Linux.