Merge remote branch 'paparazzi/master' into dev

This commit is contained in:
Felix Ruess
2011-04-06 10:17:44 +02:00
20 changed files with 736 additions and 195 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>
+14 -20
View File
@@ -10,12 +10,14 @@
<airframe name="Funjet mm 1">
<firmware name="fixedwing">
<define name="AGR_CLIMB"/>
<define name="LOITER_TRIM"/>
<define name="ALT_KALMAN"/>
<define name="WIND_INFO"/>
<define name="WIND_INFO_RET"/>
<define name="USE_PERSISTENT_SETTINGS"/>
<target name="ap" board="tiny_2.11">
<define name="AGR_CLIMB"/>
<define name="LOITER_TRIM"/>
<define name="ALT_KALMAN"/>
<define name="WIND_INFO"/>
<define name="WIND_INFO_RET"/>
<define name="USE_I2C0"/>
<define name="SENSOR_SYNC_SEND"/>
<define name="ADC_CHANNEL_GENERIC1" value="ADC_3"/>
@@ -25,30 +27,22 @@
</target>
<target name="sim" board="pc">
<define name="AGR_CLIMB"/>
<define name="LOITER_TRIM"/>
<define name="ALT_KALMAN"/>
<define name="WIND_INFO"/>
<define name="WIND_INFO_RET"/>
</target>
<!-- RC -->
<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 -->
<subsystem name="i2c"/>
<!--subsystem name="spi"/-->
</firmware>
<firmware name="setup">
@@ -60,16 +54,14 @@
<!-- modules -->
<modules>
<load name="humid_sht_i2c.xml"/>
<!--load name="windturbine.xml"/>
<!--load name="adc_generic.xml"/>
<load name="windturbine.xml"/>
<load name="dust_gp2y.xml"/>
<load name="light_temt.xml"/>
<load name="temp_temod.xml"/>
<load name="adc_generic.xml"/>
<load name="trig_test.xml"/>
<load name="airspeed_ets.xml"/>
<load name="alt_srf08.xml"/>
<load name="mag_micromag_fw.xml"/>
<load name="baro_bmp.xml"/>
<load name="baro_scp.xml"/>
<load name="humid_hih.xml"/>
@@ -79,6 +71,8 @@
<load name="humid_dpicco.xml"/>
<load name="humid_sht.xml"/>
<load name="baro_MS5534A.xml"/>
<load name="humid_sht_i2c.xml"/>
<load name="mag_micromag_fw.xml"/>
<load name="baro_scp_i2c.xml"/-->
</modules>
@@ -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 -->
@@ -138,6 +138,8 @@ ns_srcs += $(SRC_ARCH)/sys_time_hw.c
#
ns_srcs += $(SRC_ARCH)/mcu_periph/uart_arch.c
ns_srcs += subsystems/settings.c
ns_srcs += $(SRC_ARCH)/subsystems/settings_arch.c
#
# ANALOG
@@ -191,6 +193,9 @@ sim.srcs += $(SRC_ARCH)/sim_ap.c
sim.CFLAGS += -DDOWNLINK -DDOWNLINK_TRANSPORT=IvyTransport
sim.srcs += downlink.c $(SRC_FIRMWARE)/datalink.c $(SRC_ARCH)/sim_gps.c $(SRC_ARCH)/ivy_transport.c $(SRC_ARCH)/sim_adc_generic.c
sim.srcs += subsystems/settings.c
sim.srcs += $(SRC_ARCH)/subsystems/settings_arch.c
######################################################################
##
## JSBSIM THREAD SPECIFIC
+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>
+109
View File
@@ -0,0 +1,109 @@
<!DOCTYPE settings SYSTEM "settings.dtd">
<!-- A conf to use to tune a new A/C -->
<settings>
<dl_settings>
<dl_settings NAME="flight params">
<dl_setting MAX="1000" MIN="0" STEP="10" VAR="flight_altitude" shortname="altitude"/>
<dl_setting MAX="10" MIN="-10" STEP="0.5" VAR="wind_east"/>
<dl_setting MAX="10" MIN="-10" STEP="0.5" VAR="wind_north"/>
</dl_settings>
<dl_settings NAME="mode">
<dl_setting MAX="2" MIN="0" STEP="1" VAR="pprz_mode" module="autopilot"/>
<dl_setting MAX="1" MIN="0" STEP="1" VAR="alt_kalman_enabled" shortname="alt_kalman" module="estimator"/>
<dl_setting MAX="0" MIN="0" STEP="1" VAR="estimator_flight_time" shortname="flight time"/>
<dl_setting MAX="1000" MIN="0" STEP="1" VAR="stage_time"/>
<dl_setting MAX="1" MIN="0" STEP="1" VAR="launch"/>
<dl_setting MAX="1" MIN="0" STEP="1" VAR="kill_throttle"/>
<dl_setting MAX="2" MIN="0" STEP="1" VAR="telemetry_mode_Ap_DefaultChannel" shortname="tele_AP" module="downlink"/>
<dl_setting MAX="1" MIN="0" STEP="1" VAR="telemetry_mode_Fbw_DefaultChannel" shortname="tele_FBW" module="downlink"/>
<dl_setting MAX="2" MIN="0" STEP="1" VAR="gps_reset" module="gps_ubx" handler="Reset" shortname="GPS reset"/>
<dl_setting MAX="200" MIN="-200" STEP="10" VAR="nav_radius" module="subsystems/nav" handler="SetNavRadius">
<strip_button icon="circle-right.png" name="Circle right" value="1"/>
<strip_button icon="circle-left.png" name="Circle left" value="-1"/>
<key_press key="greater" value="1"/>
<key_press key="less" value="-1"/>
</dl_setting>
</dl_settings>
<dl_settings NAME="control">
<dl_settings NAME="ir">
<dl_setting MAX="0.3" MIN="-0.3" STEP="0.01" VAR="infrared.roll_neutral" shortname="roll_neutral" param="IR_ROLL_NEUTRAL_DEFAULT" unit="rad" persistent="true" />
<dl_setting MAX="0.5" MIN="-0.3" STEP="0.01" VAR="infrared.pitch_neutral" shortname="pitch_neutral" param="IR_PITCH_NEUTRAL_DEFAULT" unit="rad" persistent="true" />
<dl_setting MAX="1.5" MIN="0." STEP="0.1" VAR="infrared.lateral_correction" shortname="360_lat_corr" module="subsystems/sensors/infrared" param="IR_LATERAL_CORRECTION"/>
<dl_setting MAX="1.5" MIN="0." STEP="0.1" VAR="infrared.longitudinal_correction" shortname="360_log_corr" param="IR_LONGITUDINAL_CORRECTION"/>
<dl_setting MAX="1.5" MIN="0.5" STEP="0.1" VAR="infrared.vertical_correction" shortname="360_vert_corr" param="IR_VERTICAL_CORRECTION"/>
<dl_setting MAX="1.5" MIN="0.5" STEP="0.1" VAR="infrared.correction_left" shortname="corr_left" param="IR_CORRECTION_LEFT"/>
<dl_setting MAX="1.5" MIN="0.5" STEP="0.1" VAR="infrared.correction_right" shortname="corr_right" param="IR_CORRECTION_RIGHT"/>
<dl_setting MAX="1.5" MIN="0.5" STEP="0.1" VAR="infrared.correction_up" shortname="corr_up" param="IR_CORRECTION_UP"/>
<dl_setting MAX="1.5" MIN="0.5" STEP="0.1" VAR="infrared.correction_down" shortname="corr_down" param="IR_CORRECTION_DOWN"/>
</dl_settings>
<dl_settings NAME="attitude">
<dl_setting MAX="25000" MIN="000" STEP="250" VAR="h_ctl_roll_pgain" shortname="roll_pgain" module="stabilization/stabilization_attitude"/>
<dl_setting MAX="1" MIN="0" STEP="0.05" VAR="h_ctl_roll_max_setpoint" shortname="max_roll" param="H_CTL_ROLL_MAX_SETPOINT"/>
<dl_setting MAX="000" MIN="-25000" STEP="250" VAR="h_ctl_pitch_pgain" shortname="pitch_pgain" param="H_CTL_PITCH_PGAIN"/>
<dl_setting MAX="0" MIN="-50000" STEP="10" VAR="h_ctl_pitch_dgain" shortname="pitch_dgain" param="H_CTL_PITCH_DGAIN"/>
<dl_setting MAX="5000" MIN="0" STEP="100" VAR="h_ctl_elevator_of_roll" shortname="elevator_of_roll" param="H_CTL_ELEVATOR_OF_ROLL"/>
<dl_setting MAX="5000" MIN="0" STEP="100" VAR="h_ctl_aileron_of_throttle" shortname="aileron_of_throttle"/>
<dl_setting MAX="0" MIN="-15000" STEP="250" VAR="h_ctl_roll_attitude_gain" shortname="roll attitude pgain" param="H_CTL_ROLL_ATTITUDE_GAIN"/>
<dl_setting MAX="0" MIN="-15000" STEP="250" VAR="h_ctl_roll_rate_gain" shortname="roll rate gain" param="H_CTL_ROLL_RATE_GAIN"/>
</dl_settings>
<dl_settings name="alt">
<dl_setting MAX="0" MIN="-0.2" STEP="0.01" VAR="v_ctl_altitude_pgain" shortname="alt_pgain" param="V_CTL_ALTITUDE_PGAIN"/>
</dl_settings>
<dl_settings name="auto_throttle">
<dl_setting MAX="1" MIN="0.0" STEP="0.05" VAR="v_ctl_auto_throttle_cruise_throttle" shortname="cruise throttle" module="guidance/guidance_v" handler="SetCruiseThrottle" param="V_CTL_AUTO_THROTTLE_NOMINAL_CRUISE_THROTTLE">
<strip_button name="Loiter" value="0.1"/>
<strip_button name="Cruise" value="0"/>
<strip_button name="Dash" value="1"/>
</dl_setting>
<dl_setting MAX="0.00" MIN="-0.05" STEP="0.005" VAR="v_ctl_auto_throttle_pgain" shortname="throttle_pgain" param="V_CTL_AUTO_THROTTLE_PGAIN"/>
<dl_setting MAX="1" MIN="0.0" STEP="0.05" VAR="v_ctl_auto_throttle_igain" shortname="throttle_igain" param="V_CTL_AUTO_THROTTLE_IGAIN"/>
<dl_setting MAX="2" MIN="0.0" STEP="0.1" VAR="v_ctl_auto_throttle_dgain" shortname="throttle_dgain"/>
<!-- commented by poine - does anybody use that ?at all ? -->
<!-- <dl_setting MAX="0" MIN="-4000" STEP="100" VAR="v_ctl_auto_throttle_dash_trim" shortname="dash trim"/> -->
<!-- <dl_setting MIN="0" MAX="3000" STEP="100" VAR="v_ctl_auto_throttle_loiter_trim" shortname="loiter trim" param="V_CTL_AUTO_THROTTLE_LOITER_TRIM"/> -->
<dl_setting MAX="1" MIN="0" STEP="0.01" VAR="v_ctl_auto_throttle_climb_throttle_increment" shortname="throttle_incr" param="V_CTL_AUTO_THROTTLE_CLIMB_THROTTLE_INCREMENT"/>
<dl_setting MAX="1" MIN="0" STEP="0.01" VAR="v_ctl_auto_throttle_pitch_of_vz_pgain" shortname="pitch_of_vz" param="V_CTL_AUTO_THROTTLE_PITCH_OF_VZ_PGAIN"/>
<dl_setting MAX="10" MIN="-10" STEP="0.1" VAR="v_ctl_auto_throttle_pitch_of_vz_dgain" shortname="pitch_of_vz (d)"/>
</dl_settings>
<dl_settings name="auto_pitch">
<dl_setting MAX="-0.01" MIN="-0.1" STEP="0.01" VAR="v_ctl_auto_pitch_pgain" shortname="pgain" param="V_CTL_AUTO_PITCH_PGAIN"/>
<dl_setting MAX="1" MIN="0" STEP="0.01" VAR="v_ctl_auto_pitch_igain" shortname="igain" param="V_CTL_AUTO_PITCH_IGAIN"/>
</dl_settings>
<dl_settings name="nav">
<dl_setting MAX="-0.1" MIN="-3" STEP="0.05" VAR="h_ctl_course_pgain" shortname="course pgain" param="H_CTL_COURSE_PGAIN"/>
<dl_setting MAX="2" MIN="0" STEP="0.1" VAR="h_ctl_course_dgain" shortname="course dgain" param="H_CTL_COURSE_DGAIN"/>
<dl_setting MAX="2" MIN="0.1" STEP="0.05" VAR="h_ctl_course_pre_bank_correction" shortname="pre bank cor" param="H_CTL_COURSE_PRE_BANK_CORRECTION"/>
<dl_setting MAX="1" MIN="0.0" STEP="0.05" VAR="nav_glide_pitch_trim" shortname="glide pitch trim" param="NAV_GLIDE_PITCH_TRIM"/>
<dl_setting MAX="1" MIN="0.02" STEP="0.01" VAR="h_ctl_roll_slew" shortname="roll slew"/>
<dl_setting MAX="500" MIN="-500" STEP="5" VAR="nav_radius"/>
<dl_setting MAX="359" MIN="0" STEP="5" VAR="nav_course"/>
<dl_setting MAX="2" MIN="1" STEP="1" VAR="nav_mode"/>
<dl_setting MAX="5" MIN="-5" STEP="0.5" VAR="nav_climb"/>
<dl_setting MAX="15" MIN="-15" STEP="1" VAR="fp_pitch"/>
<dl_setting MAX="50" MIN="-50" STEP="5" VAR="nav_shift" module="subsystems/nav" handler="IncreaseShift" shortname="inc. shift"/>
<dl_setting MAX="50" MIN="5" STEP="0.5" VAR="nav_ground_speed_setpoint" shortname="ground speed"/>
<dl_setting MAX="0." MIN="-0.2" STEP="0.01" VAR="nav_ground_speed_pgain" shortname="ground speed pgain"/>
<dl_setting MAX="500" MIN="50" STEP="5" VAR="nav_survey_shift"/>
</dl_settings>
</dl_settings>
</dl_settings>
</settings>
+7 -2
View File
@@ -7,8 +7,13 @@ STACK_SIZE = 0x1000;
/* Memory Definitions */
MEMORY
{
ROM (rx) : ORIGIN = 0x00004000, LENGTH = 484k
RAM (rw) : ORIGIN = 0x40000000, LENGTH = 32k
/* 0x00000000: Paparazzi bootloader (16k) */
/* 0x00004000: Paparazzi code (480k) */
/* 0x0007C000: persistent settings (4k) */
/* 0x0007D000: Philips/NXP bootloader (12k) */
ROM (rx) : ORIGIN = 0x00004000, LENGTH = 480k
/* topmost 32 bytes are reserved for IAP operations */
RAM (rw) : ORIGIN = 0x40000000, LENGTH = 32736
}
/* Section Definitions */
@@ -1,10 +1,272 @@
/*
* Paparazzi persistent settings low level flash routines lpc21
*
* 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.
*
*/
/*
LPC2148 flash data is located in the last available page
0x00000000: Paparazzi bootloader (16k)
0x00004000: Paparazzi code (480k)
0x0007C000: persistent settings (4k)
0x0007D000: Philips/NXP bootloader (12k)
data flash_addr
data_size flash_end - FSIZ
checksum flash_end - FCHK
LPC21: minimum write size 256 bytes, endurance 100k cycles,
max sector erase time 400ms, max prog time 1ms per 256 bytes
*/
#include "subsystems/settings.h"
#define IAP_LOCATION 0x7FFFFFF1
#define IAP_PREPARE_SECTORS 50
#define IAP_COPY_RAM_TO_FLASH 51
#define IAP_ERASE_SECTORS 52
#define IAP_BLANK_CHECK_SECTORS 53
#define IAP_READ_PART_ID 54
#define IAP_COMPARE 56
/* we have to operate on 256 byte flash boundaries */
#define BOUND 256
#define FSIZ 8
#define FCHK 4
typedef void (*IAP)(uint32_t[], uint32_t[]);
typedef struct {
uint32_t addr;
uint32_t total_size;
uint32_t page_nr;
uint32_t page_size;
} FlashInfo;
static uint32_t pflash_checksum(uint32_t ptr, uint32_t size);
static int32_t flash_detect(FlashInfo* flash);
static int32_t pflash_erase_page(FlashInfo* flash);
static int32_t pflash_program_array(FlashInfo* flash,
uint32_t dest,
uint32_t src);
static int32_t pflash_program_bytes(FlashInfo* flash,
uint32_t src,
uint32_t size,
uint32_t chksum);
static uint32_t pflash_checksum(uint32_t ptr, uint32_t size) {
uint32_t i, sum = 0;
/* do it cheap for now */
for (i=0; i<size; i++) {
sum += *(uint8_t*) (ptr+i);
}
return sum;
}
static int32_t flash_detect(FlashInfo* flash) {
uint32_t command[5], result[3];
IAP iap_entry;
iap_entry = (IAP) IAP_LOCATION;
/* get part ID */
command[0] = IAP_READ_PART_ID;
disableIRQ();
iap_entry(command, result);
enableIRQ();
if (result[0] != 0) return result[0];
switch (result[1]) {
/* LPC2141, 32k Flash, 8k RAM */
case 0x0402FF01:
/* LPC2142, 64k Flash, 16k RAM */
case 0x0402FF11:
/* LPC2144, 128k Flash, 16k RAM */
case 0x0402FF12:
/* LPC2146, 256k Flash, 32k+8k RAM */
case 0x0402FF23:
{
return -1;
break;
}
/* have LPC2148 support only */
/* LPC2148, 512k Flash, 32k+8k RAM */
case 0x0402FF25:
{
flash->page_size = 0x1000;
flash->page_nr = 26;
flash->addr = 0x7C000;
break;
}
default: return -1;
}
return 0;
}
static int32_t pflash_erase_page(FlashInfo* flash) {
uint32_t command[5], result[3];
IAP iap_entry;
iap_entry = (IAP) IAP_LOCATION;
/* prepare page/sector */
command[0] = IAP_PREPARE_SECTORS;
command[1] = flash->page_nr;
command[2] = flash->page_nr;
disableIRQ();
iap_entry(command, result);
enableIRQ();
if (result[0] != 0) return result[0];
/* erase page/sector */
command[0] = IAP_ERASE_SECTORS;
command[1] = flash->page_nr;
command[2] = flash->page_nr;
disableIRQ();
iap_entry(command, result);
enableIRQ();
if (result[0] != 0) return result[0];
/* verify erase */
command[0] = IAP_BLANK_CHECK_SECTORS;
command[1] = flash->page_nr;
command[2] = flash->page_nr;
iap_entry(command, result);
if (result[0] != 0) return result[0];
return 0;
}
static int32_t pflash_program_array(FlashInfo* flash,
uint32_t dest,
uint32_t src) {
uint32_t command[5], result[3];
IAP iap_entry;
iap_entry = (IAP) IAP_LOCATION;
/* prepare page/sector */
command[0] = IAP_PREPARE_SECTORS;
command[1] = flash->page_nr;
command[2] = flash->page_nr;
disableIRQ();
iap_entry(command, result);
enableIRQ();
if (result[0] != 0) return result[0];
/* flash from ram */
command[0] = IAP_COPY_RAM_TO_FLASH;
command[1] = dest;
command[2] = src;
command[3] = BOUND;
command[4] = CCLK/1000;
disableIRQ();
iap_entry(command, result);
enableIRQ();
if (result[0] != 0) return result[0];
return 0;
}
static int32_t pflash_program_bytes(FlashInfo* flash,
uint32_t src,
uint32_t size,
uint32_t chksum) {
uint32_t data[BOUND/4], i, j, ret;
uint32_t ptr = (uint32_t) &data;
/* erase */
if ((ret = pflash_erase_page(flash))) return ret;
/* write data in arrays */
for (i=0; i<size; i+=BOUND) {
/* copy data to aligned memory */
for (j=0; j<BOUND; j++) {
*(uint8_t*) (ptr+j) = *(uint8_t*) (src+i+j);
}
if (i == flash->page_size - BOUND) {
data[(BOUND-FSIZ)/4] = size;
data[(BOUND-FCHK)/4] = chksum;
}
if ((ret = pflash_program_array(flash, flash->addr+i, ptr))) return ret;
}
/* last array */
if (i <= flash->page_size - BOUND) {
data[(BOUND-FSIZ)/4] = size;
data[(BOUND-FCHK)/4] = chksum;
if ((ret = pflash_program_array(flash,
flash->addr+flash->page_size-BOUND,
ptr)))
return ret;
}
/* 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) {
return 0;
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,
ptr,
size,
pflash_checksum(ptr, size));
}
int32_t persistent_read(uint32_t ptr, uint32_t size) {
FlashInfo flash;
uint32_t i;
/* 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 */
for (i=0; i<size; i++) {
*(uint8_t*) (ptr+i) = *(uint8_t*) (flash.addr+i);
}
return 0;
}
@@ -0,0 +1,31 @@
/*
* Paparazzi persistent settings low level flash routines lpc21
*
* 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.
*
*/
#ifndef LPC21_SUBSYSTEMS_SETTINGS_H
#define LPC21_SUBSYSTEMS_SETTINGS_H
#endif /* LPC21_SUBSYSTEMS_SETTINGS_H */
@@ -2,9 +2,13 @@
int32_t persistent_write(uint32_t ptr, uint32_t size) {
ptr=ptr;
size=size;
return 0;
}
int32_t persistent_read(uint32_t ptr, uint32_t size) {
ptr=ptr;
size=size;
return 0;
}
+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
+100 -93
View File
@@ -1,26 +1,16 @@
#include "subsystems/sensors/baro.h"
#include <stm32/gpio.h>
struct Baro baro;
struct BaroBoard baro_board;
struct i2c_transaction baro_trans;
static inline void baro_board_write_to_register(uint8_t baro_addr, uint8_t reg_addr, uint8_t val_msb, uint8_t val_lsb);
static inline void baro_board_read_from_register(uint8_t baro_addr, uint8_t reg_addr);
static inline void baro_board_set_current_register(uint8_t baro_addr, uint8_t reg_addr);
static inline void baro_board_read(void);
struct bmp085_baro_calibration calibration;
#define BMP085_SAMPLE_PERIOD_MS (3 + (2 << BMP085_OSS) * 3)
#define BMP085_SAMPLE_PERIOD (BMP075_SAMPLE_PERIOD_MS >> 1)
void baro_init(void) {
baro.status = BS_UNINITIALIZED;
baro.absolute = 0;
baro.differential = 0;
baro_board.status = LBS_UNINITIALIZED;
}
// FIXME: BARO DRDY connected to PB0 for lisa/m
static inline void bmp085_write_reg(uint8_t addr, uint8_t value)
{
@@ -33,56 +23,23 @@ static inline void bmp085_write_reg(uint8_t addr, uint8_t value)
while (baro_trans.status == I2CTransPending || baro_trans.status == I2CTransRunning);
}
static inline void bmp085_request_pressure(void)
static inline void bmp085_read_reg16(uint8_t addr)
{
bmp085_write_reg(0xF4, 0x34 + (BMP085_OSS << 6));
}
void baro_periodic(void) {
// check i2c_done
if (!i2c_idle(&i2c2)) return;
switch (baro_board.status) {
case LBS_UNINITIALIZED:
baro_board_send_reset();
baro_board.status = LBS_RESETED;
break;
case LBS_RESETED:
baro_board_send_config();
baro_board.status = LBS_INITIALIZING;
break;
case LBS_INITIALIZING:
baro_board_set_current_register(BMP085_ADDR, 0x00);
baro_board.status = LBS_INITIALIZING_1;
break;
case LBS_INITIALIZING_1:
baro.status = BS_RUNNING;
case LBS_REQUEST:
bmp085_request_pressure();
baro_board.status = LBS_READ;
break;
case LBS_READ:
baro_board_read();
baro_board.status = LBS_READING;
break;
default:
break;
}
}
void baro_board_send_config(void) {
/* maybe we should read factory calibration here */
//baro_board_write_to_register(BMP085_ADDR, 0x01, 0x86, 0x83);
}
void baro_board_send_reset(void) {
baro_trans.type = I2CTransTx;
baro_trans.slave_addr = 0x00;
baro_trans.type = I2CTransTxRx;
baro_trans.slave_addr = BMP085_ADDR;
baro_trans.len_w = 1;
baro_trans.buf[0] = 0x06;
i2c_submit(&i2c2,&baro_trans);
baro_trans.len_r = 2;
baro_trans.buf[0] = addr;
i2c_submit(&i2c2, &baro_trans);
}
static inline int16_t bmp085_read_reg16_blocking(uint8_t addr)
{
bmp085_read_reg16(addr);
while (baro_trans.status == I2CTransPending || baro_trans.status == I2CTransRunning);
return ((baro_trans.buf[0] << 8) | baro_trans.buf[1]);
}
static inline void bmp085_read_reg24(uint8_t addr)
@@ -93,51 +50,101 @@ static inline void bmp085_read_reg24(uint8_t addr)
baro_trans.len_r = 3;
baro_trans.buf[0] = addr;
i2c_submit(&i2c2, &baro_trans);
//while (baro_trans.status == I2CTransPending || baro_trans.status == I2CTransRunning);
//return (baro_trans.buf[0] << 16) | (baro_trans.buf[1] >> 8) | (baro_trans.buf[2]);
}
static inline void baro_board_write_to_register(uint8_t baro_addr, uint8_t reg_addr, uint8_t val_msb, uint8_t val_lsb) {
baro_trans.type = I2CTransTx;
baro_trans.slave_addr = baro_addr;
baro_trans.len_w = 3;
baro_trans.buf[0] = reg_addr;
baro_trans.buf[1] = val_msb;
baro_trans.buf[2] = val_lsb;
i2c_submit(&i2c2,&baro_trans);
static void bmp085_baro_read_calibration(void)
{
calibration.ac1 = bmp085_read_reg16_blocking(0xAA); // AC1
calibration.ac2 = bmp085_read_reg16_blocking(0xAC); // AC2
calibration.ac3 = bmp085_read_reg16_blocking(0xAE); // AC3
calibration.ac4 = bmp085_read_reg16_blocking(0xB0); // AC4
calibration.ac5 = bmp085_read_reg16_blocking(0xB2); // AC5
calibration.ac6 = bmp085_read_reg16_blocking(0xB4); // AC6
calibration.b1 = bmp085_read_reg16_blocking(0xB6); // B1
calibration.b2 = bmp085_read_reg16_blocking(0xB8); // B2
calibration.mb = bmp085_read_reg16_blocking(0xBA); // MB
calibration.mc = bmp085_read_reg16_blocking(0xBC); // MC
calibration.md = bmp085_read_reg16_blocking(0xBE); // MD
}
static inline void baro_board_read_from_register(uint8_t baro_addr, uint8_t reg_addr) {
baro_trans.type = I2CTransTxRx;
baro_trans.slave_addr = baro_addr;
baro_trans.len_w = 1;
baro_trans.len_r = 2;
baro_trans.buf[0] = reg_addr;
i2c_submit(&i2c2,&baro_trans);
void baro_init(void) {
baro.status = BS_UNINITIALIZED;
baro.absolute = 0;
baro.differential = 0;
baro_board.status = LBS_UNINITIALIZED;
bmp085_baro_read_calibration();
/* STM32 specific (maybe this is a LISA/M specific driver anyway?) */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
static inline void baro_board_set_current_register(uint8_t baro_addr, uint8_t reg_addr) {
baro_trans.type = I2CTransTx;
baro_trans.slave_addr = baro_addr;
baro_trans.len_w = 1;
baro_trans.buf[0] = reg_addr;
i2c_submit(&i2c2,&baro_trans);
static inline int baro_eoc(void)
{
return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0);
}
static inline void bmp085_request_pressure(void)
{
bmp085_write_reg(0xF4, 0x34 + (BMP085_OSS << 6));
}
static inline void bmp085_request_temp(void)
{
bmp085_write_reg(0xF4, 0x2E);
}
static inline void bmp085_read_pressure(void)
{
bmp085_read_reg24(0xF6);
}
static inline void baro_board_read()
static inline void bmp085_read_temp(void)
{
//int32_t x;
//bmp085_request_pressure();
bmp085_read_pressure();
//baro_trans.type = I2CTransRx;
//baro_trans.slave_addr = BMP085_ADDR;
//baro_trans.len_r = 2;
//i2c_submit(&i2c2,&baro_trans);
bmp085_read_reg16(0xF6);
}
void baro_periodic(void) {
// check that nothing is in progress
if (baro_trans.status == I2CTransPending) return;
if (baro_trans.status == I2CTransRunning) return;
if (!i2c_idle(&i2c2)) return;
switch (baro_board.status) {
case LBS_UNINITIALIZED:
baro_board_send_reset();
baro_board.status = LBS_REQUEST;
baro.status = BS_RUNNING;
break;
case LBS_REQUEST:
bmp085_request_pressure();
baro_board.status = LBS_READ;
break;
case LBS_READ:
if (baro_eoc()) {
bmp085_read_pressure();
baro_board.status = LBS_READING;
}
break;
case LBS_REQUEST_TEMP:
bmp085_request_temp();
baro_board.status = LBS_READ_TEMP;
break;
case LBS_READ_TEMP:
if (baro_eoc()) {
bmp085_read_temp();
baro_board.status = LBS_READING_TEMP;
}
break;
default:
break;
}
}
void baro_board_send_reset(void) {
// This is a NOP at the moment
}
+70 -17
View File
@@ -10,44 +10,97 @@
#include "std.h"
#include "mcu_periph/i2c.h"
// absolute
// absolute addr
#define BMP085_ADDR 0xEE
// Over sample setting (0-3)
#define BMP085_OSS 3
enum LisaBaroStatus {
LBS_UNINITIALIZED,
LBS_RESETED,
LBS_INITIALIZING,
LBS_INITIALIZING_1,
LBS_IDLE,
LBS_REQUEST,
LBS_READING,
LBS_READ,
LBS_REQUEST_TEMP,
LBS_READING_TEMP,
LBS_READ_TEMP,
};
struct BaroBoard {
enum LisaBaroStatus status;
};
struct bmp085_baro_calibration {
// These values come from EEPROM on sensor
int16_t ac1;
int16_t ac2;
int16_t ac3;
uint16_t ac4;
uint16_t ac5;
uint16_t ac6;
int16_t b1;
int16_t b2;
int16_t mb;
int16_t mc;
int16_t md;
// These values are calculated
int32_t b5;
};
extern struct BaroBoard baro_board;
extern struct i2c_transaction baro_trans;
extern struct bmp085_baro_calibration calibration;
extern void baro_board_send_reset(void);
extern void baro_board_send_config(void);
#define BaroEvent(_b_abs_handler, _b_diff_handler) { \
if (baro_board.status == LBS_READING && \
baro_trans.status != I2CTransPending) { \
baro_board.status = LBS_REQUEST; \
if (baro_trans.status == I2CTransSuccess) { \
int32_t tmp = (baro_trans.buf[0]<<16) | (baro_trans.buf[1] << 8) | baro_trans.buf[0]; \
baro.absolute = tmp >> ( 8 - BMP085_OSS); \
_b_abs_handler(); \
} \
} \
// Apply temp calibration and sensor calibration to raw measurement to get Pa (from BMP085 datasheet)
static inline int32_t baro_apply_calibration(int32_t raw)
{
int32_t b6 = calibration.b5 - 4000;
int x1 = (calibration.b2 * (b6 * b6 >> 12)) >> 11;
int x2 = calibration.ac2 * b6 >> 11;
int32_t x3 = x1 + x2;
int32_t b3 = (((calibration.ac1 * 4 + x3) << BMP085_OSS) + 2)/4;
x1 = calibration.ac3 * b6 >> 13;
x2 = (calibration.b1 * (b6 * b6 >> 12)) >> 16;
x3 = ((x1 + x2) + 2) >> 2;
uint32_t b4 = (calibration.ac4 * (uint32_t) (x3 + 32768)) >> 15;
uint32_t b7 = (raw - b3) * (50000 >> BMP085_OSS);
int32_t p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
return p + ((x1 + x2 + 3791) >> 4);
}
static inline void baro_event(void (*b_abs_handler)(void), void (*b_diff_handler)(void))
{
if (baro_board.status == LBS_READING &&
baro_trans.status != I2CTransPending && baro_trans.status != I2CTransRunning) {
baro_board.status = LBS_REQUEST_TEMP;
if (baro_trans.status == I2CTransSuccess) {
int32_t tmp = (baro_trans.buf[0]<<16) | (baro_trans.buf[1] << 8) | baro_trans.buf[2];
tmp = tmp >> (8 - BMP085_OSS);
baro.absolute = baro_apply_calibration(tmp);
b_abs_handler();
}
}
if (baro_board.status == LBS_READING_TEMP &&
baro_trans.status != I2CTransPending && baro_trans.status != I2CTransRunning) {
baro_board.status = LBS_REQUEST;
if (baro_trans.status == I2CTransSuccess) {
// abuse differential to store temp in 0.1C for now
int32_t tmp = (baro_trans.buf[0] << 8) | baro_trans.buf[1];
int32_t x1 = ((tmp - calibration.ac6) * calibration.ac5) >> 15;
int32_t x2 = (calibration.mc << 11) / (x1 + calibration.md);
calibration.b5 = x1 + x2;
baro.differential = (calibration.b5 + 8) >> 4;
b_diff_handler();
}
}
}
#define BaroEvent(_b_abs_handler, _b_diff_handler) baro_event(_b_abs_handler,_b_diff_handler)
#endif /* BOARDS_LISA_M_BARO_H */
@@ -52,6 +52,7 @@
#include "sys_time.h"
#include "generated/flight_plan.h"
#include "datalink.h"
#include "subsystems/settings.h"
#include "xbee.h"
#include "gpio.h"
@@ -554,6 +555,8 @@ void init_ap( void ) {
modules_init();
settings_init();
/** - start interrupt task */
mcu_int_enable();
+9 -2
View File
@@ -24,7 +24,7 @@
#define LPC21IAP_VER_MAJ 1
#define LPC21IAP_VER_MIN 1
#define LPC21IAP_VER_MIN 2
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -156,9 +156,10 @@ int main(int argc, char *argv[])
tIntermediateBuffer* actBuf = NULL;
tIntermediateBuffer* startBuf = NULL;
printf("lpc21iap v%d.%d\n", LPC21IAP_VER_MAJ, LPC21IAP_VER_MIN);
if ((argc < 2) || (argc > 3))
{
printf("lpc21iap version v%d.%d, ", LPC21IAP_VER_MAJ, LPC21IAP_VER_MIN);
printf("usage: %s file.elf [usb_serial_number]\n", argv[0]);
exit(1);
}
@@ -353,6 +354,12 @@ int main(int argc, char *argv[])
exit(2);
}
/* flashing code: persistent settings needs highest sector to be erased */
if (highFlash >= BOOTLOAD_SECT*MAX_SECT)
{
highFlash = maxFlash-1;
}
/* anything to flash erase? */
if (lowFlash != maxFlash)
{