From 66bd2ae21aa026138811b7f63a44b54c4176e751 Mon Sep 17 00:00:00 2001 From: DiSlord Date: Mon, 3 Aug 2020 12:15:16 +0300 Subject: [PATCH] Change sweep timing strategy, use timer for check clean data ready, and run measure on next buffer ready Start si5351 on 32MHz, this allow send correct clock to AIC3204 and start it Move init si5351 after display init Cleanup screen at startup --- ili9341.c | 1 + main.c | 247 +++++++++++++++++++++++++++--------------------- si5351.c | 53 +++++------ tlv320aic3204.c | 10 +- 4 files changed, 168 insertions(+), 143 deletions(-) diff --git a/ili9341.c b/ili9341.c index 24d1e24..5d355c7 100644 --- a/ili9341.c +++ b/ili9341.c @@ -430,6 +430,7 @@ void ili9341_init(void) p += 2 + p[1]; chThdSleepMilliseconds(5); } + ili9341_clear_screen(); } void ili9341_bulk_8bit(int x, int y, int w, int h, uint16_t *palette) diff --git a/main.c b/main.c index a861aa6..ee48acb 100644 --- a/main.c +++ b/main.c @@ -93,6 +93,7 @@ static void apply_edelay(void); static uint16_t get_sweep_mode(void); static void cal_interpolate(void); static void update_frequencies(bool interpolate); +static int set_frequency(uint32_t freq); static void set_frequencies(uint32_t start, uint32_t stop, uint16_t points); static bool sweep(bool break_on_operation, uint16_t sweep_mode); static void transform_domain(void); @@ -341,59 +342,6 @@ VNA_SHELL_FUNCTION(cmd_reset) ; } -#ifdef ENABLE_GAIN_COMMAND -static uint8_t gain_table[][2] = { -#else -static const uint8_t gain_table[][2] = { -#endif - { 0, 0 }, // 1st: 0 ~ 300MHz - { 50, 50 }, // 2nd: 300 ~ 900MHz - { 75, 75 }, // 3th: 900 ~ 1500MHz - { 85, 85 }, // 4th: 1500 ~ 2100MHz - { 95, 95 }, // 5th: 2100 ~ 2700MHz -}; - -#define DELAY_GAIN_CHANGE 4 - -static int -adjust_gain(uint32_t newfreq) -{ - int new_order = si5351_get_harmonic_lvl(newfreq); - int old_order = si5351_get_harmonic_lvl(si5351_get_frequency()); - if (new_order != old_order) { - tlv320aic3204_set_gain(gain_table[new_order][0], gain_table[new_order][1]); - return DELAY_GAIN_CHANGE; - } - return 0; -} - -#ifdef ENABLE_GAIN_COMMAND -VNA_SHELL_FUNCTION(cmd_gain) -{ - int rvalue = 0; - int lvalue = 0; - if (argc < 1 && argc > 3) { - shell_printf("usage: gain idx {lgain(0-95)} [rgain(0-95)]\r\n"); - return; - } - int idx = my_atoui(argv[0]); - lvalue = rvalue = my_atoui(argv[1]); - if (argc == 3) - rvalue = my_atoui(argv[2]); - tlv320aic3204_set_gain(lvalue, rvalue); - gain_table[idx][0] = lvalue; - gain_table[idx][1] = rvalue; -} -#endif - -int set_frequency(uint32_t freq) -{ - int delay = adjust_gain(freq); - uint8_t ds = drive_strength; - delay += si5351_set_frequency(freq, ds); - return delay; -} - // Use macro, std isdigit more big #define _isdigit(c) (c >= '0' && c <= '9') // Rewrite universal standart str to value functions to more compact @@ -625,18 +573,6 @@ VNA_SHELL_FUNCTION(cmd_clearconfig) "Do reset manually to take effect. Then do touch cal and save.\r\n"); } -static struct { - int16_t rms[2]; - int16_t ave[2]; - int callback_count; - -#if 0 - int32_t last_counter_value; - int32_t interval_cycles; - int32_t busy_cycles; -#endif -} stat; - VNA_SHELL_FUNCTION(cmd_data) { int i; @@ -830,22 +766,22 @@ duplicate_buffer_to_dump(int16_t *p) // // DMA i2s callback function, called on get 'half' and 'full' buffer size data // need for process data, while DMA fill next buffer +static volatile systime_t ready_time = 0; + void i2s_end_callback(I2SDriver *i2sp, size_t offset, size_t n) { int16_t *p = &rx_buffer[offset]; (void)i2sp; - if (wait_count > 0){ - if (wait_count <= config.bandwidth+1){ - if (wait_count == config.bandwidth+1) - reset_dsp_accumerator(); - dsp_process(p, n); - } + if (wait_count == 0 || chVTGetSystemTimeX() < ready_time) return; + if (wait_count == config.bandwidth+2) // At this moment in buffer exist noise data, reset and wait next clean buffer + reset_dsp_accumerator(); + else if (wait_count <= config.bandwidth+1) // Clean data ready, process it + dsp_process(p, n); #ifdef ENABLED_DUMP_COMMAND - duplicate_buffer_to_dump(p); + duplicate_buffer_to_dump(p); #endif - --wait_count; - } - stat.callback_count++; + --wait_count; +// stat.callback_count++; } static const I2SConfig i2sconfig = { @@ -858,11 +794,22 @@ static const I2SConfig i2sconfig = { 0 // i2spr }; -#define DSP_START(delay) {wait_count = delay + config.bandwidth;} -#define DSP_WAIT_READY while (wait_count) {__WFI();} +#ifdef ENABLE_SI5351_TIMINGS +extern uint16_t timings[16]; +#define DELAY_GAIN_CHANGE timings[6] +#define DELAY_CHANNEL_CHANGE timings[7] +#define DELAY_SWEEP_START timings[8] + +#else +// Use x 100us settings +#define DELAY_SWEEP_START 25 // Sweep start delay, allow remove noise at 1 point +#define DELAY_CHANNEL_CHANGE 3 // Delay for switch ADC channel +#define DELAY_GAIN_CHANGE 30 // Delay for change gain (and band) +#endif + +#define DSP_START(delay) {ready_time = chVTGetSystemTimeX() + delay; wait_count = config.bandwidth+2;} #define DSP_WAIT while (wait_count) {__WFI();} #define RESET_SWEEP {p_sweep = 0;} -#define DELAY_CHANNEL_CHANGE 2 #define SWEEP_CH0_MEASURE 1 #define SWEEP_CH1_MEASURE 2 @@ -886,53 +833,110 @@ bool sweep(bool break_on_operation, uint16_t sweep_mode) if (p_sweep>=sweep_points || break_on_operation == false) RESET_SWEEP; if (break_on_operation && sweep_mode == 0) return false; - uint16_t start_sweep = p_sweep; - // blink LED while scanning + // Blink LED while scanning palClearPad(GPIOC, GPIOC_LED); - // Power stabilization after LED off, before measure - int st_delay = 3; - for (; p_sweep < sweep_points; p_sweep++) { // 5300 +// START_PROFILE; + // Wait some time for stable power + int st_delay = DELAY_SWEEP_START; + for (; p_sweep < sweep_points; p_sweep++) { if (frequencies[p_sweep] == 0) break; delay = set_frequency(frequencies[p_sweep]); + // CH0:REFLECTION, reset and begin measure if (sweep_mode & SWEEP_CH0_MEASURE){ - tlv320aic3204_select(0); // CH0:REFLECTION, reset and begin measure + tlv320aic3204_select(0); DSP_START(delay+st_delay); delay = DELAY_CHANNEL_CHANGE; //================================================ // Place some code thats need execute while delay //================================================ - DSP_WAIT_READY; + DSP_WAIT; (*sample_func)(measured[0][p_sweep]); // calculate reflection coefficient - if (!APPLY_CALIBRATION_AFTER_SWEEP && cal_status & CALSTAT_APPLY) + if (APPLY_CALIBRATION_AFTER_SWEEP == 0 && cal_status & CALSTAT_APPLY) apply_CH0_error_term_at(p_sweep); } + // CH1:TRANSMISSION, reset and begin measure if (sweep_mode & SWEEP_CH1_MEASURE){ - tlv320aic3204_select(1); // CH1:TRANSMISSION, reset and begin measure + tlv320aic3204_select(1); DSP_START(delay+st_delay); //================================================ // Place some code thats need execute while delay //================================================ - DSP_WAIT_READY; - (*sample_func)(measured[1][p_sweep]); // calculate transmission coefficient - if (!APPLY_CALIBRATION_AFTER_SWEEP && cal_status & CALSTAT_APPLY) + DSP_WAIT; + (*sample_func)(measured[1][p_sweep]); // Measure transmission coefficient + if (APPLY_CALIBRATION_AFTER_SWEEP == 0 && cal_status & CALSTAT_APPLY) apply_CH1_error_term_at(p_sweep); } if (operation_requested && break_on_operation) break; st_delay = 0; // Display SPI made noise on measurement (can see in CW mode) -// ili9341_fill(OFFSETX+CELLOFFSETX, OFFSETY, (p_sweep * WIDTH)/(sweep_points-1), 1, RGB565(0,0,255)); + if (config.bandwidth >= BANDWIDTH_100) + ili9341_fill(OFFSETX+CELLOFFSETX, OFFSETY, (p_sweep * WIDTH)/(sweep_points-1), 1, RGB565(0,0,255)); } - if (APPLY_CALIBRATION_AFTER_SWEEP && (cal_status & CALSTAT_APPLY)){ - for (;start_sweep<=p_sweep;start_sweep++){ + // Apply calibration at end if need + if (APPLY_CALIBRATION_AFTER_SWEEP && (cal_status & CALSTAT_APPLY) && p_sweep == sweep_points){ + uint16_t start_sweep; + for (start_sweep = 0; start_sweep < p_sweep; start_sweep++){ if (sweep_mode & SWEEP_CH0_MEASURE) apply_CH0_error_term_at(start_sweep); if (sweep_mode & SWEEP_CH1_MEASURE) apply_CH1_error_term_at(start_sweep); } } +// STOP_PROFILE; // blink LED while scanning palSetPad(GPIOC, GPIOC_LED); return p_sweep == sweep_points; } +#ifdef ENABLE_GAIN_COMMAND +static uint8_t gain_table[][2] = { +#else +static const uint8_t gain_table[][2] = { +#endif + { 0, 0 }, // 1st: 0 ~ 300MHz + { 50, 50 }, // 2nd: 300 ~ 900MHz + { 75, 75 }, // 3th: 900 ~ 1500MHz + { 85, 85 }, // 4th: 1500 ~ 2100MHz + { 95, 95 }, // 5th: 2100 ~ 2700MHz +}; + +static int +adjust_gain(uint32_t newfreq) +{ + int new_order = si5351_get_harmonic_lvl(newfreq); + int old_order = si5351_get_harmonic_lvl(si5351_get_frequency()); + if (new_order != old_order) { + tlv320aic3204_set_gain(gain_table[new_order][0], gain_table[new_order][1]); + return DELAY_GAIN_CHANGE; + } + return 0; +} + +#ifdef ENABLE_GAIN_COMMAND +VNA_SHELL_FUNCTION(cmd_gain) +{ + int rvalue = 0; + int lvalue = 0; + if (argc < 1 && argc > 3) { + shell_printf("usage: gain idx {lgain(0-95)} [rgain(0-95)]\r\n"); + return; + } + int idx = my_atoui(argv[0]); + lvalue = rvalue = my_atoui(argv[1]); + if (argc == 3) + rvalue = my_atoui(argv[2]); + tlv320aic3204_set_gain(lvalue, rvalue); + gain_table[idx][0] = lvalue; + gain_table[idx][1] = rvalue; +} +#endif + +static int set_frequency(uint32_t freq) +{ + int delay = adjust_gain(freq); + uint8_t ds = drive_strength; + delay += si5351_set_frequency(freq, ds); + return delay; +} + void set_bandwidth(uint16_t bw_count){ config.bandwidth = bw_count&0xFF; redraw_request|=REDRAW_FREQUENCY; @@ -2090,6 +2094,17 @@ VNA_SHELL_FUNCTION(cmd_port) #endif #ifdef ENABLE_STAT_COMMAND +static struct { + int16_t rms[2]; + int16_t ave[2]; +#if 0 + int callback_count; + int32_t last_counter_value; + int32_t interval_cycles; + int32_t busy_cycles; +#endif +} stat; + VNA_SHELL_FUNCTION(cmd_stat) { int16_t *p = &rx_buffer[0]; @@ -2547,13 +2562,13 @@ static const I2CConfig i2ccfg = { #elif STM32_I2C1SW == STM32_I2C1SW_SYSCLK // STM32_I2C1SW == STM32_I2C1SW_SYSCLK (SYSCLK = 48MHz) // 400kHz @ SYSCLK 48MHz (Use 26.4.10 I2C_TIMINGR register configuration examples from STM32 RM0091 Reference manual) -// STM32_TIMINGR_PRESC(5U) | -// STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(3U) | -// STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U), + STM32_TIMINGR_PRESC(5U) | + STM32_TIMINGR_SCLDEL(3U) | STM32_TIMINGR_SDADEL(3U) | + STM32_TIMINGR_SCLH(3U) | STM32_TIMINGR_SCLL(9U), // 600kHz @ SYSCLK 48MHz, manually get values, x1.5 I2C speed - STM32_TIMINGR_PRESC(0U) | - STM32_TIMINGR_SCLDEL(10U) | STM32_TIMINGR_SDADEL(10U) | - STM32_TIMINGR_SCLH(30U) | STM32_TIMINGR_SCLL(50U), +// STM32_TIMINGR_PRESC(0U) | +// STM32_TIMINGR_SCLDEL(10U) | STM32_TIMINGR_SDADEL(10U) | +// STM32_TIMINGR_SCLH(30U) | STM32_TIMINGR_SCLL(50U), // 900kHz @ SYSCLK 48MHz, manually get values, x2 I2C speed // STM32_TIMINGR_PRESC(0U) | // STM32_TIMINGR_SCLDEL(10U) | STM32_TIMINGR_SDADEL(10U) | @@ -2566,8 +2581,8 @@ static const I2CConfig i2ccfg = { }; static DACConfig dac1cfg1 = { - //init: 2047U, - init: 1922U, + //init: 1922U, + init: 0, datamode: DAC_DHRM_12BIT_RIGHT }; @@ -2580,6 +2595,13 @@ int main(void) { halInit(); chSysInit(); + +/* + * Starting DAC1 driver, setting up the output pin as analog as suggested + * by the Reference Manual. + */ + dacStart(&DACD2, &dac1cfg1); + #ifdef __USE_RTC__ rtc_init(); // Initialize RTC library #endif @@ -2587,11 +2609,6 @@ int main(void) #ifdef USE_VARIABLE_OFFSET generate_DSP_Table(FREQUENCY_OFFSET); #endif - //palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN); - //palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN); - i2cStart(&I2CD1, &i2ccfg); - si5351_init(); - // MCO on PA8 //palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(0)); /* @@ -2616,20 +2633,26 @@ int main(void) /* restore config */ config_recall(); + /* restore frequencies and calibration 0 slot properties from flash memory */ load_properties(0); - dac1cfg1.init = config.dac_value; /* - * Starting DAC1 driver, setting up the output pin as analog as suggested - * by the Reference Manual. + * I2C bus */ - dacStart(&DACD2, &dac1cfg1); + //palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN); + //palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(1) | PAL_STM32_OTYPE_OPENDRAIN); + i2cStart(&I2CD1, &i2ccfg); +/* + * Start si5351 + */ + si5351_init(); /* * I2S Initialize */ + chThdSleepMilliseconds(100); tlv320aic3204_init(); i2sInit(); i2sObjectInit(&I2SD2); @@ -2640,6 +2663,10 @@ int main(void) //Initialize graph plotting plot_init(); redraw_frame(); + + // Set config DAC value + dacPutChannelX(&DACD2, 0, config.dac_value); + chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO-1, Thread1, NULL); while (1) { diff --git a/si5351.c b/si5351.c index 0e692db..889ff97 100644 --- a/si5351.c +++ b/si5351.c @@ -41,33 +41,29 @@ static int32_t current_offset = FREQUENCY_OFFSET; // Use cache for this reg, not update if not change static uint8_t clk_cache[3] = {0, 0, 0}; -#if 1 -// Minimum value is 2, freq change apply at next dsp measure, and need skip it -#define DELAY_NORMAL 2 -// Delay for bands (depend set band 1 more fast (can change before next dsp buffer ready, need wait additional interval) -#define DELAY_BAND_1_2 2 -#define DELAY_BAND_3_4 2 -// Band changes need set additional delay after reset PLL -#define DELAY_BANDCHANGE_1_2 3 -#define DELAY_BANDCHANGE_3_4 4 -// Delay after set new PLL values, and send reset (on band 1 unstable if less then 900, on 2000-5000 no amplitude spike on change) -#define DELAY_RESET_PLL_BEFORE 1000 -#define DELAY_RESET_PLL_AFTER 3500 +// Generator ready delays, values in x100 us +#if 0 + uint16_t timings[16]={ 3, 3, 10, 10, 0, 0, 30, 3, 25}; // For H device timings +//uint16_t timings[16]={ 2, 2, 10, 10, 0, 0, 30, 3, 25}; // For H4 device timings +void si5351_set_timing(int i, int v) {timings[i]=v;} +#define DELAY_BAND_1_2 timings[0] // Delay for bands +#define DELAY_BAND_3_4 timings[1] // Delay for bands +#define DELAY_BANDCHANGE_1_2 timings[2] // Band changes need set additional delay after reset PLL +#define DELAY_BANDCHANGE_3_4 timings[3] // Band changes need set additional delay after reset PLL +#define DELAY_RESET_PLL_BEFORE timings[4] // Delay after set new PLL values +#define DELAY_RESET_PLL_AFTER timings[5] // Delay after set new PLL values +//#define DELAY_GAIN_CHANGE timings[6] // defined in main.c change gain delay +//#define DELAY_CHANNEL_CHANGE timings[7] // defined in main.c switch channel delay +//#define DELAY_SWEEP_START timings[8] // defined in main.c delay at sweep start #else -// Debug timer set -uint16_t timings[8]={2,2,2,3,4,1000, 3500}; -void si5351_set_timing(int i, int v) {timings[i]=v;} -#define DELAY_NORMAL timings[0] -// Delay for bands (depend set band 1 more fast (can change before next dsp buffer ready, need wait additional interval) -#define DELAY_BAND_1_2 timings[1] -#define DELAY_BAND_3_4 timings[2] -// Band changes need set additional delay after reset PLL -#define DELAY_BANDCHANGE_1_2 timings[3] -#define DELAY_BANDCHANGE_3_4 timings[4] -// Delay after set new PLL values, and send reset (on band 1-2 unstable if less then 900, on 2000-5000 no amplitude spike on change) -#define DELAY_RESET_PLL_BEFORE timings[5] -#define DELAY_RESET_PLL_AFTER timings[6] +#define DELAY_BAND_1_2 3 // Delay for bands 1-2 +#define DELAY_BAND_3_4 3 // Delay for bands 3-4 +#define DELAY_BANDCHANGE_1_2 10 // Band changes need set additional delay after reset PLL +#define DELAY_BANDCHANGE_3_4 10 // Band changes need set additional delay after reset PLL +// Delay after set new PLL values, and send reset +#define DELAY_RESET_PLL_BEFORE 0 // 1000 possibly not need it if align freq +#define DELAY_RESET_PLL_AFTER 0 // 3500 possibly not need it if align freq #endif uint32_t si5351_get_frequency(void) @@ -147,6 +143,8 @@ si5351_init(void) si5351_bulk_write(p, len); p += len; } + // Set any (let it be 32MHz) frequency for AIC can run + si5351_set_frequency(32000000U, 0); } static const uint8_t disable_output[] = { @@ -418,9 +416,6 @@ int si5351_set_frequency(uint32_t freq, uint8_t drive_strength) { uint8_t band; - if (freq == current_freq) - return DELAY_NORMAL; - int delay; uint32_t ofreq = freq + current_offset; @@ -450,6 +445,8 @@ si5351_set_frequency(uint32_t freq, uint8_t drive_strength) omul = 5; } #endif + if (freq == current_freq) + return 0; // Select optimal band for prepared freq if (freq < 10000U) { rdiv = SI5351_R_DIV_128; diff --git a/tlv320aic3204.c b/tlv320aic3204.c index 8cc3186..e97bcd7 100644 --- a/tlv320aic3204.c +++ b/tlv320aic3204.c @@ -119,11 +119,11 @@ static const uint8_t conf_data[] = { // P #if AUDIO_CLOCK_REF == 8000000U // MCLK = 8.000MHz * 10.7520 = 86.016MHz, - 0x04, 0x03, // PLL Clock Low (80MHz - 137MHz), MCLK pin is input to PLL, PLL as CODEC_CLKIN - 0x05, 0x91, // Power up PLL, P=1,R=1 - 0x06, 0x0a, // J=10 - 0x07, 0x1D, // D=7520 = 0x1D60 - 0x08, 0x60, + 0x04, 0x03, // PLL Clock Low (80MHz - 137MHz), MCLK pin is input to PLL, PLL as CODEC_CLKIN + 0x05, 0x91, // Power up PLL, P=1,R=1 + 0x06, 10, // J=10 + 0x07, (7520>>8)&0xFF, // D=7520 = 0x1D60 + 0x08, (7520>>0)&0xFF, #elif AUDIO_CLOCK_REF == 10752000U // MCLK = 10.752MHz * 4 * 2.0 / 1 = 86.016MHz 0x04, 0x03, // PLL Clock Low (80MHz - 137MHz),MCLK pin is input to PLL, PLL as CODEC_CLKIN