mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-25 23:46:04 +08:00
some stm32 persistent settings fixes
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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 -->
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user