Ejemplo n.º 1
0
int main(void)
{
	setupLEDs();
	for(;;){
 		_delay_ms(500.0);
  		setGreenLED();
  		clrRedLED();
  		_delay_ms(500.0);
  		clrGreenLED();
  		setRedLED();
	}
}
Ejemplo n.º 2
0
/**************************************************************************//**
 * @brief The Heart Rate Monitor loop
 *        It implements the main state machine.
 *****************************************************************************/
bool HeartRateMonitor_Loop( bool displaySpO2, bool forceStop, bool checkSkinContact )
{
  static int32_t hrmStatus;
  int16_t heartRate;
  int16_t spo2;
  static HRMSpO2State_t state = HRM_STATE_IDLE; // stores the main state of the state machine
  HANDLE si114xHandle;
  int32_t skinDetect = 0;
  si114xhrm_GetLowLevelHandle(hrmHandle, &si114xHandle);
  static bool updateDisplay = false; // flag to save when display needs to update

  if (forceStop && state!=HRM_STATE_IDLE)
  {
    // main application sets forceStop to true to force the HRM algo to quit*/
    state = HRM_STATE_IDLE;
    stopHRM ();
    checkSkinContact = false;
  }

  if(state == HRM_STATE_IDLE)
  {
    /*
     * in the idle state we periodically check for skin contact
     * and if detected start the algorithm
     */
    resetInactiveTimer();
    if (checkSkinContact)
      si114xhrm_DetectSkinContact(hrmHandle, &skinDetect);
    if (skinDetect)
    {
      state = HRM_STATE_NOSIGNAL;
#ifdef USB_DEBUG
      if (USBDebug_IsUSBConfigured())
      {
        configMessage[0] = 0x43; //Configuration message starts with ASCII C
        USBDebug_ProcessConfigurationMessage(configMessage+1, currentHRMConfig);
        si114xhrm_OutputDebugMessage(hrmHandle, (int8_t*)configMessage);
      }
#endif
      // start the algorithm
      si114xhrm_Run(hrmHandle);
    }
    else
      return false;
  }

  // call the main HRM algorithm processing function
#ifdef USB_DEBUG

  if(si114xhrm_Process(hrmHandle, &heartRate, &spo2, &hrmStatus, &hrmData) == SI114xHRM_SUCCESS)
  {
#else
  if(si114xhrm_Process(hrmHandle, &heartRate, &spo2, &hrmStatus, 0) == SI114xHRM_SUCCESS)
  {
#endif
    // when STATUS_FRAME_PROCESSED is set new data is available
    if (hrmStatus&SI114xHRM_STATUS_FRAME_PROCESSED)
    {
      hrmStatus &= ~SI114xHRM_STATUS_FRAME_PROCESSED;
#ifdef USB_DEBUG
      debugMessage[0] = 0x44; //Debug message starts with ASCII D
      sprintf(debugMessage+1, "Fs = %hd, Pi = %hu, Status = %ld, Pulse = %hdbpm, SpO2 = %hd%%", hrmData.Fs, hrmData.spo2IrPerfusionIndex, hrmStatus, heartRate, spo2);
      si114xhrm_OutputDebugMessage(hrmHandle, (int8_t*)debugMessage);
#endif
      // process error codes
      heartRateStateMachine(&state,hrmStatus);
      // if heart rate is valid save the value
      if (state == HRM_STATE_ACTIVE)
        displayHeartRateValue = heartRate;
      // if we want to display SpO2 check the SpO2 status too*/
      if (displaySpO2)
      {
        spo2StateMachine(&state,hrmStatus);
        // if spo2 value is valid save the value
        if (state == HRM_STATE_ACTIVE)
          displaySpo2Value = spo2;

      }
      // if data is invalid start a timeout
      if (state == HRM_STATE_INVALID)
      {
        enableInvalidTimer = true;
        // when timeout expires clear old data
        if(invalidTimeout == true)
        {
          state = HRM_STATE_IDLE;
          stopHRM ();
          resetInvalidTimer();
        }
      }
      // update the display when we get new data*/
      updateDisplay = true;
    }
  }
  if ( (updateDisplay) &&  (HeartRateMonitor_SamplesPending () == false) )
  {
    HeartRateMonitor_UpdateDisplay(state, displaySpO2);
    updateDisplay = false;
  }
  // this timeout turns off the red led to produce the flash effect
  if (redLEDTimeout)
  {
    redLEDTimeout = false;
    setRedLED(false);
  }

  return ( state!=HRM_STATE_IDLE );
}



/**************************************************************************//**
 * @brief Update the display based on the HRM state
 *****************************************************************************/
static void HeartRateMonitor_UpdateDisplay(HRMSpO2State_t state, bool displaySpO2)
{
  bool showWait = false;
  int t;

  if (displaySpO2)
    t = displaySpo2Value;
  else
    t = displayHeartRateValue;

  if (bufferOverrunError)
  {
    GRAPHICS_DrawError ();
  }
  else
  {
    switch(state)
    {
      case HRM_STATE_IDLE:
      case HRM_STATE_NOSIGNAL:
        setRedLED(false);
        setGreenLED(false);
        resetInvalidTimer();
        break;
      case HRM_STATE_ACQUIRING:
        // flash red led
        setRedLED(true);
        showWait = true;
        enableInvalidTimer = true;
        break;
      case HRM_STATE_ACTIVE:
        setGreenLED(true);
        resetInvalidTimer();
        break;
     case HRM_STATE_INVALID:
       if (t == 0)
       {
         showWait = true;
         setRedLED(true);
         setGreenLED(false);
       }
       break;
    }

    if (displaySpO2)
      GRAPHICS_ShowSpO2Status(showWait, displaySpo2Value, false);
    else
      GRAPHICS_ShowHRMStatus(showWait, displayHeartRateValue, false);

  }
}
Ejemplo n.º 3
0
/**************************************************************************//**
 * @brief This function enables the 100us timer for HRM.
 *****************************************************************************/
static void startTimer ()
{
  // Enable clock for TIMER module
  CMU_ClockEnable(CLK_HRM_TIMER1, true);
  CMU_ClockEnable(CLK_HRM_TIMER2, true);
  TIMER_Reset(HRM_TIMER1);
  TIMER_Reset(HRM_TIMER2);
  // Select TIMER parameters
  TIMER_Init_TypeDef timerInit1 =
  {
    .enable     = true,
    .debugRun   = true,
    .prescale   = timerPrescale1,
    .clkSel     = timerClkSelHFPerClk,
    .fallAction = timerInputActionNone,
    .riseAction = timerInputActionNone,
    .mode       = timerModeUp,
    .dmaClrAct  = false,
    .quadModeX4 = false,
    .oneShot    = false,
    .sync       = false,
  };
  TIMER_Init_TypeDef timerInit2 =
    {
      .enable     = true,
      .debugRun   = true,
      .prescale   = timerPrescale1,
      .clkSel     = timerClkSelCascade,
      .fallAction = timerInputActionNone,
      .riseAction = timerInputActionNone,
      .mode       = timerModeUp,
      .dmaClrAct  = false,
      .quadModeX4 = false,
      .oneShot    = false,
      .sync       = false,
    };
  // Set TIMER Top value
  TIMER_TopSet(HRM_TIMER1, CMU_ClockFreqGet(cmuClock_HF)/1/10000); /*overflow every 100us*/
  TIMER_TopSet(HRM_TIMER2, 0xffff); /*max 16 bits*/
  // Configure TIMER
  TIMER_Init(HRM_TIMER1, &timerInit1);
  TIMER_Init(HRM_TIMER2, &timerInit2);
}

/**************************************************************************//**
 * @brief Initiate the Heart Rate Monitor
 *****************************************************************************/
void HeartRateMonitor_Init( Si114xPortConfig_t* i2c, HeartRateMonitor_Config_t configSelect )
{
  // Setup SysTick Timer for 10msec interrupts.
  if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 100)) while (1) ;
   // Setup Timer as 100 usec counter.  The HRM API requires a 100usec timestamp.
  startTimer ();
  dataStorage.spo2 = &spo2Data;
  dataStorage.hrm = &hrmDataStorage;
  hrmHandle = &dataStorage;

  si114xhrm_Initialize(i2c, 0, &hrmHandle);
  if (configSelect == BIOMETRIC_EXP)
  {
    si114xhrm_Configure(hrmHandle, &biometricEXPHRMConfig);
    currentHRMConfig = &biometricEXPHRMConfig;
  }
  else if (configSelect == SI1143_PS)
  {
    si114xhrm_Configure(hrmHandle, &Si1143PsHRMConfig);
    currentHRMConfig = &Si1143PsHRMConfig;
  }
  else if (configSelect == SI1147_PS)
  {
    si114xhrm_Configure(hrmHandle, &Si1147PsHRMConfig);
    currentHRMConfig = &Si1147PsHRMConfig;
  }

  //turn off LEDs
  setRedLED (false);
  setGreenLED (false);
  bufferOverrunError = false;
  displayHeartRateValue = 0;
  displaySpo2Value = 0;
  HeartRateMonitor_UpdateDisplay(HRM_STATE_NOSIGNAL, false);
}

/**************************************************************************//**
 * @brief Check for samples in irq queue
 *****************************************************************************/
bool HeartRateMonitor_SamplesPending ()
{
  HANDLE si114xHandle;
  si114xhrm_GetLowLevelHandle(hrmHandle, &si114xHandle);
  return (Si114xIrqQueueNumentries(si114xHandle)>0);
}

/**************************************************************************//**
 * @brief Reset inactive timer values
 *****************************************************************************/
static void resetInactiveTimer()
{
  enableInactiveTimer = false;
  inactiveTimeout = false;
  inactiveTimerCounter = 0;
}