some stm32 persistent settings fixes

This commit is contained in:
Martin Mueller
2011-04-02 15:18:50 +02:00
parent ed568625af
commit 17e6d4bb1c
9 changed files with 121 additions and 60 deletions
+2
View File
@@ -7,6 +7,8 @@ test settings
<airframe name="test settings">
<firmware name="lisa_l_test_progs">
<define name="USE_PERMANENT_SETTINGS"/>
<target name="test_settings" board="lisa_m_1.0"/>
</firmware>
+2 -6
View File
@@ -14,14 +14,10 @@
<define name="USE_MAX11040"/>
<define name="MAX11040_DEBUG"/>
</target>
<subsystem name="telemetry" type="xbee_api">
<param name="MODEM_BAUD" value="B57600"/>
</subsystem>
<subsystem name="telemetry" type="xbee_api"/>
<subsystem name="control"/>
<subsystem name="attitude" type="infrared"/>
<subsystem name="gps" type="ublox_lea5h">
<param name="GPS_BAUD" value="B38400"/>
</subsystem>
<subsystem name="gps" type="ublox_lea5h"/>
<subsystem name="navigation"/>
</firmware>
+2 -6
View File
@@ -7,14 +7,10 @@
<firmware name="fixedwing">
<target name="ap" board="tiny_2.11">
</target>
<subsystem name="telemetry" type="xbee_api">
<param name="MODEM_BAUD" value="B57600"/>
</subsystem>
<subsystem name="telemetry" type="xbee_api"/>
<subsystem name="control"/>
<subsystem name="attitude" type="infrared"/>
<subsystem name="gps" type="ublox_lea5h">
<param name="GPS_BAUD" value="B38400"/>
</subsystem>
<subsystem name="gps" type="ublox_lea5h"/>
<subsystem name="navigation"/>
</firmware>
@@ -29,17 +29,13 @@
<subsystem name="radio_control" type="ppm"/>
<!-- Communication -->
<subsystem name="telemetry" type="xbee_api">
<param name="MODEM_BAUD" value="B57600"/>
</subsystem>
<subsystem name="telemetry" type="xbee_api"/>
<!-- Actuators are automatically chosen according to board-->
<subsystem name="control"/>
<!-- Sensors -->
<!--subsystem name="attitude" type="infrared"/-->
<subsystem name="gps" type="ublox_lea5h">
<param name="GPS_BAUD" value="B38400"/>
</subsystem>
<subsystem name="gps" type="ublox_lea5h"/>
<!-- Nav -->
<subsystem name="navigation"/>
<!-- Interfaces -->
+1 -1
View File
@@ -7,7 +7,7 @@
<dl_setting var="setting_a" min="0" step="1" max="42" shortname ="a" module="test/subsystems/test_settings"/>
<dl_setting var="setting_b" min="0" step="1" max="42" shortname ="b" persistent="true"/>
<dl_setting var="setting_c" min="0" step="1" max="42" shortname ="c" persistent="true"/>
<dl_setting var="setting_d" min="0" step="1" max="42" shortname ="d" persistent="true" module="test/subsystems/test_settings" handler="SetD"/>
<dl_setting var="setting_d" min="0" step="1" max="42" shortname ="d" persistent="true" />
<dl_setting var="settings_store_now" min="0" step="1" max="1" shortname ="store" handler="StoreSettings" module="subsystems/settings"/>
</dl_settings>
+2 -1
View File
@@ -25,7 +25,8 @@
MEMORY
{
RAM (xrw): ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
/* last page (1k) flash for persistent settings */
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 127K
FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
}
+2 -1
View File
@@ -25,7 +25,8 @@
MEMORY
{
RAM (xrw): ORIGIN = 0x20000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K
/* last page (2k) flash for persistent settings */
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 510K
FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
}
+107 -26
View File
@@ -1,5 +1,41 @@
/*
* Paparazzi persistent settings low level flash routines stm32
*
* Copyright (C) 2011 Martin Mueller <martinmm@pfump.org>
*
* This file is part of Paparazzi.
*
* Paparazzi is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* Paparazzi is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Paparazzi; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
/*
flash data is located in the last page/sector of flash
data flash_addr
data_size flash_end - FSIZ
checksum flash_end - FCHK
STM32: minimum write size 2 bytes, endurance 10k cycles,
max sector erase time 40ms, max prog time 70us per 2 bytes
*/
#include "subsystems/settings.h"
#include <libopencm3/stm32/dbgmcu.h>
#include <libopencm3/stm32/flash.h>
#include <libopencm3/stm32/crc.h>
@@ -18,8 +54,9 @@ static int32_t pflash_program_bytes(struct FlashInfo* flash,
uint32_t size,
uint32_t chksum);
#define FLASH_SIZE_ MMIO16(0x1FFFF7E0)
#define FLASH_BEGIN 0x08000000
#define FLASH_SIZE 0x1FFFF7E0
#define FSIZ 8
#define FCHK 4
@@ -59,18 +96,21 @@ static uint32_t pflash_checksum(uint32_t ptr, uint32_t size) {
(*(uint8_t*) (ptr+i+1)) << 8 |
(*(uint8_t*) (ptr+i+2)) << 16;
break;
default:
break;
default:
break;
}
return CRC_DR;
}
static int32_t flash_detect(struct FlashInfo* flash) {
uint32_t device_id;
flash->total_size = (MMIO32(FLASH_SIZE) * 0x400)&0x00FFFFFF;
flash->total_size = FLASH_SIZE_ * 0x400;
#if 1
/* FIXME This will not work for connectivity line (needs ID, see below), but
device ID is only readable when freshly loaded through JTAG?! */
switch (flash->total_size) {
/* low density */
@@ -95,16 +135,58 @@ static int32_t flash_detect(struct FlashInfo* flash) {
}
default: {return -1;}
}
#else /* this is the correct way of detecting page sizes */
/* read device id */
device_id = DBGMCU_IDCODE & DBGMCU_IDCODE_DEV_ID_MASK;
switch (device_id) {
/* low density */
case 0x412:
/* medium density, e.g. STM32F103RB (Olimex STM32-H103) */
case 0x410:
{
flash->page_size = 0x400;
break;
}
/* high density, e.g. STM32F103RE (Joby Lisa/L) */
case 0x414:
/* XL density */
case 0x430:
/* connectivity line */
case 0x418:
{
flash->page_size = 0x800;
break;
}
default: return -1;
}
switch (flash->total_size) {
case 0x00004000: /* 16 kBytes */
case 0x00008000: /* 32 kBytes */
case 0x00010000: /* 64 kBytes */
case 0x00200000: /* 128 kBytes */
case 0x00040000: /* 256 kBytes */
case 0x00080000: /* 512 kBytes */
case 0x000C0000: /* 768 kBytes */
case 0x00100000: /* 1 MByte */
break;
default: return -1;
}
#endif
flash->page_nr = (flash->total_size / flash->page_size) - 1;
flash->addr = FLASH_BEGIN + flash->page_nr * flash->page_size;
return 0;
}
// (gdb) p *flash
// $1 = {addr = 134739968, total_size = 524288, page_nr = 255, page_size = 2048}
// 0x807F800 0x80000
static int32_t pflash_program_bytes(struct FlashInfo* flash,
uint32_t src,
uint32_t size,
@@ -113,19 +195,18 @@ static int32_t pflash_program_bytes(struct FlashInfo* flash,
/* erase */
flash_unlock();
flash_erase_page(flash->addr);
flash_erase_page(flash->addr);
flash_lock();
/* verify erase */
for (i=0; i<flash->page_size; i+=4) {
if ((*(uint32_t*) (flash->addr + i)) != 0xFFFFFFFF) return -1;
}
flash_unlock();
/* write full 16 bit words */
for (i=0; i<(size & ~1); i+=2) {
flash_program_half_word(flash->addr+i,
flash_program_half_word(flash->addr+i,
(uint16_t)(*(uint8_t*)(src+i) | (*(uint8_t*)(src+i+1)) << 8));
}
/* fill bytes with a zero */
@@ -133,36 +214,35 @@ static int32_t pflash_program_bytes(struct FlashInfo* flash,
flash_program_half_word(flash->addr+i, (uint16_t)(*(uint8_t*)(src+i)));
}
/* write size */
flash_program_half_word(flash->addr+flash->page_size-FSIZ,
flash_program_half_word(flash->addr+flash->page_size-FSIZ,
(uint16_t)(size & 0xFFFF));
flash_program_half_word(flash->addr+flash->page_size-FSIZ+2,
flash_program_half_word(flash->addr+flash->page_size-FSIZ+2,
(uint16_t)((size >> 16) & 0xFFFF));
/* write checksum */
flash_program_half_word(flash->addr+flash->page_size-FCHK,
flash_program_half_word(flash->addr+flash->page_size-FCHK,
(uint16_t)(chksum & 0xFFFF));
flash_program_half_word(flash->addr+flash->page_size-FCHK+2,
flash_program_half_word(flash->addr+flash->page_size-FCHK+2,
(uint16_t)((chksum >> 16) & 0xFFFF));
flash_lock();
/* verify data */
for (i=0; i<size; i++) {
if ((*(uint8_t*) (flash->addr+i)) != (*(uint8_t*) (src+i))) return -2;
}
if (*(uint32_t*) (flash->addr+flash->page_size-FSIZ) != size) return -3;
if (*(uint32_t*) (flash->addr+flash->page_size-FCHK) != chksum) return -4;
return 0;
}
int32_t persistent_write(uint32_t ptr, uint32_t size) {
struct FlashInfo flash_info;
if (flash_detect(&flash_info)) return -1;
if ((size > flash_info.page_size-FSIZ) || (size == 0)) return -2;
return pflash_program_bytes(&flash_info,
return pflash_program_bytes(&flash_info,
ptr,
size,
size,
pflash_checksum(ptr, size));
}
@@ -173,17 +253,18 @@ int32_t persistent_read(uint32_t ptr, uint32_t size) {
/* check parameters */
if (flash_detect(&flash)) return -1;
if ((size > flash.page_size-FSIZ) || (size == 0)) return -2;
/* check consistency */
if (size != *(uint32_t*)(flash.addr+flash.page_size-FSIZ)) return -3;
if (pflash_checksum(flash.addr, size) !=
*(uint32_t*)(flash.addr+flash.page_size-FCHK))
return -4;
/* copy data */
/* copy data */
for (i=0; i<size; i++) {
*(uint8_t*) (ptr+i) = *(uint8_t*) (flash.addr+i);
}
return 0;
}
@@ -1,5 +1,5 @@
/*
* Paparazzi stm32 persistent flash low level routines
* Paparazzi persistent settings low level flash routines stm32
*
* Copyright (C) 2011 Martin Mueller <martinmm@pfump.org>
*
@@ -23,18 +23,6 @@
*/
/*
TODO:
- remove last sector from usable flash memory in STM32 linker script
flash data is located in the last page/sector of flash
data_begin flash_info.addr
data_size flash_info.addr + flash_info.size - 8
checksum flash_info.addr + flash_info.size - 4
*/
#ifndef STM32_SUBSYSTEMS_SETTINGS_H
#define STM32_SUBSYSTEMS_SETTINGS_H