fixed errors in flash write module

This commit is contained in:
eddyem 2015-02-06 14:23:56 +03:00
parent a54c3e3a66
commit 3c6450b9d4
8 changed files with 88 additions and 63 deletions

View File

@ -3,6 +3,8 @@ First PCB have been prodused, so I need "only" to solder elements & finish the c
Pinout of MCU is in file schematics/STM32_PINS Pinout of MCU is in file schematics/STM32_PINS
USE FUNCTION rat() in GNU/octave to calculate rational approximation to ADC conversion coefficients
-- OLD -- -- OLD --

View File

@ -21,6 +21,7 @@
#include "flash.h" #include "flash.h"
#include <libopencm3/stm32/flash.h> #include <libopencm3/stm32/flash.h>
#include <string.h>
/* /*
* this is a default values of stored data * this is a default values of stored data
@ -29,13 +30,29 @@
*/ */
#define FLASH_BLOCK_SIZE (2048) #define FLASH_BLOCK_SIZE (2048)
#define FLASH_WRONG_DATA_WRITTEN 0x80 #define FLASH_WRONG_DATA_WRITTEN 0x80
/*
.bss._flash_buffer
0x20001000 0x800 mk/flash.o
0x20001000 _flash_buffer
*/
const uint8_t _flash_buffer[FLASH_BLOCK_SIZE] __attribute__ ((aligned(FLASH_BLOCK_SIZE))); //const uint8_t _flash_buffer[FLASH_BLOCK_SIZE] __attribute__ ((aligned(FLASH_BLOCK_SIZE)));
const flash_data Stored_Data __attribute__ ((aligned(FLASH_BLOCK_SIZE))) = {
//.magick = FLASH_MAGICK,
._ADC_multipliers = {100000,100000,100000,100000,100000,100000,100000,100000, // TRD
26, // shutter
2 // power
},
._ADC_divisors = {1,1,1,1,1,1,1,1, // TRD
25, // shutter
7 // power
}
};
/** /**
* these are default values * these are default values
* they can be changed in runtime to change data stored in flash * they can be changed in runtime to change data stored in flash
*/ *
flash_data Default_stored_data = { flash_data Default_stored_data = {
.magick = FLASH_MAGICK, .magick = FLASH_MAGICK,
._ADC_multipliers = {100000,100000,100000,100000,100000,100000,100000,100000, // TRD ._ADC_multipliers = {100000,100000,100000,100000,100000,100000,100000,100000, // TRD
@ -48,49 +65,28 @@ flash_data Default_stored_data = {
} }
}; };
flash_data *Stored_Data = (flash_data*) _flash_buffer; */
//flash_data *Stored_Data = (flash_data*) _flash_buffer;
uint32_t flash_write_data(uint8_t *var, uint8_t *data, uint16_t datalen){ uint32_t flash_write_data(uint32_t *dataptr, uint16_t datalen){
uint32_t start_address = (uint32_t)var, page_address = (uint32_t)Stored_Data; uint32_t start_address = (uint32_t)&Stored_Data;
uint32_t *dataptr = (uint32_t*)data;
uint16_t i, rem; uint16_t i, rem;
uint32_t ret = 0; uint32_t ret = 0;
// check start address - it should be inside
if((start_address - page_address) >= FLASH_BLOCK_SIZE){
// DBG("bad starting address\n");
return 1;
}
flash_unlock(); flash_unlock();
DBG("erase\n");
//Erasing page //Erasing page
flash_erase_page(page_address); flash_erase_page(start_address);
//DBG("erase flash ");
/* if(FLASH_SR_EOP != (ret = flash_get_status_flags()))
goto endoffunction;
*/
//DBG("OK\nwrite");
rem = datalen % 4; // remainder rem = datalen % 4; // remainder
datalen /= 4; // round to 4 datalen /= 4; // round to 4
/*
print_int(datalen, lastsendfun);
DBG(" blocks of 4 bytes\n");
*/
// copy data by blocks of four // copy data by blocks of four
for(i = 0; i < datalen; i++, dataptr++, start_address += 4){ for(i = 0; i < datalen; i++, dataptr++, start_address += 4){
// write data word // write data word
flash_program_word(start_address, *dataptr); flash_program_word(start_address, *dataptr);
/* if(FLASH_SR_EOP != (ret = flash_get_status_flags())) //verify
goto endoffunction;
*/ //verify
if(*((uint32_t*)start_address) != *dataptr){ if(*((uint32_t*)start_address) != *dataptr){
ret = FLASH_WRONG_DATA_WRITTEN; ret = FLASH_WRONG_DATA_WRITTEN;
goto endoffunction; goto endoffunction;
} }
/*
DBG("Written: ");
print_int((int32_t)(uint32_t*)dataptr, lastsendfun);
lastsendfun('\n');
*/
} }
// remainder // remainder
if(rem){ if(rem){
@ -100,8 +96,6 @@ lastsendfun('\n');
if(rem == 3){ halfwords[1] = *((uint8_t*)dataptr+3); n = 2;} if(rem == 3){ halfwords[1] = *((uint8_t*)dataptr+3); n = 2;}
for(i = 0; i < n; i++, start_address += 2){ for(i = 0; i < n; i++, start_address += 2){
flash_program_half_word(start_address, halfwords[i]); flash_program_half_word(start_address, halfwords[i]);
if(FLASH_SR_EOP != (ret = flash_get_status_flags()))
goto endoffunction;
//verify //verify
if(*((uint16_t*)start_address) != halfwords[i]){ if(*((uint16_t*)start_address) != halfwords[i]){
ret = FLASH_WRONG_DATA_WRITTEN; ret = FLASH_WRONG_DATA_WRITTEN;
@ -109,25 +103,20 @@ lastsendfun('\n');
} }
} }
} }
DBG("ok written\n");
endoffunction: endoffunction:
flash_lock(); flash_lock();
/*
DBG("end, status: ");
print_int(ret, lastsendfun);
lastsendfun('\n');
*/
return ret; return ret;
} }
uint32_t flash_store_U32(uint32_t addr, uint32_t *data){
/** flash_data Saved_Data;
* checks magick in start of data block and fill block with default data uint32_t sz, ptrdiff;
* if flash is uninitialized sz = (uint32_t)&Stored_Data.last_addr - (uint32_t)&Stored_Data;
*/ ptrdiff = addr - (uint32_t)&Stored_Data;
uint32_t check_flash_data(){ memcpy((void*)&Saved_Data, (void*)&Stored_Data, sz);
if(Stored_Data->magick == FLASH_MAGICK) return 0; memcpy((void*)((uint32_t)&Saved_Data + ptrdiff), (void*)data, 4);
DBG("copy data\n"); return flash_write_data((uint32_t*)&Saved_Data, sz);
return flash_write_data((uint8_t*)Stored_Data, (uint8_t*)&Default_stored_data, sizeof(flash_data));
} }
/** /**
@ -135,8 +124,8 @@ uint32_t check_flash_data(){
*/ */
void dump_flash_data(sendfun s){ void dump_flash_data(sendfun s){
int i; int i;
P("magick: ", s); // P("magick: ", s);
print_int(Stored_Data->magick, s); // print_int(Stored_Data.magick, s);
P("\nADC multipliers: ", s); P("\nADC multipliers: ", s);
for(i = 0; i < ADC_CHANNELS_NUMBER; i++){ for(i = 0; i < ADC_CHANNELS_NUMBER; i++){
if(i) P(", ", s); if(i) P(", ", s);

View File

@ -29,18 +29,20 @@
#define FLASH_MAGICK ((uint32_t) 0xAA55A55A) #define FLASH_MAGICK ((uint32_t) 0xAA55A55A)
typedef struct{ typedef struct{
uint32_t magick; // magick value //uint32_t magick; // magick value
// A-D value[x] = ADU * ADC_multipliers[x] / ADC_divisors[x] // A-D value[x] = ADU * ADC_multipliers[x] / ADC_divisors[x]
uint32_t _ADC_multipliers[ADC_CHANNELS_NUMBER]; uint32_t _ADC_multipliers[ADC_CHANNELS_NUMBER];
uint32_t _ADC_divisors[ADC_CHANNELS_NUMBER]; uint32_t _ADC_divisors[ADC_CHANNELS_NUMBER];
char last_addr[0];
char struct_end[0] __attribute__ ((aligned(2048)));
} flash_data; } flash_data;
extern flash_data *Stored_Data; extern const flash_data Stored_Data;
#define ADC_multipliers Stored_Data->_ADC_multipliers #define ADC_multipliers Stored_Data._ADC_multipliers
#define ADC_divisors Stored_Data->_ADC_divisors #define ADC_divisors Stored_Data._ADC_divisors
uint32_t check_flash_data();
void dump_flash_data(sendfun s); void dump_flash_data(sendfun s);
uint32_t flash_store_U32(uint32_t addr, uint32_t *data);
#endif // __FLASH_H__ #endif // __FLASH_H__

View File

@ -234,6 +234,7 @@ int shutter_voltage(){
* 3.3V == 4096 ADU, 10..12V comes to ADC in through resistor divider 4.7k:12k, so * 3.3V == 4096 ADU, 10..12V comes to ADC in through resistor divider 4.7k:12k, so
* U10(V/100) = Uadc(ADU) * 167/47 * 33/40960 * 100 = Uadc(ADU) * 5511 / 19251 * U10(V/100) = Uadc(ADU) * 167/47 * 33/40960 * 100 = Uadc(ADU) * 5511 / 19251
* ==> approximately this is equal to val*2/7 * ==> approximately this is equal to val*2/7
* (real: approx 17/58)
*/ */
int power_voltage(){ int power_voltage(){
uint32_t val = ADC_value[POWER_SENSE_NUMBER]; // 9 uint32_t val = ADC_value[POWER_SENSE_NUMBER]; // 9

Binary file not shown.

View File

@ -31,7 +31,7 @@ usbd_device *usbd_dev;
uint8_t ADC_monitoring = 0; // ==1 to make continuous monitoring uint8_t ADC_monitoring = 0; // ==1 to make continuous monitoring
uint32_t ad7794_on = 0, flash_status = 1; uint32_t ad7794_on = 0;
uint32_t ad7794_values[TRD_NO]; uint32_t ad7794_values[TRD_NO];
uint8_t doubleconv = 1; // ==0 to single conversion; 1 to double (with currents reversing) uint8_t doubleconv = 1; // ==0 to single conversion; 1 to double (with currents reversing)
#define ADC_direct() setup_AD7794(EXTREFIN_1 | REF_DETECTION | UNIPOLAR_CODING, IEXC_DIRECT | IEXC_1MA) #define ADC_direct() setup_AD7794(EXTREFIN_1 | REF_DETECTION | UNIPOLAR_CODING, IEXC_DIRECT | IEXC_1MA)
@ -175,7 +175,6 @@ int main(){
usb_connect(); // turn on USB usb_connect(); // turn on USB
shutter_init(); shutter_init();
flash_status = check_flash_data(); // init flash block if uninitialized
while(1){ while(1){
usbd_poll(usbd_dev); usbd_poll(usbd_dev);
if(usbdatalen){ // there's something in USB buffer if(usbdatalen){ // there's something in USB buffer

View File

@ -55,7 +55,6 @@
extern uint32_t ad7794_values[]; // array with ADC data extern uint32_t ad7794_values[]; // array with ADC data
extern uint8_t doubleconv; // single/double ADC conversion extern uint8_t doubleconv; // single/double ADC conversion
extern uint32_t ad7794_on; // ==1 after AD7794 initialisation extern uint32_t ad7794_on; // ==1 after AD7794 initialisation
extern uint32_t flash_status; // == 0 if flash OK, or == FLASH_SR/FLASH_SR2
extern uint8_t ADC_monitoring; // ==1 to make continuous monitoring extern uint8_t ADC_monitoring; // ==1 to make continuous monitoring
void AD7794_init(); void AD7794_init();

View File

@ -23,6 +23,7 @@
#include "main.h" #include "main.h"
#include "uart.h" #include "uart.h"
#include "hardware_ini.h" #include "hardware_ini.h"
#include "flash.h"
// integer value given by user // integer value given by user
static volatile int32_t User_value = 0; static volatile int32_t User_value = 0;
@ -71,20 +72,53 @@ void set_shtr_delay(int32_t v, sendfun s){
print_int(d, s); print_int(d, s);
} }
int adc_channel = -1;
int div_mul = 0; // 0 - multip., !0 - div.
void ch_divmul(int32_t v, sendfun s){
uint32_t val = (uint32_t) v;
if(adc_channel == -1) return;
if(div_mul){ // != 0 - divisors
flash_store_U32((uint32_t)&ADC_divisors[adc_channel], &val);
}else{ // == 0 - mul
flash_store_U32((uint32_t)&ADC_multipliers[adc_channel], &val);
}
adc_channel = -1;
P("stored\n", s);
}
/**
* Change divisor
* @param v - user value (sensor number)
* @param s - active sendfunction
*/
void try_ch_divmul(int32_t v, sendfun s){
if(v > ADC_CHANNELS_NUMBER || v < 0){
P("wrong channel number\n", s);
adc_channel = -1;
return; // error
}
adc_channel = v;
I = ch_divmul;
read_int(NULL, 0); //start reading next int
}
void parce_incoming_buf(char *buf, int len, sendfun s){ void parce_incoming_buf(char *buf, int len, sendfun s){
uint8_t command; uint8_t command;
//uint32_t utmp;
int i = 0, j, m; int i = 0, j, m;
lastsendfun = s; lastsendfun = s;
if(Uval_ready == UVAL_START){ // we are in process of user's value reading if(Uval_ready == UVAL_START){ // we are in process of user's value reading
i += read_int(buf, len); i += read_int(buf, len);
} }
if(Uval_ready == UVAL_ENTERED){ if(Uval_ready == UVAL_ENTERED){
P("confirm entered value (+/-): ", s);
print_int(User_value, s); // printout readed integer value for error control print_int(User_value, s); // printout readed integer value for error control
Uval_ready = UVAL_PRINTED; Uval_ready = UVAL_PRINTED;
} }
if(I && Uval_ready == UVAL_CHECKED){ if(I && Uval_ready == UVAL_CHECKED){
Uval_ready = UVAL_BAD; // clear Uval_ready Uval_ready = UVAL_BAD; // clear Uval_ready
I(User_value, s); I(User_value, s);
return;
} }
for(; i < len; i++){ for(; i < len; i++){
command = buf[i]; command = buf[i];
@ -201,15 +235,14 @@ void parce_incoming_buf(char *buf, int len, sendfun s){
dump_flash_data(s); dump_flash_data(s);
break; break;
case 'd': // change ADC_divisor case 'd': // change ADC_divisor
; div_mul = 1; //divisors
I = try_ch_divmul;
READINT();
break; break;
case 'm': // change ADC_multiplier case 'm': // change ADC_multiplier
; div_mul = 0; // multipliers
break; I = try_ch_divmul;
case 'z': // temporary: refresh READINT();
flash_status = check_flash_data();
print_int(flash_status, s);
s('\n');
break; break;
case '\n': // show newline as is case '\n': // show newline as is
break; break;