unsigned char LcdRtcUpdateHandlerIsr(void) { static unsigned char lastMin = 61; unsigned char ExitLpm = pdFALSE; /* send a message every second or once a minute */ if (RtcUpdateEnabled && CurrentMode == IDLE_MODE) { tMessage Msg; unsigned char Minute = RTCMIN; if (PageType == PAGE_TYPE_IDLE && (GetProperty(PROP_TIME_SECOND) || Minute != lastMin)) { SetupMessage(&Msg, UpdateClockMsg, MSG_OPT_NONE); SendMessageToQueueFromIsr(DISPLAY_QINDEX, &Msg); lastMin = Minute; ExitLpm = pdTRUE; } #if COUNTDOWN_TIMER else if (CurrentPage[PageType] == CountdownPage) { if (CountdownMode() == COUNTING && Minute != lastMin) { SetupMessage(&Msg, CountDownMsg, MSG_OPT_CNTDWN_TIME); SendMessageToQueueFromIsr(DISPLAY_QINDEX, &Msg); lastMin = Minute; ExitLpm = pdTRUE; } } #endif } return ExitLpm; }
unsigned char TermModeIsr(void) { static unsigned char i = 0; if (!ReceiveCompleted) { CmdBuf[i] = UCA3RXBUF; /* parse things based on carriage return */ if (CmdBuf[i] == DELIMITER || CmdBuf[i] == END_OF_XMIT) { /* change delimiter to null */ CmdBuf[i] = '\0'; i = 0; ReceiveCompleted = TRUE; /* send message so that message can be processed */ tMessage Msg; SetupMessage(&Msg, TermModeMsg, MSG_OPT_NONE); SendMessageToQueueFromIsr(DISPLAY_QINDEX, &Msg); return TRUE; } else i = (i < MAX_COMMAND_LENGTH - 1) ? i + 1 : 0; } return FALSE; }
unsigned char RxTestModeCharacterIsr(unsigned char Character) { unsigned char ExitLpm = 0; if ( WaitForCommandToBeProcessed == 0 ) { CmdString[RxIndex++] = Character; /* parse things based on carriage return */ if ( ( Character == DELIMITER_CHARACTER || Character == END_OF_XMIT_CHARACTER ) && RxIndex > MIN_COMMAND_LENGTH ) { /* change delimiter to null */ CmdString[RxIndex-1] = 0; WaitForCommandToBeProcessed = 1; /* send message so that message can be processed */ tMessage Msg; SetupMessage(&Msg, TestModeMsg, MSG_OPT_NONE); SendMessageToQueueFromIsr(DISPLAY_QINDEX, &Msg); ExitLpm = 1; } else if ( RxIndex > MAX_COMMAND_LENGTH-1 ) /* always let last char be 0 */ { RxIndex = 0; } } return ExitLpm; }
static unsigned char RateTestCallback(void) { unsigned char ExitLpm = 0; StartCrystalTimer(CRYSTAL_TIMER_ID3, RateTestCallback, RATE_TEST_INTERVAL_MS); /* send messages once we are connected and sniff mode */ if ( QueryConnectionState() == Connected && QuerySniffState() == Sniff ) { DEBUG5_PULSE(); tMessage Msg; SetupMessage(&Msg,RateTestMsg,NO_MSG_OPTIONS); SendMessageToQueueFromIsr(BACKGROUND_QINDEX,&Msg); ExitLpm = 1; } return ExitLpm; }
__interrupt void RTC_ISR(void) { unsigned char ExitLpm = 0; tMessage Msg; // compiler intrinsic, value must be even, and in the range of 0 to 10 switch(__even_in_range(RTCIV,10)) { case RTC_NO_INTERRUPT: break; case RTC_RDY_IFG: break; case RTC_EV_IFG: break; case RTC_A_IFG: break; case RTC_PRESCALE_ZERO_IFG: // divide by four to get 32 Hz if (DivideByFour >= 4-1) { DivideByFour = 0; if (RtcInUseMask & RTC_TIMER_VIBRATION) VibrationMotorStateMachineIsr(); if (RtcInUseMask & RTC_TIMER_BUTTON) { SetupMessage(&Msg, ButtonStateMsg, MSG_OPT_NONE); SendMessageToQueueFromIsr(DISPLAY_QINDEX, &Msg); ExitLpm = 1; } } else { DivideByFour ++; } break; case RTC_PRESCALE_ONE_IFG: #ifdef DIGITAL ExitLpm |= LcdRtcUpdateHandlerIsr(); #endif ExitLpm |= OneSecondTimerHandlerIsr(); break; default: break; } if (ExitLpm) EXIT_LPM_ISR(); }
unsigned char LcdRtcUpdateHandlerIsr(void) { /* send a message every second or once a minute */ if (RtcUpdateEnabled && CurrentMode == IDLE_MODE && PageType == PAGE_TYPE_IDLE && (GetProperty(PROP_TIME_SECOND) || lastMin != RTCMIN)) { lastMin = RTCMIN; tMessage Msg; SetupMessage(&Msg, UpdateClockMsg, MSG_OPT_NONE); SendMessageToQueueFromIsr(DISPLAY_QINDEX, &Msg); return pdTRUE; } else return pdFALSE; }
/* * The interrupt can either send a message to the host or * it can send data (send a message that causes the task to read data from * part and then send it to the host). */ void AccelerometerPinIsr(void) { #if 0 /* disabling the interrupt is the easiest way to make sure that * the stack does not get blasted with * data when it is in sleep mode */ ACCELEROMETER_INT_DISABLE(); #endif /* can't allocate buffer here so we must go to task to send interrupt * occurred message */ tMessage Msg; SetupMessage(&Msg, AccelMsg, MSG_OPT_ACCEL_DATA); SendMessageToQueueFromIsr(DISPLAY_QINDEX, &Msg); }
void SendMessage(tMessage* pMsg, unsigned char Type, unsigned char Options) { SetupMessage(pMsg, Type, Options); RouteMsg(pMsg); }
/*! Handle the messages routed to the background task */ static void BackgroundMessageHandler(tMessage* pMsg) { tMessage OutgoingMsg; switch(pMsg->Type) { case SetCallbackTimerMsg: SetCallbackTimerHandler(pMsg); break; case GetDeviceType: SetupMessageAndAllocateBuffer(&OutgoingMsg, GetDeviceTypeResponse, NO_MSG_OPTIONS); OutgoingMsg.pBuffer[0] = BOARD_TYPE; OutgoingMsg.Length = 1; RouteMsg(&OutgoingMsg); break; case AdvanceWatchHandsMsg: AdvanceWatchHandsHandler(pMsg); break; case SetVibrateMode: SetVibrateModeHandler(pMsg); break; case SetRealTimeClock: halRtcSet((tRtcHostMsgPayload*)pMsg->pBuffer); #ifdef DIGITAL SetupMessage(&OutgoingMsg,IdleUpdate,NO_MSG_OPTIONS); RouteMsg(&OutgoingMsg); #endif break; case GetRealTimeClock: SetupMessageAndAllocateBuffer(&OutgoingMsg, GetRealTimeClockResponse, NO_MSG_OPTIONS); halRtcGet((tRtcHostMsgPayload*)OutgoingMsg.pBuffer); OutgoingMsg.Length = sizeof(tRtcHostMsgPayload); RouteMsg(&OutgoingMsg); break; case EnableButtonMsg: EnableButtonMsgHandler(pMsg); break; case DisableButtonMsg: DisableButtonMsgHandler(pMsg); break; case ReadButtonConfigMsg: ReadButtonConfigHandler(pMsg); break; case BatteryChargeControl: #ifdef DIGITAL /* update the screen if there has been a change in charging status */ if ( BatteryChargingControl() ) { SetupMessage(&OutgoingMsg, IdleUpdate, NO_MSG_OPTIONS); RouteMsg(&OutgoingMsg); } #endif BatterySenseCycle(); LowBatteryMonitor(); #ifdef TASK_DEBUG UTL_FreeRtosTaskStackCheck(); #endif #if 0 LightSenseCycle(); #endif break; case LedChange: LedChangeHandler(pMsg); break; case BatteryConfigMsg: SetBatteryLevels(pMsg->pBuffer); break; case ReadBatteryVoltageMsg: ReadBatteryVoltageHandler(); break; case ReadLightSensorMsg: ReadLightSensorHandler(); break; case SoftwareResetMsg: SoftwareResetHandler(pMsg); break; case NvalOperationMsg: NvalOperationHandler(pMsg); break; case GeneralPurposeWatchMsg: /* insert handler here */ break; case ButtonStateMsg: ButtonStateHandler(); break; /* * Accelerometer Messages */ case AccelerometerEnableMsg: AccelerometerEnable(); break; case AccelerometerDisableMsg: AccelerometerDisable(); break; case AccelerometerSendDataMsg: AccelerometerSendDataHandler(); break; case AccelerometerAccessMsg: AccelerometerAccessHandler(pMsg); break; case AccelerometerSetupMsg: AccelerometerSetupHandler(pMsg); break; /* * */ case RateTestMsg: SetupMessageAndAllocateBuffer(&OutgoingMsg,DiagnosticLoopback,NO_MSG_OPTIONS); /* don't care what data is */ OutgoingMsg.Length = 10; RouteMsg(&OutgoingMsg); break; /* * */ default: PrintStringAndHex("<<Unhandled Message>> in Background Task: Type 0x", pMsg->Type); break; } }
/*! Function to implement the BackgroundTask loop * * \param pvParameters not used * */ static void BackgroundTask(void *pvParameters) { if ( QueueHandles[BACKGROUND_QINDEX] == 0 ) { PrintString("Background Queue not created!\r\n"); } PrintString(SPP_DEVICE_NAME); PrintString2("\r\nSoftware Version ",VERSION_STRING); PrintString("\r\n\r\n"); InitializeRstNmiConfiguration(); /* * check on the battery */ ConfigureBatteryPins(); BatteryChargingControl(); BatterySenseCycle(); /* * now set up a timer that will cause the battery to be checked at * a regular frequency. */ BatteryMonitorTimerId = AllocateOneSecondTimer(); InitializeBatteryMonitorInterval(); SetupOneSecondTimer(BatteryMonitorTimerId, nvBatteryMonitorIntervalInSeconds, REPEAT_FOREVER, BACKGROUND_QINDEX, BatteryChargeControl, NO_MSG_OPTIONS); StartOneSecondTimer(BatteryMonitorTimerId); /* * Setup a timer to use with the LED for the LCD. */ LedTimerId = AllocateOneSecondTimer(); SetupOneSecondTimer(LedTimerId, ONE_SECOND*3, NO_REPEAT, BACKGROUND_QINDEX, LedChange, LED_OFF_OPTION); // Allocate a timer for wake-up iOS background BLE app CallbackTimerId = AllocateOneSecondTimer(); /****************************************************************************/ #ifdef RAM_TEST RamTestTimerId = AllocateOneSecondTimer(); SetupOneSecondTimer(RamTestTimerId, ONE_SECOND*20, NO_REPEAT, DISPLAY_QINDEX, RamTestMsg, NO_MSG_OPTIONS); StartOneSecondTimer(RamTestTimerId); #endif /****************************************************************************/ InitializeAccelerometer(); #ifdef ACCELEROMETER_DEBUG SetupMessageAndAllocateBuffer(&BackgroundMsg, AccelerometerSetupMsg, ACCELEROMETER_SETUP_INTERRUPT_CONTROL_OPTION); BackgroundMsg.pBuffer[0] = INTERRUPT_CONTROL_ENABLE_INTERRUPT; BackgroundMsg.Length = 1; RouteMsg(&BackgroundMsg); /* don't call AccelerometerEnable() directly use a message*/ SetupMessage(&BackgroundMsg,AccelerometerEnableMsg,NO_MSG_OPTIONS); RouteMsg(&BackgroundMsg); #endif /****************************************************************************/ #ifdef RATE_TEST StartCrystalTimer(CRYSTAL_TIMER_ID3,RateTestCallback,RATE_TEST_INTERVAL_MS); #endif /****************************************************************************/ for(;;) { if( pdTRUE == xQueueReceive(QueueHandles[BACKGROUND_QINDEX], &BackgroundMsg, portMAX_DELAY ) ) { PrintMessageType(&BackgroundMsg); BackgroundMessageHandler(&BackgroundMsg); SendToFreeQueue(&BackgroundMsg); CheckStackUsage(xBkgTaskHandle,"Background Task"); CheckQueueUsage(QueueHandles[BACKGROUND_QINDEX]); } } }
BOOL CInformErrorDialog::OnInitDialog() { CDialog::OnInitDialog(); String_64 BoxTitle; BoxTitle = _R(IDS_ERROR_BOX_SERIOUS_ERROR); // "Serious error" String_256 VerySeriousError; VerySeriousError = _R(IDS_ERROR_BOX_VERY_SERIOUS_ERROR); // "A very serious error has occured - please consult your technical support." // Andy Hills, 22-11-00 // Store the help context. // We need to do this here, because the global help context variable // nNextMessageHelpContext may change before the user clicks the 'Help' // button. This fixes bug 6359. m_nHelpContext = Error::GetErrorNumber(); if (! m_nHelpContext) m_nHelpContext = GetNextMsgHelpContext(); // Find out how many buttons there are. for (INT32 NumButtons = ERRORDLG_MAXBUTTONS; NumButtons > 0; NumButtons--) { if (m_ButtonStr[NumButtons - 1] != 0) break; } // Adjust the OK and Cancel fields if necessary if (m_OK > (UINT32) NumButtons) { if (IsUserName("Tim")) { TRACE( _T("OK out of range, OK=%u, NumButtons=%d\n"), m_OK, NumButtons); } // Default to first button m_OK = 1; } if (m_Cancel > (UINT32) NumButtons) { if (IsUserName("Tim")) { TRACE( _T("Cancel out of range, Cancel=%u, NumButtons=%d\n"), m_Cancel, NumButtons); } // Default to be the same as OK (this means a box with a single OK box will // respond to Enter and Esc without the user having to specify a Cancel ID). m_Cancel = m_OK; } if (m_Help > (UINT32) NumButtons) { TRACEUSER( "JustinF", _T("Help button (%d) out of range (%d)\n"), (INT32) m_Help, (INT32) NumButtons); // The only really safe thing we can do is drop the help button. m_Help = 0; } // Make sure we have correct dialog information GetDialogInfo(); if (!ValidInfo) { // Serious error - fall back to to MessageBox(). goto SevereError; } // Get icon position IconPos = DefIconPos; // Get a DC for this dialog, so we can find out the size of text strings. // We'll also need to select in our font or else it'll base the width upon the // System font rather than the font we're using (MS Sans Serif at last check) CDC *pDC; CFont *OldFont; pDC = GetDC(); ENSURE(pDC != NULL, "Can't get DC for error box dialog"); // Check the DC if (pDC == NULL) goto SevereError; OldFont = pDC->SelectObject(GetFont()); // Set buttons text and move/resize buttons according to the number of them, // and their contents. BOOL Success; Success = SetupButtons(pDC->m_hDC, NumButtons); // Size the error message control, and put the message in it. Success = Success && SetupMessage(pDC->m_hDC); if (OldFont != NULL) pDC->SelectObject(OldFont); // We've finished with this DC now. ReleaseDC(pDC); // Check for failure in button/message setup. if (!Success) goto SevereError; // Play the appropriate sound and set the appropriate title bar text ID. UINT32 TitleID; TitleID = m_TitleStr; switch (m_ErrorBoxType) { case ERRORTYPE_NORMAL: // No sound for this one - it's just a message; nothing to shout about. if (TitleID == 0) TitleID = _R(IDS_ERRORBOX_NORMAL); break; case ERRORTYPE_QUESTION: MessageBeep(MB_ICONQUESTION); if (TitleID == 0) TitleID = _R(IDS_ERRORBOX_NORMAL); break; case ERRORTYPE_ERROR: MessageBeep(MB_ICONEXCLAMATION); if (TitleID == 0) TitleID = _R(IDS_ERRORBOX_ERROR); break; case ERRORTYPE_WARNING: MessageBeep(MB_ICONASTERISK); if (TitleID == 0) TitleID = _R(IDS_ERRORBOX_WARNING); break; case ERRORTYPE_SERIOUS: MessageBeep(MB_ICONHAND); if (TitleID == 0) TitleID = _R(IDS_ERRORBOX_SERIOUS); break; case ERRORTYPE_ENSURE: MessageBeep(MB_ICONHAND); if (TitleID == 0) TitleID = _R(IDS_ERRORBOX_ENSURE); break; default: ENSURE(FALSE, "Bad errortype in CInformErrorDialog::OnInitDialog()"); goto SevereError; break; } // Set the title bar text if necessary. if (TitleID != 0) { String_64 Title(TitleID); SetWindowText((TCHAR*) Title); } // Centre the dialog on the screen (Code stolen from splash.cpp) // Get the size of the screen INT32 ScreenWidth, ScreenHeight; ScreenWidth = GetSystemMetrics(SM_CXSCREEN); ScreenHeight = GetSystemMetrics(SM_CYSCREEN); // Get the size of the dialog box RECT DialogRect; GetWindowRect(&DialogRect); INT32 DialogWidth, DialogHeight; DialogWidth = DialogRect.right - DialogRect.left; DialogHeight = DialogRect.bottom - DialogRect.top; // Chicago M7 gives us crap values at this point if we are minimized so try and make them sane if (DialogWidth<=0) DialogWidth = ScreenWidth / 2; else if (DialogWidth > ScreenWidth) DialogWidth = ScreenWidth; if (DialogHeight<=0) DialogHeight = ScreenHeight / 2; else if (DialogHeight > ScreenHeight) DialogHeight = ScreenHeight; // Centre the dialog box and give it the 'top' style. INT32 Left, Top; Left = (ScreenWidth - DialogWidth) / 2; Top = (ScreenHeight - DialogHeight) / 2; SetWindowPos(&wndTop, Left, Top, DialogWidth, DialogHeight, SWP_SHOWWINDOW); // If we got this far, then we changed the keyboard focus, so return FALSE. return FALSE; SevereError: // Ooer - deeply catastrophic error...report to user and exit. String_256 Message; // First - check that this isn't just because of an empty error message. if (m_StaticTextStr == 0) { // Get the error message TCHAR *pMsg = Error::GetErrorString(); if ((pMsg == NULL) || (pMsg[0] == 0)) { // // There is no error message! // // In debug builds, give developer a chance to go into debugger to see who is not // setting an error message. #ifdef _DEBUG if (::MessageBox(ParentHwnd, "Somebody reported an error without an error message being set.\r" "Click OK to continue, or Cancel to go into debugger", "DEBUG Warning from Camelot", MB_OKCANCEL| MB_SYSTEMMODAL | MB_ICONHAND) == IDCANCEL) { // User wants to go into debugger DebugBreak(); } #endif // Tell the user a spurious error has occured, if (!Message.Load(_R(IDS_ERRORBOX_SPURIOUS))) // Can't load error message - panic. goto VerySevereError; // Try to get the string that says "Warning from Camelot" String_64 Title; if (!Title.Load(_R(IDS_ERRORBOX_WARNING))) goto VerySevereError; if (::MessageBox(ParentHwnd, (TCHAR *) Message, (TCHAR *) Title, MB_OK | MB_SYSTEMMODAL | MB_ICONHAND) == 0) // Could not create the message box - try our fallback one (probably won't // work but what the hell). goto VerySevereError; // Simulate user hitting default button. EndDialog((INT32) m_OK); return TRUE; // We haven't set the keyboard focus. } } // Inform the user that we've got a bit of a bad karma situation, and that the error // box might be not be completely accurate. if (!Message.Load(_R(IDS_ERRORBOX_SEVERE))) goto VerySevereError; if (::MessageBox(ParentHwnd, (TCHAR *) Message, (TCHAR *)BoxTitle, /*"Serious Error", */ MB_OK | MB_SYSTEMMODAL | MB_ICONHAND) == 0) // Could not create the message box - try our fallback one (probably won't // work but what the hell). goto VerySevereError; // Ok - try to report the error as best we can... // Work out what buttons to put on the dialog... // We use SYSTEMMODAL with ICONHAND because the SDK docs recommend this for low // memory/severe error situations. UINT32 MBFlags; MBFlags = MB_SYSTEMMODAL | MB_ICONHAND; // Do we need a cancel icon? if (m_Cancel != m_OK) MBFlags |= MB_OKCANCEL; else MBFlags |= MB_OK; if (m_StaticTextStr != 0) { if (Message.Load(m_StaticTextStr, m_OwnerModule)) { // Error message loaded ok - display it INT32 Result = ::MessageBox(ParentHwnd, (TCHAR *) Message, (TCHAR *)BoxTitle, MBFlags); if (Result == 0) // Could not create the message box - try our fallback one (probably won't // work but what the hell). goto VerySevereError; if (Result == IDCANCEL) { // Simulate user hitting cancel button. EndDialog((INT32) m_Cancel); } else { // Simulate user hitting default button. EndDialog((INT32) m_OK); } return TRUE; // We haven't set the keyboard focus. } else { // Can't load error message - bail out goto VerySevereError; } } else { // Get the error message TCHAR *pMsg = Error::GetErrorString(); if (pMsg == NULL) // No error message! goto VerySevereError; // Found error message ok - display it INT32 Result = ::MessageBox(ParentHwnd, pMsg, (TCHAR *)BoxTitle, MBFlags); if (Result == 0) // Could not create the message box - try our fallback one (probably won't // work but what the hell). goto VerySevereError; if (Result == IDCANCEL) { // Simulate user hitting cancel button. EndDialog((INT32) m_Cancel); } else { // Simulate user hitting default button. EndDialog((INT32) m_OK); } return TRUE; // We haven't set the keyboard focus. } VerySevereError: // Very bad - we can't even report the error - just let the user that something deeply // sad has happened, and pretend that the OK button was pressed. ::MessageBox(ParentHwnd, (TCHAR *)VerySeriousError, (TCHAR *)BoxTitle, MB_OK | MB_SYSTEMMODAL | MB_ICONHAND); // Simulate user hitting default button. EndDialog((INT32) m_OK); return TRUE; // We haven't set the keyboard focus. }