Maxim Integrated's IoT development kit.

Dependencies:   MAX30101 MAX30003 MAX113XX_Pixi MAX30205 max32630fthr USBDevice

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*******************************************************************************
00002 * Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved.
00003 *
00004 * Permission is hereby granted, free of charge, to any person obtaining a
00005 * copy of this software and associated documentation files (the "Software"),
00006 * to deal in the Software without restriction, including without limitation
00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 * and/or sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following conditions:
00010 *
00011 * The above copyright notice and this permission notice shall be included
00012 * in all copies or substantial portions of the Software.
00013 *
00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020 * OTHER DEALINGS IN THE SOFTWARE.
00021 *
00022 * Except as contained in this notice, the name of Maxim Integrated
00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024 * Products, Inc. Branding Policy.
00025 *
00026 * The mere transfer of this software does not imply any licenses
00027 * of trade secrets, proprietary technology, copyrights, patents,
00028 * trademarks, maskwork rights, or any other form of intellectual
00029 * property whatsoever. Maxim Integrated Products, Inc. retains all
00030 * ownership rights.
00031 *******************************************************************************
00032 */
00033 #include <mbed.h>
00034 #include <events/mbed_events.h>
00035 #include <rtos.h>
00036 #include "config.h"
00037 #include "ble/BLE.h"
00038 #include "ble/Gap.h"
00039 #include "max32630fthr.h"
00040 #include "ble_gatt.h"
00041 #if defined(LIB_MAX30205)
00042 #   include "max30205_app.h"
00043 #endif
00044 #if defined(LIB_MAX30101)
00045 #   include "max30101_app.h"
00046 #endif
00047 #if defined(LIB_MAX30003)
00048 #   include "max30003_app.h"
00049 #endif
00050 #if defined(LIB_MAX113XX_PIXI)
00051 #   include "max113xx_pixi_app.h"
00052 #endif
00053 
00054 
00055 /******************************************************************************/
00056 
00057 MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
00058 
00059 InterruptIn button(P2_3);
00060 
00061 SPI spim2(SPI2_MOSI, SPI2_MISO, SPI2_SCK);
00062 
00063 I2C i2c1(I2C1_SDA, I2C1_SCL);       /* I2C bus, P3_4 = SDA, P3_5 = SCL */
00064 
00065 /* LEDs */
00066 DigitalOut rLED(LED1, LED_OFF);
00067 DigitalOut gLED(LED2, LED_OFF);
00068 DigitalOut bLED(LED3, LED_OFF);
00069 
00070 /* Hardware serial port over DAPLink */
00071 Serial daplink(USBTX, USBRX, 115200);
00072 
00073 int alive_led_event_id;
00074 
00075 /******************************************************************************/
00076 const static char     DEVICE_NAME[] = MAXIM_PLATFORM_NAME;
00077 //static const uint16_t uuid16_list[] = {0xFFFF}; //Custom UUID, FFFF is reserved for development
00078 
00079 /* Set Up custom Characteristics */
00080 UUID iot_service_uuid("00001520-1d66-11e8-b467-0ed5f89f718b");
00081 
00082 static ble_desc_gatt_cpf_t cpf_float32 = {.format = BLE_DESC_GATT_CPF_FORMAT_FLOAT32};
00083 static ble_desc_gatt_cpf_t cpf_uint16 = {.format = BLE_DESC_GATT_CPF_FORMAT_UINT16};
00084 static ble_desc_gatt_cpf_t cpf_uint8 = {.format = BLE_DESC_GATT_CPF_FORMAT_UINT8};
00085 
00086 GattAttribute gatt_attr_cpf_format_float32(BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT, (uint8_t *)&cpf_float32, sizeof(ble_desc_gatt_cpf_t));
00087 GattAttribute gatt_attr_cpf_format_uint16(BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT, (uint8_t *)&cpf_uint16, sizeof(ble_desc_gatt_cpf_t));
00088 GattAttribute gatt_attr_cpf_format_uint8(BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT, (uint8_t *)&cpf_uint8, sizeof(ble_desc_gatt_cpf_t));
00089 
00090 UUID gatt_char_uuid_pushbutton("00001522-1d66-11e8-b467-0ed5f89f718b");
00091 static uint8_t pushbutton_press_count = 0;
00092 GattAttribute pushbutton_user_desc_descriptor(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Push Button", sizeof("Push Button"));
00093 GattAttribute *pushbutton_descriptors[] = {&pushbutton_user_desc_descriptor, &gatt_attr_cpf_format_uint8};
00094 GattCharacteristic gatt_char_pushbutton(gatt_char_uuid_pushbutton, &pushbutton_press_count, 1, 1,
00095                                         GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY,
00096                                         pushbutton_descriptors,
00097                                         sizeof(pushbutton_descriptors) / sizeof(GattAttribute*));
00098 
00099 UUID gatt_char_uuid_led("00001523-1d66-11e8-b467-0ed5f89f718b");
00100 static uint8_t led_init_value[] = {LED_OFF, LED_OFF, LED_OFF};
00101 GattAttribute led_user_desc_descriptor(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"LED", sizeof("LED"));
00102 GattAttribute *led_descriptors[] = {&led_user_desc_descriptor};
00103 ReadWriteArrayGattCharacteristic<uint8_t, sizeof(led_init_value)> gatt_char_led(gatt_char_uuid_led, led_init_value,
00104                                                                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NONE,
00105                                                                                 led_descriptors,
00106                                                                                 sizeof(led_descriptors) / sizeof(GattAttribute*));
00107 
00108 #if defined(LIB_MAX30003)
00109 UUID gatt_char_uuid_bpm("00001524-1d66-11e8-b467-0ed5f89f718b");
00110 static float bpm_init_value;
00111 GattAttribute bpm_user_desc_descriptor(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"BPM", sizeof("BPM"));
00112 GattAttribute *bpm_descriptors[] = {&bpm_user_desc_descriptor, &gatt_attr_cpf_format_float32};
00113 ReadOnlyGattCharacteristic<float> gatt_char_bpm(gatt_char_uuid_bpm, &bpm_init_value,
00114                                                 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY,
00115                                                 bpm_descriptors,
00116                                                 sizeof(bpm_descriptors) / sizeof(GattAttribute*));
00117 #endif
00118 
00119 #if defined(LIB_MAX30101)
00120 UUID gatt_char_uuid_heartrate("00001525-1d66-11e8-b467-0ed5f89f718b");
00121 static uint16_t heartrate_init_value;
00122 GattAttribute heartrate_user_desc_descriptor(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Heart Rate", sizeof("Heart Rate"));
00123 GattAttribute *heartrate_descriptors[] = {&heartrate_user_desc_descriptor, &gatt_attr_cpf_format_uint16};
00124 ReadOnlyGattCharacteristic<uint16_t> gatt_char_heartrate(gatt_char_uuid_heartrate,
00125                                                          &heartrate_init_value,
00126                                                          GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY,
00127                                                          heartrate_descriptors,
00128                                                          sizeof(heartrate_descriptors) / sizeof(GattAttribute*));
00129 
00130 UUID gatt_char_uuid_spo2("00001526-1d66-11e8-b467-0ed5f89f718b");
00131 static uint16_t spo2_init_value;
00132 GattAttribute spo2_user_desc_descriptor(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"SPO2", sizeof("SPO2"));
00133 GattAttribute *spo2_descriptors[] = {&spo2_user_desc_descriptor, &gatt_attr_cpf_format_uint16};
00134 ReadOnlyGattCharacteristic<uint16_t> gatt_char_spo2(gatt_char_uuid_spo2,
00135                                                     &spo2_init_value,
00136                                                     GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY,
00137                                                     spo2_descriptors,
00138                                                     sizeof(spo2_descriptors) / sizeof(GattAttribute*));
00139 #endif
00140 
00141 #if defined(LIB_MAX113XX_PIXI)
00142 UUID gatt_char_uuid_voltage("00001527-1d66-11e8-b467-0ed5f89f718b");
00143 static float voltage_init_value;
00144 GattAttribute voltage_user_desc_descriptor(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"ADC Voltage", sizeof("ADC Voltage"));
00145 GattAttribute *voltage_descriptors[] = {&voltage_user_desc_descriptor, &gatt_attr_cpf_format_float32};
00146 ReadOnlyGattCharacteristic<float> gatt_char_voltage(gatt_char_uuid_voltage,
00147                                                     &voltage_init_value,
00148                                                     GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY,
00149                                                     voltage_descriptors,
00150                                                     sizeof(voltage_descriptors) / sizeof(GattAttribute*));
00151 #endif
00152 
00153 #if defined(LIB_MAX30205)
00154 UUID gatt_char_uuid_temp("00001528-1d66-11e8-b467-0ed5f89f718b");
00155 static float temp_init_value;
00156 GattAttribute temp_user_desc_descriptor(BLE_UUID_DESCRIPTOR_CHAR_USER_DESC, (uint8_t *)"Temperature", sizeof("Temperature"));
00157 GattAttribute *temp_descriptors[] = {&temp_user_desc_descriptor, &gatt_attr_cpf_format_float32};
00158 ReadOnlyGattCharacteristic<float> gatt_char_temp(gatt_char_uuid_temp,
00159                                                  &temp_init_value,
00160                                                  GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY,
00161                                                  temp_descriptors,
00162                                                  sizeof(temp_descriptors) / sizeof(GattAttribute*));
00163 #endif
00164 
00165 /* Set up custom service */
00166 GattCharacteristic *characteristics[] = {&gatt_char_led, &gatt_char_pushbutton,
00167 #if defined(LIB_MAX30003)
00168                                          &gatt_char_bpm,
00169 #endif
00170 #if defined(LIB_MAX30205)
00171                                          &gatt_char_temp,
00172 #endif
00173 #if defined(LIB_MAX30101)
00174                                          &gatt_char_heartrate,
00175                                          &gatt_char_spo2,
00176 #endif
00177 #if defined(LIB_MAX113XX_PIXI)
00178                                          &gatt_char_voltage,
00179 #endif
00180 };
00181 
00182 GattService iot_gatt_service(iot_service_uuid, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
00183 
00184 /******************************************************************************/
00185 
00186 static EventQueue eventQueue(/* event count */ 10 * /* event size */ 32);
00187 
00188 void updateButtonState(uint8_t newState) {
00189     printf("Button pressed...\r\n");
00190     bleGattAttrWrite(gatt_char_pushbutton.getValueHandle(), (uint8_t *)&newState, sizeof(uint8_t));
00191 }
00192 
00193 void buttonPressedCallback(void)
00194 {
00195     eventQueue.call(Callback<void(uint8_t)>(&updateButtonState), ++pushbutton_press_count);
00196 }
00197 
00198 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
00199 {
00200     printf("disc\r\n");
00201     BLE::Instance().gap().startAdvertising(); // restart advertising
00202 }
00203 
00204 /* Connection */
00205 void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
00206 {
00207     printf("succ\r\n");
00208 }
00209 
00210 void blinkCallback(void)
00211 {
00212     gLED = !gLED;
00213 }
00214 
00215 void onBleInitError(BLE &ble, ble_error_t error)
00216 {
00217     /* Initialization error handling should go here */
00218 }
00219 
00220 /**
00221  * This callback allows the LEDService to receive updates to the ledState Characteristic.
00222  *
00223  * @param[in] params
00224  *     Information about the characteristic being updated.
00225  */
00226 void onDataWrittenCallback(const GattWriteCallbackParams *params)
00227 {
00228     if ((params->handle == gatt_char_led.getValueHandle()) && (params->len >= 3)) {
00229         rLED = (params->data[0] != 0) ? LED_OFF : LED_ON;
00230         gLED = (params->data[1] != 0) ? LED_OFF : LED_ON;
00231         bLED = (params->data[2] != 0) ? LED_OFF : LED_ON;
00232     }
00233 }
00234 
00235 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
00236 {
00237     BLE&        ble   = params->ble;
00238     ble_error_t error = params->error;
00239 
00240     if (error != BLE_ERROR_NONE) {
00241         /* In case of error, forward the error handling to onBleInitError */
00242         onBleInitError(ble, error);
00243         return;
00244     }
00245 
00246     /* Ensure that it is the default instance of BLE */
00247     if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
00248         return;
00249     }
00250 
00251     ble.gap().onDisconnection(disconnectionCallback);
00252     ble.gap().onConnection(connectionCallback);
00253 
00254     ble.gattServer().onDataWritten(onDataWrittenCallback);
00255 
00256     ble.gattServer().addService(iot_gatt_service);
00257 
00258     /* setup advertising */
00259     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00260     //ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00261     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
00262     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00263     ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
00264     ble.gap().startAdvertising();
00265 
00266     button.fall(buttonPressedCallback);
00267 }
00268 
00269 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
00270     BLE &ble = BLE::Instance();
00271     eventQueue.call(Callback<void()>(&ble, &BLE::processEvents));
00272 }
00273 
00274 int main()
00275 {
00276     osStatus status;
00277     rLED = LED_OFF; gLED = LED_OFF; bLED = LED_OFF;
00278 
00279     alive_led_event_id = eventQueue.call_every(1000, blinkCallback);
00280 
00281     printf("Initializing BLE service...\r\n");
00282 
00283     BLE &ble = BLE::Instance();
00284     ble.onEventsToProcess(scheduleBleEventsProcessing);
00285     ble.init(bleInitComplete);
00286 
00287 #if defined(LIB_MAX30205)
00288     Thread thread_max30205_reader;
00289     struct max30205_reader_task_args args_max30205 = {
00290             i2c1,
00291             gatt_char_temp.getValueHandle(),
00292             MAX30205_BLE_NOTIFY_PERIOD_SEC};
00293     status = thread_max30205_reader.start(callback(max30205_reader_task, &args_max30205));
00294     if (status != osOK) {
00295         printf("Starting thread_max30205_reader thread failed(%ld)!\r\n", status);
00296     }
00297 #endif
00298 
00299 #if defined(LIB_MAX30101)
00300     Thread thread_max30101_reader;
00301     struct max30101_reader_task_args args_max30101 = {
00302             &thread_max30101_reader,
00303             i2c1, P3_2, P3_3,
00304             gatt_char_heartrate.getValueHandle(),
00305             gatt_char_spo2.getValueHandle(),
00306             MAX30101_BLE_NOTIFY_PERIOD_SEC};
00307     status = thread_max30101_reader.start(callback(max30101_reader_task, &args_max30101));
00308     if (status != osOK) {
00309         printf("Starting thread_max30205_reader thread failed(%ld)!\r\n", status);
00310     }
00311 #endif
00312 
00313 #if defined(LIB_MAX30003)
00314     Thread thread_max30003_reader;
00315     struct max30003_reader_task_args args_max30003 = {
00316             &thread_max30003_reader,
00317             spim2, SPI2_SS,
00318             gatt_char_bpm.getValueHandle(),
00319             MAX30003_BLE_NOTIFY_PERIOD_SEC};
00320     status = thread_max30003_reader.start(callback(max30003_reader_task, &args_max30003));
00321     if (status != osOK) {
00322         printf("Starting thread_max30205_reader thread failed(%ld)!\r\n", status);
00323     }
00324 #endif
00325 
00326 #if defined(LIB_MAX113XX_PIXI)
00327     Thread thread_max11301_reader;
00328     struct max11301_reader_task_args args_max11301 = {
00329             i2c1,
00330             gatt_char_voltage.getValueHandle(),
00331             MAX113XX_PIXI_BLE_NOTIFY_PERIOD_SEC};
00332     status = thread_max11301_reader.start(callback(max11301_reader_task, &args_max11301));
00333     if (status != osOK) {
00334         printf("Starting thread_max30205_reader thread failed(%ld)!\r\n", status);
00335     }
00336 #endif
00337 
00338     eventQueue.dispatch_forever();
00339 
00340     return 0;
00341 }
00342