LELEC2811 - I&S / Mbed OS LELEC2811_LIS2MDL_Magnetometer

Dependencies:   X_NUCLEO_IKS01A3

Committer:
martlefebvre94
Date:
Mon Sep 23 13:07:49 2019 +0000
Revision:
10:0f471469279a
Parent:
9:1534c762ca3b
Child:
11:b16d3b1a061e
Sampling frequency -> Readout frequency

Who changed what in which revision?

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