diff --git a/adc.c b/adc.c index cd8c459..1da498d 100644 --- a/adc.c +++ b/adc.c @@ -74,6 +74,33 @@ uint16_t adc_single_read(ADC_TypeDef *adc, uint32_t chsel) return adc->DR; } + +int16_t adc_vbat_read(ADC_TypeDef *adc) +{ +#define ADC_FULL_SCALE 3300 +#define VBAT_DIODE_VF 500 +#define VREFINT_CAL (*((uint16_t*)0x1FFFF7BA)) + float vbat = 0; + float vrefint = 0; + + ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_VBATEN; + // VREFINT == ADC_IN17 + vrefint = adc_single_read(adc, ADC_CHSELR_CHSEL17); + // VBAT == ADC_IN18 + // VBATEN enables resiter devider circuit. It consume vbat power. + vbat = adc_single_read(adc, ADC_CHSELR_CHSEL18); + ADC->CCR &= ~(ADC_CCR_VREFEN | ADC_CCR_VBATEN); + + uint16_t vbat_raw = (ADC_FULL_SCALE * VREFINT_CAL * vbat * 2 / (vrefint * ((1<<12)-1))); + if (vbat_raw < 100) { + // maybe D2 is not installed + return -1; + } + + return vbat_raw + VBAT_DIODE_VF; + +} + void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel) { uint32_t cfgr1; diff --git a/main.c b/main.c index 8968977..2a82795 100644 --- a/main.c +++ b/main.c @@ -57,7 +57,7 @@ int8_t sweep_once = FALSE; int8_t cal_auto_interpolate = TRUE; int8_t redraw_requested = FALSE; int8_t stop_the_world = FALSE; - +int16_t vbat = 0; BaseSequentialStream *saved_chp; static THD_WORKING_AREA(waThread1, 640); @@ -85,6 +85,13 @@ static THD_FUNCTION(Thread1, arg) ui_process(); } + if (vbat != -1) { + adc_stop(ADC1); + vbat = adc_vbat_read(ADC1); + touch_start_watchdog(); + draw_battery_status(); + } + /* calculate trace coordinates */ plot_into_index(measured); /* plot trace as raster */ @@ -643,6 +650,7 @@ static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[]) chMtxUnlock(&mutex); #if 0 float gamma[2]; + int i; int32_t freq, step; int delay; (void)argc; @@ -654,7 +662,7 @@ static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[]) step = (frequency1 - frequency0) / (sweep_points-1); set_frequency(freq); delay = 4; - for (int i = 0; i < sweep_points; i++) { + for (i = 0; i < sweep_points; i++) { freq = freq + step; wait_dsp(delay); delay = set_frequency(freq); @@ -1737,7 +1745,6 @@ static void cmd_touchtest(BaseSequentialStream *chp, int argc, char *argv[]) } - static void cmd_frequencies(BaseSequentialStream *chp, int argc, char *argv[]) { int i; @@ -1897,7 +1904,6 @@ static void cmd_vbat(BaseSequentialStream *chp, int argc, char *argv[]) chprintf(chp, "%d mV\r\n", vbat); } - static THD_WORKING_AREA(waThread2, /* cmd_* max stack size + alpha */442); static const ShellCommand commands[] = @@ -1935,6 +1941,7 @@ static const ShellCommand commands[] = { "marker", cmd_marker }, { "edelay", cmd_edelay }, { "capture", cmd_capture }, + { "vbat", cmd_vbat }, { NULL, NULL } }; diff --git a/nanovna.h b/nanovna.h index 1dbf8a2..a63f498 100644 --- a/nanovna.h +++ b/nanovna.h @@ -162,7 +162,7 @@ extern const uint32_t numfont20x24[][24]; #define TRACES_MAX 4 enum { - TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF, TRC_TDR + TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF }; // LOGMAG: SCALE, REFPOS, REFVAL @@ -244,6 +244,7 @@ void marker_position(int m, int t, int *x, int *y); int search_nearest_index(int x, int y, int t); extern int8_t redraw_requested; +extern int16_t vbat; /* * ili9341.c @@ -369,10 +370,21 @@ uint16_t adc_single_read(ADC_TypeDef *adc, uint32_t chsel); void adc_start_analog_watchdogd(ADC_TypeDef *adc, uint32_t chsel); void adc_stop(ADC_TypeDef *adc); void adc_interrupt(ADC_TypeDef *adc); +int16_t adc_vbat_read(ADC_TypeDef *adc); /* * misclinous */ #define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0) +// convert vbat [mV] to battery indicator +static inline uint8_t vbat2bati(int16_t vbat) +{ + if (vbat < 3200) return 0; + if (vbat < 3450) return 25; + if (vbat < 3700) return 50; + if (vbat < 4100) return 75; + return 100; +} + /*EOF*/ diff --git a/plot.c b/plot.c index d962724..83ed0fb 100644 --- a/plot.c +++ b/plot.c @@ -504,7 +504,6 @@ trace_into_index(int x, int t, int i, float coeff[2]) v = refpos - phase(coeff) * scale; break; case TRC_LINEAR: - case TRC_TDR: v = refpos + linear(coeff) * scale; break; case TRC_SWR: @@ -797,21 +796,9 @@ mark_cells_from_index(void) } } -void plot_into_index(float measured[2][MEASURED_LENGTH][2]) +void plot_into_index(float measured[2][101][2]) { int i, t; -#if 0 - if (trace[0].type == TRD_TDR && trace[0].enabled) { -// Covert real part of S11 to complex FFT in S21 - for (i = 0; i < sweep_points; i++) { - int x = i * (WIDTH-1) / (sweep_points-1); - trace_index[t][i] = trace_into_index(x, 0, i, measured[1][i]); - } - } - - - } else - #endif for (i = 0; i < sweep_points; i++) { int x = i * (WIDTH-1) / (sweep_points-1); for (t = 0; t < TRACES_MAX; t++) { @@ -1523,6 +1510,76 @@ draw_cal_status(void) } } +void +draw_battery_status(void) +{ + int w = 10, h = 14; + int x = 0, y = 0; + int i, c; + uint16_t *buf = spi_buffer; + uint8_t vbati = vbat2bati(vbat); + uint16_t col = vbati == 0 ? RGB565(0, 255, 0) : RGB565(0, 0, 240); + memset(spi_buffer, 0, w * h * 2); + + // battery head + x = 3; + buf[y * w + x++] = col; + buf[y * w + x++] = col; + buf[y * w + x++] = col; + buf[y * w + x++] = col; + + y++; + x = 3; + buf[y * w + x++] = col; + x++; x++; + buf[y * w + x++] = col; + + y++; + x = 1; + for (i = 0; i < 8; i++) + buf[y * w + x++] = col; + + for (c = 0; c < 3; c++) { + y++; + x = 1; + buf[y * w + x++] = col; + x++; x++; x++; x++; x++; x++; + buf[y * w + x++] = col; + + y++; + x = 1; + buf[y * w + x++] = col; + x++; + for (i = 0; i < 4; i++) + buf[y * w + x++] = ( ((c+1) * 25) >= (100 - vbati)) ? col : 0; + x++; + buf[y * w + x++] = col; + + y++; + x = 1; + buf[y * w + x++] = col; + x++; + for (i = 0; i < 4; i++) + buf[y * w + x++] = ( ((c+1) * 25) >= (100 - vbati)) ? col : 0; + x++; + buf[y * w + x++] = col; + } + + // battery foot + y++; + x = 1; + buf[y * w + x++] = col; + x++; x++; x++; x++; x++; x++; + buf[y * w + x++] = col; + + y++; + x = 1; + for (i = 0; i < 8; i++) + buf[y * w + x++] = col; + + ili9341_bulk(0, 1, w, h); +} + void request_to_redraw_grid(void) {