Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: X_NUCLEO_IKS01A3
main.cpp
00001 /** 00002 ****************************************************************************** 00003 * @file main.cpp 00004 * @author SRA 00005 * @version V1.0.0 00006 * @date 5-March-2019 00007 * @brief Simple Example application for using the X_NUCLEO_IKS01A3 00008 * MEMS Inertial & Environmental Sensor Nucleo expansion board. 00009 ****************************************************************************** 00010 * @attention 00011 * 00012 * <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2> 00013 * 00014 * Redistribution and use in source and binary forms, with or without modification, 00015 * are permitted provided that the following conditions are met: 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 2. Redistributions in binary form must reproduce the above copyright notice, 00019 * this list of conditions and the following disclaimer in the documentation 00020 * and/or other materials provided with the distribution. 00021 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00022 * may be used to endorse or promote products derived from this software 00023 * without specific prior written permission. 00024 * 00025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00026 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00028 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00029 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00030 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00031 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00032 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00033 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00034 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 ****************************************************************************** 00037 */ 00038 00039 /* 00040 LELEC2811 Multisensor IKS01A3 Project 00041 M. Lefebvre - 2019-2020 00042 */ 00043 00044 /* Includes */ 00045 #include <stdlib.h> 00046 #include <time.h> 00047 #include <math.h> 00048 #include "mbed.h" 00049 #include "XNucleoIKS01A3.h" 00050 #include "stm32l073xx.h" 00051 #include "stm32l0xx_hal.h" 00052 #include "stm32l0xx_hal_flash.h" 00053 #include "main.h" 00054 #include "adc.h" 00055 #include "gpio.h" 00056 00057 /* Defines */ 00058 #define VDD 3.3 // Supply voltage (V) 00059 #define FS 10.0 // Readout frequency (Hz) - /!\ Must be below 19Hz 00060 #define DATA_SIZE 64 // Number of bytes to store in Flash memory 00061 #define FLASH_WRITE_TIME 0.00328 // Flash write time (s) 00062 #define TS (1/FS)-((DATA_SIZE/4)*FLASH_WRITE_TIME) 00063 00064 // GPIO 00065 #define RED_LED GPIO_PIN_5 00066 #define IR_LED GPIO_PIN_6 00067 #define GREEN_LED GPIO_PIN_7 00068 00069 // LIS2MDL Magnetometer 00070 #define LIS2MDL_ODR 50.0 // Output data rate (10, 20, 50 or 100 Hz) 00071 #define LIS2MDL_LP 0 // Power mode (0 for high-resolution mode, 1 for low-power mode) 00072 #define LIS2MDL_LPF 0 // Bandwidth (0 for ODR/2, 1 for ODR/4) 00073 #define LIS2MDL_COMP_TEMP_EN 1 // Temperature compensation (0 disabled, 1 enabled) 00074 #define LIS2MDL_OFF_CANC 1 // Offset cancellation (0 for no offset cancellation, 1 for offset cancellation, 2 for set pulse only at power-on) 00075 #define LIS2MDL_DATA_SIZE 12 // Number of bytes for LIS2MDL magnetometer data 00076 00077 // LPS22HH Pressure sensor 00078 #define P0 1013.26 // Sea level pressure (hPa) 00079 #define LPS22HH_ODR 50.0 // Output data rate (one-shot, 1, 10, 25, 50, 75, 100, 200 Hz) 00080 #define LPS22HH_LOW_NOISE_EN 1 // Low-noise (0 disabled, 1 enabled) 00081 #define LPS22HH_LPF_CFG 3 // Device bandwidth (0 for ODR/2, 2 for ODR/9, 3 for ODR/20) 00082 #define LPS22HH_DATA_SIZE 8 // Number of bytes for LPS22HH pressure sensor data 00083 00084 // LIS2DW12 Accelerometer 00085 #define LIS2DW12_ODR 4 // 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) 00086 #define LIS2DW12_FS 4 // Full-scale +-(2, 4, 8 or 16 g) 00087 #define LIS2DW12_BW_FILT 2 // Filter bandwidth (0 for ODR/2, 1 for ODR/4, 2 for ODR/10, 3 for ODR/20) 00088 #define LIS2DW12_LP_MODE 0 // Low-power modes 1 to 4 (1 gives the max. rms noise, 4 gives the min. rms noise) 00089 #define LIS2DW12_MODE 1 // Mode (0 for low-power, 1 for high-performance, 2 for single data conversion) 00090 #define LIS2DW12_LOW_NOISE 1 // Low-noise (0 disabled, 1 enabled) 00091 #define LIS2DW12_POWER_MODE LIS2DW12_LP_MODE + (LIS2DW12_MODE << 2) + (LIS2DW12_LOW_NOISE << 4) 00092 #define LIS2DW12_DATA_SIZE 12 // Number of bytes for LIS2DW12 accelerometer sensor data 00093 00094 // HTS221 Relative humidity and temperature sensor 00095 #define HTS221_ODR 1 // Output data rate (one-shot, 1Hz, 7Hz, 12.5Hz) 00096 #define HTS221_HEATER 0 // Heater configuration (0 disabled, 1 enabled) 00097 #define HTS221_AVGH 32 // Humidity averaging (4 to 512) 00098 #define HTS221_AVGT 16 // Temperature averaging (2 to 256) 00099 00100 // LSM6DSO Accelerometer + gyroscope 00101 #define LSM6DSO_ODR_XL 12.5 // Accelerometer output data rate (12.5, 26, 52, 104, 208, 416, 833, 1.66k, 3.33k, 6.66kHz) 00102 #define LSM6DSO_FS_XL 4 // Accelerometer full scale (2, 4, 8, 16g) 00103 #define LSM6DSO_XL_HM_MODE 1 // Accelerometer high-performance mode (0 enabled, 1 disabled) 00104 #define LSM6DSO_XL_ULP_EN 0 // Accelerometer ultra-low-power configuration (0 disabled, 1 enabled) 00105 #define LSM6DSO_LPF2_XL_EN 1 // Accelerometer high-resolution selection (0 for 1st stage of digital filtering, 1 for 2nd stage) 00106 #define LSM6DSO_HP_SLOPE_XL_EN 0 // Accelerometer high-pass filter selection (0 for low-pass, 1 for high-pass) 00107 #define LSM6DSO_HPCF_XL 2 // Accelerometer filter configuration and cutoff setting (0 for ODR/4, 1 for ODR/10, 2 for ODR/20, 3 for ODR/45, 4 for ODR/100, 5 for ODR/200, 6 for ODR/400, 7 for ODR/800) 00108 #define LSM6DSO_ODR_G 16 // Gyroscope output data rate (12.5, 26, 52, 104, 208, 416, 833, 1.66k, 3.33k, 6.66kHz) 00109 #define LSM6DSO_FS_G 1000 // Gyroscope full scale (250, 500, 1000, 2000dps) 00110 #define LSM6DSO_G_HM_MODE 1 // Gyroscope high-performance mode (0 enabled, 1 disabled) 00111 #define LSM6DSO_LPF1_SEL_G 1 // Gyroscope digital LPF1 enable (0 disabled, 1 enabled) 00112 #define LSM6DSO_FTYPE 3 // Gyroscope LPF1 bandwidth selection (0 ultra light, 1 very light, 2 light, 3 medium, 4 strong, 5 very strong, 6 aggressive, 7 xtreme) 00113 #define LSM6DSO_HP_EN_G 1 // Gyroscope digital HPF enable (0 HPF disabled, 1 HPF enabled) 00114 #define LSM6DSO_HPM_G 2 // Gyroscope HPF cutoff selection (0 for 16mHz, 1 for 65mHz, 10 for 260 mHz, 11 for 1.04Hz) 00115 00116 /* Functions definition */ 00117 bool acquisition_task(bool verbose); 00118 void read_task(); 00119 void print_flash_info(); 00120 bool erase_flash(bool verbose); 00121 bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose); 00122 void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes); 00123 void button1_enabled_cb(void); 00124 void button1_onpressed_cb(void); 00125 static char *print_double(char *str, double v); 00126 float pressure_to_altitude(double pressure); 00127 uint32_t FloatToUint(float n); 00128 float UintToFloat(uint32_t n); 00129 00130 static void SystemClock_Config(void); 00131 00132 /* ADC */ 00133 uint32_t adcValue=0; 00134 00135 /* Serial link */ 00136 Serial pc(SERIAL_TX, SERIAL_RX); 00137 00138 /* Button */ 00139 InterruptIn button1(USER_BUTTON); 00140 volatile bool button1_pressed = false; // Used in the main loop 00141 volatile bool button1_enabled = true; // Used for debouncing 00142 Timeout button1_timeout; // Used for debouncing 00143 00144 /* Instantiate the expansion board */ 00145 static XNucleoIKS01A3 *mems_expansion_board = XNucleoIKS01A3::instance(D14, D15, D4, D5, A3, D6, A4); 00146 00147 /* Retrieve the composing elements of the expansion board */ 00148 static LIS2MDLSensor *magnetometer = mems_expansion_board->magnetometer; 00149 static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; 00150 static LPS22HHSensor *press_temp = mems_expansion_board->pt_sensor; 00151 static LSM6DSOSensor *acc_gyro = mems_expansion_board->acc_gyro; 00152 static LIS2DW12Sensor *accelerometer = mems_expansion_board->accelerometer; 00153 static STTS751Sensor *temp = mems_expansion_board->t_sensor; 00154 00155 /* Main */ 00156 int main() 00157 { 00158 // Reset of all peripherals 00159 HAL_Init(); 00160 00161 // Configure the system clock 00162 SystemClock_Config(); 00163 00164 uint8_t id; 00165 float read_reg, read_reg_1; 00166 uint8_t read_reg_int, read_reg_int_1, read_reg_int_2; 00167 00168 bool save_data = false; 00169 uint32_t Flash_addr = FLASH_BANK2_BASE; 00170 00171 /* Serial link configuration */ 00172 pc.baud(115200); 00173 00174 /* GPIO configuration */ 00175 MX_GPIO_Init(); 00176 00177 /* ADC configuration */ 00178 MX_ADC_Init(); 00179 HAL_ADC_Start(&hadc); 00180 00181 /* Button configuration */ 00182 button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event 00183 00184 /* Reset message */ 00185 printf("\n\r**************************************************\n\r"); 00186 printf("LELEC2811 IKS01A3 Multisensor Program\n\r"); 00187 printf("**************************************************\n\r"); 00188 00189 /* LIS2MDL magnetometer sensor configuration */ 00190 magnetometer->enable(); 00191 printf("/***** LIS2MDL magnetometer configuration *****/\r\n"); 00192 00193 magnetometer->read_id(&id); 00194 printf("LIS2MDL magnetometer = 0x%X\r\n", id); 00195 00196 magnetometer->set_m_odr(LIS2MDL_ODR); 00197 magnetometer->get_m_odr(&read_reg); 00198 printf("LIS2MDL ODR = %1.1f [Hz]\r\n", read_reg); 00199 00200 magnetometer->set_m_lp(LIS2MDL_LP); 00201 magnetometer->get_m_lp(&read_reg_int); 00202 printf("LIS2MDL LP = %1d\r\n", read_reg_int); 00203 00204 magnetometer->set_m_lpf(LIS2MDL_LPF); 00205 magnetometer->get_m_lpf(&read_reg_int); 00206 printf("LIS2MDL LPF = %1d\r\n", read_reg_int); 00207 00208 magnetometer->set_m_comp_temp_en(LIS2MDL_COMP_TEMP_EN); 00209 magnetometer->get_m_comp_temp_en(&read_reg_int); 00210 printf("LIS2MDL COMP_TEMP_EN = %1d\r\n", read_reg_int); 00211 00212 magnetometer->set_m_off_canc(LIS2MDL_OFF_CANC); 00213 magnetometer->get_m_off_canc(&read_reg_int); 00214 printf("LIS2MDL OFF_CANC = %1d\r\n", read_reg_int); 00215 00216 /* LPS22HH pressure sensor configuration */ 00217 press_temp->enable(); 00218 printf("/***** LPS22HH pressure sensor configuration *****/\r\n"); 00219 00220 press_temp->read_id(&id); 00221 printf("LPS22HH pressure = 0x%X\r\n", id); 00222 00223 press_temp->set_odr(LPS22HH_ODR, LPS22HH_LOW_NOISE_EN); 00224 press_temp->get_odr(&read_reg, &read_reg_int); 00225 printf("LPS22HH ODR = %1.1f [Hz]\r\n", read_reg); 00226 printf("LPS22HH LOW_NOISE_EN = %1d\r\n", read_reg_int); 00227 00228 press_temp->set_lpfp_cfg(LPS22HH_LPF_CFG); 00229 press_temp->get_lpfp_cfg(&read_reg_int); 00230 printf("LPS22HH LPF_CFG = %1d\r\n", read_reg_int); 00231 00232 /* LIS2DW12 accelerometer sensor configuration */ 00233 accelerometer->enable_x(); 00234 printf("/***** LIS2DW12 accelerometer sensor configuration *****/\r\n"); 00235 00236 accelerometer->read_id(&id); 00237 printf("LIS2DW12 accelerometer = 0x%X\r\n", id); 00238 00239 accelerometer->set_x_odr(LIS2DW12_ODR); 00240 accelerometer->get_x_odr(&read_reg); 00241 printf("LIS2DW12 ODR = %1.3f [Hz]\r\n", read_reg); 00242 00243 accelerometer->set_x_fs(LIS2DW12_FS); 00244 accelerometer->get_x_fs(&read_reg); 00245 printf("LIS2DW12 FS = %1.3f [g]\r\n", read_reg); 00246 00247 accelerometer->set_x_bw_filt(LIS2DW12_BW_FILT); 00248 accelerometer->get_x_bw_filt(&read_reg_int); 00249 printf("LIS2DW12 BW_FILT = %1d\r\n", read_reg_int); 00250 00251 accelerometer->set_x_power_mode(LIS2DW12_POWER_MODE); 00252 accelerometer->get_x_power_mode(&read_reg_int, &read_reg_int_1, &read_reg_int_2); 00253 printf("LIS2DW12 LP_MODE = %1d\r\n", read_reg_int); 00254 printf("LIS2DW12 MODE = %1d\r\n", read_reg_int_1); 00255 printf("LIS2DW12 LOW_NOISE = %1d\r\n", read_reg_int_2); 00256 00257 /* HTS221 relative humidity and temperature sensor configuration */ 00258 hum_temp->enable(); 00259 printf("/***** HTS221 humidity sensor configuration *****/\r\n"); 00260 00261 hum_temp->read_id(&id); 00262 printf("HTS221 humidity & temperature = 0x%X\r\n", id); 00263 00264 hum_temp->set_odr(HTS221_ODR); 00265 hum_temp->get_odr(&read_reg); 00266 printf("HTS221 ODR = %1.3f [Hz]\r\n", read_reg); 00267 00268 hum_temp->set_heater(HTS221_HEATER); 00269 hum_temp->get_heater(&read_reg_int); 00270 printf("HTS221 HEATER = %1d\r\n", read_reg_int); 00271 00272 hum_temp->set_avg(HTS221_AVGH, HTS221_AVGT); 00273 hum_temp->get_avg(&read_reg, &read_reg_1); 00274 printf("HTS221 AVGH = %1.0f\r\n", read_reg); 00275 printf("HTS221 AVGT = %1.0f\r\n", read_reg_1); 00276 00277 /* STTS751 Temperature sensor configuration */ 00278 temp->enable(); 00279 printf("/***** STTS751 temperature sensor configuration *****/\r\n"); 00280 00281 temp->read_id(&id); 00282 printf("STTS751 temperature = 0x%X\r\n", id); 00283 00284 /* LSM6DSO Accelerometer and gyroscope configuration */ 00285 acc_gyro->enable_x(); 00286 acc_gyro->enable_g(); 00287 printf("/***** LSM6DSO accelerometer and gyroscope sensor configuration *****/\r\n"); 00288 00289 acc_gyro->read_id(&id); 00290 printf("LSM6DSO accelerometer & gyroscope = 0x%X\r\n", id); 00291 00292 acc_gyro->set_x_odr(LSM6DSO_ODR_XL); 00293 acc_gyro->get_x_odr(&read_reg); 00294 printf("LSM6DSO ODR_XL = %1.3f [Hz]\r\n", read_reg); 00295 00296 acc_gyro->set_x_fs(LSM6DSO_FS_XL); 00297 acc_gyro->get_x_fs(&read_reg); 00298 printf("LSM6DSO FS_XL = %1.3f [g]\r\n", read_reg); 00299 00300 acc_gyro->set_x_power_mode(LSM6DSO_XL_HM_MODE, LSM6DSO_XL_ULP_EN); 00301 acc_gyro->get_x_power_mode(&read_reg_int, &read_reg_int_1); 00302 printf("LSM6DSO XL_HM_MODE = %1d\r\n", read_reg_int); 00303 printf("LSM6DSO XL_ULP_EN = %1d\r\n", read_reg_int_1); 00304 00305 acc_gyro->set_x_lpf2_en(LSM6DSO_LPF2_XL_EN); 00306 acc_gyro->get_x_lpf2_en(&read_reg_int); 00307 printf("LSM6DSO LPF2_XL_EN = %1d\r\n", read_reg_int); 00308 00309 acc_gyro->set_x_filter_config(LSM6DSO_HP_SLOPE_XL_EN, LSM6DSO_HPCF_XL); 00310 acc_gyro->get_x_filter_config(&read_reg_int, &read_reg_int_1); 00311 printf("LSM6DSO HP_SLOPE_XL_EN = %1d\r\n", read_reg_int); 00312 printf("LSM6DSO HPCF_XL = %1d\r\n", read_reg_int_1); 00313 00314 acc_gyro->set_g_odr(LSM6DSO_ODR_G); 00315 acc_gyro->get_g_odr(&read_reg); 00316 printf("LSM6DSO ODR_G = %1.3f [Hz]\r\n", read_reg); 00317 00318 acc_gyro->set_g_fs(LSM6DSO_FS_XL); 00319 acc_gyro->get_g_fs(&read_reg); 00320 printf("LSM6DSO FS_G = %1.3f [dps]\r\n", read_reg); 00321 00322 acc_gyro->set_g_power_mode(LSM6DSO_G_HM_MODE); 00323 acc_gyro->get_g_power_mode(&read_reg_int); 00324 printf("LSM6DSO G_HM_MODE = %1d\r\n", read_reg_int); 00325 00326 acc_gyro->set_g_lpf_config(LSM6DSO_LPF1_SEL_G, LSM6DSO_FTYPE); 00327 acc_gyro->get_g_lpf_config(&read_reg_int, &read_reg_int_1); 00328 printf("LSM6DSO LPF1_SEL_G = %1d\r\n", read_reg_int); 00329 printf("LSM6DSO FTYPE = %1d\r\n", read_reg_int_1); 00330 00331 acc_gyro->set_g_hpf_config(LSM6DSO_HP_EN_G, LSM6DSO_HPM_G); 00332 acc_gyro->get_g_hpf_config(&read_reg_int, &read_reg_int_1); 00333 printf("LSM6DSO HP_EN_G = %1d\r\n", read_reg_int); 00334 printf("LSM6DSO HPM_G = %1d\r\n", read_reg_int_1); 00335 00336 /* Print Flash memory information */ 00337 print_flash_info(); 00338 00339 /* Information for the user */ 00340 printf("Press blue button to start data acquisition\r\n"); 00341 printf("Press 'R' to read previously measured data\r\n"); 00342 00343 /* GPIO setting */ 00344 HAL_GPIO_WritePin(GPIOA, RED_LED, GPIO_PIN_RESET); 00345 HAL_GPIO_WritePin(GPIOA, IR_LED, GPIO_PIN_RESET); 00346 HAL_GPIO_WritePin(GPIOA, GREEN_LED, GPIO_PIN_SET); 00347 00348 /* Acquisition loop */ 00349 while(1) { 00350 // Start saving data when button is pushed 00351 if (button1_pressed) { 00352 button1_pressed = false; 00353 save_data = true; 00354 erase_flash(false); 00355 printf("Acquiring data...\r\n"); 00356 printf("Press blue button to stop data acquisition\r\n"); 00357 Flash_addr = FLASH_BANK2_BASE; 00358 } 00359 00360 if (save_data) { 00361 // Acquisition task 00362 save_data = acquisition_task(true); 00363 } 00364 else { 00365 // Read task 00366 read_task(); 00367 } 00368 } 00369 } 00370 00371 /* Acquisition task */ 00372 bool acquisition_task(bool verbose) 00373 { 00374 int32_t m_axes[3]; 00375 int32_t acc_axes[3]; 00376 int32_t acc_axes_1[3]; 00377 int32_t gyro_axes[3]; 00378 float pressure_value, hum_value, temp_value, temp_value_1; 00379 int32_t data_buffer[DATA_SIZE/4]; 00380 00381 uint32_t Flash_addr = FLASH_BANK2_BASE; 00382 00383 while (Flash_addr <= FLASH_BANK2_END-DATA_SIZE+1) { 00384 // Read sensors data 00385 magnetometer->get_m_axes(m_axes); 00386 press_temp->get_pressure(&pressure_value); 00387 accelerometer->get_x_axes(acc_axes); 00388 hum_temp->get_temperature(&temp_value); 00389 hum_temp->get_humidity(&hum_value); 00390 temp->get_temperature(&temp_value_1); 00391 acc_gyro->get_x_axes(acc_axes_1); 00392 acc_gyro->get_g_axes(gyro_axes); 00393 00394 // Save data to Flash memory 00395 data_buffer[0] = m_axes[0]; 00396 data_buffer[1] = m_axes[1]; 00397 data_buffer[2] = m_axes[2]; 00398 data_buffer[3] = acc_axes[0]; 00399 data_buffer[4] = acc_axes[1]; 00400 data_buffer[5] = acc_axes[2]; 00401 data_buffer[6] = acc_axes_1[0]; 00402 data_buffer[7] = acc_axes_1[1]; 00403 data_buffer[8] = acc_axes_1[2]; 00404 data_buffer[9] = gyro_axes[0]; 00405 data_buffer[10] = gyro_axes[1]; 00406 data_buffer[11] = gyro_axes[2]; 00407 data_buffer[12] = (int32_t) FloatToUint(pressure_value); 00408 data_buffer[13] = (int32_t) FloatToUint(hum_value); 00409 data_buffer[14] = (int32_t) FloatToUint(temp_value); 00410 if (HAL_ADC_PollForConversion(&hadc, 5) == HAL_OK) 00411 { 00412 adcValue = HAL_ADC_GetValue(&hadc); 00413 } 00414 data_buffer[15] = (int32_t) FloatToUint(((float) adcValue)/4096 * VDD); 00415 00416 write_flash(Flash_addr, (uint32_t*) &data_buffer[0], DATA_SIZE/4, false); 00417 00418 // Increase Flash address 00419 Flash_addr += DATA_SIZE; 00420 00421 // Print data in terminal 00422 if (verbose) { 00423 printf("LIS2MDL: [mag/mgauss] %6d, %6d, %6d\r\n", ((uint32_t) m_axes[0]), ((uint32_t) m_axes[1]), ((uint32_t) m_axes[2])); 00424 printf("LPS22HH: [press/mbar] %1.3f, [alt/m] %1.3f\r\n", pressure_value, pressure_to_altitude(pressure_value)); 00425 printf("HTS221: [temp/deg C] %1.3f, [hum/%%] %1.3f\r\n", temp_value, hum_value); 00426 printf("STTS751 [temp/deg C] %1.3f\r\n", temp_value_1); 00427 printf("LIS2DW12: [acc/mg] %6d, %6d, %6d\r\n", ((uint32_t) acc_axes[0]), ((uint32_t) acc_axes[1]), ((uint32_t) acc_axes[2])); 00428 printf("LSM6DSO: [acc/mg] %6d, %6d, %6d\r\n", ((uint32_t) acc_axes_1[0]), ((uint32_t) acc_axes_1[1]), ((uint32_t) acc_axes_1[2])); 00429 printf("LSM6DSO: [gyro/mdps] %6d, %6d, %6d\r\n", ((uint32_t) gyro_axes[0]), ((uint32_t) gyro_axes[1]), ((uint32_t) gyro_axes[2])); 00430 } 00431 00432 // Wait for acquisition period 00433 wait(TS); 00434 00435 // Stop saving data when button is pushed 00436 if (button1_pressed) { 00437 button1_pressed = false; 00438 printf("Data acquisition stopped\r\n"); 00439 printf("Press 'R' to read the data\r\n"); 00440 return false; 00441 } 00442 } 00443 printf("Data acquisition stopped\r\n"); 00444 printf("Press 'R' to read the data\r\n"); 00445 return false; 00446 } 00447 00448 /* Read task */ 00449 void read_task() 00450 { 00451 char pc_input; 00452 uint32_t Flash_rdata[DATA_SIZE/4]; 00453 bool flash_empty = false; 00454 00455 // Read terminal input 00456 if (pc.readable()) { 00457 pc_input = pc.getc(); 00458 } 00459 else { 00460 pc_input = ' '; 00461 } 00462 00463 // Read Flash memory if 'R' is pressed 00464 if ((pc_input == 'r') || (pc_input == 'R')) { 00465 // Data labels 00466 printf("mag_X\tmag_Y\tmag_Z\tacc_X\tacc_Y\tacc_Z\tacc_X_1\tacc_Y_1\tacc_Z_1\tgyr_X\tgyr_Y\tgyr_Z\tpress\thum\ttemp\ttemp_1\r\n"); 00467 00468 // Read 1st Flash data 00469 uint32_t Flash_addr_temp = FLASH_BANK2_BASE; 00470 read_flash(Flash_addr_temp, &Flash_rdata[0], DATA_SIZE); 00471 00472 // Read Flash data 00473 while ((Flash_addr_temp <= FLASH_BANK2_END-DATA_SIZE+1) && !flash_empty) { 00474 // Print read data in the terminal 00475 printf("%6d\t%6d\t%6d\t%6d\t%6d\t%6d\t%6d\t%6d\t%6d\t%6d\t%6d\t%6d\t%1.6f\t%1.6f\t%1.6f\t%1.6f\r\n", Flash_rdata[0], Flash_rdata[1], Flash_rdata[2], Flash_rdata[3], Flash_rdata[4], Flash_rdata[5], Flash_rdata[6], Flash_rdata[7], Flash_rdata[8], Flash_rdata[9], Flash_rdata[10], Flash_rdata[11], UintToFloat(Flash_rdata[12]), UintToFloat(Flash_rdata[13]), UintToFloat(Flash_rdata[14]), UintToFloat(Flash_rdata[15])); 00476 Flash_addr_temp += DATA_SIZE; 00477 00478 // Check if the next address is not empty (erased Flash only contains 0) 00479 if (Flash_addr_temp <= FLASH_BANK2_END-DATA_SIZE+1) { 00480 read_flash(Flash_addr_temp, &Flash_rdata[0], DATA_SIZE); 00481 if ((Flash_rdata[0] == 0) && (Flash_rdata[1] == 0) && (Flash_rdata[2] == 0)) { 00482 flash_empty = true; 00483 } 00484 } 00485 } 00486 } 00487 } 00488 00489 /* Print Flash memory info */ 00490 void print_flash_info() 00491 { 00492 printf("**************************************************\n\r"); 00493 printf("/***** Flash memory info *****/\r\n"); 00494 printf("Flash size: %d [B]\r\n", FLASH_SIZE); 00495 printf("Flash page size: %d [B]\r\n", FLASH_PAGE_SIZE); 00496 printf("Flash nb of pages: %d \r\n", FLASH_SIZE/FLASH_PAGE_SIZE); 00497 printf("Flash bank 1 base address: 0x%X\r\n", FLASH_BASE); 00498 printf("Flash bank 1 end address: 0x%X\r\n", FLASH_BANK1_END); 00499 printf("Flash bank 2 base address: 0x%X\r\n", FLASH_BANK2_BASE); 00500 printf("Flash bank 2 end address: 0x%X\r\n", FLASH_BANK2_END); 00501 printf("**************************************************\n\r"); 00502 } 00503 00504 /* Erase content of Flash memory */ 00505 bool erase_flash(bool verbose) 00506 { 00507 printf("Erasing Flash memory...\r\n"); 00508 00509 // Unlock Flash memory 00510 HAL_FLASH_Unlock(); 00511 00512 // Erase Flash memory 00513 FLASH_EraseInitTypeDef eraser; 00514 uint32_t Flash_addr = FLASH_BANK2_BASE; 00515 uint32_t page_error = 0; 00516 int32_t page = 1; 00517 00518 while (Flash_addr < FLASH_BANK2_END) { 00519 eraser.TypeErase = FLASH_TYPEERASE_PAGES; 00520 eraser.PageAddress = Flash_addr; 00521 eraser.NbPages = 1; 00522 if(HAL_OK != HAL_FLASHEx_Erase(&eraser, &page_error)) { 00523 if (verbose) {printf("Flash erase failed!\r\n");} 00524 printf("Error 0x%X\r\n", page_error); 00525 HAL_FLASH_Lock(); 00526 return false; 00527 } 00528 if (verbose) {printf("Erased page %d at address: 0x%X\r\n", page, Flash_addr);} 00529 Flash_addr += FLASH_PAGE_SIZE; 00530 page++; 00531 } 00532 00533 if (verbose) {printf("Flash erase succesful!\r\n");} 00534 return true; 00535 } 00536 00537 /* Write Flash memory */ 00538 bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose) 00539 { 00540 clock_t time; 00541 if (verbose) {time = clock();} 00542 00543 // Unlock Flash memory 00544 HAL_FLASH_Unlock(); 00545 00546 // Write Flash memory 00547 for (int i=0; i<n_words; i++) { 00548 if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Flash_addr, Flash_wdata[i])) { 00549 if (verbose) {printf("Flash write failed!\r\n");} 00550 HAL_FLASH_Lock(); 00551 return false; 00552 } 00553 Flash_addr += 4; 00554 } 00555 if (verbose) {printf("Flash write succesful!\r\n");} 00556 00557 HAL_FLASH_Lock(); 00558 00559 if (verbose) { 00560 time = clock() - time; 00561 printf("Time to write: %1.6f [s]\r\n", (((double) time)/CLOCKS_PER_SEC)); 00562 } 00563 00564 return true; 00565 } 00566 00567 /* Read Flash memory */ 00568 void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes) 00569 { 00570 memcpy(Flash_rdata, (uint32_t*) Flash_addr, n_bytes); 00571 } 00572 00573 /* Enables button when bouncing is over */ 00574 void button1_enabled_cb(void) 00575 { 00576 button1_enabled = true; 00577 } 00578 00579 /* ISR handling button pressed event */ 00580 void button1_onpressed_cb(void) 00581 { 00582 if (button1_enabled) { // Disabled while the button is bouncing 00583 button1_enabled = false; 00584 button1_pressed = true; // To be read by the main loop 00585 button1_timeout.attach(callback(button1_enabled_cb), 0.3); // Debounce time 300 ms 00586 } 00587 } 00588 00589 /* Helper function for printing floats & doubles */ 00590 static char *print_double(char *str, double v) 00591 { 00592 int decimalDigits = 6; 00593 int i = 1; 00594 int intPart, fractPart; 00595 int len; 00596 char *ptr; 00597 00598 /* prepare decimal digits multiplicator */ 00599 for (; decimalDigits != 0; i *= 10, decimalDigits--); 00600 00601 /* calculate integer & fractinal parts */ 00602 intPart = (int)v; 00603 fractPart = (int)((v - (double)(int)v) * i); 00604 00605 /* fill in integer part */ 00606 sprintf(str, "%i.", intPart); 00607 00608 /* prepare fill in of fractional part */ 00609 len = strlen(str); 00610 ptr = &str[len]; 00611 00612 /* fill in leading fractional zeros */ 00613 for (i /= 10; i > 1; i /= 10, ptr++) { 00614 if (fractPart >= i) { 00615 break; 00616 } 00617 *ptr = '0'; 00618 } 00619 00620 /* fill in (rest of) fractional part */ 00621 sprintf(ptr, "%i", fractPart); 00622 00623 return str; 00624 } 00625 00626 /* Pressure to altitude conversion */ 00627 float pressure_to_altitude(double pressure) 00628 { 00629 return 44330.77 * (1-pow(pressure/P0, 0.1902632)); 00630 } 00631 00632 uint32_t FloatToUint(float n) 00633 { 00634 return (uint32_t)(*(uint32_t*)&n); 00635 } 00636 00637 float UintToFloat(uint32_t n) 00638 { 00639 return (float)(*(float*)&n); 00640 } 00641 00642 static void SystemClock_Config(void) 00643 { 00644 RCC_OscInitTypeDef RCC_OscInitStruct; 00645 RCC_ClkInitTypeDef RCC_ClkInitStruct; 00646 00647 /* Configure the main internal regulator output voltage */ 00648 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); 00649 00650 /* Initializes the CPU, AHB and APB busses clocks */ 00651 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; 00652 RCC_OscInitStruct.HSIState = RCC_HSI_ON; 00653 RCC_OscInitStruct.HSICalibrationValue = 16; 00654 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 00655 if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) 00656 { 00657 printf("Error in oscillator configuration\r\n"); 00658 } 00659 00660 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); 00661 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; 00662 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 00663 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; 00664 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; 00665 if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) 00666 { 00667 printf("Error in clock configuration\r\n"); 00668 } 00669 } 00670 00671 /** 00672 * @brief Conversion complete callback in non blocking mode 00673 * @param AdcHandle : AdcHandle handle 00674 * @note This example shows a simple way to report end of conversion, and 00675 * you can add your own implementation. 00676 * @retval None 00677 */ 00678 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *AdcHandle) 00679 { 00680 adcValue = HAL_ADC_GetValue(AdcHandle); 00681 } 00682 00683 /** 00684 * @brief This function is executed in case of error occurrence. 00685 * @param file: The file name as string. 00686 * @param line: The line in file as a number. 00687 * @retval None 00688 */ 00689 void _Error_Handler(char *file, int line) 00690 { 00691 while(1) 00692 { 00693 } 00694 }
Generated on Sat Jul 16 2022 00:25:56 by
1.7.2