mirror of
https://github.com/eddyem/mmpp.git
synced 2025-12-06 10:35:16 +03:00
Fix EEPROM in flash emulation; can't fix error in ADC16/ADC17 (temperature and Vdd calculation)
This commit is contained in:
parent
22d195d38b
commit
1210df589e
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
BIN
STM32/steppers/steppers.bin
Executable file
Binary file not shown.
@ -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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user