2019-2020 LIS2DW12 Accelerometer Project

Dependencies:   X_NUCLEO_IKS01A3

Committer:
martlefebvre94
Date:
Tue Sep 24 10:11:03 2019 +0000
Revision:
15:7d938eef43c4
Parent:
14:8b7ce0fc3971
LIS2DW12 accelerometer project

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