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
Revision 4:0803151bc5e4, committed 2018-02-12
- 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
--- /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 +