Пример #1
0
/* Send interrupt notification to the phone or 
 * read data from the accelerometer and send it to the phone
 */
static void AccelerometerSendDataHandler(void)
{
  tMessage Msg;

  SetupMessageWithBuffer(&Msg, AccelIndMsg, MSG_OPT_NONE);
  if (Msg.pBuffer != NULL)
  {
    if (Control & WUF_ENABLE)
    {
      AccelerometerRead(KIONIX_XOUT_HPF_L, Data, XYZ_DATA_LENGTH);
      AccelerometerRead(KIONIX_INT_REL, Data, ONE_BYTE); //clear int
    }
    else AccelerometerRead(KIONIX_XOUT_L, Data, XYZ_DATA_LENGTH);

    Msg.pBuffer[0] = CONVERT_TO_8_BIT(0);
    Msg.pBuffer[1] = CONVERT_TO_8_BIT(2);
    Msg.pBuffer[2] = CONVERT_TO_8_BIT(4);
    Msg.Length = 3;
    RouteMsg(&Msg);

    PrintH(Msg.pBuffer[0]); PrintC(SPACE);
    PrintH(Msg.pBuffer[1]); PrintC(SPACE);
    PrintH(Msg.pBuffer[2]); PrintR();
  }
}
Пример #2
0
// Shall be called only when clip is off
void CheckBatteryLow(void)
{
  static unsigned char Severity = WARN_LEVEL_NONE;

  unsigned int Average = Read(BATTERY);

  /* it was not possible to get a reading below 2.8V
   * the radio does not initialize when the battery voltage (from a supply)
   * is below 2.8 V
   * if the battery is not present then the readings are meaningless
   * if the battery is charging then ignore the measured voltage
   * and clear the flags
  */
  if (Average < WarningLevel)
  {
    if (Average < RadioOffLevel && Severity == WARN_LEVEL_CRITICAL)
      Severity = WARN_LEVEL_RADIO_OFF;
    
    else if (Average >= RadioOffLevel && Severity == WARN_LEVEL_NONE)
      Severity = WARN_LEVEL_CRITICAL;
    else return;

    tMessage Msg;
    SetupMessageWithBuffer(&Msg, LowBattWarning[Severity].MsgType1, MSG_OPT_NONE);
    if (Msg.pBuffer != NULL)
    {
      Msg.pBuffer[0] = (unsigned char)Average;
      Msg.pBuffer[1] = (unsigned char)(Average >> 8);
      Msg.Length = 2;
      RouteMsg(&Msg);
    }
    /* send the same message to the display task */
    SendMessage(&Msg, LowBattWarning[Severity].MsgType2, MSG_OPT_NONE);

    /* now send a vibration to the wearer */
    SetupMessageWithBuffer(&Msg, SetVibrateMode, MSG_OPT_NONE);
    if (Msg.pBuffer != NULL)
    {
      signed char i = sizeof(tSetVibrateModePayload) - 1;
      for (; i >= 0; i--)
        Msg.pBuffer[i] = *((unsigned char *)&LowBattWarning[Severity].VibrateData + i);

      RouteMsg(&Msg);
    }
  }
Пример #3
0
static void ModeTimeoutHandler()
{
  /* send a message to the host indicating that a timeout occurred */
  PrintS("- ModChgTout");
  
  tMessage Msg;
  SetupMessageWithBuffer(&Msg, ModeChangeIndMsg, CurrentMode);
  if (Msg.pBuffer != NULL)
  {
    Msg.pBuffer[0] = eScModeTimeout;
    Msg.Length = 1;
    RouteMsg(&Msg);
  }
  ChangeModeHandler(IDLE_MODE);
}
Пример #4
0
/*! Read the voltage of the battery. This provides power good, battery charging,
 * battery voltage, and battery voltage average.
 *
 * \param tHostMsg* pMsg is unused
 *
 */
static void ReadBatteryVoltageHandler(void)
{
  tMessage Msg;
  SetupMessageWithBuffer(&Msg, VBatRespMsg, MSG_OPT_NONE);
  if (Msg.pBuffer != NULL)
  {
    Msg.Length = 6;
    Msg.pBuffer[0] = ClipOn();
    Msg.pBuffer[1] = Charging();
    Msg.pBuffer[2] = BatteryPercentage();

    unsigned int bv = Read(BATTERY);
    Msg.pBuffer[4] = bv & 0xFF;
    Msg.pBuffer[5] = (bv >> 8) & 0xFF;
    RouteMsg(&Msg);
  }
Пример #5
0
static void ChangeModeHandler(unsigned char Option)
{
  PrintF("- ChgModInd:0x%02x", Option);
  PrintF(" PgTp %d Pg: %d", PageType, CurrentPage[PageType]);
  
  unsigned char Mode = Option & MODE_MASK;

  tMessage Msg;
  SetupMessageWithBuffer(&Msg, ModeChangeIndMsg, (CurrentIdleScreen() << 4) | Mode);
  if (Msg.pBuffer != NULL)
  {
    Msg.pBuffer[0] = eScUpdateComplete;
    Msg.Length = 1;
    RouteMsg(&Msg);
  }

  if (Option & MSG_OPT_CHGMOD_IND) return; // ask for current idle page only
    
//  StopTimer(ModeTimer);

  if (Mode == MUSIC_MODE) SendMessage(&Msg, UpdConnParamMsg, ShortInterval);
  else if (CurrentMode == MUSIC_MODE) SendMessage(&Msg, UpdConnParamMsg, LongInterval);

  CurrentMode = Mode;
  
  if (Mode == IDLE_MODE)
  {
#if COUNTDOWN_TIMER
    if (CurrentPage[PageType] == CountdownPage) SendMessage(&Msg, CountDownMsg, MSG_OPT_NONE);
    else
#endif
    {
//    PageType = PAGE_TYPE_IDLE;
      IdleUpdateHandler();
    }
  }
  else
  {
    SetTimer(ModeTimer, ModeTimeOut[Mode], TOUT_ONCE);
    
    if (Option & MSG_OPT_UPD_INTERNAL) SendMessage(&Msg, UpdateDisplayMsg, Option);
  }
}
Пример #6
0
static void HandleMusicPlayStateChange(unsigned char State)
{
  // music icon fits into one message
  PrintF("- HdlMusicPlyChg:%d", State);
  tMessage Msg;
  SetupMessageWithBuffer(&Msg, WriteBufferMsg,
    MUSIC_MODE | MSG_OPT_WRTBUF_MULTILINE | ICON_MUSIC_WIDTH << 3);
  
  if (Msg.pBuffer != NULL)
  {
    Msg.pBuffer[0] = MUSIC_STATE_START_ROW;
    Msg.Length = ICON_MUSIC_WIDTH * ICON_MUSIC_HEIGHT + 1;
    PrintF("- start:%d Len: %d", Msg.pBuffer[0], Msg.Length);
    
    unsigned char i = 1;
    for (; i < Msg.Length; ++i) Msg.pBuffer[i] = pIconMusicState[1 - State][i - 1];
    RouteMsg(&Msg);
  }

  SendMessage(&Msg, UpdateDisplayMsg, MUSIC_MODE);
}
Пример #7
0
static void ShowCall(tString *pString, unsigned char Type)
{
  static tString CallerId[15] = "";
  tMessage Msg;

  if (Type == SHOW_NOTIF_CALLER_ID) strcpy(CallerId, pString);
  
  if (Type == SHOW_NOTIF_CALLER_NAME && *CallerId)
  {
    PrintF("- Caller:%s", pString);
  
    SetupMessageWithBuffer(&Msg, SetVibrateMode, MSG_OPT_NONE);
    if (Msg.pBuffer != NULL)
    {
      *(tSetVibrateModePayload *)Msg.pBuffer = RingTone;
      RouteMsg(&Msg);
    }
    PageType = PAGE_TYPE_INFO;
    CurrentPage[PageType] = CallPage;
    DrawCallScreen(CallerId, pString);

    // set a 5s timer for switching back to idle screen
    StartTimer(ShowCallTimer);
  }
  else if (Type == SHOW_NOTIF_END || Type == SHOW_NOTIF_REJECT_CALL)
  {
    PrintF("- Call Notif End");
    
    *CallerId = NULL;
    StopTimer(ShowCallTimer);

    PageType = PAGE_TYPE_IDLE;
    SendMessage(&Msg, UpdateDisplayMsg, CurrentMode | MSG_OPT_UPD_INTERNAL |
                (CurrentMode == IDLE_MODE ? MSG_OPT_NEWUI : 0));

    if (Type == SHOW_NOTIF_REJECT_CALL) SendMessage(&Msg, HfpMsg, MSG_OPT_HFP_HANGUP);
  }
}
Пример #8
0
static void MenuButtonHandler(unsigned char MsgOptions)
{
  tMessage Msg;
  
  switch (MsgOptions)
  {
  case MENU_BUTTON_OPTION_EXIT:

    IdleUpdateHandler();
    break;

  case MENU_BUTTON_OPTION_TOGGLE_BLUETOOTH:

    if (BluetoothState() != Initializing)
      SendMessage(&Msg, RadioOn() ? TurnRadioOffMsg : TurnRadioOnMsg, MSG_OPT_NONE);
    break;

  case MENU_BUTTON_OPTION_DISPLAY_SECONDS:
    ToggleProperty(PROP_TIME_SECOND);
    MenuModeHandler(0);
    break;
    
  case MENU_BUTTON_OPTION_TOGGLE_LINK_ALARM:
    LinkAlarmEnable = !LinkAlarmEnable;
    MenuModeHandler(0);
    break;

  case MENU_BUTTON_OPTION_INVERT_DISPLAY:
    ToggleProperty(PROP_INVERT_DISPLAY);
    MenuModeHandler(0);
    break;

  case MENU_BUTTON_OPTION_TOGGLE_RST_NMI_PIN:
    if (RESET_PIN) {SET_RESET_PIN_RST();}
    else {SET_RESET_PIN_NMI();}
    MenuModeHandler(0);
    break;

  case MENU_BUTTON_OPTION_TOGGLE_SERIAL_SBW_GND:
    ToggleSerialGndSbw();
    MenuModeHandler(0);
    break;
    
  case MENU_BUTTON_OPTION_TOGGLE_ENABLE_CHARGING:
    ToggleCharging();
//    SendMessage(&Msg, AccelMsg, 0); //test accel
    MenuModeHandler(0);
    break;
    
  case MENU_BUTTON_OPTION_ENTER_BOOTLOADER_MODE:
    EnterBootloader();
    break;

  case MENU_BUTTON_OPTION_TEST:
  
    SetupMessageWithBuffer(&Msg, SetVibrateMode, MSG_OPT_NONE);
    if (Msg.pBuffer != NULL)
    {
      *(tSetVibrateModePayload *)Msg.pBuffer = TestTone;
      RouteMsg(&Msg);
    }
    // test accelemeter MSG_OPT_ACCEL_ENABLE
//    SendMessage(&Msg, AccelMsg, 1);
    break;

  default:
    break;
  }
}
Пример #9
0
/*! Handle the messages routed to the display queue */
static void DisplayQueueMessageHandler(tMessage* pMsg)
{
  tMessage Msg;
  unsigned char i = 0;

  switch (pMsg->Type)
  {
  case WriteBufferMsg:
    WriteBufferHandler(pMsg);
    break;

  case SetWidgetListMsg:
    SetWidgetList(pMsg);
    break;
  
  case UpdateDisplayMsg:
    if ((!(pMsg->Options & MSG_OPT_UPD_INTERNAL) &&
          (pMsg->Options & MODE_MASK) == NOTIF_MODE) &&
        GetProperty(PROP_AUTO_BACKLIGHT))
      SendMessage(&Msg, AutoBacklightMsg, MSG_OPT_NONE);

    UpdateDisplayHandler(pMsg);
    break;
    
  case UpdateClockMsg:
    UpdateClock();
    break;
    
  case DrawClockWidgetMsg:
    DrawClockWidget(pMsg->Options);
    break;

  case MonitorBatteryMsg:
    MonitorBattery();
    break;

  case BluetoothStateChangeMsg:
    BluetoothStateChangeHandler(pMsg);
    break;

  case IdleUpdateMsg:
    IdleUpdateHandler();
    break;

  case ButtonStateMsg:
    ButtonStateHandler();
    break;

  case CallerIdMsg:
    pMsg->pBuffer[pMsg->Length] = NUL;
    ShowCall((char *)pMsg->pBuffer, pMsg->Options);
    break;
    
  case CallerNameMsg:
    if (pMsg->Length)
    {
      pMsg->pBuffer[pMsg->Length] = NUL;
      ShowCall((char *)pMsg->pBuffer, SHOW_NOTIF_CALLER_NAME);

      if (GetProperty(PROP_AUTO_BACKLIGHT)) SendMessage(&Msg, AutoBacklightMsg, MSG_OPT_NONE);
    }
    else ShowCall("", pMsg->Options);
    break;

  case MusicPlayStateMsg:
    HandleMusicPlayStateChange(pMsg->Options);
    break;
    
  case ChangeModeMsg:
    ChangeModeHandler(pMsg->Options);
    break;
  
  case ControlFullScreenMsg:
    SetProperty(PROP_PHONE_DRAW_TOP, pMsg->Options || *pMsg->pBuffer ? PROP_PHONE_DRAW_TOP : 0);
    break;

  case ModifyTimeMsg:
    ModifyTimeHandler(pMsg);
    break;

  case MenuModeMsg:
    MenuModeHandler(pMsg->Options);
    break;

  case MenuButtonMsg:
    MenuButtonHandler(pMsg->Options);
    break;

  case EnableButtonMsg:
    EnableButtonMsgHandler(pMsg);
    break;

  case DevTypeMsg:

    SetupMessageWithBuffer(&Msg, DevTypeRespMsg, BOARD_TYPE); //default G2
    if (Msg.pBuffer != NULL)
    {
      Msg.pBuffer[0] = BOARD_TYPE; // backward compatible
      Msg.Length = 1;

      if (GetMsp430HardwareRevision() < 'F')
      {
        Msg.Options = DIGITAL_WATCH_TYPE_G1;
        Msg.pBuffer[0] = DIGITAL_WATCH_TYPE_G1; // backward compatible
      }

      Msg.Options |= pMsg->Options & 0x80; // support ACK
      RouteMsg(&Msg);
    }

    PrintF("- DevTypeResp:%d", Msg.Options);

    // set ACK bit
    SendMessage(&Msg, ConnTypeMsg, pMsg->Options);
    break;

  case VerInfoMsg:
    SetupMessageWithBuffer(&Msg, VerInfoRespMsg, MSG_OPT_NONE);
    if (Msg.pBuffer != NULL)
    {
      /* exclude middle '.' */
      strncpy((char *)Msg.pBuffer, BUILD, 3);
      strncpy((char *)Msg.pBuffer + 3, BUILD + 4, 3);
      Msg.Length += strlen(BUILD) - 1;
        
      *(Msg.pBuffer + Msg.Length++) = (unsigned char)atoi(VERSION);
      
      while (VERSION[i++] != '.');
      *(Msg.pBuffer + Msg.Length++) = atoi(VERSION + i);
      *(Msg.pBuffer + Msg.Length++) = NULL;
      
      RouteMsg(&Msg);
    }
    PrintS("-Ver:"); for (i = 6; i < Msg.Length; ++i) PrintH(Msg.pBuffer[i]);
    break;
    
  case SetVibrateMode:
    SetVibrateModeHandler(pMsg);
    break;

  case SetRtcMsg:
    SetRtc((Rtc_t *)pMsg->pBuffer);

#if COUNTDOWN_TIMER
    if (CurrentPage[PageType] == CountdownPage && CountdownMode() == COUNTING)
      SendMessage(&Msg, CountDownMsg, MSG_OPT_CNTDWN_TIME);
#endif
    UpdateClock();
    break;
    
#if COUNTDOWN_TIMER
  case CountDownMsg:
    if (pMsg->Options == MSG_OPT_NONE)
    {
      PageType = PAGE_TYPE_INFO;
      CurrentPage[PageType] = CountdownPage;
    }
    DrawCountdownScreen(pMsg->Options);
    break;

  case SetCountdownDoneMsg:
    // for testing
//    Rtc_t Done;
//    Done.Month = 5;
//    Done.Day = 1;
//    Done.Hour = 0;
//    Done.Minute = 0;
//    SetDoneTime(&Done);

    // Valid only DoneTime is different
    if (SetDoneTime((Rtc_t *)pMsg->pBuffer)) SendMessage(&Msg, CountDownMsg, MSG_OPT_NONE);
    break;
#endif

  case ServiceMenuMsg:
    ServiceMenuHandler();
    break;
    
  case DisableButtonMsg:
    DisableButtonMsgHandler(pMsg);
    break;

  case ReadButtonConfigMsg:
    ReadButtonConfigHandler(pMsg);
    break;

  case SetBacklightMsg:
    SetBacklight(pMsg->Options);
    // testing
//    pMsg->Type = AccelMsg;
//    pMsg->Options = 1; //enable
//    HandleAccelerometer(pMsg);
    break;

  case AutoBacklightMsg:
    if (LightSenseCycle() < DARK_LEVEL) SetBacklight(LED_ON_OPTION);
    break;

  case BatteryConfigMsg:
    SetBatteryLevels(pMsg->pBuffer);
    break;

  case ReadBatteryVoltageMsg:
    ReadBatteryVoltageHandler();
    break;

  case ResetMsg:
    SoftwareResetHandler(pMsg);
    break;

  case NvalOperationMsg:
    NvalOperationHandler(pMsg);
    break;

  case SecInvertMsg:
    HandleSecInvert(pMsg->Options);
    break;

  case LoadTemplateMsg:
    LoadTemplateHandler(pMsg);
    break;

  case LinkAlarmMsg:
    if (LinkAlarmEnable)
    {
      SetupMessageWithBuffer(&Msg, SetVibrateMode, MSG_OPT_NONE);
      if (Msg.pBuffer != NULL)
      {
        *(tSetVibrateModePayload *)Msg.pBuffer = LnkAlmTone;
        RouteMsg(&Msg);
      }
    }
    break;

  case ModeTimeoutMsg:
    ModeTimeoutHandler();
    break;

  case WatchStatusMsg:
    PageType = PAGE_TYPE_INFO;
    CurrentPage[PageType] = StatusPage;
    DrawWatchStatusScreen();
    break;

//  case ListPairedDevicesMsg:
//    ListPairedDevicesHandler();
//    break;

  case WatchDrawnScreenTimeout:
    IdleUpdateHandler();
    break;

  case TermModeMsg:
    TermModeHandler();
    break;
    
  case LowBatteryWarningMsg:
    break;
    
  case LowBatteryBtOffMsg:
    UpdateClock();
    break;

#if __IAR_SYSTEMS_ICC__
  case EraseTemplateMsg:
    EraseTemplateHandler(pMsg);
    break;
    
  case WriteToTemplateMsg:
    WriteToTemplateHandler(pMsg);
    break;
#endif

  case AccelMsg:
    HandleAccelerometer(pMsg);
    break;

  case ReadLightSensorMsg:
    ReadLightSensorHandler();
    break;

  case RateTestMsg:
    SetupMessageWithBuffer(&Msg, DiagnosticLoopback, MSG_OPT_NONE);
    if (Msg.pBuffer != NULL)
    {
      /* don't care what data is */
      Msg.Length = 10;
      RouteMsg(&Msg);
    }
    break;
    
  default:
    PrintF("# Disp Msg: 0x%02x", pMsg->Type);
    break;
  }
}