The HexiHeart is a demo project product that takes advantage of many of the onboard Hexiwear sensors and capabilities to create a multifunctional fitness and safety watch.

Dependencies:   FXAS21002 FXOS8700 Hexi_KW40Z Hexi_OLED_SSD1351 MAXIM W25Q64FVSSIG HTU21D MPL3115A2 TSL2561

Fork of HexiHeart_Alex by Hexiwear_zeta

Files at this revision

API Documentation at this revision

Comitter:
nbaker
Date:
Mon Feb 12 19:31:23 2018 +0000
Parent:
3:6792c1ba586c
Child:
5:e1431272be79
Commit message:
This version has the free-fall detect incorporated into the main code, as well as the battery percentage display on the main screen.

Changed in this revision

Hexi_Battery/hexi_battery.cpp Show annotated file Show diff for this revision Revisions of this file
Hexi_Battery/hexi_battery.h Show annotated file Show diff for this revision Revisions of this file
W25Q64FVSSIG.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexi_Battery/hexi_battery.cpp	Mon Feb 12 19:31:23 2018 +0000
@@ -0,0 +1,525 @@
+
+#include "hexi_battery.h"
+#include "mbed.h"
+
+#define BITBAND_ACCESS32(Reg,Bit) (*((uint32_t volatile*)(0x42000000u + (32u*((uintptr_t)(Reg) - (uintptr_t)0x40000000u)) + (4u*((uintptr_t)(Bit))))))
+#define ADC_SC1_REG(base,index)                  ((base)->SC1[index])
+#define ADC_WR_SC1(base, index, value) (ADC_SC1_REG(base, index) = (value))
+#define ADC_BRD_SC1_COCO(base, index) (BITBAND_ACCESS32(&ADC_SC1_REG(base, index), ADC_SC1_COCO_SHIFT))
+#define ADC_RD_R_D(base, index) ((ADC_R_REG(base, index) & ADC_R_D_MASK) >> ADC_R_D_SHIFT)
+#define ADC_BRD_R_D(base, index) (ADC_RD_R_D(base, index))
+#define ADC_R_REG(base,index)                    ((base)->R[index])
+#define SIM_BWR_SCGC_BIT(base, index, value) (BITBAND_ACCESS32(&SIM_SCGC_BIT_REG((base), (index)), SIM_SCGC_BIT_SHIFT(index)) = (uint32_t)(value))
+#define SIM_SCGC_BIT_SHIFT(index)            ((uint32_t)(index) & ((1U << 5) - 1U))
+#define SIM_SCGC_BIT_REG(base, index)        (*((volatile uint32_t *)&SIM_SCGC1_REG(base) + (((uint32_t)(index) >> 5) - 0U)))
+#define SIM_SCGC1_REG(base)                      ((base)->SCGC1)
+
+#define ADC_RD_CFG1(base)        (ADC_CFG1_REG(base))
+#define ADC_WR_CFG1(base, value) (ADC_CFG1_REG(base) = (value))
+
+#define ADC_CFG1_REG(base)                       ((base)->CFG1)
+#define ADC_WR_CFG2(base, value) (ADC_CFG2_REG(base) = (value))
+#define ADC_CFG2_REG(base)                       ((base)->CFG2)
+
+#define ADC_WR_CV1(base, value)  (ADC_CV1_REG(base) = (value))
+#define ADC_CV1_REG(base)                        ((base)->CV1)
+#define ADC_WR_CV2(base, value)  (ADC_CV2_REG(base) = (value))
+#define ADC_CV2_REG(base)                        ((base)->CV2)
+
+#define ADC_WR_SC2(base, value)  (ADC_SC2_REG(base) = (value))
+#define ADC_SC2_REG(base)                        ((base)->SC2)
+
+#define ADC_WR_SC3(base, value)  (ADC_SC3_REG(base) = (value))
+#define ADC_SC3_REG(base)                        ((base)->SC3)
+
+#define ADC_RD_SC2(base)         (ADC_SC2_REG(base))
+#define ADC_RD_CFG2(base)        (ADC_CFG2_REG(base))
+#define ADC_CFG2_REG(base)                       ((base)->CFG2)
+
+#define ADC_RD_SC3(base)         (ADC_SC3_REG(base))
+#define ADC_SC3_REG(base)                        ((base)->SC3)
+
+#define ADC_INSTANCE_COUNT (2U) /*!< Number of instances of the ADC module. */
+const IRQn_Type g_adcIrqId[ADC_INSTANCE_COUNT] = ADC_IRQS;
+
+typedef enum _adc16_chn {
+    kAdc16Chn0  = 0U,  /*!< AD0. */
+    kAdc16Chn1  = 1U,  /*!< AD1. */
+    kAdc16Chn2  = 2U,  /*!< AD2. */
+    kAdc16Chn3  = 3U,  /*!< AD3. */
+    kAdc16Chn4  = 4U,  /*!< AD4. */
+    kAdc16Chn5  = 5U,  /*!< AD5. */
+    kAdc16Chn6  = 6U,  /*!< AD6. */
+    kAdc16Chn7  = 7U,  /*!< AD6. */
+    kAdc16Chn8  = 8U,  /*!< AD8.  */
+    kAdc16Chn9  = 9U,  /*!< AD9.  */
+    kAdc16Chn10 = 10U, /*!< AD10. */
+    kAdc16Chn11 = 11U, /*!< AD11. */
+    kAdc16Chn12 = 12U, /*!< AD12. */
+    kAdc16Chn13 = 13U, /*!< AD13. */
+    kAdc16Chn14 = 14U, /*!< AD14. */
+    kAdc16Chn15 = 15U, /*!< AD15. */
+    kAdc16Chn16 = 16U, /*!< AD16. */
+    kAdc16Chn17 = 17U, /*!< AD17. */
+    kAdc16Chn18 = 18U, /*!< AD18. */
+    kAdc16Chn19 = 19U, /*!< AD19. */
+    kAdc16Chn20 = 20U, /*!< AD20. */
+    kAdc16Chn21 = 21U, /*!< AD21. */
+    kAdc16Chn22 = 22U, /*!< AD22. */
+    kAdc16Chn23 = 23U, /*!< AD23. */
+    kAdc16Chn24 = 24U, /*!< AD24. */
+    kAdc16Chn25 = 25U, /*!< AD25. */
+    kAdc16Chn26 = 26U, /*!< AD26. */
+    kAdc16Chn27 = 27U, /*!< AD27. */
+    kAdc16Chn28 = 28U, /*!< AD28. */
+    kAdc16Chn29 = 29U, /*!< AD29. */
+    kAdc16Chn30 = 30U, /*!< AD30. */
+    kAdc16Chn31 = 31U,  /*!< AD31. */
+
+    kAdc16Chn0d = kAdc16Chn0,  /*!< DAD0. */
+    kAdc16Chn1d = kAdc16Chn1,  /*!< DAD1. */
+    kAdc16Chn2d = kAdc16Chn2,  /*!< DAD2. */
+    kAdc16Chn3d = kAdc16Chn3,  /*!< DAD3. */
+    kAdc16Chn4a = kAdc16Chn4,  /*!< AD4a. */
+    kAdc16Chn5a = kAdc16Chn5,  /*!< AD5a. */
+    kAdc16Chn6a = kAdc16Chn6,  /*!< AD6a. */
+    kAdc16Chn7a = kAdc16Chn7,  /*!< AD7a. */
+    kAdc16Chn4b = kAdc16Chn4,  /*!< AD4b. */
+    kAdc16Chn5b = kAdc16Chn5,  /*!< AD5b. */
+    kAdc16Chn6b = kAdc16Chn6,  /*!< AD6b. */
+    kAdc16Chn7b = kAdc16Chn7   /*!< AD7b. */
+
+} adc16_chn_t;
+
+typedef enum _adc16_status {
+    kStatus_ADC16_Success         = 0U, /*!< Success. */
+    kStatus_ADC16_InvalidArgument = 1U, /*!< Invalid argument existed. */
+    kStatus_ADC16_Failed          = 2U  /*!< Execution failed. */
+} adc16_status_t;
+
+typedef struct Adc16ChnConfig {
+    adc16_chn_t chnIdx;          /*!< Select the sample channel index. */
+    bool convCompletedIntEnable; /*!< Enable the conversion complete interrupt. */
+#if FSL_FEATURE_ADC16_HAS_DIFF_MODE
+    bool diffConvEnable;         /*!< Enable the differential conversion. */
+#endif  /** FSL_FEATURE_ADC16_HAS_DIFF_MODE */
+} adc16_chn_config_t;
+
+extern const adc16_chn_config_t BATTERY_ADC_ChnConfig;
+
+const adc16_chn_config_t BATTERY_ADC_ChnConfig = {
+    .chnIdx = kAdc16Chn16,
+    .convCompletedIntEnable = false,
+    .diffConvEnable = false
+};
+
+ADC_Type * const g_adcBase[] = ADC_BASE_PTRS;
+
+
+void ADC16_HAL_ConfigChn(ADC_Type * base, uint32_t chnGroup, const adc16_chn_config_t *configPtr)
+{
+    uint16_t tmp = 0U;
+
+    /** Interrupt enable. */
+    if (configPtr->convCompletedIntEnable) {
+        tmp |= ADC_SC1_AIEN_MASK;
+    }
+
+    /** Differential mode enable. */
+#if FSL_FEATURE_ADC16_HAS_DIFF_MODE
+    if (configPtr->diffConvEnable) {
+        tmp |= ADC_SC1_DIFF_MASK;
+    }
+#endif  /** FSL_FEATURE_ADC16_HAS_DIFF_MODE */
+
+    /** Input channel select. */
+    tmp |= ADC_SC1_ADCH((uint32_t)(configPtr->chnIdx));
+
+    ADC_WR_SC1(base, chnGroup, tmp);
+}
+
+adc16_status_t ADC16_DRV_ConfigConvChn(uint32_t instance,
+                                       uint32_t chnGroup, const adc16_chn_config_t *configPtr)
+{
+    ADC_Type * base = g_adcBase[instance];
+
+    if (!configPtr) {
+        return kStatus_ADC16_InvalidArgument;
+    }
+
+    ADC16_HAL_ConfigChn(base, chnGroup, configPtr);
+
+    return kStatus_ADC16_Success;
+}
+
+static inline bool ADC16_HAL_GetChnConvCompletedFlag(ADC_Type * base, uint32_t chnGroup)
+{
+    return (1U == ADC_BRD_SC1_COCO(base, chnGroup) );
+}
+
+void ADC16_DRV_WaitConvDone(uint32_t instance, uint32_t chnGroup)
+{
+    ADC_Type * base = g_adcBase[instance];
+
+    while ( !ADC16_HAL_GetChnConvCompletedFlag(base, chnGroup) )
+        {}
+}
+
+static inline uint16_t ADC16_HAL_GetChnConvValue(ADC_Type * base, uint32_t chnGroup )
+{
+    return (uint16_t)(ADC_BRD_R_D(base, chnGroup) );
+}
+
+uint16_t ADC16_DRV_GetConvValueRAW(uint32_t instance, uint32_t chnGroup)
+{
+
+    ADC_Type * base = g_adcBase[instance];
+
+    return ADC16_HAL_GetChnConvValue(base, chnGroup);
+}
+
+int16_t ADC16_DRV_GetConvValueSigned(uint32_t instance, uint32_t chnGroup)
+{
+    return (int16_t)ADC16_DRV_GetConvValueRAW(instance, chnGroup);
+}
+
+void ADC16_DRV_PauseConv(uint32_t instance, uint32_t chnGroup)
+{
+    adc16_chn_config_t configStruct;
+
+    configStruct.chnIdx = kAdc16Chn31;
+    configStruct.convCompletedIntEnable = false;
+#if FSL_FEATURE_ADC16_HAS_DIFF_MODE
+    configStruct.diffConvEnable = false;
+#endif
+    ADC16_DRV_ConfigConvChn(instance, chnGroup, &configStruct);
+}
+
+typedef enum _adc16_clk_divider {
+    kAdc16ClkDividerOf1 = 0U, /*!< For divider 1 from the input clock to ADC16. @internal gui name="1" */
+    kAdc16ClkDividerOf2 = 1U, /*!< For divider 2 from the input clock to ADC16. @internal gui name="2" */
+    kAdc16ClkDividerOf4 = 2U, /*!< For divider 4 from the input clock to ADC16. @internal gui name="4" */
+    kAdc16ClkDividerOf8 = 3U  /*!< For divider 8 from the input clock to ADC16. @internal gui name="8" */
+} adc16_clk_divider_t;
+
+typedef enum _adc16_resolution {
+    kAdc16ResolutionBitOf8or9 = 0U,
+    /*!< 8-bit for single end sample, or 9-bit for differential sample. @internal gui name="" */
+    kAdc16ResolutionBitOfSingleEndAs8 = kAdc16ResolutionBitOf8or9, /*!< 8-bit for single end sample. @internal gui name="8 bit in single mode" */
+    kAdc16ResolutionBitOfDiffModeAs9 = kAdc16ResolutionBitOf8or9, /*!< 9-bit for differential sample. @internal gui name="9 bit in differential mode" */
+
+    kAdc16ResolutionBitOf12or13 = 1U,
+    /*!< 12-bit for single end sample, or 13-bit for differential sample. @internal gui name="" */
+    kAdc16ResolutionBitOfSingleEndAs12 = kAdc16ResolutionBitOf12or13, /*!< 12-bit for single end sample. @internal gui name="12 bit in single mode" */
+    kAdc16ResolutionBitOfDiffModeAs13 = kAdc16ResolutionBitOf12or13, /*!< 13-bit for differential sample. @internal gui name="13 bit in differential mode" */
+
+    kAdc16ResolutionBitOf10or11 = 2U,
+    /*!< 10-bit for single end sample, or 11-bit for differential sample. @internal gui name="" */
+    kAdc16ResolutionBitOfSingleEndAs10 = kAdc16ResolutionBitOf10or11, /*!< 10-bit for single end sample. @internal gui name="10 bit in single mode" */
+    kAdc16ResolutionBitOfDiffModeAs11 = kAdc16ResolutionBitOf10or11 /*!< 11-bit for differential sample. @internal gui name="11 bit in differential mode" */
+#if (FSL_FEATURE_ADC16_MAX_RESOLUTION >= 16U)
+    , kAdc16ResolutionBitOf16 = 3U,
+    /*!< 16-bit for both single end sample and differential sample. @internal gui name="16-bit" */
+    kAdc16ResolutionBitOfSingleEndAs16 = kAdc16ResolutionBitOf16, /*!< 16-bit for single end sample. @internal gui name="" */
+    kAdc16ResolutionBitOfDiffModeAs16 = kAdc16ResolutionBitOf16 /*!< 16-bit for differential sample. @internal gui name="" */
+
+#endif  /** FSL_FEATURE_ADC16_MAX_RESOLUTION */
+} adc16_resolution_t;
+
+typedef enum _adc16_long_sample_cycle {
+    kAdc16LongSampleCycleOf24 = 0U, /*!< 20 extra ADCK cycles, 24 ADCK cycles total. */
+    kAdc16LongSampleCycleOf16 = 1U, /*!< 12 extra ADCK cycles, 16 ADCK cycles total. */
+    kAdc16LongSampleCycleOf10 = 2U, /*!< 6 extra ADCK cycles, 10 ADCK cycles total. */
+    kAdc16LongSampleCycleOf4  = 3U  /*!< 2 extra ADCK cycles, 6 ADCK cycles total. */
+} adc16_long_sample_cycle_t;
+
+typedef enum _adc16_clk_src_mode {
+    kAdc16ClkSrcOfBusClk  = 0U, /*!< For input as bus clock. @internal gui name="Bus clock" */
+    kAdc16ClkSrcOfAltClk2 = 1U, /*!< For input as alternate clock 2 (AltClk2). @internal gui name="Alternate clock 2" */
+    kAdc16ClkSrcOfAltClk  = 2U, /*!< For input as alternate clock (ALTCLK). @internal gui name="Alternate clock 1" */
+    kAdc16ClkSrcOfAsynClk = 3U  /*!< For input as asynchronous clock (ADACK). @internal gui name="Asynchronous clock" */
+} adc16_clk_src_mode_t;
+
+typedef enum _adc16_ref_volt_src {
+    kAdc16RefVoltSrcOfVref = 0U, /*!< For external pins pair of VrefH and VrefL. @internal gui name="Vref pair" */
+    kAdc16RefVoltSrcOfValt = 1U  /*!< For alternate reference pair of ValtH and ValtL. @internal gui name="Valt pair" */
+} adc16_ref_volt_src_t;
+
+typedef struct Adc16ConverterConfig {
+    bool                    lowPowerEnable; /*!< Enable low power. @internal gui name="Low power mode" id="LowPowerMode" */
+    adc16_clk_divider_t     clkDividerMode; /*!< Select the divider of input clock source. @internal gui name="Clock divider" id="ClockDivider" */
+    bool                    longSampleTimeEnable; /*!< Enable the long sample time. @internal gui name="Long sample time" id="LongSampleTime" */
+    adc16_resolution_t      resolution; /*!< Select the sample resolution mode. @internal gui name="Resolution" id="Resolution" */
+    adc16_clk_src_mode_t    clkSrc; /*!< Select the input clock source to converter. @internal gui name="Clock source" id="ClockSource" */
+    bool                    asyncClkEnable; /*!< Enable the asynchronous clock inside the ADC. @internal gui name="Internal async. clock" id="InternalAsyncClock" */
+    bool                    highSpeedEnable; /*!< Enable the high speed mode. @internal gui name="High speed mode" id="HighSpeed" */
+    adc16_long_sample_cycle_t longSampleCycleMode; /*!< Select the long sample mode. @internal gui name="Long sample mode" id="LongSampleMode" */
+    bool                    hwTriggerEnable; /*!< Enable hardware trigger function. @internal gui name="Hardware trigger" id="HwTrigger" */
+    adc16_ref_volt_src_t    refVoltSrc; /*!< Select the reference voltage source. @internal gui name="Voltage reference" id="ReferenceVoltage" */
+    bool                    continuousConvEnable; /*!< Enable continuous conversion mode. @internal gui name="Continuous mode" id="ContinuousMode" */
+#if FSL_FEATURE_ADC16_HAS_DMA
+    bool                    dmaEnable; /*!< Enable the DMA for ADC converter. @internal gui name="DMA mode" id="DMASupport" */
+#endif  /** FSL_FEATURE_ADC16_HAS_DMA */
+} adc16_converter_config_t;
+
+const adc16_converter_config_t BATTERY_ADC_InitConfig = {
+    .lowPowerEnable = false,
+    .clkDividerMode = kAdc16ClkDividerOf1,
+    .longSampleTimeEnable = false,
+    .resolution = kAdc16ResolutionBitOf16,
+    .clkSrc = kAdc16ClkSrcOfBusClk,
+    .asyncClkEnable = false,
+    .highSpeedEnable = true,
+    .longSampleCycleMode = kAdc16LongSampleCycleOf4,
+    .hwTriggerEnable = false,
+    .refVoltSrc = kAdc16RefVoltSrcOfVref,
+    .continuousConvEnable = false,
+    .dmaEnable = false,
+};
+
+#define FSL_SIM_SCGC_BIT(SCGCx, n) (((SCGCx-1U)<<5U) + n)
+
+typedef enum _sim_clock_gate_name {
+    kSimClockGateI2c2      = FSL_SIM_SCGC_BIT(1U, 6U),
+    kSimClockGateUart4     = FSL_SIM_SCGC_BIT(1U, 10U),
+    kSimClockGateUart5     = FSL_SIM_SCGC_BIT(1U, 11U),
+    kSimClockGateEnet0     = FSL_SIM_SCGC_BIT(2U, 0U),
+    kSimClockGateDac0      = FSL_SIM_SCGC_BIT(2U, 12U),
+    kSimClockGateDac1      = FSL_SIM_SCGC_BIT(2U, 13U),
+    kSimClockGateSpi2      = FSL_SIM_SCGC_BIT(3U, 12U),
+    kSimClockGateSdhc0     = FSL_SIM_SCGC_BIT(3U, 17U),
+    kSimClockGateFtm3      = FSL_SIM_SCGC_BIT(3U, 25U),
+    kSimClockGateAdc1      = FSL_SIM_SCGC_BIT(3U, 27U),
+    kSimClockGateEwm0      = FSL_SIM_SCGC_BIT(4U, 1U),
+    kSimClockGateCmt0      = FSL_SIM_SCGC_BIT(4U, 2U),
+    kSimClockGateI2c0      = FSL_SIM_SCGC_BIT(4U, 6U),
+    kSimClockGateI2c1      = FSL_SIM_SCGC_BIT(4U, 7U),
+    kSimClockGateUart0     = FSL_SIM_SCGC_BIT(4U, 10U),
+    kSimClockGateUart1     = FSL_SIM_SCGC_BIT(4U, 11U),
+    kSimClockGateUart2     = FSL_SIM_SCGC_BIT(4U, 12U),
+    kSimClockGateUart3     = FSL_SIM_SCGC_BIT(4U, 13U),
+    kSimClockGateUsbfs0    = FSL_SIM_SCGC_BIT(4U, 18U),
+    kSimClockGateCmp       = FSL_SIM_SCGC_BIT(4U, 19U),
+    kSimClockGateVref0     = FSL_SIM_SCGC_BIT(4U, 20U),
+    kSimClockGateLptmr0    = FSL_SIM_SCGC_BIT(5U, 0U),
+    kSimClockGatePortA     = FSL_SIM_SCGC_BIT(5U, 9U),
+    kSimClockGatePortB     = FSL_SIM_SCGC_BIT(5U, 10U),
+    kSimClockGatePortC     = FSL_SIM_SCGC_BIT(5U, 11U),
+    kSimClockGatePortD     = FSL_SIM_SCGC_BIT(5U, 12U),
+    kSimClockGatePortE     = FSL_SIM_SCGC_BIT(5U, 13U),
+    kSimClockGateFtf0      = FSL_SIM_SCGC_BIT(6U, 0U),
+    kSimClockGateDmamux0   = FSL_SIM_SCGC_BIT(6U, 1U),
+    kSimClockGateFlexcan0  = FSL_SIM_SCGC_BIT(6U, 4U),
+    kSimClockGateRnga0     = FSL_SIM_SCGC_BIT(6U, 9U),
+    kSimClockGateSpi0      = FSL_SIM_SCGC_BIT(6U, 12U),
+    kSimClockGateSpi1      = FSL_SIM_SCGC_BIT(6U, 13U),
+    kSimClockGateSai0      = FSL_SIM_SCGC_BIT(6U, 15U),
+    kSimClockGateCrc0      = FSL_SIM_SCGC_BIT(6U, 18U),
+    kSimClockGateUsbdcd0   = FSL_SIM_SCGC_BIT(6U, 21U),
+    kSimClockGatePdb0      = FSL_SIM_SCGC_BIT(6U, 22U),
+    kSimClockGatePit0      = FSL_SIM_SCGC_BIT(6U, 23U),
+    kSimClockGateFtm0      = FSL_SIM_SCGC_BIT(6U, 24U),
+    kSimClockGateFtm1      = FSL_SIM_SCGC_BIT(6U, 25U),
+    kSimClockGateFtm2      = FSL_SIM_SCGC_BIT(6U, 26U),
+    kSimClockGateAdc0      = FSL_SIM_SCGC_BIT(6U, 27U),
+    kSimClockGateRtc0      = FSL_SIM_SCGC_BIT(6U, 29U),
+    kSimClockGateFlexbus0  = FSL_SIM_SCGC_BIT(7U, 0U),
+    kSimClockGateDma0      = FSL_SIM_SCGC_BIT(7U, 1U),
+    kSimClockGateMpu0      = FSL_SIM_SCGC_BIT(7U, 2U),
+#if (defined(DOXYGEN_OUTPUT) && (DOXYGEN_OUTPUT))
+} sim_clock_gate_name_k64f12_t;
+#else
+} sim_clock_gate_name_t;
+#endif
+
+static const sim_clock_gate_name_t adcGateTable[] = {
+    kSimClockGateAdc0,
+    kSimClockGateAdc1
+};
+
+static inline void SIM_HAL_EnableClock(SIM_Type * base, sim_clock_gate_name_t name)
+{
+    SIM_BWR_SCGC_BIT(base, name, 1U);
+}
+
+void CLOCK_SYS_EnableAdcClock(uint32_t instance)
+{
+    SIM_HAL_EnableClock(SIM, adcGateTable[instance]);
+}
+
+void ADC16_HAL_Init(ADC_Type * base)
+{
+    ADC_WR_CFG1(base, 0U);
+    ADC_WR_CFG2(base, 0U);
+    ADC_WR_CV1(base, 0U);
+    ADC_WR_CV2(base, 0U);
+    ADC_WR_SC2(base, 0U);
+    ADC_WR_SC3(base, 0U);
+#if FSL_FEATURE_ADC16_HAS_PGA
+    ADC_WR_PGA(base, 0U);
+#endif  /** FSL_FEATURE_ADC16_HAS_PGA */
+}
+
+void ADC16_HAL_ConfigConverter(ADC_Type * base, const adc16_converter_config_t *configPtr)
+{
+    uint16_t cfg1, cfg2, sc2, sc3;
+
+    cfg1 = ADC_RD_CFG1(base);
+    cfg1 &= ~(  ADC_CFG1_ADLPC_MASK
+                | ADC_CFG1_ADIV_MASK
+                | ADC_CFG1_ADLSMP_MASK
+                | ADC_CFG1_MODE_MASK
+                | ADC_CFG1_ADICLK_MASK );
+
+    /** Low power mode. */
+    if (configPtr->lowPowerEnable) {
+        cfg1 |= ADC_CFG1_ADLPC_MASK;
+    }
+    /** Clock divider. */
+    cfg1 |= ADC_CFG1_ADIV(configPtr->clkDividerMode);
+    /** Long sample time. */
+    if (configPtr->longSampleTimeEnable) {
+        cfg1 |= ADC_CFG1_ADLSMP_MASK;
+    }
+    /** Sample resolution mode. */
+    cfg1 |= ADC_CFG1_MODE(configPtr->resolution);
+    /** Clock source input. */
+    cfg1 |= ADC_CFG1_ADICLK(configPtr->clkSrc);
+
+    cfg2 = ADC_RD_CFG2(base);
+    cfg2 &= ~( ADC_CFG2_ADACKEN_MASK
+               | ADC_CFG2_ADHSC_MASK
+               | ADC_CFG2_ADLSTS_MASK );
+    /** Asynchronous clock output enable. */
+    if (configPtr->asyncClkEnable) {
+        cfg2 |= ADC_CFG2_ADACKEN_MASK;
+    }
+    /** High speed configuration. */
+    if (configPtr->highSpeedEnable) {
+        cfg2 |= ADC_CFG2_ADHSC_MASK;
+    }
+    /** Long sample time select. */
+    cfg2 |= ADC_CFG2_ADLSTS(configPtr->longSampleCycleMode);
+
+    sc2 = ADC_RD_SC2(base);
+    sc2 &= ~( ADC_SC2_ADTRG_MASK
+              | ADC_SC2_REFSEL_MASK
+#if FSL_FEATURE_ADC16_HAS_DMA
+              | ADC_SC2_DMAEN_MASK
+#endif  /** FSL_FEATURE_ADC16_HAS_DMA */
+            );
+    /** Conversion trigger select. */
+    if (configPtr->hwTriggerEnable) {
+        sc2 |= ADC_SC2_ADTRG_MASK;
+    }
+    /** Voltage reference selection. */
+    sc2 |= ADC_SC2_REFSEL(configPtr->refVoltSrc);
+#if FSL_FEATURE_ADC16_HAS_DMA
+    /** DMA. */
+    if (configPtr->dmaEnable) {
+        sc2 |= ADC_SC2_DMAEN_MASK;
+    }
+#endif  /** FSL_FEATURE_ADC16_HAS_DMA */
+
+    sc3 = ADC_RD_SC3(base);
+    sc3 &= ~( ADC_SC3_ADCO_MASK
+              | ADC_SC3_CALF_MASK );
+    /** Continuous conversion enable. */
+    if (configPtr->continuousConvEnable) {
+        sc3 |= ADC_SC3_ADCO_MASK;
+    }
+
+    ADC_WR_CFG1(base, cfg1);
+    ADC_WR_CFG2(base, cfg2);
+    ADC_WR_SC2(base, sc2);
+    ADC_WR_SC3(base, sc3);
+}
+
+static inline void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
+{
+    /** call core API to enable the IRQ*/
+    NVIC_EnableIRQ(irqNumber);
+}
+
+adc16_status_t ADC16_DRV_Init(uint32_t instance, const adc16_converter_config_t *userConfigPtr)
+{
+    ADC_Type * base = g_adcBase[instance];
+
+    if (!userConfigPtr) {
+        return kStatus_ADC16_InvalidArgument;
+    }
+    /** Enable clock for ADC. */
+    CLOCK_SYS_EnableAdcClock(instance);
+
+    /** Reset all the register to a known state. */
+    ADC16_HAL_Init(base);
+    ADC16_HAL_ConfigConverter(base, userConfigPtr);
+
+    /** Enable ADC interrupt in NVIC level.*/
+    INT_SYS_EnableIRQ(g_adcIrqId[instance] );
+
+    return kStatus_ADC16_Success;
+}
+
+static uint8_t bat_convert_data(uint16_t input)
+{
+    uint8_t output = 0;
+
+    uint16_t bat_mvolts = (uint16_t)( ( (float)input * ( 3.3 / 65535.0 ) ) * 1000 );
+
+    if ( bat_mvolts > 2670 ) {
+        output = 100;
+    }
+
+    else if ( bat_mvolts > 2500 ) {
+        output = (uint8_t)( 50 + 50.0 * ( ( bat_mvolts - 2500 ) / 170.0 ) );
+    } else if ( bat_mvolts > 2430 ) {
+        output = (uint8_t)( 30 + 20.0 * ( ( bat_mvolts - 2430 ) / 70.0 ) );
+    } else if ( bat_mvolts > 2370 ) {
+        output = (uint8_t)( 10 + 20.0 * ( ( bat_mvolts - 2370 ) / 60.0 ) );
+    } else {
+        output = 0;
+    }
+    return output;
+
+}
+
+HexiwearBattery::HexiwearBattery()
+{
+    batCharging = new DigitalIn(PTC12);
+    batSensSwitch = new DigitalOut(PTC14);
+    ADC16_DRV_Init(0, &BATTERY_ADC_InitConfig);
+    ADC16_DRV_ConfigConvChn(0, 0U, &BATTERY_ADC_ChnConfig);
+}
+
+HexiwearBattery::~HexiwearBattery()
+{
+    delete batSensSwitch;
+    delete batCharging;
+}
+
+void HexiwearBattery::sensorOn()
+{
+    *batSensSwitch = 0;
+};
+
+
+void HexiwearBattery::sensorOff()
+{
+    *batSensSwitch = 1;
+};
+
+bool HexiwearBattery::isBatteryCharging()
+{
+    return *batCharging == 0;
+}
+
+uint8_t HexiwearBattery::readLevelPercent()
+{
+    ADC16_DRV_ConfigConvChn( 0, 0, &BATTERY_ADC_ChnConfig);
+    ADC16_DRV_WaitConvDone ( 0, 0 );
+    int16_t result = ADC16_DRV_GetConvValueSigned( 0, 0 );
+    ADC16_DRV_PauseConv(0, 0 );
+    return bat_convert_data(result);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Hexi_Battery/hexi_battery.h	Mon Feb 12 19:31:23 2018 +0000
@@ -0,0 +1,62 @@
+/** Battery Driver for Hexiwear 
+ *  This file contains battery driver functionality for check battery level and status
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * 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.
+ *
+ * Neither the name of NXP, 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.
+ *
+ * visit: http://www.mikroe.com and http://www.nxp.com
+ *
+ * get support at: http://www.mikroe.com/forum and https://community.nxp.com
+ *
+ * Project HEXIWEAR, 2015
+ */
+ 
+#ifndef HG_HEXI_BATTERY
+#define HG_HEXI_BATTERY
+
+#include "mbed.h"
+
+class HexiwearBattery
+{
+
+public:
+    HexiwearBattery();
+    ~HexiwearBattery();
+    uint8_t readLevelPercent();
+    void sensorOn();
+    void sensorOff();
+    bool isBatteryCharging();
+
+
+private:
+
+    DigitalOut *batSensSwitch;
+    DigitalIn *batCharging;
+
+};
+
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/W25Q64FVSSIG.lib	Mon Feb 12 19:31:23 2018 +0000
@@ -0,0 +1,1 @@
+http://os.mbed.com/users/DimiterK/code/W25Q64FVSSIG/#b71060e03299
--- a/main.cpp	Thu Feb 08 03:25:01 2018 +0000
+++ b/main.cpp	Mon Feb 12 19:31:23 2018 +0000
@@ -13,10 +13,14 @@
 #include "FXOS8700.h"           // 3D Accelorometer & Mag
 #include "FXAS21002.h"          // 3-Axis Gyroscope
 #include "Hexi_OLED_SSD1351.h"  // OLED fuctions
+                                // Non-Freescale HTU21D - combo temperature and Humidity
+#include "W25Q64FV.h"           // W25Q64FVSSIG Serial Flash 
+                                // Non-Freescale MPL3115A2 - pressure sensor 
+#include "Hexi_Battery/hexi_battery.h"  // Battery status
 #include "OLED_types.h"         // Text attributs
 #include "string.h"
 #include "OpenSans_Font.h"
-#include "MAX30101.h"
+#include "MAX30101.h"           // Non-Freescale MAX30101 - Optical Heart rate sensor
 
 
 /* We need to confirm whether it's better to include and
@@ -36,13 +40,15 @@
 #define EXIT_BELOW      75
 #define EXIT_ABOVE      100
 #define VIB_OPT_2       75
+#define FXOS8700_I2C_ADDRESS_ (0x1E<<1) //pins SA0,SA1=0 
 
 
 void StartHaptic(void);
 void StartHaptic(int x);
 void StopHaptic(void const *n);
 void error_screen(void);
-void update_display(void);
+void update_display(void);// Screen lables refreshed
+void update_data(void);   // Screen data(only)refreshed 
 void Decrement_Age();
 void Set_Max_Bpm();
 void Set_Zone_Boundaries();
@@ -59,6 +65,11 @@
 void Disable_Heart_Rate();
 void Led_Zone_Indicator();
 
+void fall_config(uint8_t); 
+void fall_detect(void);
+void fall_det_end(void);
+void fall_detect_off(void);
+void impact_detect(void);
 
 // *****************  Global variables  ***********************
 char text_1[20];            // Text buffer - Do we need more?
@@ -66,7 +77,7 @@
 bool Led_Zones = 1;
 bool HR_Enable = 0;
 bool OLED_ON = 1;           // Turn OLED power on/off
-bool Fall_Alert = 0;        // Initialize as no active alert
+bool Fall_Alert = 1;        // Initialize as no active alert
 bool Panic_Alert = 0;        // Initialize as no active alert
 bool Fall_Alert_Mode = 1;   //  Initialize with fall alert mode on
 bool Heart_Rate_Mode = 0;   //  Initialize with Heart rate off
@@ -99,10 +110,24 @@
 FXOS8700 mag(PTC11, PTC10);   // Mag (same chip as Accel)
 //MAX30101 heart(PTB1, PTB0); //Heart Rate Chip
 
+// initialize I2C bus for FXOS8700, FXAS-Gyro, MPL-Pressure
+    I2C i2c_bus1(PTC11, PTC10);  // (SDA, SCL)
+
 DigitalOut RED_Led(LED1);
 DigitalOut GRN_Led(LED2);
 DigitalOut BLU_Led(LED3);
 DigitalOut haptic(PTB9);
+DigitalOut Led_clk1(PTA12);
+DigitalOut Led_clk2(PTA13);
+DigitalOut Led_clk3(PTA14);
+
+DigitalOut OLED_PWR(PTC13);     // this pin turns on/off 15V to OLED display
+DigitalOut Non_Free_PWR(PTB13);  // this pin turns on/off non-freescale sensors (Pres/Temp/Hum/Light)
+DigitalOut HR_PWR(PTA29);       // this pin turns on/off Heart rate sensor
+//DigitalIn   Sw1(PTA12);  //Switch 'T1' on docking station AND Led_clk1!!
+//DigitalIn   Sw2(PTA13);  //Switch 'T2' on docking station AND Led_clk2!!
+DigitalIn   Sw3(PTA15);  //Switch 'T3' on docking station 
+
 
 /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */
 KW40Z kw40z_device(PTE24, PTE25);
@@ -110,14 +135,18 @@
 /* Define timer for haptic feedback */
 RtosTimer hapticTimer(StopHaptic, osTimerOnce);
 
+//***************** Interrups *****************
+InterruptIn Accel_INT1(PTC1);  // Accel sensor's interupt 1
+InterruptIn Accel_INT2(PTD13);  // Accel sensor's interupt 2
+
 //***************** Tickers and Timers *****************
 Ticker Screen_Timer;// use ticker to turn off OLED
 
-void timout_timer() // turn off display mode
-{
-    oled.FillScreen(COLOR_BLACK); // Clear screen.. is there a better command for this?
-    OLED_ON = 0;  // set flag to off
-    Screen_Timer.detach();
+void timout_timer(){ // turn off display mode
+//  oled.FillScreen(COLOR_BLACK); // Clear screen.. is there a better command for this?
+     OLED_PWR = 0;  // Turn off OLED power supply
+     OLED_ON = 0;  // set flag to off
+     Screen_Timer.detach();  // detach Ticker
 }//end routine
 
 void ButtonUp(void)
@@ -421,7 +450,15 @@
             }
             case 2: {// Fall Alert option
                 StartHaptic();
-                // toggle on/off
+                if(Fall_Alert == 1){
+                    Accel_INT1.fall(&fall_detect_off); // turn off Accel sensor's int#1 calls interupt routine
+                    Fall_Alert = 0;
+                    }
+                else{     
+                    Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
+                    Fall_Alert = 1;
+                    }
+                update_display();
                 break;
             }
             case 3: {// Heart Rate Monitoring option
@@ -668,24 +705,39 @@
 
 int main()
 {
+    OLED_PWR = 1;  // Turn on OLED power supply
     oled.FillScreen(COLOR_BLACK); // Clear screen
 // *****************  Local variables  ***********************
 //   float accel_data[3]; float accel_rms=0.0;
-
+    int i;
+ 
 // **************  configure sensor modules  ******************
-    accel.accel_config();
+    //    accel.accel_config();   // configure sensor
+    fall_config(1);         // configure sensor for fall detect
+    // Fall_config(Fall_Alert_Mode); // configure sensor for fall mode
     mag.mag_config();
-//    gyro.gyro_config();
+    gyro.gyro_config();
 
     RED_Led = LED_OFF;
     GRN_Led = LED_OFF;
     BLU_Led = LED_OFF;
+    Led_clk1 = 0; // LEDs on docking station default to off, need to turn on with a 1
+    Led_clk2 = 0; // LEDs on docking station default to off, need to turn on with a 1
+    Led_clk3 = 0; // LEDs on docking station default to off, need to turn on with a 1
+    Non_Free_PWR = 1;   // Start with non-freescale sensors (Pres/Temp/Hum/Light)on
+    HR_PWR = 1;         // Start with Heart rate sensor powered on
+    
 // ***** Register callbacks/interupts to application functions *********
     kw40z_device.attach_buttonUp(&ButtonUp);
     kw40z_device.attach_buttonDown(&ButtonDown);
     kw40z_device.attach_buttonLeft(&ButtonLeft);
     kw40z_device.attach_buttonRight(&ButtonRight);
-    kw40z_device.attach_buttonSlide(&ButtonSlide);
+ //   kw40z_device.attach_buttonSlide(&ButtonSlide);
+
+// ***** attaching interupts to functions *********
+   Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
+ //  Accel_INT2.fall(&impact_detect); //Accel sensor's int#2 calls interupt routine
+   
 
 // **** Get OLED Class Default Text Properties ****************
     oled_text_properties_t textProperties = {0};
@@ -715,20 +767,56 @@
     Screen_Timer.attach(&timout_timer,(SCRN_TIME));//start ticker timer for turning off LCD
 //  ******************* Main Loop *************************
     while (true) {
+            i=0;
+    while (i<20)// used for "Heart beat flash and updated any displayed data)
+    {
+    Thread::wait(500);          // wait 0.5 sec each loop
+    if(OLED_PWR==1){
+ //       update_data();
+        }// end if
+    i++;
+    }// end while(i<20)
+//    wait(10);          // wait 10 sec each loop, was orig half sec
+    RED_Led = LED_ON;    // Used only for diagnostic of wait command
+    Led_clk3 = 1;         // Used only for diagnostic of wait command
+    wait(0.01);          // BLIP led 1/10 sec each loop
+    RED_Led = LED_OFF;    // Used only for diagnostic of wait command
+    Led_clk3 = 0; 
+    Thread::wait(490);    // keep up the pace, at 0.5 sec (0.01s+0.49s) update date
 
-        Thread::wait(500); // wait half a sec in each loop
-    }
+//    update_data();        // refresh display date w/o updating entire display 
+
+    } // end of while(true)
+
 }
 //  ************** end of main()
 
 void update_display(void)
 {
+    OLED_PWR = 1;  // make sure OLED power supply is on
     oled_text_properties_t textProperties = {0};  // Need these to change font color
     oled.GetTextProperties(&textProperties);      // Need these to change font color
     switch(Screen_Num) {
         case 0: {// Main Screen
+            HexiwearBattery battery;
+            battery.sensorOn();  
             oled.FillScreen(COLOR_BLACK); // Clear screen
-            oled.Label((uint8_t *)"Batt",60,0); // Display "Batt" at x,y
+            
+            if (battery.isBatteryCharging()) {
+            textProperties.fontColor = COLOR_GREEN;
+            oled.SetTextProperties(&textProperties);  
+  //          sprintf(text_1, "%s", "chrg");           
+            sprintf(text_1, "%i%%+", (uint8_t)battery.readLevelPercent());
+            Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED while fully charged
+            } else {
+            sprintf(text_1, "%i%%", (uint8_t)battery.readLevelPercent());
+            }
+            oled.TextBox((uint8_t *)text_1,60,0,35,15); //show level value of battery originaly at  55,40,35,15
+        
+        textProperties.fontColor = COLOR_WHITE;
+        oled.SetTextProperties(&textProperties);
+            
+            oled.Label((uint8_t *)"Batt",35,0); // Display "Batt" at x,y
             oled.Label((uint8_t *)"Date",35,20); // Display "Date" at x,y
             oled.Label((uint8_t *)"Time",35,40); // Display "Time" at x,y
             oled.Label((uint8_t *)"H.I.",10,80); // Display "H.I." at x,y
@@ -751,6 +839,13 @@
         case 2: {// Fall Alert option
             oled.FillScreen(COLOR_BLACK); // Clear screen
             oled.Label((uint8_t *)"Fall Alert",20,5); // Display at x,y
+            oled.Label((uint8_t *)"Protection",15,25);  
+            if (Fall_Alert == 1){  
+            oled.Label((uint8_t *)" On ",42,40);   
+            }
+            else {               
+            oled.Label((uint8_t *)" Off ",40,40);   
+                } 
             oled.Label((uint8_t *)"*",85,15); // "*" at x,y
             oled.Label((uint8_t *)"*",85,60); // "*" at x,y
             oled.Label((uint8_t *)"Back",10,80); // Display "Back" at x,y
@@ -1516,7 +1611,7 @@
     } else {
         Heart_Rate -= 1;
     }
-}
+}  // end of Decrement_Heart_Rate
 
 void Led_Zone_Indicator()
 {
@@ -1568,6 +1663,178 @@
         wait(0.5);  
         RED_Led = LED_OFF; 
     }
-  }   
+  }  
+}//end of Led_Zone_Indicator 
+/*****************************************************************************
+Name: fall_detect()
+Purpose: Interupt rutine called when accelerometer IC has detected a free-fall >= 0.5g
+
+******************************************************************************/
+
+void fall_detect(){// fall detect interupt rutine
+if(Fall_Alert == 1){
+ 
+// for now just turn on display and give haptic feedback
+   Screen_Num = 22;  //Change to screen 22 (Fall diag screen)
+    Screen_Timer.attach(&timout_timer,(SCRN_TIME));// Reset/restart ticker timer for OLED
+        if (OLED_ON == 0) {
+        OLED_ON = 1; // Scree was off, set to On  
+         }  // endif
+         
+//__disable_irq();    // Disable all Interrupts
+//    oled.Label((uint8_t *)" Fall Detected ",05,70); // Display at x,y 
+ 
+    update_display();
+    BLU_Led = LED_ON;  // LEDs default to on, need to turn off
+    Led_clk2 = 1;  // Turn LED2 on docking station on
+    haptic = 1;
+    Accel_INT1.rise(&fall_det_end); // Accel sensor's int#1 calls interupt routine
+//__enable_irq();     // Enable all Interrupts
+}// end if     
+}//end fall_detect interupt routine
+
+
+void fall_detect_off(){// fall detect interupt rutine
+// for now just turn on display and give haptic feedback
+}//end fall_detect_off interupt routine
+  
+void fall_det_end(){
+    haptic = 0;         // Turn off Haptic
+    BLU_Led = LED_OFF;  // Turn off HexiHeart Blue LED
+    Led_clk2 = 0;       // Turn off LED2 on docking station on
+    oled.Label((uint8_t *)"                         ",05,70); // clear display at x,y
+    Accel_INT1.fall(&fall_detect); // Accel sensor's int#1 calls interupt routine
+}    //end fall_det_end interupt routine
+
+/*****************************************************************************
+Name: impact_detect()
+Purpose: Interupt rutine called when accelerometer IC has detected a vector
+magnitude acceleration >= 3.0g
+
+******************************************************************************/
+      
+void impact_detect(){
+ //       oled.Label((uint8_t *)" Impact Detected ",05,60); // Display at x,y
+ //       GRN_Led = LED_ON;  // LEDs default to on, need to turn off
+        Led_clk3 = 1;  // Turn LED2 on docking station on
+}//end impact_detect interupt routine
+
+/*****************************************************************************
+Name: fall_config()
+Purpose: Used to set accelerometer IC's internal registers to set up chip level
+interrupts
+Inputs: int value from 0 to 256
+Returns: None
+******************************************************************************/
+      
 
-}
+void fall_config(uint8_t Num){ 
+// use case switches here to configure for 
+switch(Num) {
+                case 0: {// configure as normal (or maybe sleep)
+                  char d[2]; 
+                    d[0] = FXOS8700_CTRL_REG1;                     //Puts device in Standby mode
+                    d[1] = 0x00; 
+                    i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2);
+                    
+                    d[0] = FXOS8700_CTRL_REG1;                     //Puts device back into active mode
+                    d[1] = 0x01;
+                    i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d, 2);
+                    oled.Label((uint8_t *)" Mode 0 ",30,60); // Display "mode" at x,y
+                    break;
+                }
+                case 1: {// configure for free-fall int
+                    StartHaptic();  // for debug
+                    char d[2]; 
+                    d[0] = FXOS8700_CTRL_REG1;                      //Config reg1
+                    d[1] = 0x00;                                    //Put device in Standby mode
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step1 error ",30,05); // Display "error" at x,y                  
+                        wait(3.0); // display for 3 seconds
+                    }//end if
+                    
+                    d[0] = 0x0e;                                    //XYZ_DATA_CFG (set full-scall range)
+                    d[1] = 0b00000000;                              //Set data to default range of +/-2g for full range (2x0.488mg/LSB), High-pass filter off
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step1a error ",30,05); // Display "error" at x,y      
+                        wait(3.0); // display for 3 seconds
+                    }//end if
+ 
+                    d[0] = 0x0a;                                    //TRIG_CFG (address of trigger config reg)
+                    d[1] = 0b00000100;                              //Trigger on freefall
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step2 error ",30,05); // Display "error" at x,y      
+                        wait(3.0); // display for 3 seconds
+                    }//end if
+                    
+                    d[0] = 0x15;                                    //A_FFMT_CFG (address of Free fall trigger config reg), write in Standby only
+                    d[1] = 0b00111000;                              //set to freefall, and look at all axis.
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step3 error ",30,05); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if
+                       
+                    d[0] = 0x17;                                    //A_FFMT_THS (address of Free fall threshold reg), write in Active or Standby
+                    d[1] = 0b00001000;                                //set freefall threshold to about 756mg for now                   
+  //                 d[1] = uint8_t(1000*Fall_Thresh/63);            //set freefall threshold - Resolution is 63mg/LSB, 0b111_1111 is maximum value
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step4 error ",30,05); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if  
+                     
+                    d[0] = 0x18;                                    //A_FFMT_COUNT (address of Free fall debounce counter), write in Active or Standby
+                    d[1] = 0b00000110;                              //with ODR at 100Hz, should equal 60mS debounce time or 120mS in Sleep
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step5 error ",30,05); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if 
+                           
+                    d[0] = 0x2b;                                    //CTRL_REG2 (address of control reg), write in Standby only
+                    d[1] = 0b00001101;                              //Turns Auto-Sleep mode on and low-noise, low power
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step6 error ",30,05); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if    
+                    
+                    d[0] = 0x2c;                                    //CTRL_REG3 (address of Int control reg), write in Standby only
+                    d[1] = 0b00001000;                              //FFMT will wake chip from sleep, int are active high
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step7 error ",30,05); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if    
+                        
+                    d[0] = 0x2d;                                    //CTRL_REG4 (address of Int enable reg), write in Standby only
+                    d[1] = 0b00000100;                              // FFMT int enabled and for debug I'm using a sleep int
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step8 error ",30,05); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if            
+                 
+                    d[0] = 0x2e;                                    //CTRL_REG5 (Int routing reg), write in Standby only
+                    d[1] = 0b00000100;                              // Make FFMT int output on pin INT1(PTC1)
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step9 error ",30,05); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if                  
+                    
+                    d[0] = FXOS8700_CTRL_REG1;                     //CTRL_REG1, write in Standby only except for bit[0]
+                    d[1] = 0b00011001;                    //Auto-Sleep mode on set to 50Hz, ODR set to 100Hz Puts device back into Active mode 
+                    if(i2c_bus1.write(FXOS8700_I2C_ADDRESS_, d,2) ==1){
+                        oled.Label((uint8_t *)" Step10 error ",30,05); // Display "error" at x,y 
+                        wait(3.0); // display for 3 seconds
+                    }//end if  
+                    
+                    //oled.FillScreen(COLOR_BLACK); // Clear screen
+                    oled.Label((uint8_t *)" Mode 1 ",30,60); // Display "mode" at x,y   
+                    GRN_Led = LED_ON;  // LEDs default to on, need to turn on     
+                    break;
+                }
+                default: {
+                    oled.Label((uint8_t *)" Mode ? ",30,60); // Display "mode" at x,y
+                    // unknown config
+                    break;
+                } 
+}// end switch                
+
+}// end Fall_config
+