Fix EEPROM in flash emulation; can't fix error in ADC16/ADC17 (temperature and Vdd calculation)

This commit is contained in:
eddyem 2017-12-06 21:46:16 +03:00
parent 22d195d38b
commit 1210df589e
7 changed files with 87 additions and 47 deletions

View File

@ -23,6 +23,7 @@
#include "stm32f0.h"
#include "flash.h"
#include "adc.h"
#include "usart.h"
/*
* 0 - Steppers current
@ -39,9 +40,11 @@ uint16_t ADC_array[NUMBER_OF_ADC_CHANNELS];
void adc_setup(){
// AIN: PA0..3, PA13, PA14. ADC_IN16 - inner temperature. ADC_IN17 - VREFINT
/* (1) Enable the peripheral clock of the ADC */
/* (2) Set peripheral prescaler to /2 so PCLK = HCLK/2 = 24MHz */
/* (2) Start HSI14 RC oscillator */
/* (3) Wait HSI14 is ready */
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; /* (1) */
RCC->CFGR |= RCC_CFGR_PPRE_2; /* (2) */
RCC->CR2 |= RCC_CR2_HSI14ON; /* (2) */
while ((RCC->CR2 & RCC_CR2_HSI14RDY) == 0) /* (3) */
/* (1) Ensure that ADEN = 0 */
/* (2) Clear ADEN */
/* (3) Launch the calibration by setting ADCAL */
@ -56,12 +59,12 @@ void adc_setup(){
do{
ADC1->CR |= ADC_CR_ADEN; /* (1) */
}while ((ADC1->ISR & ADC_ISR_ADRDY) == 0) /* (2) */;
/* (1) Select PCLK/2 by writing 01 in CKMODE */
/* (1) Select HSI14 by writing 00 in CKMODE (reset value) */
/* (2) Select the continuous mode */
/* (3) Select CHSEL0..3, 13,14, 16,17 */
/* (4) Select a sampling mode of 111 i.e. 239.5 ADC clk to be greater than 17.1us */
/* (5) Wake-up the VREFINT and Temperature sensor (only for VBAT, Temp sensor and VRefInt) */
ADC1->CFGR2 |= ADC_CFGR2_CKMODE_0; /* (1) */
// ADC1->CFGR2 &= ~ADC_CFGR2_CKMODE; /* (1) */
ADC1->CFGR1 |= ADC_CFGR1_CONT; /* (2)*/
ADC1->CHSELR = ADC_CHSELR_CHSEL0 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL2 |
ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL13 | ADC_CHSELR_CHSEL14 |
@ -87,25 +90,47 @@ void adc_setup(){
}
// return MCU temperature (degrees of celsius)
uint32_t getTemp(){
uint32_t temperature = ADC_array[6];
temperature = ((temperature * VDD_APPLI / VDD_CALIB) - (uint32_t) *TEMP30_CAL_ADDR ) ;
temperature *= (uint32_t)(110 - 30);
temperature /= (uint32_t)(*TEMP110_CAL_ADDR - *TEMP30_CAL_ADDR);
temperature += 30;
int32_t getTemp(){
int32_t temperature = (int32_t)ADC_array[6];
write2trbuf("getTemp()\ncal30=");
put_uint(*TEMP30_CAL_ADDR);
write2trbuf(", cal110=");
put_uint(*TEMP110_CAL_ADDR);
write2trbuf(", t=");
put_int(temperature);
SENDBUF();
temperature = ((int32_t) *TEMP30_CAL_ADDR - temperature);
put_int(temperature);
SENDBUF();
temperature *= (int32_t)(1100 - 300);
put_int(temperature);
SENDBUF();
temperature = temperature / (int32_t)(*TEMP30_CAL_ADDR - *TEMP110_CAL_ADDR);
put_int(temperature);
SENDBUF();
temperature += 300;
return(temperature);
}
//static uint32_t calval = 0;
// return Vdd * 10 (V)
uint32_t getVdd(){
write2trbuf("getVdd(), val=");
put_uint(ADC_array[7]);
write2trbuf(", cal=");
put_uint(*VREFINT_CAL_ADDR);
SENDBUF();
/* if(!calval){
calval = ((uint32_t) *VREFINT_CAL_ADDR) * VDD_CALIB;
calval /= VDD_APPLI;
} */
uint32_t vdd = ADC_array[7] * (uint32_t)33 * the_conf.v33numerator; // 3.3V
uint32_t vdd = ((uint32_t) *VREFINT_CAL_ADDR) * (uint32_t)33 * the_conf.v33numerator; // 3.3V
put_uint(vdd);
SENDBUF();
//vdd /= calval * the_conf.v33denominator;
vdd /= ((uint32_t) *VREFINT_CAL_ADDR) * the_conf.v33denominator;
vdd /= ADC_array[7] * the_conf.v33denominator;
put_uint(vdd);
SENDBUF();
return vdd;
}

View File

@ -38,7 +38,7 @@ typedef enum{
ESW_ERROR
} ESW_status;
uint32_t getTemp();
int32_t getTemp();
uint32_t getVdd();
uint32_t getVmot();
uint32_t getImot();

View File

@ -28,9 +28,10 @@
// start of configuration data in flash (from 15kB, one kB size)
#define FLASH_CONF_START_ADDR ((uint32_t)0x08003C00)
static const int maxnum = 1024 / sizeof(user_conf);
user_conf the_conf = {
.good_data_pos = 0xffffffff
.userconf_sz = sizeof(user_conf)
,.devID = 0
,.v12numerator = 1
,.v12denominator = 1
@ -41,66 +42,81 @@ user_conf the_conf = {
,.ESW_thres = 150
};
static int maxnum = 0x800 / sizeof(user_conf);
static int erase_flash();
static int get_gooddata(){
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
uint32_t datapos = c->good_data_pos;
if(datapos == 0xffffffff){ // virginity clear
return maxnum;
}
// have data - move it to `the_conf`
if(maxnum > 32) maxnum = 32;
int idx;
for(idx = 1; idx < maxnum; ++idx){ // find current settings index - first non-zero bit
if(datapos & 1<<idx){
break;
//write2trbuf("get_gooddata()\n");
for(idx = 0; idx < maxnum; ++idx){ // find current settings index - first good
uint16_t sz = c[idx].userconf_sz;
/*write2trbuf("idx=");
put_int((int32_t) idx);
write2trbuf(", sz=");
put_uint((uint32_t) sz);
write2trbuf(", devID=");
put_uint((uint32_t) c[idx].devID);
write2trbuf(", ESW_thres=");
put_uint((uint32_t) c[idx].ESW_thres);
SENDBUF();*/
if(sz != sizeof(user_conf)){
if(sz == 0xffff) break; // first clear
else{
return -2; // flash corrupt, need to erase
}
}
}
return idx-1;
return idx-1; // -1 if there's no data at all & flash is clear; maxnum-1 if flash is full
}
void get_userconf(){
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
int idx = get_gooddata();
if(idx == maxnum) return;
if(idx < 0) return; // no data stored
memcpy(&the_conf, &c[idx], sizeof(user_conf));
}
// store new configuration
// @return 0 if all OK
int store_userconf(){
char buf[2] = {0,0};
int ret = 0;
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
int idx = get_gooddata();
if(idx == maxnum || idx == maxnum - 1){ // first run or there's no more place
if(idx == -2 || idx == maxnum - 1){ // data corruption or there's no more place
idx = 0;
if(erase_flash()) return 1;
}else ++idx; // take next data position
if (FLASH->CR & FLASH_CR_LOCK){
/*write2trbuf("store_userconf()\nidx=");
put_int((int32_t) idx);
SENDBUF();*/
if (FLASH->CR & FLASH_CR_LOCK){ // unloch flash
FLASH->KEYR = FLASH_FKEY1;
FLASH->KEYR = FLASH_FKEY2;
}
the_conf.good_data_pos = 0xffffffff ^ (1<<idx); // write zero to corresponding position
while (FLASH->SR & FLASH_SR_BSY);
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
if(FLASH->SR & FLASH_SR_WRPERR) return 1; // write protection
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR; // clear all flags
FLASH->CR |= FLASH_CR_PG;
uint16_t *data = (uint16_t*) &the_conf;
uint16_t *address = (uint16_t*) &c[idx];
uint32_t i, count = sizeof(user_conf) / 2;
for (i = 0; i < count; ++i){
//*(volatile uint16_t*)(address + i) = (((uint8_t)data[i + 1]) << 8) | data[i];
*(volatile uint16_t*)(address + i) = data[i];
//while (!(FLASH->SR & FLASH_SR_EOP));
while((FLASH->SR & FLASH_SR_BSY));
buf[0] = '0' + i;
usart1_send_blocking(buf);
if(FLASH->SR & FLASH_SR_PGERR) ret = 1;
buf[0] = ret + '0';
usart1_send_blocking(buf);
while (FLASH->SR & FLASH_SR_BSY);
if(FLASH->SR & FLASH_SR_PGERR) ret = 1; // program error - meet not 0xffff
else while (!(FLASH->SR & FLASH_SR_EOP));
/*write2trbuf("write byte ");
put_int((int32_t) i);
write2trbuf(", write value=");
put_uint(data[i]);
write2trbuf(", read value=");
put_uint(address[i]);
SENDBUF();
if(ret){
write2trbuf("PGERR");
SENDBUF();
}*/
FLASH->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
}
FLASH->CR &= ~(FLASH_CR_PG);
@ -110,6 +126,8 @@ usart1_send_blocking(buf);
static int erase_flash(){
int ret = 0;
/*write2trbuf("erase_flash()");
SENDBUF();*/
/* (1) Wait till no operation is on going */
/* (2) Clear error & EOP bits */
/* (3) Check that the Flash is unlocked */

View File

@ -26,7 +26,7 @@
#define __FLASH_H__
typedef struct{
uint32_t good_data_pos; // position of data (index of mostly left zero)
uint16_t userconf_sz; // size of data
uint16_t devID; // device address (id)
uint16_t ESW_thres; // ADC threshold for end-switches/Hall sensors
// calibration values for current/voltage sensors

View File

@ -27,8 +27,6 @@
#include "string.h"
#include "usart.h"
#define SENDBUF() do{usart1_send_blocking(gettrbuf()); cleartrbuf();}while(0)
static const char *eodata = "DATAEND";
static const char *badcmd = "BADCMD";
static const char *allok = "ALL OK";
@ -158,6 +156,7 @@ typedef struct{
} user_conf_descr;
static const user_conf_descr descrarr[] = {
{"CONFSZ", &the_conf.userconf_sz},
{"DEVID", &the_conf.devID},
{"V12NUM", &the_conf.v12numerator},
{"V12DEN", &the_conf.v12denominator},
@ -171,9 +170,6 @@ static const user_conf_descr descrarr[] = {
static char *get_conf(){
const user_conf_descr *curdesc = descrarr;
write2trbuf("DATAPOS=");
put_uint(the_conf.good_data_pos);
SENDBUF();
do{
write2trbuf(curdesc->fieldname);
put2trbuf('=');
@ -274,9 +270,9 @@ static char *setESWthres(char *str){
}
static char *get_temper(){
uint32_t t = getTemp();
int32_t t = getTemp();
write2trbuf("TEMP=");
put_uint(t);
put_int(t);
SENDBUF();
return NULL;
}

BIN
STM32/steppers/steppers.bin Executable file

Binary file not shown.

View File

@ -47,6 +47,7 @@ void USART1_config();
int usart1_getline(char **line);
TXstatus usart1_send(char *str);
#define usart1_send_blocking(str) do{}while(LINE_BUSY == usart1_send(str))
#define SENDBUF() do{usart1_send_blocking(gettrbuf()); cleartrbuf();}while(0)
#define cleartrbuf() do{trbufidx = 0;}while(0)
#define trbufisfull() (trbufidx)