TEST
Dependencies: max32630fthr Adafruit_FeatherOLED USBDevice
main.cpp
- Committer:
- Emre.Eken@IST-LT-36262.maxim-ic.internal
- Date:
- 2019-07-29
- Revision:
- 3:2fe2ff1ca0dc
- Parent:
- 1:f60eafbf009a
- Child:
- 4:291477e8690d
File content as of revision 3:2fe2ff1ca0dc:
/*******************************************************************************
* Copyright (C) Maxim Integrated Products, Inc., All rights Reserved.
*
* This software is protected by copyright laws of the United States and
* of foreign countries. This material may also be protected by patent laws
* and technology transfer regulations of the United States and of foreign
* countries. This software is furnished under a license agreement and/or a
* nondisclosure agreement and may only be used or reproduced in accordance
* with the terms of those agreements. Dissemination of this information to
* any party or parties not specified in the license agreement and/or
* nondisclosure agreement is expressly prohibited.
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*******************************************************************************
*/
#include "mbed.h"
#include "USBSerial.h"
#include "version.h"
#include "DSInterface.h"
#include "Peripherals.h"
#include "usb_regs.h"
#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