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: max32630fthr Adafruit_FeatherOLED USBDevice
Diff: main.cpp
- Revision:
- 1:f60eafbf009a
- Parent:
- 0:07d28b5db986
- Child:
- 3:2fe2ff1ca0dc
--- a/main.cpp Wed Apr 10 11:51:07 2019 +0000 +++ b/main.cpp Wed Apr 10 14:56:25 2019 +0300 @@ -1,2 +1,546 @@ +#include "mbed.h" +#include "USBSerial.h" +#include "version.h" +#include "DSInterface.h" +#include "Peripherals.h" +#include "usb_regs.h" -#include "mbed.h" \ No newline at end of file +#define GPIO_PRIOINVERSION_MASK NVIC_SetPriority(GPIO_P0_IRQn, 5); \ + NVIC_SetPriority(GPIO_P1_IRQn, 5); \ + NVIC_SetPriority(GPIO_P2_IRQn, 5); \ + NVIC_SetPriority(GPIO_P3_IRQn, 5); \ + NVIC_SetPriority(GPIO_P4_IRQn, 5); \ + NVIC_SetPriority(GPIO_P5_IRQn, 5); \ + NVIC_SetPriority(GPIO_P6_IRQn, 5); + + +#if defined(MBED_MEM_TRACING_ENABLED) +#include "mbed_mem_trace.h" +#endif /* MBED_MEM_TRACING_ENABLED */ + +#if defined(MBED_HEAP_STATS_ENABLED) +#include "mbed_stats.h" +#endif /* MBED_HEAP_STATS_ENABLED */ + +#if defined(MBED_STACK_STATS_ENABLED) +#include "cmsis_os.h" +#endif /* MBED_STACK_STATS_ENABLED */ + + + + + +// +// BOARD +// +#include "max32630hsp.h" +DigitalIn button(P6_5); +InterruptIn interruptIn_PowerButton(P7_6); +MAX32630HSP icarus(MAX32630HSP::VIO_1V8, &interruptIn_PowerButton); + +// +// LED +// +#include "LEDStatus.h" +LEDStatus ledStatus(LED1, LED_ON, LED2, LED_ON, LED3, LED_OFF); + +// Virtual serial port over USB +USBSerial microUSB(0x1f00, 0x2012, 0x0001, false); +#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)) + +// +// DS INTERFACE. COMMAND IN DATA OUT POINT FOR HOST. ROOF INTERFACE TO ALL SUB MODULES +// +DSInterface dsInterface(µUSB); + +// +// BLE +// +#include "BLE.h" +#include "BLE_ICARUS.h" +#ifdef ENABLE_BLETEST_COMM +#include "BleTestComm.h" +BleTestComm bleTestComm(µUSB); +#endif + + + + +// +// DISPLAY INTERFACE. +// +#include "LS013B7DH03.h" +#include "mbed_logo.h" +SPI displaySPI(P0_5, P0_6, P0_4, NC); + +#include "WatchInterface.h" +#define PIN_BUTTON_UP P2_3 +#define PIN_BUTTON_DOWN P6_5 +#define PIN_BUTTON_PWR P7_6 +#define PIN_displayCS P0_7 +#define PIN_displayEXTCOM P6_4 +#define PIN_displayDISP P6_6 +WatchInterface watchInterface(PIN_BUTTON_UP, PIN_BUTTON_DOWN, PIN_BUTTON_PWR, PIN_displayCS, PIN_displayEXTCOM, PIN_displayDISP, &displaySPI); + + +// +// HOST ACCELEROMETER. +// +#include "bmi160.h" +//#include "C:\Users\mehmet.gok\Desktop\DEV\BPTDEMO\wearables_MBED\Drivers\BMI160\bmi160.h" +InterruptIn bmi160_int_pin(P3_6); +I2C I2CM2(P5_7, P6_0); /* SDA, SCL */ +BMI160_I2C bmi160_dev(&I2CM2, BMI160_I2C::I2C_ADRS_SDO_LO, &bmi160_int_pin); + + +// +// ECG SENSOR +// +#include "EcgComm.h" +EcgComm ecgCommHandler(µUSB); + +#include "MAX30001.h" +#include "MAX30001_Helper.h" +SPI max30001_spi(P5_1, P5_2, P5_0); +DigitalOut max30001_cs(P5_3); +MAX30001 max30001(&max30001_spi, &max30001_cs); +InterruptIn max30001_InterruptB(P5_5); +InterruptIn max30001_Interrupt2B(P6_2); + + +// +// TEMP SENSOR +// +#include "TempComm.h" +TempComm tpCommHandler(µUSB); +#include "MAX30205.h" +I2C i2c(P3_4, P3_5); +MAX30205 max30205(&i2c, (0x90 >> 1)); +//enable the LDO for temp sensor +DigitalOut max30205_LDO_EN(P7_1, 1); + + +// +// ME11 SMART SENSOR INTERFACE +// +#include "SSInterface.h" +I2C ssI2C(P3_4, P3_5); +PinName ss_mfio(P5_4); +PinName ss_reset(P5_6); +SSInterface ssInterface(ssI2C, ss_mfio, ss_reset); + +#include "SSBootloaderComm.h" +SSBootloaderComm ssBoot(µUSB, &ssInterface, &dsInterface); + +#include "SSMAX8614XComm.h" +SSMAX8614XComm ssMAX8614X(µUSB, &ssInterface, &dsInterface); + +#include "SSGenericCmd.h" +SSGenericCmd ssGenericCmd(µUSB, &ssInterface, &dsInterface); + + +// +// MX25U Flash Driver Definition +// +#define MHZ_VALUE 1000000 +#define SPI_MHZ 16 +#define SPI_FREQUENCY (SPI_MHZ * MHZ_VALUE) +#include "SPIFBlockDevice.h" +#include "FATFileSystem.h" + +DigitalOut flash_nHOLD(P1_5); +SPIFBlockDevice spif(P1_1, P1_2, P1_0, P1_3, SPI_FREQUENCY); +FATFileSystem filesystem("fs"); +// USB MSD +#include "USBMSD_BD.h" + + + +// +// Hardware serial port over DAPLink +// +Serial daplink(USBTX, USBRX, 115200); + + + +static void setup_ble(void); +static void process_ble(void); +static void print_build_version(void); +static void HSP_run_in_usbmcd_mode(void); +static void HSP_mount_filesystem(void); + +#ifdef ENABLE_MEMORY_DEBUG +void print_memory_info(); +#endif + + +int main() +{ + wait_ms(100); + + HSP_mount_filesystem(); + + if (watchInterface.getButtonStatus(WatchInterface::BUTTON_UP) == WatchInterface::BUTTON_RELEASED) { + HSP_run_in_usbmcd_mode(); + } + wait_ms(500); + + + GPIO_PRIOINVERSION_MASK; + + // used by the MAX30001 + NVIC_SetPriority(SPIM2_IRQn, 0); + + + watchInterface.bootComplete = true; + print_build_version(); + daplink.printf("daplink serial port\r\n"); + microUSB.printf("micro USB serial port\r\n"); + + //dsInterface.set_fw_version(FIRMWARE_VERSION); + dsInterface.set_fw_platform(MAXIM_PLATFORM_NAME); + Peripherals::setUSBSerial(µUSB); + + icarus.max20303.Max20303_IsBattery_Connected(); + watchInterface.m_max20303_ = &icarus.max20303; + + + setup_ble(); +#ifdef ENABLE_BLETEST_COMM + dsInterface.add_sensor_comm(&bleTestComm); +#endif + + // + // MAX30001 + // + printf("Init MAX30001 callbacks, interrupts...\r\n"); + MAX30001_Helper m_max30001helper(&max30001, &max30001_InterruptB, &max30001_Interrupt2B); + Peripherals::setMAX30001(&max30001); + Peripherals::setMAX30001Helper(&m_max30001helper); + ecgCommHandler.comm_init(&m_max30001helper); + dsInterface.add_sensor_comm(&ecgCommHandler); + + // + //MAX30205 + // + tpCommHandler.comm_init(&max30205); + dsInterface.add_sensor_comm(&tpCommHandler); + + //Configure mfio as a level based interrupt (no mbed API for this, must use Maxim-specific code) + //gpio_cfg_t mfio_gpio_cfg = {PORT_5, PIN_4, GPIO_FUNC_GPIO, GPIO_PAD_INPUT_PULLUP}; + //GPIO_IntConfig(&mfio_gpio_cfg, GPIO_INT_LOW_LEVEL); + ssI2C.frequency(400000); + dsInterface.set_fw_platform(ssInterface.get_ss_platform_name()); + dsInterface.set_fw_version(ssInterface.get_ss_fw_version()); + + // + //REGISTER BOOTLOADER API TO SS INTERFACE + // + dsInterface.add_sensor_comm(&ssBoot); + + // + //REGISTER 8614X PPG SENSOR API TO SS INTERFACE + // + dsInterface.add_sensor_comm(&ssMAX8614X); + ssMAX8614X.setBMI160(&bmi160_dev); + + // + //REGISTER GENERIC COMMAND API TO SS INTERFACE + // + dsInterface.add_sensor_comm(&ssGenericCmd); + + + //Blink green if SmartSensor is present, yellow otherwise + SS_STATUS status = ssInterface.ss_comm_check(); + if (status == SS_SUCCESS) + ledStatus.set_state(LED_OFF, LED_ON, LED_OFF); + else + ledStatus.set_state(LED_ON, LED_ON, LED_OFF); + ledStatus.blink(100, 1900); + ledStatus.blink(100, 1900); + + // + //MAIN CONTEXT LOOP + // + while (1) { + + USBSerial* serial = µUSB; + uint8_t ch; + while (serial->readable()) { + ch = serial->_getc(); + dsInterface.enable_console_interface(); + dsInterface.build_command(ch); + } + + + if(dsInterface.recordingStarted) { + if((icarus.status_powerButton == MAX32630HSP::BUTTONSTATUS_LONG_PRESS_WAITING) || + (watchInterface.batteryLevel <= BATTERY_CRITICAL_LEVEL)) { + dsInterface.stopcommand(); + dsInterface.force_file_close(); + } + } + + icarus.Max32630HSP_CheckInterrupt_Status(); + // + // DSINTERFACE CONTEXT as all other interfaces is run by call to its data_report_execute function!! + // + dsInterface.data_report_execute(); + + if (ecgCommHandler.is_enabled() != watchInterface.ecg_enabled) { + + if (ecgCommHandler.is_enabled()) { + + if (!dsInterface.recordingStarted) { + watchInterface.displayMode = DISPLAYMODE_ECG; + } + + // Turn off LEDs + ledStatus.set_state(1, 1, 1); + ledStatus.solid(); + ledStatus.set_state(1, 1, 1); + } else { + + if (!dsInterface.recordingStarted) { + watchInterface.displayMode = DISPLAYMODE_TIME; + } + + } + watchInterface.ecg_enabled = ecgCommHandler.is_enabled(); + + } + + // Sensor Interface Updates on Watch display mode changes + if (watchInterface.modeUpdated) { + + watchInterface.modeUpdated = false; + watchInterface.DisplayModeUpdated(); + + // Tethered mode + if ((watchInterface.BLE_Interface_Exists) || (watchInterface.USB_Interface_Exists)) { + + + // Stop all sensors + if(!dsInterface.recordingStarted) + dsInterface.stopcommand(); + + + } else + // Not in tethered mode + { + + switch (watchInterface.displayMode) { + + case DISPLAYMODE_INFO : + + // Before switching to INFO screen, stop all sensors + if (!dsInterface.recordingStarted) { + dsInterface.stopcommand(); + } + + break; + case DISPLAYMODE_TIME : + + // Before switching to TIME screen, stop all sensors + if (!dsInterface.recordingStarted) { + dsInterface.stopcommand(); + } + + break; + case DISPLAYMODE_PPG : + + // Before switching to PPG screen, stop all sensors + if (!dsInterface.recordingStarted) { + dsInterface.stopcommand(); + dsInterface.parse_command_str("set_reg ppg 2a 10"); + dsInterface.parse_command_str("set_reg ppg 23 ff"); + dsInterface.parse_command_str("read ppg 0"); + } + + break; + + case DISPLAYMODE_TEMP : + + // Before switching to TEMP screen, stop all sensors + if (!dsInterface.recordingStarted) { + dsInterface.stopcommand(); + dsInterface.parse_command_str("set_cfg temp sr 500"); + dsInterface.parse_command_str("read temp 0"); + } + + break; + + } + } + } + + // Update the watch interface with the latest data + watchInterface.instant_temp_celsius = tpCommHandler.TempComm_instant_temp_celsius; + watchInterface.instant_hr = ssMAX8614X.instant_hr; + watchInterface.instant_hr_conf = ssMAX8614X.instant_hr_conf; + + watchInterface.BLE_Interface_Exists = BLE::Instance().gap().getState().connected; + watchInterface.USB_Interface_Exists = IS_USB_HOST_CONNECTED(); + + if (watchInterface.recordingStopFlag) { + + watchInterface.recordingStopFlag = false; + watchInterface.recording = false; + watchInterface.recording_old = false; + dsInterface.stopcommand(); + ledStatus.set_state(LED_OFF, LED_ON, LED_OFF); + ledStatus.blink(100, 1900); + } else { + watchInterface.recording = dsInterface.recordingStarted; + } + + + if (watchInterface.BLE_Interface_Exists || watchInterface.USB_Interface_Exists) { + watchInterface.connection_indicator++; + if (watchInterface.connection_indicator == 1) { + + if (!dsInterface.recordingStarted) { + dsInterface.stopcommand(); + } + + } else if (watchInterface.connection_indicator > 50) { + watchInterface.connection_indicator = 2; + } + + } + + watchInterface.execute(); + process_ble(); + ledStatus.update(); + +#ifdef ENABLE_MEMORY_DEBUG + print_memory_info(); +#endif + } +} + + + + +static void setup_ble(void) +{ + + //Set up BLE communication + BLE& ble = BLE::Instance(); + ble.init(bleInitComplete); + while (BLE::Instance().hasInitialized() == false) { /* spin loop */ } + BLE_Icarus_SetDSInterface(&dsInterface); + + char addr[6]; + BLE_ICARUS_Get_Mac_Address(addr); + printf("BLE MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\r\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + + + memcpy(watchInterface.m_mac_addr_, addr, 6); + + + +} + +static void process_ble(void) +{ + + if (BLE::Instance().gap().getState().connected) { + BLE_Icarus_TransferDataFromQueue(); + } + BLE::Instance().waitForEvent(); + +} + +static void print_build_version(void) +{ + printf("\n\nICARUS mBED EVKit\r\n"); + printf("Fw version: %s, mbed version: %d\r\n", FIRMWARE_VERSION, MBED_VERSION); + printf("Build source: (%s) %s\r\n", BUILD_SOURCE_BRANCH, BUILD_SOURCE_HASH); + printf("Build time: %s %s\r\n\n", __TIME__, __DATE__); +} + +static void HSP_run_in_usbmcd_mode(void){ + + int err; + + const int writecyclecount = 256; + watchInterface.USB_Interface_Exists = false; + watchInterface.USB_Interface_MSD = true; + watchInterface.bootComplete = true; + watchInterface.displayMode = DISPLAYMODE_TETHERED_USB; + watchInterface.updateDisplay(4); + + for(int i = 0; i < writecyclecount; ++i) { + watchInterface.execute(); + wait_ms(1); + } + + USBMSD_BD msd(&spif); + printf("Starting MSD... "); + msd.disk_initialize(); + err = msd.connect(); + ledStatus.set_state(1, 1, 0); + printf("%s\n", (err < 0 ? "Fail :(" : "OK")); + + msd.disk_initialize(); + err = msd.connect(); + + GPIO_PRIOINVERSION_MASK; + + while (1) { + + icarus.Max32630HSP_CheckInterrupt_Status(); + + wait_ms(1); + } +} + +static void HSP_mount_filesystem(void){ + + // For ISSI part, in 3-wire SPI mode, HOLD pin should be tied to high to un-pause communication + flash_nHOLD = 1; + // Try to mount the filesystem + printf("Mounting the filesystem... "); + fflush(stdout); + int err = filesystem.mount(&spif); + printf("%s\n", (err ? "Fail :(" : "OK")); + if (err) { + // Reformat if we can't mount the filesystem + // this should only happen on the first boot + printf("No filesystem found, formatting... "); + fflush(stdout); + err = filesystem.reformat(&spif); + printf("%s\n", (err ? "Fail :(" : "OK")); + } + +} + + + +#ifdef ENABLE_MEMORY_DEBUG +void print_memory_info() { + static int threadStackSize[8] = {0}; + static int heapSize = 0; + // allocate enough room for every thread's stack statistics + int cnt = osThreadGetCount(); + mbed_stats_stack_t *stats = (mbed_stats_stack_t*) malloc(cnt * sizeof(mbed_stats_stack_t)); + + cnt = mbed_stats_stack_get_each(stats, cnt); + for (int i = 0; i < cnt; i++) { + if(threadStackSize[i] < stats[i].max_size){ + printf("Thread: 0x%lX, Stack size: %lu / %lu\r\n", stats[i].thread_id, stats[i].max_size, stats[i].reserved_size); + threadStackSize[i] = stats[i].max_size; + } + } + free(stats); + + // Grab the heap statistics + mbed_stats_heap_t heap_stats; + mbed_stats_heap_get(&heap_stats); + if(heapSize < heap_stats.current_size){ + printf("Heap size: %lu / %lu bytes\r\n", heap_stats.current_size, heap_stats.reserved_size); + heapSize = heap_stats.current_size; + } +} +#endif