2019-2020 LPS22HH Altimeter Project
Dependencies: X_NUCLEO_IKS01A3
main.cpp@15:913ecebcc7ed, 2019-09-23 (annotated)
- Committer:
- martlefebvre94
- Date:
- Mon Sep 23 13:07:09 2019 +0000
- Revision:
- 15:913ecebcc7ed
- Parent:
- 14:abc98c6982b5
Sampling frequency -> Readout frequency
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cparata | 0:535249dc4bf5 | 1 | /** |
cparata | 0:535249dc4bf5 | 2 | ****************************************************************************** |
cparata | 0:535249dc4bf5 | 3 | * @file main.cpp |
cparata | 0:535249dc4bf5 | 4 | * @author SRA |
cparata | 0:535249dc4bf5 | 5 | * @version V1.0.0 |
cparata | 0:535249dc4bf5 | 6 | * @date 5-March-2019 |
cparata | 5:7c883cce2bc4 | 7 | * @brief Simple Example application for using the X_NUCLEO_IKS01A3 |
cparata | 0:535249dc4bf5 | 8 | * MEMS Inertial & Environmental Sensor Nucleo expansion board. |
cparata | 0:535249dc4bf5 | 9 | ****************************************************************************** |
cparata | 0:535249dc4bf5 | 10 | * @attention |
cparata | 0:535249dc4bf5 | 11 | * |
cparata | 0:535249dc4bf5 | 12 | * <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2> |
cparata | 0:535249dc4bf5 | 13 | * |
cparata | 0:535249dc4bf5 | 14 | * Redistribution and use in source and binary forms, with or without modification, |
cparata | 0:535249dc4bf5 | 15 | * are permitted provided that the following conditions are met: |
cparata | 0:535249dc4bf5 | 16 | * 1. Redistributions of source code must retain the above copyright notice, |
cparata | 0:535249dc4bf5 | 17 | * this list of conditions and the following disclaimer. |
cparata | 0:535249dc4bf5 | 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
cparata | 0:535249dc4bf5 | 19 | * this list of conditions and the following disclaimer in the documentation |
cparata | 0:535249dc4bf5 | 20 | * and/or other materials provided with the distribution. |
cparata | 0:535249dc4bf5 | 21 | * 3. Neither the name of STMicroelectronics nor the names of its contributors |
cparata | 0:535249dc4bf5 | 22 | * may be used to endorse or promote products derived from this software |
cparata | 0:535249dc4bf5 | 23 | * without specific prior written permission. |
cparata | 0:535249dc4bf5 | 24 | * |
cparata | 0:535249dc4bf5 | 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
cparata | 0:535249dc4bf5 | 26 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
cparata | 0:535249dc4bf5 | 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
cparata | 0:535249dc4bf5 | 28 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
cparata | 0:535249dc4bf5 | 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
cparata | 0:535249dc4bf5 | 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
cparata | 0:535249dc4bf5 | 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
cparata | 0:535249dc4bf5 | 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
cparata | 0:535249dc4bf5 | 33 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
cparata | 0:535249dc4bf5 | 34 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
cparata | 0:535249dc4bf5 | 35 | * |
cparata | 0:535249dc4bf5 | 36 | ****************************************************************************** |
cparata | 5:7c883cce2bc4 | 37 | */ |
cparata | 0:535249dc4bf5 | 38 | |
martlefebvre94 | 6:b2e247935342 | 39 | /* |
martlefebvre94 | 13:b97b8bc67d43 | 40 | LELEC2811 Altimeter LPS22HH Project |
martlefebvre94 | 13:b97b8bc67d43 | 41 | M. Lefebvre - 2019-2020 |
martlefebvre94 | 6:b2e247935342 | 42 | */ |
martlefebvre94 | 6:b2e247935342 | 43 | |
cparata | 0:535249dc4bf5 | 44 | /* Includes */ |
martlefebvre94 | 6:b2e247935342 | 45 | #include <stdlib.h> |
martlefebvre94 | 8:fa346d946e7e | 46 | #include <time.h> |
cparata | 0:535249dc4bf5 | 47 | #include "mbed.h" |
cparata | 0:535249dc4bf5 | 48 | #include "XNucleoIKS01A3.h" |
martlefebvre94 | 6:b2e247935342 | 49 | #include "stm32l073xx.h" |
martlefebvre94 | 6:b2e247935342 | 50 | #include "stm32l0xx_hal_flash.h" |
martlefebvre94 | 6:b2e247935342 | 51 | |
martlefebvre94 | 6:b2e247935342 | 52 | /* Defines */ |
martlefebvre94 | 15:913ecebcc7ed | 53 | #define FS 10.0 // Readout frequency (Hz) |
martlefebvre94 | 8:fa346d946e7e | 54 | |
martlefebvre94 | 8:fa346d946e7e | 55 | // LPS22HH Pressure sensor |
martlefebvre94 | 8:fa346d946e7e | 56 | #define P0 1013.26 // Sea level pressure (hPa) |
martlefebvre94 | 14:abc98c6982b5 | 57 | #define LPS22HH_ODR 10.0 // Output data rate (one-shot, 1, 10, 25, 50, 75, 100, 200 Hz) |
martlefebvre94 | 8:fa346d946e7e | 58 | #define LPS22HH_LOW_NOISE_EN 1 // Low-noise (0 disabled, 1 enabled) |
martlefebvre94 | 8:fa346d946e7e | 59 | #define LPS22HH_LPF_CFG 3 // Device bandwidth (0 for ODR/2, 2 for ODR/9, 3 for ODR/20) |
martlefebvre94 | 13:b97b8bc67d43 | 60 | #define LPS22HH_DATA_SIZE 8 // Number of bytes for LPS22HH pressure sensor data |
martlefebvre94 | 8:fa346d946e7e | 61 | |
martlefebvre94 | 8:fa346d946e7e | 62 | /* Functions definition */ |
martlefebvre94 | 8:fa346d946e7e | 63 | bool acquisition_task(bool verbose); |
martlefebvre94 | 8:fa346d946e7e | 64 | void read_task(); |
martlefebvre94 | 8:fa346d946e7e | 65 | void print_flash_info(); |
martlefebvre94 | 8:fa346d946e7e | 66 | bool erase_flash(bool verbose); |
martlefebvre94 | 8:fa346d946e7e | 67 | bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose); |
martlefebvre94 | 8:fa346d946e7e | 68 | void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes); |
martlefebvre94 | 8:fa346d946e7e | 69 | void button1_enabled_cb(void); |
martlefebvre94 | 8:fa346d946e7e | 70 | void button1_onpressed_cb(void); |
martlefebvre94 | 8:fa346d946e7e | 71 | static char *print_double(char *str, double v); |
martlefebvre94 | 8:fa346d946e7e | 72 | float pressure_to_altitude(double pressure); |
martlefebvre94 | 13:b97b8bc67d43 | 73 | uint32_t FloatToUint(float n); |
martlefebvre94 | 13:b97b8bc67d43 | 74 | float UintToFloat(uint32_t n); |
martlefebvre94 | 6:b2e247935342 | 75 | |
martlefebvre94 | 6:b2e247935342 | 76 | /* Serial link */ |
martlefebvre94 | 6:b2e247935342 | 77 | Serial pc(SERIAL_TX, SERIAL_RX); |
martlefebvre94 | 6:b2e247935342 | 78 | |
martlefebvre94 | 6:b2e247935342 | 79 | /* Button */ |
martlefebvre94 | 6:b2e247935342 | 80 | InterruptIn button1(USER_BUTTON); |
martlefebvre94 | 6:b2e247935342 | 81 | volatile bool button1_pressed = false; // Used in the main loop |
martlefebvre94 | 6:b2e247935342 | 82 | volatile bool button1_enabled = true; // Used for debouncing |
martlefebvre94 | 6:b2e247935342 | 83 | Timeout button1_timeout; // Used for debouncing |
cparata | 0:535249dc4bf5 | 84 | |
cparata | 0:535249dc4bf5 | 85 | /* Instantiate the expansion board */ |
cparata | 0:535249dc4bf5 | 86 | static XNucleoIKS01A3 *mems_expansion_board = XNucleoIKS01A3::instance(D14, D15, D4, D5, A3, D6, A4); |
cparata | 0:535249dc4bf5 | 87 | |
cparata | 0:535249dc4bf5 | 88 | /* Retrieve the composing elements of the expansion board */ |
cparata | 0:535249dc4bf5 | 89 | static LIS2MDLSensor *magnetometer = mems_expansion_board->magnetometer; |
cparata | 0:535249dc4bf5 | 90 | static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; |
cparata | 0:535249dc4bf5 | 91 | static LPS22HHSensor *press_temp = mems_expansion_board->pt_sensor; |
cparata | 0:535249dc4bf5 | 92 | static LSM6DSOSensor *acc_gyro = mems_expansion_board->acc_gyro; |
cparata | 0:535249dc4bf5 | 93 | static LIS2DW12Sensor *accelerometer = mems_expansion_board->accelerometer; |
cparata | 0:535249dc4bf5 | 94 | static STTS751Sensor *temp = mems_expansion_board->t_sensor; |
cparata | 0:535249dc4bf5 | 95 | |
martlefebvre94 | 8:fa346d946e7e | 96 | /* Main */ |
martlefebvre94 | 8:fa346d946e7e | 97 | int main() |
martlefebvre94 | 8:fa346d946e7e | 98 | { |
martlefebvre94 | 8:fa346d946e7e | 99 | uint8_t id; |
martlefebvre94 | 8:fa346d946e7e | 100 | float read_reg, read_reg_1; |
martlefebvre94 | 8:fa346d946e7e | 101 | uint8_t read_reg_int, read_reg_int_1, read_reg_int_2; |
martlefebvre94 | 8:fa346d946e7e | 102 | |
martlefebvre94 | 8:fa346d946e7e | 103 | bool save_data = false; |
martlefebvre94 | 8:fa346d946e7e | 104 | uint32_t Flash_addr = FLASH_BANK2_BASE; |
martlefebvre94 | 8:fa346d946e7e | 105 | |
martlefebvre94 | 8:fa346d946e7e | 106 | /* Serial link configuration */ |
martlefebvre94 | 8:fa346d946e7e | 107 | pc.baud(115200); |
martlefebvre94 | 8:fa346d946e7e | 108 | |
martlefebvre94 | 8:fa346d946e7e | 109 | /* Button configuration */ |
martlefebvre94 | 8:fa346d946e7e | 110 | button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event |
martlefebvre94 | 8:fa346d946e7e | 111 | |
martlefebvre94 | 8:fa346d946e7e | 112 | /* Reset message */ |
martlefebvre94 | 8:fa346d946e7e | 113 | printf("\n\r**************************************************\n\r"); |
martlefebvre94 | 13:b97b8bc67d43 | 114 | printf("LELEC2811 LPS22HH Altimeter Program\n\r"); |
martlefebvre94 | 8:fa346d946e7e | 115 | printf("**************************************************\n\r"); |
martlefebvre94 | 8:fa346d946e7e | 116 | |
martlefebvre94 | 8:fa346d946e7e | 117 | /* LPS22HH pressure sensor configuration */ |
martlefebvre94 | 8:fa346d946e7e | 118 | press_temp->enable(); |
martlefebvre94 | 8:fa346d946e7e | 119 | printf("/***** LPS22HH pressure sensor configuration *****/\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 120 | |
martlefebvre94 | 8:fa346d946e7e | 121 | press_temp->read_id(&id); |
martlefebvre94 | 8:fa346d946e7e | 122 | printf("LPS22HH pressure = 0x%X\r\n", id); |
martlefebvre94 | 8:fa346d946e7e | 123 | |
martlefebvre94 | 8:fa346d946e7e | 124 | press_temp->set_odr(LPS22HH_ODR, LPS22HH_LOW_NOISE_EN); |
martlefebvre94 | 8:fa346d946e7e | 125 | press_temp->get_odr(&read_reg, &read_reg_int); |
martlefebvre94 | 8:fa346d946e7e | 126 | printf("LPS22HH ODR = %1.1f [Hz]\r\n", read_reg); |
martlefebvre94 | 8:fa346d946e7e | 127 | printf("LPS22HH LOW_NOISE_EN = %1d\r\n", read_reg_int); |
martlefebvre94 | 8:fa346d946e7e | 128 | |
martlefebvre94 | 8:fa346d946e7e | 129 | press_temp->set_lpfp_cfg(LPS22HH_LPF_CFG); |
martlefebvre94 | 8:fa346d946e7e | 130 | press_temp->get_lpfp_cfg(&read_reg_int); |
martlefebvre94 | 8:fa346d946e7e | 131 | printf("LPS22HH LPF_CFG = %1d\r\n", read_reg_int); |
martlefebvre94 | 8:fa346d946e7e | 132 | |
martlefebvre94 | 8:fa346d946e7e | 133 | /* Print Flash memory information */ |
martlefebvre94 | 8:fa346d946e7e | 134 | print_flash_info(); |
martlefebvre94 | 8:fa346d946e7e | 135 | |
martlefebvre94 | 8:fa346d946e7e | 136 | /* Information for the user */ |
martlefebvre94 | 8:fa346d946e7e | 137 | printf("Press blue button to start data acquisition\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 138 | printf("Press 'R' to read previously measured data\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 139 | |
martlefebvre94 | 8:fa346d946e7e | 140 | /* Acquisition loop */ |
martlefebvre94 | 8:fa346d946e7e | 141 | while(1) { |
martlefebvre94 | 8:fa346d946e7e | 142 | // Start saving data when button is pushed |
martlefebvre94 | 8:fa346d946e7e | 143 | if (button1_pressed) { |
martlefebvre94 | 8:fa346d946e7e | 144 | button1_pressed = false; |
martlefebvre94 | 8:fa346d946e7e | 145 | save_data = true; |
martlefebvre94 | 8:fa346d946e7e | 146 | erase_flash(false); |
martlefebvre94 | 8:fa346d946e7e | 147 | printf("Acquiring data...\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 148 | printf("Press blue button to stop data acquisition\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 149 | Flash_addr = FLASH_BANK2_BASE; |
martlefebvre94 | 8:fa346d946e7e | 150 | } |
martlefebvre94 | 8:fa346d946e7e | 151 | |
martlefebvre94 | 8:fa346d946e7e | 152 | if (save_data) { |
martlefebvre94 | 8:fa346d946e7e | 153 | // Acquisition task |
martlefebvre94 | 13:b97b8bc67d43 | 154 | save_data = acquisition_task(false); |
martlefebvre94 | 8:fa346d946e7e | 155 | } |
martlefebvre94 | 8:fa346d946e7e | 156 | else { |
martlefebvre94 | 8:fa346d946e7e | 157 | // Read task |
martlefebvre94 | 8:fa346d946e7e | 158 | read_task(); |
martlefebvre94 | 8:fa346d946e7e | 159 | } |
martlefebvre94 | 8:fa346d946e7e | 160 | } |
martlefebvre94 | 8:fa346d946e7e | 161 | } |
martlefebvre94 | 8:fa346d946e7e | 162 | |
martlefebvre94 | 8:fa346d946e7e | 163 | /* Acquisition task */ |
martlefebvre94 | 8:fa346d946e7e | 164 | bool acquisition_task(bool verbose) |
martlefebvre94 | 8:fa346d946e7e | 165 | { |
martlefebvre94 | 13:b97b8bc67d43 | 166 | float pressure_value, alt_value; |
martlefebvre94 | 8:fa346d946e7e | 167 | |
martlefebvre94 | 8:fa346d946e7e | 168 | uint32_t buffer_size = FLASH_PAGE_SIZE/4; |
martlefebvre94 | 8:fa346d946e7e | 169 | uint32_t data_ind = 0; |
martlefebvre94 | 8:fa346d946e7e | 170 | uint32_t data_buffer[buffer_size]; |
martlefebvre94 | 8:fa346d946e7e | 171 | |
martlefebvre94 | 8:fa346d946e7e | 172 | uint32_t Flash_addr = FLASH_BANK2_BASE; |
martlefebvre94 | 8:fa346d946e7e | 173 | |
martlefebvre94 | 8:fa346d946e7e | 174 | while (Flash_addr <= FLASH_BANK2_END-FLASH_PAGE_SIZE+1) { |
martlefebvre94 | 8:fa346d946e7e | 175 | // Read sensors data |
martlefebvre94 | 8:fa346d946e7e | 176 | press_temp->get_pressure(&pressure_value); |
martlefebvre94 | 13:b97b8bc67d43 | 177 | alt_value = pressure_to_altitude(pressure_value); |
martlefebvre94 | 8:fa346d946e7e | 178 | |
martlefebvre94 | 13:b97b8bc67d43 | 179 | // Write page in Flash memory |
martlefebvre94 | 13:b97b8bc67d43 | 180 | if (data_ind >= buffer_size) { |
martlefebvre94 | 13:b97b8bc67d43 | 181 | write_flash(Flash_addr, &data_buffer[0], buffer_size, false); |
martlefebvre94 | 13:b97b8bc67d43 | 182 | Flash_addr += FLASH_PAGE_SIZE; |
martlefebvre94 | 13:b97b8bc67d43 | 183 | data_ind = 0; |
martlefebvre94 | 13:b97b8bc67d43 | 184 | } |
martlefebvre94 | 8:fa346d946e7e | 185 | |
martlefebvre94 | 13:b97b8bc67d43 | 186 | // Write data to buffer |
martlefebvre94 | 13:b97b8bc67d43 | 187 | data_buffer[data_ind] = FloatToUint(pressure_value); |
martlefebvre94 | 13:b97b8bc67d43 | 188 | data_buffer[data_ind+1] = FloatToUint(alt_value); |
martlefebvre94 | 13:b97b8bc67d43 | 189 | data_ind = data_ind+2; |
martlefebvre94 | 8:fa346d946e7e | 190 | |
martlefebvre94 | 8:fa346d946e7e | 191 | // Print data in terminal |
martlefebvre94 | 8:fa346d946e7e | 192 | if (verbose) { |
martlefebvre94 | 13:b97b8bc67d43 | 193 | printf("LPS22HH: [press/mbar] %1.6f, [alt/m] %1.6f\r\n", pressure_value, alt_value); |
martlefebvre94 | 8:fa346d946e7e | 194 | } |
martlefebvre94 | 8:fa346d946e7e | 195 | |
martlefebvre94 | 8:fa346d946e7e | 196 | // Wait for acquisition period |
martlefebvre94 | 8:fa346d946e7e | 197 | wait(1/FS); |
martlefebvre94 | 8:fa346d946e7e | 198 | |
martlefebvre94 | 8:fa346d946e7e | 199 | // Stop saving data when button is pushed |
martlefebvre94 | 8:fa346d946e7e | 200 | if (button1_pressed) { |
martlefebvre94 | 8:fa346d946e7e | 201 | button1_pressed = false; |
martlefebvre94 | 8:fa346d946e7e | 202 | // Save remaining data to Flash memory |
martlefebvre94 | 8:fa346d946e7e | 203 | write_flash(Flash_addr, &data_buffer[0], data_ind, false); |
martlefebvre94 | 8:fa346d946e7e | 204 | printf("Data acquisition stopped\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 205 | printf("Press 'R' to read the data\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 206 | return false; |
martlefebvre94 | 8:fa346d946e7e | 207 | } |
martlefebvre94 | 8:fa346d946e7e | 208 | } |
martlefebvre94 | 8:fa346d946e7e | 209 | printf("Data acquisition stopped\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 210 | printf("Press 'R' to read the data\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 211 | return false; |
martlefebvre94 | 8:fa346d946e7e | 212 | } |
martlefebvre94 | 8:fa346d946e7e | 213 | |
martlefebvre94 | 8:fa346d946e7e | 214 | /* Read task */ |
martlefebvre94 | 8:fa346d946e7e | 215 | void read_task() |
martlefebvre94 | 8:fa346d946e7e | 216 | { |
martlefebvre94 | 8:fa346d946e7e | 217 | char pc_input; |
martlefebvre94 | 13:b97b8bc67d43 | 218 | uint32_t Flash_rdata[2]; |
martlefebvre94 | 8:fa346d946e7e | 219 | bool flash_empty = false; |
martlefebvre94 | 8:fa346d946e7e | 220 | |
martlefebvre94 | 8:fa346d946e7e | 221 | // Read terminal input |
martlefebvre94 | 8:fa346d946e7e | 222 | if (pc.readable()) { |
martlefebvre94 | 8:fa346d946e7e | 223 | pc_input = pc.getc(); |
martlefebvre94 | 8:fa346d946e7e | 224 | } |
martlefebvre94 | 8:fa346d946e7e | 225 | else { |
martlefebvre94 | 8:fa346d946e7e | 226 | pc_input = ' '; |
martlefebvre94 | 8:fa346d946e7e | 227 | } |
martlefebvre94 | 8:fa346d946e7e | 228 | |
martlefebvre94 | 8:fa346d946e7e | 229 | // Read Flash memory if 'R' is pressed |
martlefebvre94 | 8:fa346d946e7e | 230 | if ((pc_input == 'r') || (pc_input == 'R')) { |
martlefebvre94 | 8:fa346d946e7e | 231 | // Data labels |
martlefebvre94 | 13:b97b8bc67d43 | 232 | printf("press\talt\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 233 | |
martlefebvre94 | 8:fa346d946e7e | 234 | // Read 1st Flash data |
martlefebvre94 | 8:fa346d946e7e | 235 | uint32_t Flash_addr_temp = FLASH_BANK2_BASE; |
martlefebvre94 | 13:b97b8bc67d43 | 236 | read_flash(Flash_addr_temp, &Flash_rdata[0], LPS22HH_DATA_SIZE); |
martlefebvre94 | 8:fa346d946e7e | 237 | |
martlefebvre94 | 8:fa346d946e7e | 238 | // Read Flash data |
martlefebvre94 | 13:b97b8bc67d43 | 239 | while ((Flash_addr_temp <= FLASH_BANK2_END-LPS22HH_DATA_SIZE+1) && !flash_empty) { |
martlefebvre94 | 8:fa346d946e7e | 240 | // Print read data in the terminal |
martlefebvre94 | 13:b97b8bc67d43 | 241 | printf("%1.6f\t%1.6f\r\n", UintToFloat(Flash_rdata[0]), UintToFloat(Flash_rdata[1])); |
martlefebvre94 | 13:b97b8bc67d43 | 242 | Flash_addr_temp += LPS22HH_DATA_SIZE; |
martlefebvre94 | 8:fa346d946e7e | 243 | |
martlefebvre94 | 8:fa346d946e7e | 244 | // Check if the next address is not empty (erased Flash only contains 0) |
martlefebvre94 | 13:b97b8bc67d43 | 245 | if (Flash_addr_temp <= FLASH_BANK2_END-LPS22HH_DATA_SIZE+1) { |
martlefebvre94 | 13:b97b8bc67d43 | 246 | read_flash(Flash_addr_temp, &Flash_rdata[0], LPS22HH_DATA_SIZE); |
martlefebvre94 | 13:b97b8bc67d43 | 247 | if ((Flash_rdata[0] == 0) && (Flash_rdata[1] == 0)) { |
martlefebvre94 | 8:fa346d946e7e | 248 | flash_empty = true; |
martlefebvre94 | 8:fa346d946e7e | 249 | } |
martlefebvre94 | 8:fa346d946e7e | 250 | } |
martlefebvre94 | 8:fa346d946e7e | 251 | } |
martlefebvre94 | 8:fa346d946e7e | 252 | } |
martlefebvre94 | 8:fa346d946e7e | 253 | } |
martlefebvre94 | 8:fa346d946e7e | 254 | |
martlefebvre94 | 8:fa346d946e7e | 255 | /* Print Flash memory info */ |
martlefebvre94 | 8:fa346d946e7e | 256 | void print_flash_info() |
martlefebvre94 | 8:fa346d946e7e | 257 | { |
martlefebvre94 | 8:fa346d946e7e | 258 | printf("**************************************************\n\r"); |
martlefebvre94 | 8:fa346d946e7e | 259 | printf("/***** Flash memory info *****/\r\n"); |
martlefebvre94 | 8:fa346d946e7e | 260 | printf("Flash size: %d [B]\r\n", FLASH_SIZE); |
martlefebvre94 | 8:fa346d946e7e | 261 | printf("Flash page size: %d [B]\r\n", FLASH_PAGE_SIZE); |
martlefebvre94 | 8:fa346d946e7e | 262 | printf("Flash nb of pages: %d \r\n", FLASH_SIZE/FLASH_PAGE_SIZE); |
martlefebvre94 | 8:fa346d946e7e | 263 | printf("Flash bank 1 base address: 0x%X\r\n", FLASH_BASE); |
martlefebvre94 | 8:fa346d946e7e | 264 | printf("Flash bank 1 end address: 0x%X\r\n", FLASH_BANK1_END); |
martlefebvre94 | 8:fa346d946e7e | 265 | printf("Flash bank 2 base address: 0x%X\r\n", FLASH_BANK2_BASE); |
martlefebvre94 | 8:fa346d946e7e | 266 | printf("Flash bank 2 end address: 0x%X\r\n", FLASH_BANK2_END); |
martlefebvre94 | 8:fa346d946e7e | 267 | printf("**************************************************\n\r"); |
martlefebvre94 | 8:fa346d946e7e | 268 | } |
martlefebvre94 | 8:fa346d946e7e | 269 | |
martlefebvre94 | 6:b2e247935342 | 270 | /* Erase content of Flash memory */ |
martlefebvre94 | 6:b2e247935342 | 271 | bool erase_flash(bool verbose) |
cparata | 0:535249dc4bf5 | 272 | { |
martlefebvre94 | 6:b2e247935342 | 273 | printf("Erasing Flash memory...\r\n"); |
martlefebvre94 | 6:b2e247935342 | 274 | |
martlefebvre94 | 6:b2e247935342 | 275 | // Unlock Flash memory |
martlefebvre94 | 6:b2e247935342 | 276 | HAL_FLASH_Unlock(); |
cparata | 0:535249dc4bf5 | 277 | |
martlefebvre94 | 6:b2e247935342 | 278 | // Erase Flash memory |
martlefebvre94 | 6:b2e247935342 | 279 | FLASH_EraseInitTypeDef eraser; |
martlefebvre94 | 6:b2e247935342 | 280 | uint32_t Flash_addr = FLASH_BANK2_BASE; |
martlefebvre94 | 6:b2e247935342 | 281 | uint32_t page_error = 0; |
martlefebvre94 | 6:b2e247935342 | 282 | int32_t page = 1; |
martlefebvre94 | 6:b2e247935342 | 283 | |
martlefebvre94 | 6:b2e247935342 | 284 | while (Flash_addr < FLASH_BANK2_END) { |
martlefebvre94 | 6:b2e247935342 | 285 | eraser.TypeErase = FLASH_TYPEERASE_PAGES; |
martlefebvre94 | 6:b2e247935342 | 286 | eraser.PageAddress = Flash_addr; |
martlefebvre94 | 6:b2e247935342 | 287 | eraser.NbPages = 1; |
martlefebvre94 | 6:b2e247935342 | 288 | if(HAL_OK != HAL_FLASHEx_Erase(&eraser, &page_error)) { |
martlefebvre94 | 6:b2e247935342 | 289 | if (verbose) {printf("Flash erase failed!\r\n");} |
martlefebvre94 | 6:b2e247935342 | 290 | printf("Error 0x%X\r\n", page_error); |
martlefebvre94 | 6:b2e247935342 | 291 | HAL_FLASH_Lock(); |
martlefebvre94 | 6:b2e247935342 | 292 | return false; |
martlefebvre94 | 6:b2e247935342 | 293 | } |
martlefebvre94 | 6:b2e247935342 | 294 | if (verbose) {printf("Erased page %d at address: 0x%X\r\n", page, Flash_addr);} |
martlefebvre94 | 6:b2e247935342 | 295 | Flash_addr += FLASH_PAGE_SIZE; |
martlefebvre94 | 6:b2e247935342 | 296 | page++; |
martlefebvre94 | 6:b2e247935342 | 297 | } |
martlefebvre94 | 6:b2e247935342 | 298 | |
martlefebvre94 | 6:b2e247935342 | 299 | if (verbose) {printf("Flash erase succesful!\r\n");} |
martlefebvre94 | 6:b2e247935342 | 300 | return true; |
martlefebvre94 | 6:b2e247935342 | 301 | } |
cparata | 0:535249dc4bf5 | 302 | |
martlefebvre94 | 6:b2e247935342 | 303 | /* Write Flash memory */ |
martlefebvre94 | 8:fa346d946e7e | 304 | bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose) |
martlefebvre94 | 6:b2e247935342 | 305 | { |
martlefebvre94 | 8:fa346d946e7e | 306 | clock_t time; |
martlefebvre94 | 8:fa346d946e7e | 307 | if (verbose) {time = clock();} |
martlefebvre94 | 8:fa346d946e7e | 308 | |
martlefebvre94 | 6:b2e247935342 | 309 | // Unlock Flash memory |
martlefebvre94 | 6:b2e247935342 | 310 | HAL_FLASH_Unlock(); |
martlefebvre94 | 6:b2e247935342 | 311 | |
martlefebvre94 | 6:b2e247935342 | 312 | // Write Flash memory |
martlefebvre94 | 8:fa346d946e7e | 313 | for (int i=0; i<n_words; i++) { |
martlefebvre94 | 8:fa346d946e7e | 314 | if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Flash_addr, Flash_wdata[i])) { |
martlefebvre94 | 8:fa346d946e7e | 315 | if (verbose) {printf("Flash write failed!\r\n");} |
martlefebvre94 | 8:fa346d946e7e | 316 | HAL_FLASH_Lock(); |
martlefebvre94 | 8:fa346d946e7e | 317 | return false; |
martlefebvre94 | 8:fa346d946e7e | 318 | } |
martlefebvre94 | 8:fa346d946e7e | 319 | Flash_addr += 4; |
martlefebvre94 | 6:b2e247935342 | 320 | } |
martlefebvre94 | 6:b2e247935342 | 321 | if (verbose) {printf("Flash write succesful!\r\n");} |
martlefebvre94 | 8:fa346d946e7e | 322 | |
martlefebvre94 | 6:b2e247935342 | 323 | HAL_FLASH_Lock(); |
martlefebvre94 | 8:fa346d946e7e | 324 | |
martlefebvre94 | 8:fa346d946e7e | 325 | if (verbose) { |
martlefebvre94 | 8:fa346d946e7e | 326 | time = clock() - time; |
martlefebvre94 | 8:fa346d946e7e | 327 | printf("Time to write: %1.6f [s]\r\n", (((double) time)/CLOCKS_PER_SEC)); |
martlefebvre94 | 8:fa346d946e7e | 328 | } |
martlefebvre94 | 8:fa346d946e7e | 329 | |
martlefebvre94 | 6:b2e247935342 | 330 | return true; |
martlefebvre94 | 6:b2e247935342 | 331 | } |
cparata | 0:535249dc4bf5 | 332 | |
martlefebvre94 | 6:b2e247935342 | 333 | /* Read Flash memory */ |
martlefebvre94 | 6:b2e247935342 | 334 | void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes) |
martlefebvre94 | 6:b2e247935342 | 335 | { |
martlefebvre94 | 6:b2e247935342 | 336 | memcpy(Flash_rdata, (uint32_t*) Flash_addr, n_bytes); |
martlefebvre94 | 6:b2e247935342 | 337 | } |
cparata | 0:535249dc4bf5 | 338 | |
martlefebvre94 | 6:b2e247935342 | 339 | /* Enables button when bouncing is over */ |
martlefebvre94 | 6:b2e247935342 | 340 | void button1_enabled_cb(void) |
martlefebvre94 | 6:b2e247935342 | 341 | { |
martlefebvre94 | 6:b2e247935342 | 342 | button1_enabled = true; |
cparata | 0:535249dc4bf5 | 343 | } |
cparata | 0:535249dc4bf5 | 344 | |
martlefebvre94 | 6:b2e247935342 | 345 | /* ISR handling button pressed event */ |
martlefebvre94 | 6:b2e247935342 | 346 | void button1_onpressed_cb(void) |
martlefebvre94 | 6:b2e247935342 | 347 | { |
martlefebvre94 | 6:b2e247935342 | 348 | if (button1_enabled) { // Disabled while the button is bouncing |
martlefebvre94 | 6:b2e247935342 | 349 | button1_enabled = false; |
martlefebvre94 | 6:b2e247935342 | 350 | button1_pressed = true; // To be read by the main loop |
martlefebvre94 | 6:b2e247935342 | 351 | button1_timeout.attach(callback(button1_enabled_cb), 0.3); // Debounce time 300 ms |
martlefebvre94 | 6:b2e247935342 | 352 | } |
martlefebvre94 | 6:b2e247935342 | 353 | } |
martlefebvre94 | 6:b2e247935342 | 354 | |
martlefebvre94 | 8:fa346d946e7e | 355 | /* Helper function for printing floats & doubles */ |
martlefebvre94 | 8:fa346d946e7e | 356 | static char *print_double(char *str, double v) |
martlefebvre94 | 6:b2e247935342 | 357 | { |
martlefebvre94 | 8:fa346d946e7e | 358 | int decimalDigits = 6; |
martlefebvre94 | 8:fa346d946e7e | 359 | int i = 1; |
martlefebvre94 | 8:fa346d946e7e | 360 | int intPart, fractPart; |
martlefebvre94 | 8:fa346d946e7e | 361 | int len; |
martlefebvre94 | 8:fa346d946e7e | 362 | char *ptr; |
martlefebvre94 | 8:fa346d946e7e | 363 | |
martlefebvre94 | 8:fa346d946e7e | 364 | /* prepare decimal digits multiplicator */ |
martlefebvre94 | 8:fa346d946e7e | 365 | for (; decimalDigits != 0; i *= 10, decimalDigits--); |
martlefebvre94 | 8:fa346d946e7e | 366 | |
martlefebvre94 | 8:fa346d946e7e | 367 | /* calculate integer & fractinal parts */ |
martlefebvre94 | 8:fa346d946e7e | 368 | intPart = (int)v; |
martlefebvre94 | 8:fa346d946e7e | 369 | fractPart = (int)((v - (double)(int)v) * i); |
martlefebvre94 | 8:fa346d946e7e | 370 | |
martlefebvre94 | 8:fa346d946e7e | 371 | /* fill in integer part */ |
martlefebvre94 | 8:fa346d946e7e | 372 | sprintf(str, "%i.", intPart); |
martlefebvre94 | 8:fa346d946e7e | 373 | |
martlefebvre94 | 8:fa346d946e7e | 374 | /* prepare fill in of fractional part */ |
martlefebvre94 | 8:fa346d946e7e | 375 | len = strlen(str); |
martlefebvre94 | 8:fa346d946e7e | 376 | ptr = &str[len]; |
martlefebvre94 | 8:fa346d946e7e | 377 | |
martlefebvre94 | 8:fa346d946e7e | 378 | /* fill in leading fractional zeros */ |
martlefebvre94 | 8:fa346d946e7e | 379 | for (i /= 10; i > 1; i /= 10, ptr++) { |
martlefebvre94 | 8:fa346d946e7e | 380 | if (fractPart >= i) { |
martlefebvre94 | 8:fa346d946e7e | 381 | break; |
martlefebvre94 | 6:b2e247935342 | 382 | } |
martlefebvre94 | 8:fa346d946e7e | 383 | *ptr = '0'; |
martlefebvre94 | 6:b2e247935342 | 384 | } |
martlefebvre94 | 6:b2e247935342 | 385 | |
martlefebvre94 | 8:fa346d946e7e | 386 | /* fill in (rest of) fractional part */ |
martlefebvre94 | 8:fa346d946e7e | 387 | sprintf(ptr, "%i", fractPart); |
martlefebvre94 | 8:fa346d946e7e | 388 | |
martlefebvre94 | 8:fa346d946e7e | 389 | return str; |
martlefebvre94 | 6:b2e247935342 | 390 | } |
martlefebvre94 | 6:b2e247935342 | 391 | |
martlefebvre94 | 8:fa346d946e7e | 392 | /* Pressure to altitude conversion */ |
martlefebvre94 | 8:fa346d946e7e | 393 | float pressure_to_altitude(double pressure) |
cparata | 5:7c883cce2bc4 | 394 | { |
martlefebvre94 | 8:fa346d946e7e | 395 | return 44330.77 * (1-pow(pressure/P0, 0.1902632)); |
martlefebvre94 | 8:fa346d946e7e | 396 | } |
martlefebvre94 | 13:b97b8bc67d43 | 397 | |
martlefebvre94 | 13:b97b8bc67d43 | 398 | uint32_t FloatToUint(float n) |
martlefebvre94 | 13:b97b8bc67d43 | 399 | { |
martlefebvre94 | 13:b97b8bc67d43 | 400 | return (uint32_t)(*(uint32_t*)&n); |
martlefebvre94 | 13:b97b8bc67d43 | 401 | } |
martlefebvre94 | 13:b97b8bc67d43 | 402 | |
martlefebvre94 | 13:b97b8bc67d43 | 403 | float UintToFloat(uint32_t n) |
martlefebvre94 | 13:b97b8bc67d43 | 404 | { |
martlefebvre94 | 13:b97b8bc67d43 | 405 | return (float)(*(float*)&n); |
martlefebvre94 | 13:b97b8bc67d43 | 406 | } |