Fixed config flash routines, added probe calibration routine

Have only tested one config write so far. Will test others and fix if needed
This commit is contained in:
true 2023-11-01 09:43:14 -07:00
parent 6394c3aaff
commit b3c799d7e7
3 changed files with 114 additions and 74 deletions

View File

@ -16,9 +16,6 @@ void probe_mode_switch(uint8_t mode);
void probe_measure();
void probe_set_thresh(uint8_t set);
uint8_t probe_get_thresh();
#endif /* _INC_PROBE_H */

View File

@ -174,6 +174,7 @@ __attribute__ ((long_call, section(".ramfunc"))) void flash_erase_page(uint32_t
// enable EOPIE (per DS, EOP isn't set unless EOPIE is set)
// and signal that we want to erase a page
FLASH->SR = FLASH_SR_EOP;
FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_PER;
// disable interrupts
@ -186,15 +187,13 @@ __attribute__ ((long_call, section(".ramfunc"))) void flash_erase_page(uint32_t
// ensure flash is not busy, then wait for end of programming
while (FLASH->SR & FLASH_SR_BSY);
while (!(FLASH->SR & FLASH_SR_EOP));
FLASH->SR |= FLASH_SR_EOP;
// re-lock flash
FLASH->CR = FLASH_CR_LOCK;
// re-enable interrupts
__set_PRIMASK(primask);
// clear EOP
FLASH->SR |= FLASH_SR_EOP;
// and re-lock flash
FLASH->CR = FLASH_CR_LOCK;
}
/*
@ -209,7 +208,7 @@ __attribute__ ((long_call, section(".ramfunc"))) void flash_write_page(uint32_t
uint8_t i;
uint32_t *src;
volatile uint32_t *dst;
uint32_t *dst;
// ensure flash is not busy
while (FLASH->SR & FLASH_SR_BSY);
@ -221,6 +220,7 @@ __attribute__ ((long_call, section(".ramfunc"))) void flash_write_page(uint32_t
// enable EOPIE (per DS, EOP isn't set unless EOPIE is set)
// and signal that we want to write a page
FLASH->SR = FLASH_SR_EOP;
FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_PG;
// disable interrupts
@ -229,28 +229,25 @@ __attribute__ ((long_call, section(".ramfunc"))) void flash_write_page(uint32_t
// write data to flash
src = data;
dst = (volatile uint32_t *)addr;
for (i = 0; i < (FLASH_PAGE_SIZE / 4); i++) {
// on the last page, enable the page write start bit to commit to flash
if (i == (FLASH_PAGE_SIZE / 4) - 1) {
FLASH->CR |= FLASH_CR_PGSTRT;
}
dst = (uint32_t *)addr;
for (i = 0; i < (FLASH_PAGE_SIZE / 4) - 1; i++) {
*dst++ = *src++;
}
// for the last word, enable the PGSTRT bit then write the word to commit to flash
FLASH->CR |= FLASH_CR_PGSTRT;
*dst = *src;
// ensure flash is not busy, then wait for end of programming
while (FLASH->SR & FLASH_SR_BSY);
while (!(FLASH->SR & FLASH_SR_EOP));
FLASH->SR |= FLASH_SR_EOP;
// re-lock flash
FLASH->CR = FLASH_CR_LOCK;
// re-enable interrupts
__set_PRIMASK(primask);
// clear EOP
FLASH->SR |= FLASH_SR_EOP;
// and re-lock flash
FLASH->CR = FLASH_CR_LOCK;
}
/*
@ -262,7 +259,7 @@ void flash_commit_conf()
uint32_t i;
uint8_t flash_idx = 0;
uint8_t flash_full;
uint8_t flash_full = 0;
struct UConf *fconf;
uint32_t *f32, *u32;
@ -280,7 +277,6 @@ void flash_commit_conf()
// if all pages are occupied, erase the first page
if (i == UCONF_COUNT) {
flash_full = 1;
flash_erase_page(UCONF_FLASH_START);
}
// copy flash page from ROM to the write buffer,
@ -310,6 +306,12 @@ void flash_commit_conf()
*u32++ = *f32++;
}
// erase this page
flash_erase_page(UCONF_FLASH_START + (UCONF_SIZE * flash_idx));
// commit to flash
flash_write_page(UCONF_FLASH_START + (UCONF_SIZE * flash_idx), write);
// if flash was full, erase other pages
if (flash_full) {
for (i = (UCONF_FLASH_START + FLASH_PAGE_SIZE); i < FLASH_END; i += FLASH_PAGE_SIZE) {

View File

@ -16,56 +16,49 @@
#include "adc.h"
#include "led.h"
#include "rgbprog.h"
#include "userio.h"
#define CONT_OPEN 1240
#include "flash.h"
// diode measurements at 3V3
#define DIODE_OPEN 3860 // test unit measures ~4060 no D1, ~3960 with D1
#define DIODE_SCHOTTKY 1960 // vishay 40V 1A SB140
#define DIODE_STANDARD 2330 // fairchild 5V2 zener, forward biased
#define DIODE_LED_BLUE 3190
#define DIODE_LED_GRN 3040 // very dim
#define DIODE_LED_RED 3020
#define DIODE_SHORT 1900 // test unit measures ~1820
#define DIODE_OPEN 3860 // test unit measures ~4060 no D1, ~3960 with D1
#define DIODE_SCHOTTKY 1960 // vishay 40V 1A SB140
#define DIODE_STANDARD 2330 // fairchild 5V2 zener, forward biased
#define DIODE_LED_BLUE 3190
#define DIODE_LED_GRN 3040 // very dim
#define DIODE_LED_RED 3020
#define DIODE_SHORT 1900 // test unit measures ~1820
#define CONT_SHORTED 858 // worst case measured value of short
#define CONT_47OHM 869 // measured value of 47ohm 1% resistor at room temp
#define CONT_100OHM 886 // measured value of 100ohm 1% resistor at room temp
#define CONT_EXTRA_COUNTS 8 // extra raw counts as a fudge factor, post-scaling
#define CONT_LATCH_THRESH 15 // extra raw counts for latching indicator, post-scaling
// continuity offsets from calibrated short value
#define CONT_47OHM 16
#define CONT_100OHM 34
#define CONT_LATCH_TIMEOUT 4 // probe measurement passes to hold latched indicator
#define CONT_EXTRA_COUNTS 3 // extra raw counts as a fudge factor
#define CONT_CAL_THRESHOLD 890 // typical short is ~845-860 region
#define CONT_LATCH_THRESHOLD 5 // extra raw counts for latching indicator
#define CONT_LATCH_TIMEOUT 4 // probe measurement passes to hold latched indicator
static uint16_t vref;
static uint16_t cont_thresh_set = 0;
static const uint16_t cont_thresh[] = {
static uint8_t cont_cal_timer;
static uint16_t cont_cal_low;
static uint16_t cont_cal_avg;
static const uint16_t cont_thresh_tbl[] = {
CONT_100OHM, CONT_47OHM
};
static uint8_t latch = 0;
static uint8_t buzzer = 0;
void probe_set_thresh(uint8_t set)
{
cont_thresh_set = set;
}
uint8_t probe_get_thresh()
{
return cont_thresh_set;
}
static inline void probe_measure_cont()
{
uint16_t probe, v_ext;
@ -75,57 +68,105 @@ static inline void probe_measure_cont()
probe = adc_avg[ADC_PROBE];
v_ext = adc_avg[ADC_VREF_EXT];
// if the button has been pushed, toggle the buzzer
if (userio_get_btn() > 0) {
buzzer ^= 1;
}
// update vref
if (!vref) vref = v_ext;
vref += v_ext;
vref >>= 1;
// if the button has been held, change the threshold
if (userio_get_btn_held() == 60) {
userio_set_btn_override();
cont_thresh_set ^= 1;
conf.cont_sensitivity ^= 1;
}
// this LED will not set anything,
// if the button has _really_ been held, clear the calibration
if (userio_get_btn_held() == 600) {
conf.cont_shorted = 0;
}
// if there is no calibration, try to perform it
if (!conf.cont_shorted) {
// until this is performed, show error LEDs
rgbprog_error_flasher(5, 0, 0, 100);
// initialize
if (!cont_cal_timer) {
cont_cal_low = 0xfff;
cont_cal_avg = 0;
}
// if probe appears to be shorted, calibrate to lowest value read
if (adc_avg[ADC_PROBE] < CONT_CAL_THRESHOLD) {
// low value
if (adc_avg[ADC_PROBE] < cont_cal_low) {
cont_cal_low = adc_avg[ADC_PROBE];
}
// average value
if (!cont_cal_avg) {
cont_cal_avg = adc_avg[ADC_PROBE];
} else {
cont_cal_avg += adc_avg[ADC_PROBE];
cont_cal_avg >>= 1;
}
cont_cal_timer++;
} else {
cont_cal_timer = 0;
}
// after held long enough, commit
if (cont_cal_timer == 180) {
cont_cal_timer = 0;
conf.cont_shorted = (cont_cal_avg + cont_cal_low) >> 1;
flash_commit_conf();
}
}
// right LED remains unused while buzzer is being used,
// but zero it out anyway
led_setrgb(1, 0, 0, 0);
// if no calibration yet, bail here
if (!conf.cont_shorted) return;
// if the button has been pushed, toggle buzzer on/off
if (userio_get_btn() > 0) {
conf.cont_buzzer ^= 1;
}
if (vref) {
// note: we don't use VREF anymore...
// it's too noisy :/
// probe level
x = probe << 12; // maximum possible level
x /= vref; // normalize to 4096max
if (x > 4095) x = 4095;
x = probe - conf.cont_shorted;
if (x > 0xfff) x = 0;
// threshold level
c = cont_thresh[cont_thresh_set] << 12;
c /= vref;
c = cont_thresh_tbl[conf.cont_sensitivity];
// are we measuring a lower value?
// are we measuring a lower ohm value on the probes than our threshold?
if (x < (c + CONT_EXTRA_COUNTS)) { // roughly 100ohm or lower
latch = CONT_LATCH_TIMEOUT; // latch any continuity for a while
}
b = buzzer ? 100 : 0;
// blue led to indicate buzzer is enabled
b = conf.cont_buzzer ? 20 : 0;
if (latch) {
// hysteresis
if (x >= c + CONT_LATCH_THRESH) latch--;
if (x >= (c + CONT_LATCH_THRESHOLD)) latch--;
// indicate continuity
led_setrgb(0, 0, 250, b);
led_buzz(0);
if (buzzer) led_buzz(1);
if (conf.cont_buzzer) led_buzz(1);
} else {
// idle
g = cont_thresh_set ? 40 : 0;
g = conf.cont_sensitivity ? 40 : 0;
led_setrgb(0, 120, g, b);
led_buzz(0);
}
}
if (!vref) vref = v_ext;
vref += v_ext;
vref >>= 1;
}
static inline void probe_measure_diode()