Maxim Integrated / Mbed OS MAXREFDES101_SOURCE

Dependencies:   max32630fthr Adafruit_FeatherOLED USBDevice

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*******************************************************************************
00002 * Copyright (C) Maxim Integrated Products, Inc., All rights Reserved.
00003 * 
00004 * This software is protected by copyright laws of the United States and
00005 * of foreign countries. This material may also be protected by patent laws
00006 * and technology transfer regulations of the United States and of foreign
00007 * countries. This software is furnished under a license agreement and/or a
00008 * nondisclosure agreement and may only be used or reproduced in accordance
00009 * with the terms of those agreements. Dissemination of this information to
00010 * any party or parties not specified in the license agreement and/or
00011 * nondisclosure agreement is expressly prohibited.
00012 *
00013 * The above copyright notice and this permission notice shall be included
00014 * in all copies or substantial portions of the Software.
00015 *
00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00017 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00019 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00020 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00021 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00022 * OTHER DEALINGS IN THE SOFTWARE.
00023 *
00024 * Except as contained in this notice, the name of Maxim Integrated
00025 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00026 * Products, Inc. Branding Policy.
00027 *
00028 * The mere transfer of this software does not imply any licenses
00029 * of trade secrets, proprietary technology, copyrights, patents,
00030 * trademarks, maskwork rights, or any other form of intellectual
00031 * property whatsoever. Maxim Integrated Products, Inc. retains all
00032 * ownership rights.
00033 *******************************************************************************
00034 */
00035 
00036 #include "mbed.h"
00037 #include "USBSerial.h"
00038 #include "version.h"
00039 #include "DSInterface.h"
00040 #include "Peripherals.h"
00041 #include "usb_regs.h"
00042 
00043 #define GPIO_PRIOINVERSION_MASK     NVIC_SetPriority(GPIO_P0_IRQn, 5); \
00044                                     NVIC_SetPriority(GPIO_P1_IRQn, 5); \
00045                                     NVIC_SetPriority(GPIO_P2_IRQn, 5); \
00046                                     NVIC_SetPriority(GPIO_P3_IRQn, 5); \
00047                                     NVIC_SetPriority(GPIO_P4_IRQn, 5); \
00048                                     NVIC_SetPriority(GPIO_P5_IRQn, 5); \
00049                                     NVIC_SetPriority(GPIO_P6_IRQn, 5);
00050 
00051 
00052 #if defined(MBED_MEM_TRACING_ENABLED)
00053 #include "mbed_mem_trace.h"
00054 #endif /* MBED_MEM_TRACING_ENABLED */
00055 
00056 #if defined(MBED_HEAP_STATS_ENABLED)
00057 #include "mbed_stats.h"
00058 #endif /* MBED_HEAP_STATS_ENABLED */
00059 
00060 #if defined(MBED_STACK_STATS_ENABLED)
00061 #include "cmsis_os.h"
00062 #endif /* MBED_STACK_STATS_ENABLED */
00063 
00064 
00065 
00066 
00067 
00068 //
00069 // BOARD
00070 //
00071 #include "max32630hsp.h"
00072 DigitalIn   button(P6_5);
00073 InterruptIn interruptIn_PowerButton(P7_6);
00074 MAX32630HSP icarus(MAX32630HSP::VIO_1V8, &interruptIn_PowerButton);
00075 
00076 //
00077 // LED
00078 //
00079 #include "LEDStatus.h"
00080 LEDStatus ledStatus(LED1, LED_ON, LED2, LED_ON, LED3, LED_OFF);
00081 
00082 // Virtual serial port over USB
00083 USBSerial microUSB(0x1f00, 0x2012, 0x0001, false);
00084 #define IS_USB_HOST_CONNECTED()  ((uint8_t)((MXC_USB->dev_intfl & MXC_F_USB_DEV_INTFL_VBUS_ST) >> MXC_F_USB_DEV_INTFL_VBUS_ST_POS))
00085 
00086 //
00087 // DS INTERFACE. COMMAND IN DATA OUT POINT FOR HOST. ROOF INTERFACE TO ALL SUB MODULES
00088 //
00089 DSInterface dsInterface(&microUSB);
00090 
00091 //
00092 // BLE
00093 //
00094 #include "BLE.h"
00095 #include "BLE_ICARUS.h"
00096 #ifdef ENABLE_BLETEST_COMM
00097 #include "BleTestComm.h"
00098 BleTestComm bleTestComm(&microUSB);
00099 #endif
00100 
00101 
00102 
00103 
00104 //
00105 // DISPLAY INTERFACE.
00106 //
00107 #include "LS013B7DH03.h"
00108 #include "mbed_logo.h"
00109 SPI displaySPI(P0_5, P0_6, P0_4, NC);
00110 
00111 #include "WatchInterface.h"
00112 #define PIN_BUTTON_UP       P2_3
00113 #define PIN_BUTTON_DOWN     P6_5
00114 #define PIN_BUTTON_PWR      P7_6
00115 #define PIN_displayCS       P0_7
00116 #define PIN_displayEXTCOM   P6_4
00117 #define PIN_displayDISP     P6_6
00118 WatchInterface watchInterface(PIN_BUTTON_UP, PIN_BUTTON_DOWN, PIN_BUTTON_PWR, PIN_displayCS, PIN_displayEXTCOM, PIN_displayDISP, &displaySPI);
00119 
00120 
00121 //
00122 // HOST ACCELEROMETER.
00123 //
00124 #include "bmi160.h"
00125 //#include "C:\Users\mehmet.gok\Desktop\DEV\BPTDEMO\wearables_MBED\Drivers\BMI160\bmi160.h"
00126 InterruptIn bmi160_int_pin(P3_6);
00127 I2C I2CM2(P5_7, P6_0); /* SDA, SCL */
00128 BMI160_I2C bmi160_dev(&I2CM2, BMI160_I2C::I2C_ADRS_SDO_LO, &bmi160_int_pin);
00129 
00130 
00131 //
00132 // ECG SENSOR
00133 //
00134 #include "EcgComm.h"
00135 EcgComm ecgCommHandler(&microUSB);
00136 
00137 #include "MAX30001.h"
00138 #include "MAX30001_Helper.h"
00139 SPI max30001_spi(P5_1, P5_2, P5_0);
00140 DigitalOut max30001_cs(P5_3);
00141 MAX30001 max30001(&max30001_spi, &max30001_cs);
00142 InterruptIn max30001_InterruptB(P5_5);
00143 InterruptIn max30001_Interrupt2B(P6_2);
00144 
00145 
00146 //
00147 // TEMP SENSOR
00148 //
00149 #include "TempComm.h"
00150 TempComm tpCommHandler(&microUSB);
00151 #include "MAX30205.h"
00152 I2C i2c(P3_4, P3_5);
00153 MAX30205 max30205(&i2c, (0x90 >> 1));
00154 //enable the LDO for temp sensor
00155 DigitalOut max30205_LDO_EN(P7_1, 1);
00156 
00157 
00158 //
00159 // ME11 SMART SENSOR INTERFACE
00160 //
00161 #include "SSInterface.h"
00162 I2C ssI2C(P3_4, P3_5);
00163 PinName ss_mfio(P5_4);
00164 PinName ss_reset(P5_6);
00165 SSInterface ssInterface(ssI2C, ss_mfio, ss_reset);
00166 
00167 #include "SSBootloaderComm.h"
00168 SSBootloaderComm ssBoot(&microUSB, &ssInterface, &dsInterface);
00169 
00170 #include "SSMAX8614XComm.h"
00171 SSMAX8614XComm ssMAX8614X(&microUSB, &ssInterface, &dsInterface);
00172 
00173 #include "SSGenericCmd.h"
00174 SSGenericCmd ssGenericCmd(&microUSB, &ssInterface, &dsInterface);
00175 
00176 
00177 //
00178 // MX25U Flash Driver Definition
00179 //
00180 #define MHZ_VALUE 1000000
00181 #define SPI_MHZ   16
00182 #define SPI_FREQUENCY (SPI_MHZ * MHZ_VALUE)
00183 #include "SPIFBlockDevice.h"
00184 #include "FATFileSystem.h"
00185 
00186 DigitalOut flash_nHOLD(P1_5);
00187 SPIFBlockDevice spif(P1_1, P1_2, P1_0, P1_3, SPI_FREQUENCY);
00188 FATFileSystem filesystem("fs");
00189 // USB MSD
00190 #include "USBMSD_BD.h"
00191 
00192 
00193 
00194 //
00195 // Hardware serial port over DAPLink
00196 //
00197 Serial daplink(USBTX, USBRX, 115200);
00198 
00199 
00200 
00201 static void setup_ble(void);
00202 static void process_ble(void);
00203 static void print_build_version(void);
00204 static void HSP_run_in_usbmcd_mode(void);
00205 static void HSP_mount_filesystem(void);
00206 
00207 #ifdef ENABLE_MEMORY_DEBUG
00208 void print_memory_info();
00209 #endif
00210 
00211 
00212 int main()
00213 {
00214     wait_ms(100);
00215 
00216     HSP_mount_filesystem();
00217 
00218     if (watchInterface.getButtonStatus(WatchInterface::BUTTON_UP) == WatchInterface::BUTTON_RELEASED) {
00219         HSP_run_in_usbmcd_mode();
00220     }
00221     wait_ms(500);
00222 
00223 
00224     GPIO_PRIOINVERSION_MASK;
00225 
00226     // used by the MAX30001
00227     NVIC_SetPriority(SPIM2_IRQn, 0);
00228 
00229 
00230     watchInterface.bootComplete = true;
00231     print_build_version();
00232     daplink.printf("daplink serial port\r\n");
00233     microUSB.printf("micro USB serial port\r\n");
00234 
00235     //dsInterface.set_fw_version(FIRMWARE_VERSION);
00236 #define MAXIM_PLATFORM_NAME "Pegasus"
00237     dsInterface.set_fw_platform(MAXIM_PLATFORM_NAME);
00238     Peripherals::setUSBSerial(&microUSB);
00239 
00240     icarus.max20303.Max20303_IsBattery_Connected();
00241     watchInterface.m_max20303_ = &icarus.max20303;
00242 
00243 
00244     setup_ble();
00245 #ifdef ENABLE_BLETEST_COMM
00246     dsInterface.add_sensor_comm(&bleTestComm);
00247 #endif
00248 
00249     //
00250     // MAX30001
00251     //
00252     printf("Init MAX30001 callbacks, interrupts...\r\n");
00253     MAX30001_Helper m_max30001helper(&max30001, &max30001_InterruptB, &max30001_Interrupt2B);
00254     Peripherals::setMAX30001(&max30001);
00255     Peripherals::setMAX30001Helper(&m_max30001helper);
00256     ecgCommHandler.comm_init(&m_max30001helper);
00257     dsInterface.add_sensor_comm(&ecgCommHandler);
00258 
00259     //
00260     //MAX30205
00261     //
00262     tpCommHandler.comm_init(&max30205);
00263     dsInterface.add_sensor_comm(&tpCommHandler);
00264 
00265     //Configure mfio as a level based interrupt (no mbed API for this, must use Maxim-specific code)
00266     //gpio_cfg_t mfio_gpio_cfg = {PORT_5, PIN_4, GPIO_FUNC_GPIO, GPIO_PAD_INPUT_PULLUP};
00267     //GPIO_IntConfig(&mfio_gpio_cfg, GPIO_INT_LOW_LEVEL);
00268     ssI2C.frequency(400000);
00269     dsInterface.set_fw_platform(ssInterface.get_ss_platform_name());
00270     dsInterface.set_fw_version(ssInterface.get_ss_fw_version());
00271 
00272     //
00273     //REGISTER BOOTLOADER API TO SS INTERFACE
00274     //
00275     dsInterface.add_sensor_comm(&ssBoot);
00276 
00277     //
00278     //REGISTER 8614X PPG SENSOR API TO SS INTERFACE
00279     //
00280     dsInterface.add_sensor_comm(&ssMAX8614X);
00281     ssMAX8614X.setBMI160(&bmi160_dev);
00282 
00283     //
00284     //REGISTER GENERIC COMMAND API TO SS INTERFACE
00285     //
00286     dsInterface.add_sensor_comm(&ssGenericCmd);
00287 
00288 
00289     //Blink green if SmartSensor is present, yellow otherwise
00290     SS_STATUS status = ssInterface.ss_comm_check();
00291     if (status == SS_SUCCESS)
00292         ledStatus.set_state(LED_OFF, LED_ON, LED_OFF);
00293     else
00294         ledStatus.set_state(LED_ON, LED_ON, LED_OFF);
00295     ledStatus.blink(100, 1900);
00296     ledStatus.blink(100, 1900);
00297 
00298     //
00299     //MAIN CONTEXT LOOP
00300     //
00301     while (1) {
00302 
00303         USBSerial* serial = &microUSB;
00304         uint8_t ch;
00305         while (serial->readable()) {
00306             ch = serial->_getc();
00307             dsInterface.enable_console_interface();
00308             dsInterface.build_command(ch);
00309         }
00310 
00311 
00312         if(dsInterface.recordingStarted) {
00313             if((icarus.status_powerButton == MAX32630HSP::BUTTONSTATUS_LONG_PRESS_WAITING) ||
00314                (watchInterface.batteryLevel <= BATTERY_CRITICAL_LEVEL)) {
00315                 dsInterface.stopcommand();
00316                 dsInterface.force_file_close();
00317             }
00318         }
00319 
00320         icarus.Max32630HSP_CheckInterrupt_Status();
00321         //
00322         // DSINTERFACE CONTEXT as all other interfaces is run by call to its data_report_execute function!!
00323         //
00324         dsInterface.data_report_execute();
00325 
00326         if (ecgCommHandler.is_enabled() != watchInterface.ecg_enabled) {
00327 
00328             if (ecgCommHandler.is_enabled()) {
00329 
00330                 if (!dsInterface.recordingStarted) {
00331                     watchInterface.displayMode = DISPLAYMODE_ECG;
00332                 }
00333 
00334                 // Turn off LEDs
00335                 ledStatus.set_state(1, 1, 1);
00336                 ledStatus.solid();
00337                 ledStatus.set_state(1, 1, 1);
00338             } else {
00339 
00340                 if (!dsInterface.recordingStarted) {
00341                     watchInterface.displayMode = DISPLAYMODE_TIME;
00342                 }
00343 
00344             }
00345             watchInterface.ecg_enabled = ecgCommHandler.is_enabled();
00346 
00347         }
00348 
00349         // Sensor Interface Updates on Watch display mode changes
00350         if (watchInterface.modeUpdated) {
00351 
00352             watchInterface.modeUpdated = false;
00353             watchInterface.DisplayModeUpdated();
00354 
00355             // Tethered mode
00356             if ((watchInterface.BLE_Interface_Exists) || (watchInterface.USB_Interface_Exists)) {
00357 
00358 
00359                 // Stop all sensors
00360                 if(!dsInterface.recordingStarted)
00361                     dsInterface.stopcommand();
00362 
00363 
00364             } else
00365                 // Not in tethered mode
00366             {
00367 
00368                 switch (watchInterface.displayMode) {
00369 
00370                     case DISPLAYMODE_INFO :
00371 
00372                         // Before switching to INFO screen, stop all sensors
00373                         if (!dsInterface.recordingStarted) {
00374                             dsInterface.stopcommand();
00375                         }
00376 
00377                         break;
00378                     case DISPLAYMODE_TIME :
00379 
00380                         // Before switching to TIME screen, stop all sensors
00381                         if (!dsInterface.recordingStarted) {
00382                             dsInterface.stopcommand();
00383                         }
00384 
00385                         break;
00386                     case DISPLAYMODE_PPG :
00387 
00388                         // Before switching to PPG screen, stop all sensors
00389                         if (!dsInterface.recordingStarted) {
00390                             dsInterface.stopcommand();
00391                             dsInterface.parse_command_str("set_reg ppg 2a 10");
00392                             dsInterface.parse_command_str("set_reg ppg 23 ff");
00393                             dsInterface.parse_command_str("read ppg 0");
00394                         }
00395 
00396                         break;
00397 
00398                     case DISPLAYMODE_TEMP :
00399 
00400                         // Before switching to TEMP screen, stop all sensors
00401                         if (!dsInterface.recordingStarted)  {
00402                             dsInterface.stopcommand();
00403                             dsInterface.parse_command_str("set_cfg temp sr 500");
00404                             dsInterface.parse_command_str("read temp 0");
00405                         }
00406 
00407                         break;
00408 
00409                 }
00410             }
00411         }
00412 
00413         // Update the watch interface with the latest data
00414         watchInterface.instant_temp_celsius = tpCommHandler.TempComm_instant_temp_celsius;
00415         watchInterface.instant_hr           = ssMAX8614X.instant_hr;
00416         watchInterface.instant_hr_conf      = ssMAX8614X.instant_hr_conf;
00417 
00418         watchInterface.BLE_Interface_Exists = BLE::Instance().gap().getState().connected;
00419         watchInterface.USB_Interface_Exists = IS_USB_HOST_CONNECTED();
00420 
00421         if (watchInterface.recordingStopFlag) {
00422 
00423             watchInterface.recordingStopFlag = false;
00424             watchInterface.recording         = false;
00425             watchInterface.recording_old     = false;
00426             dsInterface.stopcommand();
00427             ledStatus.set_state(LED_OFF, LED_ON, LED_OFF);
00428             ledStatus.blink(100, 1900);
00429         } else {
00430             watchInterface.recording            = dsInterface.recordingStarted;
00431         }
00432 
00433 
00434         if (watchInterface.BLE_Interface_Exists || watchInterface.USB_Interface_Exists) {
00435             watchInterface.connection_indicator++;
00436             if (watchInterface.connection_indicator == 1) {
00437 
00438                 if (!dsInterface.recordingStarted) {
00439                     dsInterface.stopcommand();
00440                 }
00441 
00442             } else if (watchInterface.connection_indicator > 50) {
00443                 watchInterface.connection_indicator = 2;
00444             }
00445 
00446         }
00447 
00448         watchInterface.execute();
00449         process_ble();
00450         ledStatus.update();
00451 
00452 #ifdef ENABLE_MEMORY_DEBUG
00453         print_memory_info();
00454 #endif
00455     }
00456 }
00457 
00458 
00459 
00460 
00461 static void setup_ble(void)
00462 {
00463 
00464     //Set up BLE communication
00465     BLE& ble = BLE::Instance();
00466     ble.init(bleInitComplete);
00467     while (BLE::Instance().hasInitialized() == false) { /* spin loop */ }
00468     BLE_Icarus_SetDSInterface(&dsInterface);
00469 
00470     char addr[6];
00471     BLE_ICARUS_Get_Mac_Address(addr);
00472     printf("BLE MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\r\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
00473 
00474 
00475     memcpy(watchInterface.m_mac_addr_, addr, 6);
00476 
00477 
00478 
00479 }
00480 
00481 static void process_ble(void)
00482 {
00483 
00484     if (BLE::Instance().gap().getState().connected) {
00485         BLE_Icarus_TransferDataFromQueue();
00486     }
00487     BLE::Instance().waitForEvent();
00488 
00489 }
00490 
00491 static void print_build_version(void)
00492 {
00493     printf("\n\nICARUS mBED EVKit\r\n");
00494     printf("Fw version: %s, mbed version: %d\r\n", FIRMWARE_VERSION, MBED_VERSION);
00495     printf("Build source: (%s)  %s\r\n", BUILD_SOURCE_BRANCH, BUILD_SOURCE_HASH);
00496     printf("Build time: %s  %s\r\n\n", __TIME__, __DATE__);
00497 }
00498 
00499 static void HSP_run_in_usbmcd_mode(void){
00500 
00501     int err;
00502 
00503     const int writecyclecount = 256;
00504     watchInterface.USB_Interface_Exists = false;
00505     watchInterface.USB_Interface_MSD   = true;
00506     watchInterface.bootComplete        = true;
00507     watchInterface.displayMode = DISPLAYMODE_TETHERED_USB;
00508     watchInterface.updateDisplay(4);
00509 
00510     for(int i = 0; i < writecyclecount; ++i) {
00511         watchInterface.execute();
00512         wait_ms(1);
00513     }
00514 
00515     USBMSD_BD msd(&spif);
00516     printf("Starting MSD... ");
00517     msd.disk_initialize();
00518     err = msd.connect();
00519     ledStatus.set_state(1, 1, 0);
00520     printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
00521 
00522     msd.disk_initialize();
00523     err = msd.connect();
00524 
00525     GPIO_PRIOINVERSION_MASK;
00526 
00527     while (1) {
00528 
00529         icarus.Max32630HSP_CheckInterrupt_Status();
00530 
00531         wait_ms(1);
00532     }
00533 }
00534 
00535 static void HSP_mount_filesystem(void){
00536 
00537     // For ISSI part, in 3-wire SPI mode, HOLD pin should be tied to high to un-pause communication
00538     flash_nHOLD = 1;
00539     // Try to mount the filesystem
00540     printf("Mounting the filesystem... ");
00541     fflush(stdout);
00542     int err = filesystem.mount(&spif);
00543     printf("%s\n", (err ? "Fail :(" : "OK"));
00544     if (err) {
00545         // Reformat if we can't mount the filesystem
00546         // this should only happen on the first boot
00547         printf("No filesystem found, formatting... ");
00548         fflush(stdout);
00549         err = filesystem.reformat(&spif);
00550         printf("%s\n", (err ? "Fail :(" : "OK"));
00551     }
00552 
00553 }
00554 
00555 
00556 
00557 #ifdef ENABLE_MEMORY_DEBUG
00558 void print_memory_info() {
00559     static int threadStackSize[8] = {0};
00560     static int heapSize = 0;
00561     // allocate enough room for every thread's stack statistics
00562     int cnt = osThreadGetCount();
00563     mbed_stats_stack_t *stats = (mbed_stats_stack_t*) malloc(cnt * sizeof(mbed_stats_stack_t));
00564 
00565     cnt = mbed_stats_stack_get_each(stats, cnt);
00566     for (int i = 0; i < cnt; i++) {
00567         if(threadStackSize[i] < stats[i].max_size){
00568             printf("Thread: 0x%lX, Stack size: %lu / %lu\r\n", stats[i].thread_id, stats[i].max_size, stats[i].reserved_size);
00569             threadStackSize[i] = stats[i].max_size;
00570         }
00571     }
00572     free(stats);
00573 
00574     // Grab the heap statistics
00575     mbed_stats_heap_t heap_stats;
00576     mbed_stats_heap_get(&heap_stats);
00577     if(heapSize < heap_stats.current_size){
00578         printf("Heap size: %lu / %lu bytes\r\n", heap_stats.current_size, heap_stats.reserved_size);
00579         heapSize = heap_stats.current_size;
00580     }
00581 }
00582 #endif