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