diff --git a/conf/airframes/Poine/test_settings.xml b/conf/airframes/Poine/test_settings.xml index 72186562de..644d4e99a7 100644 --- a/conf/airframes/Poine/test_settings.xml +++ b/conf/airframes/Poine/test_settings.xml @@ -7,6 +7,8 @@ test settings + + diff --git a/conf/airframes/mm/extra/probe_t.xml b/conf/airframes/mm/extra/probe_t.xml index b9120d8065..217b5f9bbd 100644 --- a/conf/airframes/mm/extra/probe_t.xml +++ b/conf/airframes/mm/extra/probe_t.xml @@ -14,14 +14,10 @@ - - - + - - - + diff --git a/conf/airframes/mm/extra/turbine_trigger.xml b/conf/airframes/mm/extra/turbine_trigger.xml index c02889cc5d..91c6cad9a1 100644 --- a/conf/airframes/mm/extra/turbine_trigger.xml +++ b/conf/airframes/mm/extra/turbine_trigger.xml @@ -7,14 +7,10 @@ - - - + - - - + diff --git a/conf/airframes/mm/fixed-wing/funjetmm.xml b/conf/airframes/mm/fixed-wing/funjetmm.xml index aaef743332..7249478bc8 100644 --- a/conf/airframes/mm/fixed-wing/funjetmm.xml +++ b/conf/airframes/mm/fixed-wing/funjetmm.xml @@ -10,12 +10,14 @@ + + + + + + + - - - - - @@ -25,30 +27,22 @@ - - - - - - - - + - - - + + @@ -60,16 +54,14 @@ - - diff --git a/conf/airframes/mm/fixed-wing/fw_ins_arduimu.xml b/conf/airframes/mm/fixed-wing/fw_ins_arduimu.xml index ced804cc9e..144fa3b68f 100644 --- a/conf/airframes/mm/fixed-wing/fw_ins_arduimu.xml +++ b/conf/airframes/mm/fixed-wing/fw_ins_arduimu.xml @@ -29,17 +29,13 @@ - - - + - - - + diff --git a/conf/autopilot/subsystems/fixedwing/autopilot.makefile b/conf/autopilot/subsystems/fixedwing/autopilot.makefile index 3079875f97..2faf78d71e 100644 --- a/conf/autopilot/subsystems/fixedwing/autopilot.makefile +++ b/conf/autopilot/subsystems/fixedwing/autopilot.makefile @@ -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 diff --git a/conf/settings/settings_test.xml b/conf/settings/settings_test.xml index d23db3776a..782c62fc1b 100644 --- a/conf/settings/settings_test.xml +++ b/conf/settings/settings_test.xml @@ -7,7 +7,7 @@ - + diff --git a/conf/settings/tuning_pers.xml b/conf/settings/tuning_pers.xml new file mode 100644 index 0000000000..28ee45a89f --- /dev/null +++ b/conf/settings/tuning_pers.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sw/airborne/arch/lpc21/LPC2148-ROM-bl.ld b/sw/airborne/arch/lpc21/LPC2148-ROM-bl.ld index 625af790cd..730c1632e3 100644 --- a/sw/airborne/arch/lpc21/LPC2148-ROM-bl.ld +++ b/sw/airborne/arch/lpc21/LPC2148-ROM-bl.ld @@ -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 */ diff --git a/sw/airborne/arch/lpc21/subsystems/settings_arch.c b/sw/airborne/arch/lpc21/subsystems/settings_arch.c index 517749b900..c493cb6521 100644 --- a/sw/airborne/arch/lpc21/subsystems/settings_arch.c +++ b/sw/airborne/arch/lpc21/subsystems/settings_arch.c @@ -1,10 +1,272 @@ +/* + * Paparazzi persistent settings low level flash routines lpc21 + * + * Copyright (C) 2011 Martin Mueller + * + * 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; ipage_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; ipage_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; iaddr+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 + * + * 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 */ diff --git a/sw/airborne/arch/sim/subsystems/settings_arch.c b/sw/airborne/arch/sim/subsystems/settings_arch.c index 517749b900..1ed8a6a601 100644 --- a/sw/airborne/arch/sim/subsystems/settings_arch.c +++ b/sw/airborne/arch/sim/subsystems/settings_arch.c @@ -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; } diff --git a/sw/airborne/arch/stm32/stm32f103rb_flash.ld b/sw/airborne/arch/stm32/stm32f103rb_flash.ld index 7e1575e460..95181a8db5 100644 --- a/sw/airborne/arch/stm32/stm32f103rb_flash.ld +++ b/sw/airborne/arch/stm32/stm32f103rb_flash.ld @@ -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 } diff --git a/sw/airborne/arch/stm32/stm32f103re_flash.ld b/sw/airborne/arch/stm32/stm32f103re_flash.ld index 3df6455c4c..94fcdbdbd3 100644 --- a/sw/airborne/arch/stm32/stm32f103re_flash.ld +++ b/sw/airborne/arch/stm32/stm32f103re_flash.ld @@ -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 } diff --git a/sw/airborne/arch/stm32/subsystems/settings_arch.c b/sw/airborne/arch/stm32/subsystems/settings_arch.c index d25d80c1f6..ee5f21a598 100644 --- a/sw/airborne/arch/stm32/subsystems/settings_arch.c +++ b/sw/airborne/arch/stm32/subsystems/settings_arch.c @@ -1,5 +1,41 @@ +/* + * Paparazzi persistent settings low level flash routines stm32 + * + * Copyright (C) 2011 Martin Mueller + * + * 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 #include #include @@ -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; ipage_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; iaddr+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 * @@ -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 diff --git a/sw/airborne/boards/lisa_m/baro_board.c b/sw/airborne/boards/lisa_m/baro_board.c index 4d87ea5003..8e686c004e 100644 --- a/sw/airborne/boards/lisa_m/baro_board.c +++ b/sw/airborne/boards/lisa_m/baro_board.c @@ -1,26 +1,16 @@ #include "subsystems/sensors/baro.h" +#include 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 } diff --git a/sw/airborne/boards/lisa_m/baro_board.h b/sw/airborne/boards/lisa_m/baro_board.h index 374f9d30ae..cbe3454983 100644 --- a/sw/airborne/boards/lisa_m/baro_board.h +++ b/sw/airborne/boards/lisa_m/baro_board.h @@ -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 */ diff --git a/sw/airborne/firmwares/fixedwing/main_ap.c b/sw/airborne/firmwares/fixedwing/main_ap.c index af661982f7..3049849fbc 100644 --- a/sw/airborne/firmwares/fixedwing/main_ap.c +++ b/sw/airborne/firmwares/fixedwing/main_ap.c @@ -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(); diff --git a/sw/ground_segment/lpc21iap/lpc21iap.c b/sw/ground_segment/lpc21iap/lpc21iap.c index 26dbd652a4..9cd73ff3be 100644 --- a/sw/ground_segment/lpc21iap/lpc21iap.c +++ b/sw/ground_segment/lpc21iap/lpc21iap.c @@ -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) {