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 "stm32f0.h"
|
||||||
#include "flash.h"
|
#include "flash.h"
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
|
#include "usart.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 0 - Steppers current
|
* 0 - Steppers current
|
||||||
@ -39,9 +40,11 @@ uint16_t ADC_array[NUMBER_OF_ADC_CHANNELS];
|
|||||||
void adc_setup(){
|
void adc_setup(){
|
||||||
// AIN: PA0..3, PA13, PA14. ADC_IN16 - inner temperature. ADC_IN17 - VREFINT
|
// AIN: PA0..3, PA13, PA14. ADC_IN16 - inner temperature. ADC_IN17 - VREFINT
|
||||||
/* (1) Enable the peripheral clock of the ADC */
|
/* (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->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 */
|
/* (1) Ensure that ADEN = 0 */
|
||||||
/* (2) Clear ADEN */
|
/* (2) Clear ADEN */
|
||||||
/* (3) Launch the calibration by setting ADCAL */
|
/* (3) Launch the calibration by setting ADCAL */
|
||||||
@ -56,12 +59,12 @@ void adc_setup(){
|
|||||||
do{
|
do{
|
||||||
ADC1->CR |= ADC_CR_ADEN; /* (1) */
|
ADC1->CR |= ADC_CR_ADEN; /* (1) */
|
||||||
}while ((ADC1->ISR & ADC_ISR_ADRDY) == 0) /* (2) */;
|
}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 */
|
/* (2) Select the continuous mode */
|
||||||
/* (3) Select CHSEL0..3, 13,14, 16,17 */
|
/* (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 */
|
/* (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) */
|
/* (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->CFGR1 |= ADC_CFGR1_CONT; /* (2)*/
|
||||||
ADC1->CHSELR = ADC_CHSELR_CHSEL0 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL2 |
|
ADC1->CHSELR = ADC_CHSELR_CHSEL0 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL2 |
|
||||||
ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL13 | ADC_CHSELR_CHSEL14 |
|
ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL13 | ADC_CHSELR_CHSEL14 |
|
||||||
@ -87,25 +90,47 @@ void adc_setup(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// return MCU temperature (degrees of celsius)
|
// return MCU temperature (degrees of celsius)
|
||||||
uint32_t getTemp(){
|
int32_t getTemp(){
|
||||||
uint32_t temperature = ADC_array[6];
|
int32_t temperature = (int32_t)ADC_array[6];
|
||||||
temperature = ((temperature * VDD_APPLI / VDD_CALIB) - (uint32_t) *TEMP30_CAL_ADDR ) ;
|
write2trbuf("getTemp()\ncal30=");
|
||||||
temperature *= (uint32_t)(110 - 30);
|
put_uint(*TEMP30_CAL_ADDR);
|
||||||
temperature /= (uint32_t)(*TEMP110_CAL_ADDR - *TEMP30_CAL_ADDR);
|
write2trbuf(", cal110=");
|
||||||
temperature += 30;
|
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);
|
return(temperature);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static uint32_t calval = 0;
|
//static uint32_t calval = 0;
|
||||||
// return Vdd * 10 (V)
|
// return Vdd * 10 (V)
|
||||||
uint32_t getVdd(){
|
uint32_t getVdd(){
|
||||||
|
write2trbuf("getVdd(), val=");
|
||||||
|
put_uint(ADC_array[7]);
|
||||||
|
write2trbuf(", cal=");
|
||||||
|
put_uint(*VREFINT_CAL_ADDR);
|
||||||
|
SENDBUF();
|
||||||
/* if(!calval){
|
/* if(!calval){
|
||||||
calval = ((uint32_t) *VREFINT_CAL_ADDR) * VDD_CALIB;
|
calval = ((uint32_t) *VREFINT_CAL_ADDR) * VDD_CALIB;
|
||||||
calval /= VDD_APPLI;
|
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 /= 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;
|
return vdd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@ typedef enum{
|
|||||||
ESW_ERROR
|
ESW_ERROR
|
||||||
} ESW_status;
|
} ESW_status;
|
||||||
|
|
||||||
uint32_t getTemp();
|
int32_t getTemp();
|
||||||
uint32_t getVdd();
|
uint32_t getVdd();
|
||||||
uint32_t getVmot();
|
uint32_t getVmot();
|
||||||
uint32_t getImot();
|
uint32_t getImot();
|
||||||
|
|||||||
@ -28,9 +28,10 @@
|
|||||||
|
|
||||||
// start of configuration data in flash (from 15kB, one kB size)
|
// start of configuration data in flash (from 15kB, one kB size)
|
||||||
#define FLASH_CONF_START_ADDR ((uint32_t)0x08003C00)
|
#define FLASH_CONF_START_ADDR ((uint32_t)0x08003C00)
|
||||||
|
static const int maxnum = 1024 / sizeof(user_conf);
|
||||||
|
|
||||||
user_conf the_conf = {
|
user_conf the_conf = {
|
||||||
.good_data_pos = 0xffffffff
|
.userconf_sz = sizeof(user_conf)
|
||||||
,.devID = 0
|
,.devID = 0
|
||||||
,.v12numerator = 1
|
,.v12numerator = 1
|
||||||
,.v12denominator = 1
|
,.v12denominator = 1
|
||||||
@ -41,66 +42,81 @@ user_conf the_conf = {
|
|||||||
,.ESW_thres = 150
|
,.ESW_thres = 150
|
||||||
};
|
};
|
||||||
|
|
||||||
static int maxnum = 0x800 / sizeof(user_conf);
|
|
||||||
|
|
||||||
static int erase_flash();
|
static int erase_flash();
|
||||||
|
|
||||||
static int get_gooddata(){
|
static int get_gooddata(){
|
||||||
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
|
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`
|
// have data - move it to `the_conf`
|
||||||
if(maxnum > 32) maxnum = 32;
|
|
||||||
int idx;
|
int idx;
|
||||||
for(idx = 1; idx < maxnum; ++idx){ // find current settings index - first non-zero bit
|
//write2trbuf("get_gooddata()\n");
|
||||||
if(datapos & 1<<idx){
|
for(idx = 0; idx < maxnum; ++idx){ // find current settings index - first good
|
||||||
break;
|
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(){
|
void get_userconf(){
|
||||||
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
|
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
|
||||||
int idx = get_gooddata();
|
int idx = get_gooddata();
|
||||||
if(idx == maxnum) return;
|
if(idx < 0) return; // no data stored
|
||||||
memcpy(&the_conf, &c[idx], sizeof(user_conf));
|
memcpy(&the_conf, &c[idx], sizeof(user_conf));
|
||||||
}
|
}
|
||||||
|
|
||||||
// store new configuration
|
// store new configuration
|
||||||
// @return 0 if all OK
|
// @return 0 if all OK
|
||||||
int store_userconf(){
|
int store_userconf(){
|
||||||
char buf[2] = {0,0};
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
|
user_conf *c = (user_conf*) FLASH_CONF_START_ADDR;
|
||||||
int idx = get_gooddata();
|
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;
|
idx = 0;
|
||||||
if(erase_flash()) return 1;
|
if(erase_flash()) return 1;
|
||||||
}else ++idx; // take next data position
|
}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_FKEY1;
|
||||||
FLASH->KEYR = FLASH_FKEY2;
|
FLASH->KEYR = FLASH_FKEY2;
|
||||||
}
|
}
|
||||||
the_conf.good_data_pos = 0xffffffff ^ (1<<idx); // write zero to corresponding position
|
|
||||||
while (FLASH->SR & FLASH_SR_BSY);
|
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;
|
FLASH->CR |= FLASH_CR_PG;
|
||||||
uint16_t *data = (uint16_t*) &the_conf;
|
uint16_t *data = (uint16_t*) &the_conf;
|
||||||
uint16_t *address = (uint16_t*) &c[idx];
|
uint16_t *address = (uint16_t*) &c[idx];
|
||||||
uint32_t i, count = sizeof(user_conf) / 2;
|
uint32_t i, count = sizeof(user_conf) / 2;
|
||||||
for (i = 0; i < count; ++i){
|
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];
|
*(volatile uint16_t*)(address + i) = data[i];
|
||||||
//while (!(FLASH->SR & FLASH_SR_EOP));
|
while (FLASH->SR & FLASH_SR_BSY);
|
||||||
while((FLASH->SR & FLASH_SR_BSY));
|
if(FLASH->SR & FLASH_SR_PGERR) ret = 1; // program error - meet not 0xffff
|
||||||
buf[0] = '0' + i;
|
else while (!(FLASH->SR & FLASH_SR_EOP));
|
||||||
usart1_send_blocking(buf);
|
/*write2trbuf("write byte ");
|
||||||
if(FLASH->SR & FLASH_SR_PGERR) ret = 1;
|
put_int((int32_t) i);
|
||||||
buf[0] = ret + '0';
|
write2trbuf(", write value=");
|
||||||
usart1_send_blocking(buf);
|
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->SR = FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR;
|
||||||
}
|
}
|
||||||
FLASH->CR &= ~(FLASH_CR_PG);
|
FLASH->CR &= ~(FLASH_CR_PG);
|
||||||
@ -110,6 +126,8 @@ usart1_send_blocking(buf);
|
|||||||
|
|
||||||
static int erase_flash(){
|
static int erase_flash(){
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
/*write2trbuf("erase_flash()");
|
||||||
|
SENDBUF();*/
|
||||||
/* (1) Wait till no operation is on going */
|
/* (1) Wait till no operation is on going */
|
||||||
/* (2) Clear error & EOP bits */
|
/* (2) Clear error & EOP bits */
|
||||||
/* (3) Check that the Flash is unlocked */
|
/* (3) Check that the Flash is unlocked */
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
#define __FLASH_H__
|
#define __FLASH_H__
|
||||||
|
|
||||||
typedef struct{
|
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 devID; // device address (id)
|
||||||
uint16_t ESW_thres; // ADC threshold for end-switches/Hall sensors
|
uint16_t ESW_thres; // ADC threshold for end-switches/Hall sensors
|
||||||
// calibration values for current/voltage sensors
|
// calibration values for current/voltage sensors
|
||||||
|
|||||||
@ -27,8 +27,6 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
|
|
||||||
#define SENDBUF() do{usart1_send_blocking(gettrbuf()); cleartrbuf();}while(0)
|
|
||||||
|
|
||||||
static const char *eodata = "DATAEND";
|
static const char *eodata = "DATAEND";
|
||||||
static const char *badcmd = "BADCMD";
|
static const char *badcmd = "BADCMD";
|
||||||
static const char *allok = "ALL OK";
|
static const char *allok = "ALL OK";
|
||||||
@ -158,6 +156,7 @@ typedef struct{
|
|||||||
} user_conf_descr;
|
} user_conf_descr;
|
||||||
|
|
||||||
static const user_conf_descr descrarr[] = {
|
static const user_conf_descr descrarr[] = {
|
||||||
|
{"CONFSZ", &the_conf.userconf_sz},
|
||||||
{"DEVID", &the_conf.devID},
|
{"DEVID", &the_conf.devID},
|
||||||
{"V12NUM", &the_conf.v12numerator},
|
{"V12NUM", &the_conf.v12numerator},
|
||||||
{"V12DEN", &the_conf.v12denominator},
|
{"V12DEN", &the_conf.v12denominator},
|
||||||
@ -171,9 +170,6 @@ static const user_conf_descr descrarr[] = {
|
|||||||
|
|
||||||
static char *get_conf(){
|
static char *get_conf(){
|
||||||
const user_conf_descr *curdesc = descrarr;
|
const user_conf_descr *curdesc = descrarr;
|
||||||
write2trbuf("DATAPOS=");
|
|
||||||
put_uint(the_conf.good_data_pos);
|
|
||||||
SENDBUF();
|
|
||||||
do{
|
do{
|
||||||
write2trbuf(curdesc->fieldname);
|
write2trbuf(curdesc->fieldname);
|
||||||
put2trbuf('=');
|
put2trbuf('=');
|
||||||
@ -274,9 +270,9 @@ static char *setESWthres(char *str){
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *get_temper(){
|
static char *get_temper(){
|
||||||
uint32_t t = getTemp();
|
int32_t t = getTemp();
|
||||||
write2trbuf("TEMP=");
|
write2trbuf("TEMP=");
|
||||||
put_uint(t);
|
put_int(t);
|
||||||
SENDBUF();
|
SENDBUF();
|
||||||
return NULL;
|
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);
|
int usart1_getline(char **line);
|
||||||
TXstatus usart1_send(char *str);
|
TXstatus usart1_send(char *str);
|
||||||
#define usart1_send_blocking(str) do{}while(LINE_BUSY == usart1_send(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 cleartrbuf() do{trbufidx = 0;}while(0)
|
||||||
#define trbufisfull() (trbufidx)
|
#define trbufisfull() (trbufidx)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user