2019-2020 LIS2MDL Magnetometer Project
Dependencies: X_NUCLEO_IKS01A3
main.cpp@11:b16d3b1a061e, 2019-09-30 (annotated)
- Committer:
- martlefebvre94
- Date:
- Mon Sep 30 22:14:36 2019 +0000
- Revision:
- 11:b16d3b1a061e
- Parent:
- 10:0f471469279a
Modification of the Flash data acquisition
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 | 6:b2e247935342 | 40 | LELEC2811 Magnetometer LIS2MDL Project |
martlefebvre94 | 9:1534c762ca3b | 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> |
cparata | 0:535249dc4bf5 | 46 | #include "mbed.h" |
cparata | 0:535249dc4bf5 | 47 | #include "XNucleoIKS01A3.h" |
martlefebvre94 | 6:b2e247935342 | 48 | #include "stm32l073xx.h" |
martlefebvre94 | 6:b2e247935342 | 49 | #include "stm32l0xx_hal_flash.h" |
martlefebvre94 | 6:b2e247935342 | 50 | |
martlefebvre94 | 6:b2e247935342 | 51 | /* Defines */ |
martlefebvre94 | 11:b16d3b1a061e | 52 | #define FS 5.0 // Readout frequency (Hz) - /!\ Must be below 100Hz |
martlefebvre94 | 11:b16d3b1a061e | 53 | #define FLASH_WRITE_TIME 0.00328 // Flash write time (s) |
martlefebvre94 | 8:5e9de5729ef6 | 54 | |
martlefebvre94 | 11:b16d3b1a061e | 55 | #define LIS2MDL_ODR 20.0 // Output data rate (10, 20, 50 or 100 Hz) |
martlefebvre94 | 11:b16d3b1a061e | 56 | #define LIS2MDL_LP 1 // Power mode (0 for high-resolution mode, 1 for low-power mode) |
martlefebvre94 | 7:4a3b6202963e | 57 | #define LIS2MDL_LPF 0 // Bandwidth (0 for ODR/2, 1 for ODR/4) |
martlefebvre94 | 7:4a3b6202963e | 58 | #define LIS2MDL_COMP_TEMP_EN 1 // Temperature compensation (0 disabled, 1 enabled) |
martlefebvre94 | 11:b16d3b1a061e | 59 | #define LIS2MDL_OFF_CANC 0 // Offset cancellation (0 disabled, 1 enabled, 2 for set pulse only at power-on) |
martlefebvre94 | 8:5e9de5729ef6 | 60 | #define LIS2MDL_DATA_SIZE 12 // Number of bytes for LIS2MDL magnetometer data |
martlefebvre94 | 8:5e9de5729ef6 | 61 | |
martlefebvre94 | 11:b16d3b1a061e | 62 | #define TS (1/FS)-((LIS2MDL_DATA_SIZE/4)*FLASH_WRITE_TIME) |
martlefebvre94 | 11:b16d3b1a061e | 63 | |
martlefebvre94 | 8:5e9de5729ef6 | 64 | /* Functions definition */ |
martlefebvre94 | 8:5e9de5729ef6 | 65 | bool acquisition_task(bool verbose); |
martlefebvre94 | 8:5e9de5729ef6 | 66 | void read_task(); |
martlefebvre94 | 8:5e9de5729ef6 | 67 | void print_flash_info(); |
martlefebvre94 | 8:5e9de5729ef6 | 68 | bool erase_flash(bool verbose); |
martlefebvre94 | 8:5e9de5729ef6 | 69 | bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose); |
martlefebvre94 | 8:5e9de5729ef6 | 70 | void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes); |
martlefebvre94 | 8:5e9de5729ef6 | 71 | void button1_enabled_cb(void); |
martlefebvre94 | 8:5e9de5729ef6 | 72 | void button1_onpressed_cb(void); |
martlefebvre94 | 9:1534c762ca3b | 73 | static char *print_double(char *str, double v); |
martlefebvre94 | 9:1534c762ca3b | 74 | uint32_t FloatToUint(float n); |
martlefebvre94 | 9:1534c762ca3b | 75 | float UintToFloat(uint32_t n); |
martlefebvre94 | 6:b2e247935342 | 76 | |
martlefebvre94 | 6:b2e247935342 | 77 | /* Serial link */ |
martlefebvre94 | 6:b2e247935342 | 78 | Serial pc(SERIAL_TX, SERIAL_RX); |
martlefebvre94 | 6:b2e247935342 | 79 | |
martlefebvre94 | 6:b2e247935342 | 80 | /* Button */ |
martlefebvre94 | 6:b2e247935342 | 81 | InterruptIn button1(USER_BUTTON); |
martlefebvre94 | 6:b2e247935342 | 82 | volatile bool button1_pressed = false; // Used in the main loop |
martlefebvre94 | 6:b2e247935342 | 83 | volatile bool button1_enabled = true; // Used for debouncing |
martlefebvre94 | 6:b2e247935342 | 84 | Timeout button1_timeout; // Used for debouncing |
cparata | 0:535249dc4bf5 | 85 | |
cparata | 0:535249dc4bf5 | 86 | /* Instantiate the expansion board */ |
cparata | 0:535249dc4bf5 | 87 | static XNucleoIKS01A3 *mems_expansion_board = XNucleoIKS01A3::instance(D14, D15, D4, D5, A3, D6, A4); |
cparata | 0:535249dc4bf5 | 88 | |
cparata | 0:535249dc4bf5 | 89 | /* Retrieve the composing elements of the expansion board */ |
cparata | 0:535249dc4bf5 | 90 | static LIS2MDLSensor *magnetometer = mems_expansion_board->magnetometer; |
cparata | 0:535249dc4bf5 | 91 | static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; |
cparata | 0:535249dc4bf5 | 92 | static LPS22HHSensor *press_temp = mems_expansion_board->pt_sensor; |
cparata | 0:535249dc4bf5 | 93 | static LSM6DSOSensor *acc_gyro = mems_expansion_board->acc_gyro; |
cparata | 0:535249dc4bf5 | 94 | static LIS2DW12Sensor *accelerometer = mems_expansion_board->accelerometer; |
cparata | 0:535249dc4bf5 | 95 | static STTS751Sensor *temp = mems_expansion_board->t_sensor; |
cparata | 0:535249dc4bf5 | 96 | |
martlefebvre94 | 6:b2e247935342 | 97 | /* Main */ |
cparata | 5:7c883cce2bc4 | 98 | int main() |
cparata | 5:7c883cce2bc4 | 99 | { |
cparata | 5:7c883cce2bc4 | 100 | uint8_t id; |
martlefebvre94 | 6:b2e247935342 | 101 | float read_reg; |
martlefebvre94 | 6:b2e247935342 | 102 | uint8_t read_reg_int; |
martlefebvre94 | 6:b2e247935342 | 103 | |
martlefebvre94 | 6:b2e247935342 | 104 | bool save_data = false; |
martlefebvre94 | 6:b2e247935342 | 105 | uint32_t Flash_addr = FLASH_BANK2_BASE; |
cparata | 5:7c883cce2bc4 | 106 | |
martlefebvre94 | 6:b2e247935342 | 107 | /* Serial link configuration */ |
martlefebvre94 | 6:b2e247935342 | 108 | pc.baud(115200); |
martlefebvre94 | 6:b2e247935342 | 109 | |
martlefebvre94 | 6:b2e247935342 | 110 | /* Button configuration */ |
martlefebvre94 | 6:b2e247935342 | 111 | button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event |
martlefebvre94 | 6:b2e247935342 | 112 | |
martlefebvre94 | 8:5e9de5729ef6 | 113 | /* Reset message */ |
martlefebvre94 | 6:b2e247935342 | 114 | printf("\n\r**************************************************\n\r"); |
martlefebvre94 | 6:b2e247935342 | 115 | printf("LELEC2811 LIS2MDL Magnetometer Program\n\r"); |
martlefebvre94 | 6:b2e247935342 | 116 | printf("**************************************************\n\r"); |
martlefebvre94 | 6:b2e247935342 | 117 | |
martlefebvre94 | 6:b2e247935342 | 118 | /* LIS2MDL magnetometer sensor configuration */ |
martlefebvre94 | 8:5e9de5729ef6 | 119 | magnetometer->enable(); |
martlefebvre94 | 6:b2e247935342 | 120 | printf("/***** LIS2MDL magnetometer configuration *****/\r\n"); |
martlefebvre94 | 6:b2e247935342 | 121 | |
martlefebvre94 | 6:b2e247935342 | 122 | magnetometer->read_id(&id); |
martlefebvre94 | 6:b2e247935342 | 123 | printf("LIS2MDL magnetometer = 0x%X\r\n", id); |
martlefebvre94 | 6:b2e247935342 | 124 | |
martlefebvre94 | 6:b2e247935342 | 125 | magnetometer->set_m_odr(LIS2MDL_ODR); |
martlefebvre94 | 6:b2e247935342 | 126 | magnetometer->get_m_odr(&read_reg); |
martlefebvre94 | 6:b2e247935342 | 127 | printf("LIS2MDL ODR = %1.1f [Hz]\r\n", read_reg); |
martlefebvre94 | 6:b2e247935342 | 128 | |
martlefebvre94 | 6:b2e247935342 | 129 | magnetometer->set_m_lp(LIS2MDL_LP); |
martlefebvre94 | 6:b2e247935342 | 130 | magnetometer->get_m_lp(&read_reg_int); |
martlefebvre94 | 6:b2e247935342 | 131 | printf("LIS2MDL LP = %1d\r\n", read_reg_int); |
martlefebvre94 | 6:b2e247935342 | 132 | |
martlefebvre94 | 6:b2e247935342 | 133 | magnetometer->set_m_lpf(LIS2MDL_LPF); |
martlefebvre94 | 6:b2e247935342 | 134 | magnetometer->get_m_lpf(&read_reg_int); |
martlefebvre94 | 6:b2e247935342 | 135 | printf("LIS2MDL LPF = %1d\r\n", read_reg_int); |
martlefebvre94 | 6:b2e247935342 | 136 | |
martlefebvre94 | 7:4a3b6202963e | 137 | magnetometer->set_m_comp_temp_en(LIS2MDL_COMP_TEMP_EN); |
martlefebvre94 | 7:4a3b6202963e | 138 | magnetometer->get_m_comp_temp_en(&read_reg_int); |
martlefebvre94 | 7:4a3b6202963e | 139 | printf("LIS2MDL COMP_TEMP_EN = %1d\r\n", read_reg_int); |
martlefebvre94 | 7:4a3b6202963e | 140 | |
martlefebvre94 | 7:4a3b6202963e | 141 | magnetometer->set_m_off_canc(LIS2MDL_OFF_CANC); |
martlefebvre94 | 7:4a3b6202963e | 142 | magnetometer->get_m_off_canc(&read_reg_int); |
martlefebvre94 | 7:4a3b6202963e | 143 | printf("LIS2MDL OFF_CANC = %1d\r\n", read_reg_int); |
martlefebvre94 | 7:4a3b6202963e | 144 | |
martlefebvre94 | 6:b2e247935342 | 145 | /* Print Flash memory information */ |
martlefebvre94 | 6:b2e247935342 | 146 | print_flash_info(); |
martlefebvre94 | 6:b2e247935342 | 147 | |
martlefebvre94 | 6:b2e247935342 | 148 | /* Information for the user */ |
martlefebvre94 | 6:b2e247935342 | 149 | printf("Press blue button to start data acquisition\r\n"); |
martlefebvre94 | 6:b2e247935342 | 150 | printf("Press 'R' to read previously measured data\r\n"); |
martlefebvre94 | 6:b2e247935342 | 151 | |
martlefebvre94 | 6:b2e247935342 | 152 | /* Acquisition loop */ |
martlefebvre94 | 6:b2e247935342 | 153 | while(1) { |
martlefebvre94 | 6:b2e247935342 | 154 | // Start saving data when button is pushed |
martlefebvre94 | 6:b2e247935342 | 155 | if (button1_pressed) { |
martlefebvre94 | 6:b2e247935342 | 156 | button1_pressed = false; |
martlefebvre94 | 6:b2e247935342 | 157 | save_data = true; |
martlefebvre94 | 6:b2e247935342 | 158 | erase_flash(false); |
martlefebvre94 | 6:b2e247935342 | 159 | printf("Acquiring data...\r\n"); |
martlefebvre94 | 6:b2e247935342 | 160 | printf("Press blue button to stop data acquisition\r\n"); |
martlefebvre94 | 8:5e9de5729ef6 | 161 | Flash_addr = FLASH_BANK2_BASE; |
martlefebvre94 | 6:b2e247935342 | 162 | } |
martlefebvre94 | 6:b2e247935342 | 163 | |
martlefebvre94 | 6:b2e247935342 | 164 | if (save_data) { |
martlefebvre94 | 6:b2e247935342 | 165 | // Acquisition task |
martlefebvre94 | 8:5e9de5729ef6 | 166 | save_data = acquisition_task(false); |
martlefebvre94 | 6:b2e247935342 | 167 | } |
martlefebvre94 | 6:b2e247935342 | 168 | else { |
martlefebvre94 | 6:b2e247935342 | 169 | // Read task |
martlefebvre94 | 6:b2e247935342 | 170 | read_task(); |
martlefebvre94 | 6:b2e247935342 | 171 | } |
cparata | 5:7c883cce2bc4 | 172 | } |
martlefebvre94 | 8:5e9de5729ef6 | 173 | } |
martlefebvre94 | 8:5e9de5729ef6 | 174 | |
martlefebvre94 | 8:5e9de5729ef6 | 175 | /* Acquisition task */ |
martlefebvre94 | 8:5e9de5729ef6 | 176 | bool acquisition_task(bool verbose) |
martlefebvre94 | 8:5e9de5729ef6 | 177 | { |
martlefebvre94 | 8:5e9de5729ef6 | 178 | uint32_t Flash_addr = FLASH_BANK2_BASE; |
martlefebvre94 | 8:5e9de5729ef6 | 179 | int32_t m_axes[3]; |
martlefebvre94 | 8:5e9de5729ef6 | 180 | |
martlefebvre94 | 8:5e9de5729ef6 | 181 | while (Flash_addr <= FLASH_BANK2_END-FLASH_PAGE_SIZE+1) { |
martlefebvre94 | 8:5e9de5729ef6 | 182 | // Read magnetometer data |
martlefebvre94 | 8:5e9de5729ef6 | 183 | magnetometer->get_m_axes(m_axes); |
martlefebvre94 | 8:5e9de5729ef6 | 184 | |
martlefebvre94 | 11:b16d3b1a061e | 185 | // Write page in Flash memory |
martlefebvre94 | 11:b16d3b1a061e | 186 | write_flash(Flash_addr, (uint32_t*) &m_axes[0], 3, false); |
martlefebvre94 | 11:b16d3b1a061e | 187 | Flash_addr += LIS2MDL_DATA_SIZE; |
martlefebvre94 | 8:5e9de5729ef6 | 188 | |
martlefebvre94 | 8:5e9de5729ef6 | 189 | // Print data in terminal |
martlefebvre94 | 8:5e9de5729ef6 | 190 | if (verbose) { |
martlefebvre94 | 8:5e9de5729ef6 | 191 | printf("LIS2MDL [mag/mgauss]: %6d, %6d, %6d\r\n", ((uint32_t) m_axes[0]), ((uint32_t) m_axes[1]), ((uint32_t) m_axes[2])); |
martlefebvre94 | 8:5e9de5729ef6 | 192 | } |
martlefebvre94 | 8:5e9de5729ef6 | 193 | |
martlefebvre94 | 8:5e9de5729ef6 | 194 | // Wait for acquisition period |
martlefebvre94 | 11:b16d3b1a061e | 195 | wait(TS); |
martlefebvre94 | 8:5e9de5729ef6 | 196 | |
martlefebvre94 | 8:5e9de5729ef6 | 197 | // Stop saving data when button is pushed |
martlefebvre94 | 8:5e9de5729ef6 | 198 | if (button1_pressed) { |
martlefebvre94 | 8:5e9de5729ef6 | 199 | button1_pressed = false; |
martlefebvre94 | 8:5e9de5729ef6 | 200 | printf("Data acquisition stopped\r\n"); |
martlefebvre94 | 8:5e9de5729ef6 | 201 | printf("Press 'R' to read the data\r\n"); |
martlefebvre94 | 8:5e9de5729ef6 | 202 | return false; |
martlefebvre94 | 8:5e9de5729ef6 | 203 | } |
martlefebvre94 | 8:5e9de5729ef6 | 204 | } |
martlefebvre94 | 8:5e9de5729ef6 | 205 | printf("Data acquisition stopped\r\n"); |
martlefebvre94 | 8:5e9de5729ef6 | 206 | printf("Press 'R' to read the data\r\n"); |
martlefebvre94 | 8:5e9de5729ef6 | 207 | return false; |
martlefebvre94 | 8:5e9de5729ef6 | 208 | } |
martlefebvre94 | 8:5e9de5729ef6 | 209 | |
martlefebvre94 | 8:5e9de5729ef6 | 210 | /* Read task */ |
martlefebvre94 | 8:5e9de5729ef6 | 211 | void read_task() |
martlefebvre94 | 8:5e9de5729ef6 | 212 | { |
martlefebvre94 | 8:5e9de5729ef6 | 213 | char pc_input; |
martlefebvre94 | 8:5e9de5729ef6 | 214 | uint32_t Flash_rdata[3]; |
martlefebvre94 | 8:5e9de5729ef6 | 215 | bool flash_empty = false; |
martlefebvre94 | 8:5e9de5729ef6 | 216 | |
martlefebvre94 | 8:5e9de5729ef6 | 217 | // Read terminal input |
martlefebvre94 | 8:5e9de5729ef6 | 218 | if (pc.readable()) { |
martlefebvre94 | 8:5e9de5729ef6 | 219 | pc_input = pc.getc(); |
martlefebvre94 | 8:5e9de5729ef6 | 220 | } |
martlefebvre94 | 8:5e9de5729ef6 | 221 | else { |
martlefebvre94 | 8:5e9de5729ef6 | 222 | pc_input = ' '; |
martlefebvre94 | 8:5e9de5729ef6 | 223 | } |
martlefebvre94 | 8:5e9de5729ef6 | 224 | |
martlefebvre94 | 8:5e9de5729ef6 | 225 | // Read Flash memory if 'R' is pressed |
martlefebvre94 | 8:5e9de5729ef6 | 226 | if ((pc_input == 'r') || (pc_input == 'R')) { |
martlefebvre94 | 8:5e9de5729ef6 | 227 | // Data labels |
martlefebvre94 | 8:5e9de5729ef6 | 228 | printf("mag_X\tmag_Y\tmag_Z\r\n"); |
martlefebvre94 | 8:5e9de5729ef6 | 229 | |
martlefebvre94 | 8:5e9de5729ef6 | 230 | // Read 1st Flash data |
martlefebvre94 | 8:5e9de5729ef6 | 231 | uint32_t Flash_addr_temp = FLASH_BANK2_BASE; |
martlefebvre94 | 8:5e9de5729ef6 | 232 | read_flash(Flash_addr_temp, &Flash_rdata[0], LIS2MDL_DATA_SIZE); |
martlefebvre94 | 8:5e9de5729ef6 | 233 | |
martlefebvre94 | 8:5e9de5729ef6 | 234 | // Read Flash data |
martlefebvre94 | 8:5e9de5729ef6 | 235 | while ((Flash_addr_temp <= FLASH_BANK2_END-LIS2MDL_DATA_SIZE+1) && !flash_empty) { |
martlefebvre94 | 8:5e9de5729ef6 | 236 | // Print read data in the terminal |
martlefebvre94 | 8:5e9de5729ef6 | 237 | printf("%6d\t%6d\t%6d\r\n", Flash_rdata[0], Flash_rdata[1], Flash_rdata[2]); |
martlefebvre94 | 8:5e9de5729ef6 | 238 | Flash_addr_temp += LIS2MDL_DATA_SIZE; |
martlefebvre94 | 8:5e9de5729ef6 | 239 | |
martlefebvre94 | 8:5e9de5729ef6 | 240 | // Check if the next address is not empty (erased Flash only contains 0) |
martlefebvre94 | 8:5e9de5729ef6 | 241 | if (Flash_addr_temp <= FLASH_BANK2_END-LIS2MDL_DATA_SIZE+1) { |
martlefebvre94 | 8:5e9de5729ef6 | 242 | read_flash(Flash_addr_temp, &Flash_rdata[0], LIS2MDL_DATA_SIZE); |
martlefebvre94 | 8:5e9de5729ef6 | 243 | if ((Flash_rdata[0] == 0) && (Flash_rdata[1] == 0) && (Flash_rdata[2] == 0)) { |
martlefebvre94 | 8:5e9de5729ef6 | 244 | flash_empty = true; |
martlefebvre94 | 8:5e9de5729ef6 | 245 | } |
martlefebvre94 | 8:5e9de5729ef6 | 246 | } |
martlefebvre94 | 8:5e9de5729ef6 | 247 | } |
martlefebvre94 | 8:5e9de5729ef6 | 248 | } |
martlefebvre94 | 8:5e9de5729ef6 | 249 | } |
martlefebvre94 | 8:5e9de5729ef6 | 250 | |
martlefebvre94 | 8:5e9de5729ef6 | 251 | /* Print Flash memory info */ |
martlefebvre94 | 8:5e9de5729ef6 | 252 | void print_flash_info() |
martlefebvre94 | 8:5e9de5729ef6 | 253 | { |
martlefebvre94 | 8:5e9de5729ef6 | 254 | printf("**************************************************\n\r"); |
martlefebvre94 | 8:5e9de5729ef6 | 255 | printf("/***** Flash memory info *****/\r\n"); |
martlefebvre94 | 8:5e9de5729ef6 | 256 | printf("Flash size: %d [B]\r\n", FLASH_SIZE); |
martlefebvre94 | 8:5e9de5729ef6 | 257 | printf("Flash page size: %d [B]\r\n", FLASH_PAGE_SIZE); |
martlefebvre94 | 8:5e9de5729ef6 | 258 | printf("Flash nb of pages: %d \r\n", FLASH_SIZE/FLASH_PAGE_SIZE); |
martlefebvre94 | 8:5e9de5729ef6 | 259 | printf("Flash bank 1 base address: 0x%X\r\n", FLASH_BASE); |
martlefebvre94 | 8:5e9de5729ef6 | 260 | printf("Flash bank 1 end address: 0x%X\r\n", FLASH_BANK1_END); |
martlefebvre94 | 8:5e9de5729ef6 | 261 | printf("Flash bank 2 base address: 0x%X\r\n", FLASH_BANK2_BASE); |
martlefebvre94 | 8:5e9de5729ef6 | 262 | printf("Flash bank 2 end address: 0x%X\r\n", FLASH_BANK2_END); |
martlefebvre94 | 8:5e9de5729ef6 | 263 | printf("**************************************************\n\r"); |
martlefebvre94 | 8:5e9de5729ef6 | 264 | } |
martlefebvre94 | 8:5e9de5729ef6 | 265 | |
martlefebvre94 | 8:5e9de5729ef6 | 266 | /* Erase content of Flash memory */ |
martlefebvre94 | 8:5e9de5729ef6 | 267 | bool erase_flash(bool verbose) |
martlefebvre94 | 8:5e9de5729ef6 | 268 | { |
martlefebvre94 | 8:5e9de5729ef6 | 269 | printf("Erasing Flash memory...\r\n"); |
martlefebvre94 | 8:5e9de5729ef6 | 270 | |
martlefebvre94 | 8:5e9de5729ef6 | 271 | // Unlock Flash memory |
martlefebvre94 | 8:5e9de5729ef6 | 272 | HAL_FLASH_Unlock(); |
martlefebvre94 | 8:5e9de5729ef6 | 273 | |
martlefebvre94 | 8:5e9de5729ef6 | 274 | // Erase Flash memory |
martlefebvre94 | 8:5e9de5729ef6 | 275 | FLASH_EraseInitTypeDef eraser; |
martlefebvre94 | 8:5e9de5729ef6 | 276 | uint32_t Flash_addr = FLASH_BANK2_BASE; |
martlefebvre94 | 8:5e9de5729ef6 | 277 | uint32_t page_error = 0; |
martlefebvre94 | 8:5e9de5729ef6 | 278 | int32_t page = 1; |
martlefebvre94 | 8:5e9de5729ef6 | 279 | |
martlefebvre94 | 8:5e9de5729ef6 | 280 | while (Flash_addr < FLASH_BANK2_END) { |
martlefebvre94 | 8:5e9de5729ef6 | 281 | eraser.TypeErase = FLASH_TYPEERASE_PAGES; |
martlefebvre94 | 8:5e9de5729ef6 | 282 | eraser.PageAddress = Flash_addr; |
martlefebvre94 | 8:5e9de5729ef6 | 283 | eraser.NbPages = 1; |
martlefebvre94 | 8:5e9de5729ef6 | 284 | if(HAL_OK != HAL_FLASHEx_Erase(&eraser, &page_error)) { |
martlefebvre94 | 8:5e9de5729ef6 | 285 | if (verbose) {printf("Flash erase failed!\r\n");} |
martlefebvre94 | 8:5e9de5729ef6 | 286 | printf("Error 0x%X\r\n", page_error); |
martlefebvre94 | 8:5e9de5729ef6 | 287 | HAL_FLASH_Lock(); |
martlefebvre94 | 8:5e9de5729ef6 | 288 | return false; |
martlefebvre94 | 8:5e9de5729ef6 | 289 | } |
martlefebvre94 | 8:5e9de5729ef6 | 290 | if (verbose) {printf("Erased page %d at address: 0x%X\r\n", page, Flash_addr);} |
martlefebvre94 | 8:5e9de5729ef6 | 291 | Flash_addr += FLASH_PAGE_SIZE; |
martlefebvre94 | 8:5e9de5729ef6 | 292 | page++; |
martlefebvre94 | 8:5e9de5729ef6 | 293 | } |
martlefebvre94 | 8:5e9de5729ef6 | 294 | |
martlefebvre94 | 8:5e9de5729ef6 | 295 | if (verbose) {printf("Flash erase succesful!\r\n");} |
martlefebvre94 | 8:5e9de5729ef6 | 296 | return true; |
martlefebvre94 | 8:5e9de5729ef6 | 297 | } |
martlefebvre94 | 8:5e9de5729ef6 | 298 | |
martlefebvre94 | 8:5e9de5729ef6 | 299 | /* Write Flash memory */ |
martlefebvre94 | 8:5e9de5729ef6 | 300 | bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose) |
martlefebvre94 | 8:5e9de5729ef6 | 301 | { |
martlefebvre94 | 8:5e9de5729ef6 | 302 | // Unlock Flash memory |
martlefebvre94 | 8:5e9de5729ef6 | 303 | HAL_FLASH_Unlock(); |
martlefebvre94 | 8:5e9de5729ef6 | 304 | |
martlefebvre94 | 8:5e9de5729ef6 | 305 | // Write Flash memory |
martlefebvre94 | 8:5e9de5729ef6 | 306 | for (int i=0; i<n_words; i++) { |
martlefebvre94 | 8:5e9de5729ef6 | 307 | if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Flash_addr, Flash_wdata[i])) { |
martlefebvre94 | 8:5e9de5729ef6 | 308 | if (verbose) {printf("Flash write failed!\r\n");} |
martlefebvre94 | 8:5e9de5729ef6 | 309 | HAL_FLASH_Lock(); |
martlefebvre94 | 8:5e9de5729ef6 | 310 | return false; |
martlefebvre94 | 8:5e9de5729ef6 | 311 | } |
martlefebvre94 | 8:5e9de5729ef6 | 312 | Flash_addr += 4; |
martlefebvre94 | 8:5e9de5729ef6 | 313 | } |
martlefebvre94 | 8:5e9de5729ef6 | 314 | if (verbose) {printf("Flash write succesful!\r\n");} |
martlefebvre94 | 8:5e9de5729ef6 | 315 | HAL_FLASH_Lock(); |
martlefebvre94 | 8:5e9de5729ef6 | 316 | return true; |
martlefebvre94 | 8:5e9de5729ef6 | 317 | } |
martlefebvre94 | 8:5e9de5729ef6 | 318 | |
martlefebvre94 | 8:5e9de5729ef6 | 319 | /* Read Flash memory */ |
martlefebvre94 | 8:5e9de5729ef6 | 320 | void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes) |
martlefebvre94 | 8:5e9de5729ef6 | 321 | { |
martlefebvre94 | 8:5e9de5729ef6 | 322 | memcpy(Flash_rdata, (uint32_t*) Flash_addr, n_bytes); |
martlefebvre94 | 8:5e9de5729ef6 | 323 | } |
martlefebvre94 | 8:5e9de5729ef6 | 324 | |
martlefebvre94 | 8:5e9de5729ef6 | 325 | /* Enables button when bouncing is over */ |
martlefebvre94 | 8:5e9de5729ef6 | 326 | void button1_enabled_cb(void) |
martlefebvre94 | 8:5e9de5729ef6 | 327 | { |
martlefebvre94 | 8:5e9de5729ef6 | 328 | button1_enabled = true; |
martlefebvre94 | 8:5e9de5729ef6 | 329 | } |
martlefebvre94 | 8:5e9de5729ef6 | 330 | |
martlefebvre94 | 8:5e9de5729ef6 | 331 | /* ISR handling button pressed event */ |
martlefebvre94 | 8:5e9de5729ef6 | 332 | void button1_onpressed_cb(void) |
martlefebvre94 | 8:5e9de5729ef6 | 333 | { |
martlefebvre94 | 8:5e9de5729ef6 | 334 | if (button1_enabled) { // Disabled while the button is bouncing |
martlefebvre94 | 8:5e9de5729ef6 | 335 | button1_enabled = false; |
martlefebvre94 | 8:5e9de5729ef6 | 336 | button1_pressed = true; // To be read by the main loop |
martlefebvre94 | 8:5e9de5729ef6 | 337 | button1_timeout.attach(callback(button1_enabled_cb), 0.3); // Debounce time 300 ms |
martlefebvre94 | 8:5e9de5729ef6 | 338 | } |
martlefebvre94 | 9:1534c762ca3b | 339 | } |
martlefebvre94 | 9:1534c762ca3b | 340 | |
martlefebvre94 | 9:1534c762ca3b | 341 | /* Helper function for printing floats & doubles */ |
martlefebvre94 | 9:1534c762ca3b | 342 | static char *print_double(char *str, double v) |
martlefebvre94 | 9:1534c762ca3b | 343 | { |
martlefebvre94 | 9:1534c762ca3b | 344 | int decimalDigits = 6; |
martlefebvre94 | 9:1534c762ca3b | 345 | int i = 1; |
martlefebvre94 | 9:1534c762ca3b | 346 | int intPart, fractPart; |
martlefebvre94 | 9:1534c762ca3b | 347 | int len; |
martlefebvre94 | 9:1534c762ca3b | 348 | char *ptr; |
martlefebvre94 | 9:1534c762ca3b | 349 | |
martlefebvre94 | 9:1534c762ca3b | 350 | /* prepare decimal digits multiplicator */ |
martlefebvre94 | 9:1534c762ca3b | 351 | for (; decimalDigits != 0; i *= 10, decimalDigits--); |
martlefebvre94 | 9:1534c762ca3b | 352 | |
martlefebvre94 | 9:1534c762ca3b | 353 | /* calculate integer & fractinal parts */ |
martlefebvre94 | 9:1534c762ca3b | 354 | intPart = (int)v; |
martlefebvre94 | 9:1534c762ca3b | 355 | fractPart = (int)((v - (double)(int)v) * i); |
martlefebvre94 | 9:1534c762ca3b | 356 | |
martlefebvre94 | 9:1534c762ca3b | 357 | /* fill in integer part */ |
martlefebvre94 | 9:1534c762ca3b | 358 | sprintf(str, "%i.", intPart); |
martlefebvre94 | 9:1534c762ca3b | 359 | |
martlefebvre94 | 9:1534c762ca3b | 360 | /* prepare fill in of fractional part */ |
martlefebvre94 | 9:1534c762ca3b | 361 | len = strlen(str); |
martlefebvre94 | 9:1534c762ca3b | 362 | ptr = &str[len]; |
martlefebvre94 | 9:1534c762ca3b | 363 | |
martlefebvre94 | 9:1534c762ca3b | 364 | /* fill in leading fractional zeros */ |
martlefebvre94 | 9:1534c762ca3b | 365 | for (i /= 10; i > 1; i /= 10, ptr++) { |
martlefebvre94 | 9:1534c762ca3b | 366 | if (fractPart >= i) { |
martlefebvre94 | 9:1534c762ca3b | 367 | break; |
martlefebvre94 | 9:1534c762ca3b | 368 | } |
martlefebvre94 | 9:1534c762ca3b | 369 | *ptr = '0'; |
martlefebvre94 | 9:1534c762ca3b | 370 | } |
martlefebvre94 | 9:1534c762ca3b | 371 | |
martlefebvre94 | 9:1534c762ca3b | 372 | /* fill in (rest of) fractional part */ |
martlefebvre94 | 9:1534c762ca3b | 373 | sprintf(ptr, "%i", fractPart); |
martlefebvre94 | 9:1534c762ca3b | 374 | |
martlefebvre94 | 9:1534c762ca3b | 375 | return str; |
martlefebvre94 | 9:1534c762ca3b | 376 | } |
martlefebvre94 | 9:1534c762ca3b | 377 | |
martlefebvre94 | 9:1534c762ca3b | 378 | uint32_t FloatToUint(float n) |
martlefebvre94 | 9:1534c762ca3b | 379 | { |
martlefebvre94 | 9:1534c762ca3b | 380 | return (uint32_t)(*(uint32_t*)&n); |
martlefebvre94 | 9:1534c762ca3b | 381 | } |
martlefebvre94 | 9:1534c762ca3b | 382 | |
martlefebvre94 | 9:1534c762ca3b | 383 | float UintToFloat(uint32_t n) |
martlefebvre94 | 9:1534c762ca3b | 384 | { |
martlefebvre94 | 9:1534c762ca3b | 385 | return (float)(*(float*)&n); |
martlefebvre94 | 6:b2e247935342 | 386 | } |