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 Altimeter LPS22HH Project 00041 M. Lefebvre - 2019-2020 00042 */ 00043 00044 /* Includes */ 00045 #include <stdlib.h> 00046 #include <time.h> 00047 #include "mbed.h" 00048 #include "XNucleoIKS01A3.h" 00049 #include "stm32l073xx.h" 00050 #include "stm32l0xx_hal_flash.h" 00051 00052 /* Defines */ 00053 #define FS 10.0 // Readout frequency (Hz) 00054 00055 // LPS22HH Pressure sensor 00056 #define P0 1013.26 // Sea level pressure (hPa) 00057 #define LPS22HH_ODR 10.0 // Output data rate (one-shot, 1, 10, 25, 50, 75, 100, 200 Hz) 00058 #define LPS22HH_LOW_NOISE_EN 1 // Low-noise (0 disabled, 1 enabled) 00059 #define LPS22HH_LPF_CFG 3 // Device bandwidth (0 for ODR/2, 2 for ODR/9, 3 for ODR/20) 00060 #define LPS22HH_DATA_SIZE 8 // Number of bytes for LPS22HH pressure sensor data 00061 00062 /* Functions definition */ 00063 bool acquisition_task(bool verbose); 00064 void read_task(); 00065 void print_flash_info(); 00066 bool erase_flash(bool verbose); 00067 bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose); 00068 void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes); 00069 void button1_enabled_cb(void); 00070 void button1_onpressed_cb(void); 00071 static char *print_double(char *str, double v); 00072 float pressure_to_altitude(double pressure); 00073 uint32_t FloatToUint(float n); 00074 float UintToFloat(uint32_t n); 00075 00076 /* Serial link */ 00077 Serial pc(SERIAL_TX, SERIAL_RX); 00078 00079 /* Button */ 00080 InterruptIn button1(USER_BUTTON); 00081 volatile bool button1_pressed = false; // Used in the main loop 00082 volatile bool button1_enabled = true; // Used for debouncing 00083 Timeout button1_timeout; // Used for debouncing 00084 00085 /* Instantiate the expansion board */ 00086 static XNucleoIKS01A3 *mems_expansion_board = XNucleoIKS01A3::instance(D14, D15, D4, D5, A3, D6, A4); 00087 00088 /* Retrieve the composing elements of the expansion board */ 00089 static LIS2MDLSensor *magnetometer = mems_expansion_board->magnetometer; 00090 static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; 00091 static LPS22HHSensor *press_temp = mems_expansion_board->pt_sensor; 00092 static LSM6DSOSensor *acc_gyro = mems_expansion_board->acc_gyro; 00093 static LIS2DW12Sensor *accelerometer = mems_expansion_board->accelerometer; 00094 static STTS751Sensor *temp = mems_expansion_board->t_sensor; 00095 00096 /* Main */ 00097 int main() 00098 { 00099 uint8_t id; 00100 float read_reg, read_reg_1; 00101 uint8_t read_reg_int, read_reg_int_1, read_reg_int_2; 00102 00103 bool save_data = false; 00104 uint32_t Flash_addr = FLASH_BANK2_BASE; 00105 00106 /* Serial link configuration */ 00107 pc.baud(115200); 00108 00109 /* Button configuration */ 00110 button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event 00111 00112 /* Reset message */ 00113 printf("\n\r**************************************************\n\r"); 00114 printf("LELEC2811 LPS22HH Altimeter Program\n\r"); 00115 printf("**************************************************\n\r"); 00116 00117 /* LPS22HH pressure sensor configuration */ 00118 press_temp->enable(); 00119 printf("/***** LPS22HH pressure sensor configuration *****/\r\n"); 00120 00121 press_temp->read_id(&id); 00122 printf("LPS22HH pressure = 0x%X\r\n", id); 00123 00124 press_temp->set_odr(LPS22HH_ODR, LPS22HH_LOW_NOISE_EN); 00125 press_temp->get_odr(&read_reg, &read_reg_int); 00126 printf("LPS22HH ODR = %1.1f [Hz]\r\n", read_reg); 00127 printf("LPS22HH LOW_NOISE_EN = %1d\r\n", read_reg_int); 00128 00129 press_temp->set_lpfp_cfg(LPS22HH_LPF_CFG); 00130 press_temp->get_lpfp_cfg(&read_reg_int); 00131 printf("LPS22HH LPF_CFG = %1d\r\n", read_reg_int); 00132 00133 /* Print Flash memory information */ 00134 print_flash_info(); 00135 00136 /* Information for the user */ 00137 printf("Press blue button to start data acquisition\r\n"); 00138 printf("Press 'R' to read previously measured data\r\n"); 00139 00140 /* Acquisition loop */ 00141 while(1) { 00142 // Start saving data when button is pushed 00143 if (button1_pressed) { 00144 button1_pressed = false; 00145 save_data = true; 00146 erase_flash(false); 00147 printf("Acquiring data...\r\n"); 00148 printf("Press blue button to stop data acquisition\r\n"); 00149 Flash_addr = FLASH_BANK2_BASE; 00150 } 00151 00152 if (save_data) { 00153 // Acquisition task 00154 save_data = acquisition_task(false); 00155 } 00156 else { 00157 // Read task 00158 read_task(); 00159 } 00160 } 00161 } 00162 00163 /* Acquisition task */ 00164 bool acquisition_task(bool verbose) 00165 { 00166 float pressure_value, alt_value; 00167 00168 uint32_t buffer_size = FLASH_PAGE_SIZE/4; 00169 uint32_t data_ind = 0; 00170 uint32_t data_buffer[buffer_size]; 00171 00172 uint32_t Flash_addr = FLASH_BANK2_BASE; 00173 00174 while (Flash_addr <= FLASH_BANK2_END-FLASH_PAGE_SIZE+1) { 00175 // Read sensors data 00176 press_temp->get_pressure(&pressure_value); 00177 alt_value = pressure_to_altitude(pressure_value); 00178 00179 // Write page in Flash memory 00180 if (data_ind >= buffer_size) { 00181 write_flash(Flash_addr, &data_buffer[0], buffer_size, false); 00182 Flash_addr += FLASH_PAGE_SIZE; 00183 data_ind = 0; 00184 } 00185 00186 // Write data to buffer 00187 data_buffer[data_ind] = FloatToUint(pressure_value); 00188 data_buffer[data_ind+1] = FloatToUint(alt_value); 00189 data_ind = data_ind+2; 00190 00191 // Print data in terminal 00192 if (verbose) { 00193 printf("LPS22HH: [press/mbar] %1.6f, [alt/m] %1.6f\r\n", pressure_value, alt_value); 00194 } 00195 00196 // Wait for acquisition period 00197 wait(1/FS); 00198 00199 // Stop saving data when button is pushed 00200 if (button1_pressed) { 00201 button1_pressed = false; 00202 // Save remaining data to Flash memory 00203 write_flash(Flash_addr, &data_buffer[0], data_ind, false); 00204 printf("Data acquisition stopped\r\n"); 00205 printf("Press 'R' to read the data\r\n"); 00206 return false; 00207 } 00208 } 00209 printf("Data acquisition stopped\r\n"); 00210 printf("Press 'R' to read the data\r\n"); 00211 return false; 00212 } 00213 00214 /* Read task */ 00215 void read_task() 00216 { 00217 char pc_input; 00218 uint32_t Flash_rdata[2]; 00219 bool flash_empty = false; 00220 00221 // Read terminal input 00222 if (pc.readable()) { 00223 pc_input = pc.getc(); 00224 } 00225 else { 00226 pc_input = ' '; 00227 } 00228 00229 // Read Flash memory if 'R' is pressed 00230 if ((pc_input == 'r') || (pc_input == 'R')) { 00231 // Data labels 00232 printf("press\talt\r\n"); 00233 00234 // Read 1st Flash data 00235 uint32_t Flash_addr_temp = FLASH_BANK2_BASE; 00236 read_flash(Flash_addr_temp, &Flash_rdata[0], LPS22HH_DATA_SIZE); 00237 00238 // Read Flash data 00239 while ((Flash_addr_temp <= FLASH_BANK2_END-LPS22HH_DATA_SIZE+1) && !flash_empty) { 00240 // Print read data in the terminal 00241 printf("%1.6f\t%1.6f\r\n", UintToFloat(Flash_rdata[0]), UintToFloat(Flash_rdata[1])); 00242 Flash_addr_temp += LPS22HH_DATA_SIZE; 00243 00244 // Check if the next address is not empty (erased Flash only contains 0) 00245 if (Flash_addr_temp <= FLASH_BANK2_END-LPS22HH_DATA_SIZE+1) { 00246 read_flash(Flash_addr_temp, &Flash_rdata[0], LPS22HH_DATA_SIZE); 00247 if ((Flash_rdata[0] == 0) && (Flash_rdata[1] == 0)) { 00248 flash_empty = true; 00249 } 00250 } 00251 } 00252 } 00253 } 00254 00255 /* Print Flash memory info */ 00256 void print_flash_info() 00257 { 00258 printf("**************************************************\n\r"); 00259 printf("/***** Flash memory info *****/\r\n"); 00260 printf("Flash size: %d [B]\r\n", FLASH_SIZE); 00261 printf("Flash page size: %d [B]\r\n", FLASH_PAGE_SIZE); 00262 printf("Flash nb of pages: %d \r\n", FLASH_SIZE/FLASH_PAGE_SIZE); 00263 printf("Flash bank 1 base address: 0x%X\r\n", FLASH_BASE); 00264 printf("Flash bank 1 end address: 0x%X\r\n", FLASH_BANK1_END); 00265 printf("Flash bank 2 base address: 0x%X\r\n", FLASH_BANK2_BASE); 00266 printf("Flash bank 2 end address: 0x%X\r\n", FLASH_BANK2_END); 00267 printf("**************************************************\n\r"); 00268 } 00269 00270 /* Erase content of Flash memory */ 00271 bool erase_flash(bool verbose) 00272 { 00273 printf("Erasing Flash memory...\r\n"); 00274 00275 // Unlock Flash memory 00276 HAL_FLASH_Unlock(); 00277 00278 // Erase Flash memory 00279 FLASH_EraseInitTypeDef eraser; 00280 uint32_t Flash_addr = FLASH_BANK2_BASE; 00281 uint32_t page_error = 0; 00282 int32_t page = 1; 00283 00284 while (Flash_addr < FLASH_BANK2_END) { 00285 eraser.TypeErase = FLASH_TYPEERASE_PAGES; 00286 eraser.PageAddress = Flash_addr; 00287 eraser.NbPages = 1; 00288 if(HAL_OK != HAL_FLASHEx_Erase(&eraser, &page_error)) { 00289 if (verbose) {printf("Flash erase failed!\r\n");} 00290 printf("Error 0x%X\r\n", page_error); 00291 HAL_FLASH_Lock(); 00292 return false; 00293 } 00294 if (verbose) {printf("Erased page %d at address: 0x%X\r\n", page, Flash_addr);} 00295 Flash_addr += FLASH_PAGE_SIZE; 00296 page++; 00297 } 00298 00299 if (verbose) {printf("Flash erase succesful!\r\n");} 00300 return true; 00301 } 00302 00303 /* Write Flash memory */ 00304 bool write_flash(uint32_t Flash_addr, uint32_t* Flash_wdata, int32_t n_words, bool verbose) 00305 { 00306 clock_t time; 00307 if (verbose) {time = clock();} 00308 00309 // Unlock Flash memory 00310 HAL_FLASH_Unlock(); 00311 00312 // Write Flash memory 00313 for (int i=0; i<n_words; i++) { 00314 if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Flash_addr, Flash_wdata[i])) { 00315 if (verbose) {printf("Flash write failed!\r\n");} 00316 HAL_FLASH_Lock(); 00317 return false; 00318 } 00319 Flash_addr += 4; 00320 } 00321 if (verbose) {printf("Flash write succesful!\r\n");} 00322 00323 HAL_FLASH_Lock(); 00324 00325 if (verbose) { 00326 time = clock() - time; 00327 printf("Time to write: %1.6f [s]\r\n", (((double) time)/CLOCKS_PER_SEC)); 00328 } 00329 00330 return true; 00331 } 00332 00333 /* Read Flash memory */ 00334 void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes) 00335 { 00336 memcpy(Flash_rdata, (uint32_t*) Flash_addr, n_bytes); 00337 } 00338 00339 /* Enables button when bouncing is over */ 00340 void button1_enabled_cb(void) 00341 { 00342 button1_enabled = true; 00343 } 00344 00345 /* ISR handling button pressed event */ 00346 void button1_onpressed_cb(void) 00347 { 00348 if (button1_enabled) { // Disabled while the button is bouncing 00349 button1_enabled = false; 00350 button1_pressed = true; // To be read by the main loop 00351 button1_timeout.attach(callback(button1_enabled_cb), 0.3); // Debounce time 300 ms 00352 } 00353 } 00354 00355 /* Helper function for printing floats & doubles */ 00356 static char *print_double(char *str, double v) 00357 { 00358 int decimalDigits = 6; 00359 int i = 1; 00360 int intPart, fractPart; 00361 int len; 00362 char *ptr; 00363 00364 /* prepare decimal digits multiplicator */ 00365 for (; decimalDigits != 0; i *= 10, decimalDigits--); 00366 00367 /* calculate integer & fractinal parts */ 00368 intPart = (int)v; 00369 fractPart = (int)((v - (double)(int)v) * i); 00370 00371 /* fill in integer part */ 00372 sprintf(str, "%i.", intPart); 00373 00374 /* prepare fill in of fractional part */ 00375 len = strlen(str); 00376 ptr = &str[len]; 00377 00378 /* fill in leading fractional zeros */ 00379 for (i /= 10; i > 1; i /= 10, ptr++) { 00380 if (fractPart >= i) { 00381 break; 00382 } 00383 *ptr = '0'; 00384 } 00385 00386 /* fill in (rest of) fractional part */ 00387 sprintf(ptr, "%i", fractPart); 00388 00389 return str; 00390 } 00391 00392 /* Pressure to altitude conversion */ 00393 float pressure_to_altitude(double pressure) 00394 { 00395 return 44330.77 * (1-pow(pressure/P0, 0.1902632)); 00396 } 00397 00398 uint32_t FloatToUint(float n) 00399 { 00400 return (uint32_t)(*(uint32_t*)&n); 00401 } 00402 00403 float UintToFloat(uint32_t n) 00404 { 00405 return (float)(*(float*)&n); 00406 }
Generated on Fri Jul 15 2022 07:28:32 by
1.7.2