2019-2020 Multisensor project using the X_NUCLEO_IKS01A3 sensor platform
Dependencies: X_NUCLEO_IKS01A3
main.cpp
- Committer:
- martlefebvre94
- Date:
- 2019-09-05
- Revision:
- 7:4a3b6202963e
- Parent:
- 6:b2e247935342
- Child:
- 8:fa346d946e7e
File content as of revision 7:4a3b6202963e:
/** ****************************************************************************** * @file main.cpp * @author SRA * @version V1.0.0 * @date 5-March-2019 * @brief Simple Example application for using the X_NUCLEO_IKS01A3 * MEMS Inertial & Environmental Sensor Nucleo expansion board. ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2> * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* LELEC2811 Magnetometer LIS2MDL Project M. Lefebvre - 2019 */ /* Includes */ #include <stdlib.h> #include "mbed.h" #include "XNucleoIKS01A3.h" #include "stm32l073xx.h" #include "stm32l0xx_hal_flash.h" /* Defines */ #define LIS2MDL_ODR 50.0 // Output data rate (10, 20, 50 or 100 Hz) #define LIS2MDL_LP 0 // Power mode (0 for high-resolution mode, 1 for low-power mode) #define LIS2MDL_LPF 0 // Bandwidth (0 for ODR/2, 1 for ODR/4) #define LIS2MDL_COMP_TEMP_EN 1 // Temperature compensation (0 disabled, 1 enabled) #define LIS2MDL_OFF_CANC 1 // Offset cancellation (0 for no offset cancellation, 1 for offset cancellation, 2 for set pulse only at power-on) #define FS 12.5 // Sampling frequency (Hz) /* Serial link */ Serial pc(SERIAL_TX, SERIAL_RX); /* Button */ InterruptIn button1(USER_BUTTON); volatile bool button1_pressed = false; // Used in the main loop volatile bool button1_enabled = true; // Used for debouncing Timeout button1_timeout; // Used for debouncing /* Instantiate the expansion board */ static XNucleoIKS01A3 *mems_expansion_board = XNucleoIKS01A3::instance(D14, D15, D4, D5, A3, D6, A4); /* Retrieve the composing elements of the expansion board */ static LIS2MDLSensor *magnetometer = mems_expansion_board->magnetometer; static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; static LPS22HHSensor *press_temp = mems_expansion_board->pt_sensor; static LSM6DSOSensor *acc_gyro = mems_expansion_board->acc_gyro; static LIS2DW12Sensor *accelerometer = mems_expansion_board->accelerometer; static STTS751Sensor *temp = mems_expansion_board->t_sensor; /* Erase content of Flash memory */ bool erase_flash(bool verbose) { printf("Erasing Flash memory...\r\n"); // Unlock Flash memory HAL_FLASH_Unlock(); // Erase Flash memory FLASH_EraseInitTypeDef eraser; uint32_t Flash_addr = FLASH_BANK2_BASE; uint32_t page_error = 0; int32_t page = 1; while (Flash_addr < FLASH_BANK2_END) { eraser.TypeErase = FLASH_TYPEERASE_PAGES; eraser.PageAddress = Flash_addr; eraser.NbPages = 1; if(HAL_OK != HAL_FLASHEx_Erase(&eraser, &page_error)) { if (verbose) {printf("Flash erase failed!\r\n");} printf("Error 0x%X\r\n", page_error); HAL_FLASH_Lock(); return false; } if (verbose) {printf("Erased page %d at address: 0x%X\r\n", page, Flash_addr);} Flash_addr += FLASH_PAGE_SIZE; page++; } if (verbose) {printf("Flash erase succesful!\r\n");} return true; } /* Write Flash memory */ bool write_flash(uint32_t Flash_addr, uint32_t Flash_wdata, bool verbose) { // Unlock Flash memory HAL_FLASH_Unlock(); // Write Flash memory if (HAL_OK != HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Flash_addr, Flash_wdata)) { if (verbose) {printf("Flash write failed!\r\n");} HAL_FLASH_Lock(); return false; } if (verbose) {printf("Flash write succesful!\r\n");} HAL_FLASH_Lock(); return true; } /* Read Flash memory */ void read_flash(uint32_t Flash_addr, uint32_t* Flash_rdata, uint32_t n_bytes) { memcpy(Flash_rdata, (uint32_t*) Flash_addr, n_bytes); } /* Print Flash memory info */ void print_flash_info() { printf("**************************************************\n\r"); printf("/***** Flash memory info *****/\r\n"); printf("Flash size: %d [B]\r\n", FLASH_SIZE); printf("Flash page size: %d [B]\r\n", FLASH_PAGE_SIZE); printf("Flash nb of pages: %d \r\n", FLASH_SIZE/FLASH_PAGE_SIZE); printf("Flash bank 1 base address: 0x%X\r\n", FLASH_BASE); printf("Flash bank 1 end address: 0x%X\r\n", FLASH_BANK1_END); printf("Flash bank 2 base address: 0x%X\r\n", FLASH_BANK2_BASE); printf("Flash bank 2 end address: 0x%X\r\n", FLASH_BANK2_END); printf("**************************************************\n\r"); } /* Enables button when bouncing is over */ void button1_enabled_cb(void) { button1_enabled = true; } /* ISR handling button pressed event */ void button1_onpressed_cb(void) { if (button1_enabled) { // Disabled while the button is bouncing button1_enabled = false; button1_pressed = true; // To be read by the main loop button1_timeout.attach(callback(button1_enabled_cb), 0.3); // Debounce time 300 ms } } /* Acquisition task */ bool acquisition_task(uint32_t* Flash_addr) { int32_t m_axes[3]; while (*Flash_addr < FLASH_BANK2_END) { // Read magnetometer data magnetometer->get_m_axes(m_axes); // Save data to Flash memory for (int i=0; i<3; i++) { //printf("Writing to address: 0x%X\r\n", *Flash_addr); write_flash(*Flash_addr, (uint32_t) m_axes[i], false); *Flash_addr += 4; } // Print data in terminal //printf("LIS2MDL [mag/mgauss]: %6d, %6d, %6d\r\n", ((uint32_t) m_axes[0]), ((uint32_t) m_axes[1]), ((uint32_t) m_axes[2])); // Wait for acquisition period wait(1/FS); // Stop saving data when button is pushed if (button1_pressed) { button1_pressed = false; printf("Data acquisition stopped\r\n"); printf("Press 'R' to read the data\r\n"); // Save last address in Flash memory write_flash(FLASH_BANK2_BASE, *Flash_addr, false); return false; } } return false; } /* Read task */ void read_task() { char pc_input; uint32_t Flash_rdata[3]; uint32_t Flash_addr; // Read terminal input if (pc.readable()) { pc_input = pc.getc(); //printf("Read character: %c\r\n", pc_input); } else { pc_input = 'a'; } // Read Flash memory if 'R' is pressed if ((pc_input == 'r') || (pc_input == 'R')) { // Read last written Flash address in Flash memory read_flash(FLASH_BANK2_BASE, &Flash_addr, 4); // Data names printf("mag_X\tmag_Y\tmag_Z\r\n"); // Read Flash data uint32_t Flash_addr_temp = FLASH_BANK2_BASE + 4; while (Flash_addr_temp < Flash_addr) { //printf("Reading from address: 0x%X\r\n", Flash_addr_temp); read_flash(Flash_addr_temp, &Flash_rdata[0], 12); Flash_addr_temp += 12; printf("%6d\t%6d\t%6d\r\n", Flash_rdata[0], Flash_rdata[1], Flash_rdata[2]); } } } /* Main */ int main() { uint8_t id; float read_reg; uint8_t read_reg_int; bool save_data = false; uint32_t Flash_addr = FLASH_BANK2_BASE; /* Serial link configuration */ pc.baud(115200); /* Button configuration */ button1.fall(callback(button1_onpressed_cb)); // Attach ISR to handle button press event // Reset message printf("\n\r**************************************************\n\r"); printf("LELEC2811 LIS2MDL Magnetometer Program\n\r"); printf("**************************************************\n\r"); /* Enable LIS2MDL magnetometer sensor */ magnetometer->enable(); /* LIS2MDL magnetometer sensor configuration */ printf("/***** LIS2MDL magnetometer configuration *****/\r\n"); magnetometer->read_id(&id); printf("LIS2MDL magnetometer = 0x%X\r\n", id); magnetometer->set_m_odr(LIS2MDL_ODR); magnetometer->get_m_odr(&read_reg); printf("LIS2MDL ODR = %1.1f [Hz]\r\n", read_reg); magnetometer->set_m_lp(LIS2MDL_LP); magnetometer->get_m_lp(&read_reg_int); printf("LIS2MDL LP = %1d\r\n", read_reg_int); magnetometer->set_m_lpf(LIS2MDL_LPF); magnetometer->get_m_lpf(&read_reg_int); printf("LIS2MDL LPF = %1d\r\n", read_reg_int); magnetometer->set_m_comp_temp_en(LIS2MDL_COMP_TEMP_EN); magnetometer->get_m_comp_temp_en(&read_reg_int); printf("LIS2MDL COMP_TEMP_EN = %1d\r\n", read_reg_int); magnetometer->set_m_off_canc(LIS2MDL_OFF_CANC); magnetometer->get_m_off_canc(&read_reg_int); printf("LIS2MDL OFF_CANC = %1d\r\n", read_reg_int); /* Print Flash memory information */ print_flash_info(); /* Information for the user */ printf("Press blue button to start data acquisition\r\n"); printf("Press 'R' to read previously measured data\r\n"); /* Acquisition loop */ while(1) { // Start saving data when button is pushed if (button1_pressed) { button1_pressed = false; save_data = true; erase_flash(false); printf("Acquiring data...\r\n"); printf("Press blue button to stop data acquisition\r\n"); Flash_addr = FLASH_BANK2_BASE + 4; } if (save_data) { // Acquisition task save_data = acquisition_task(&Flash_addr); } else { // Read task read_task(); } } }