Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -r402885eda2ed755a079c854d1228ac5f76cbec7c -r0589eeee132373075cccc56eab04db2b5160ae81 --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 402885eda2ed755a079c854d1228ac5f76cbec7c) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 0589eeee132373075cccc56eab04db2b5160ae81) @@ -42,7 +42,19 @@ #define BROADCAST_HD_OP_MODE_INTERVAL ( 250 / TASK_GENERAL_INTERVAL ) ///< HD operation mode broadcast interval (in task interval/sec). #define DATA_PUBLISH_COUNTER_START_COUNT 11 ///< Data publish counter start count. +#define NUM_CONFIRM_REQUESTS 4 ///< Number of available confirmation requests. +#define CONFIRMATION_REQUEST_TIMEOUT_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Confirmation response timeout in ms +/// Structure for confirmation request. +typedef struct +{ + GENERIC_CONFIRM_ID_T requestID; ///< Request ID + GENERIC_CONFIRM_COMMAND_T requestType; ///< Request Type + U32 timeStamp; ///< Timestamp for request + CONFIRMATION_REQUEST_STATUS_T status; ///< Request status (pending, accepted, rejected) +} CONFIRMATION_REQUEST_T; + + // ********** private data ********** static volatile BOOL modeRequest[ NUM_OF_MODES - 1 ]; ///< Pending operation mode change requests. @@ -53,6 +65,11 @@ /// Interval (in task intervals) at which to publish operation mode data to CAN bus. static OVERRIDE_U32_T opModePublishInterval = { BROADCAST_HD_OP_MODE_INTERVAL, BROADCAST_HD_OP_MODE_INTERVAL, BROADCAST_HD_OP_MODE_INTERVAL, 0 }; static U32 priorSubMode = 0; ///< The prior submode state. +static CONFIRMATION_REQUEST_T confirmRequests[NUM_CONFIRM_REQUESTS] = + { GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, + GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, + GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, + GENERIC_CONFIRM_ID_NONE, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0, CONFIRMATION_REQUEST_STATUS_UNUSED, }; /// This matrix determines legal transitions from one mode to another static const HD_OP_MODE_T MODE_TRANSITION_TABLE[ NUM_OF_MODES - 1 ][ NUM_OF_MODES - 1 ] = { @@ -71,6 +88,7 @@ static HD_OP_MODE_T arbitrateModeRequest( void ); static void transitionToNewOperationMode( HD_OP_MODE_T newMode ); static void broadcastOperationMode( void ); +static void updateConfirmationRequestTimeouts( void ); /*********************************************************************//** * @brief @@ -200,6 +218,8 @@ } priorSubMode = currentSubMode; + updateConfirmationRequestTimeouts( ); + // Broadcast current operation mode on interval broadcastOperationMode(); } @@ -415,7 +435,154 @@ } } +/*********************************************************************//** + * @brief + * The updateConfirmationRequestTimeouts function checks the status of + * all active confirmation requests and updates the timeout. + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] status updated if timeout. + * @param none + * @return none + *************************************************************************/ +void updateConfirmationRequestTimeouts( void ) +{ + U08 i; + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( CONFIRMATION_REQUEST_STATUS_PENDING == confirmRequests[ i ].status ) + { + if ( TRUE == didTimeout( confirmRequests[ i ].timeStamp, CONFIRMATION_REQUEST_TIMEOUT_MS ) ) + { + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_TIMEOUT; + } + } + } +} + +/*********************************************************************//** + * @brief + * The getConfirmationRequestStatus function returns the status of a confirmation request + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] cleared if completed. + * @param request ID + * @return CONFIRMATION_REQUEST_STATUS_T + *************************************************************************/ +CONFIRMATION_REQUEST_STATUS_T getConfirmationRequestStatus( GENERIC_CONFIRM_ID_T request_id ) +{ + U08 i; + CONFIRMATION_REQUEST_STATUS_T status = CONFIRMATION_REQUEST_STATUS_PENDING; + BOOL pending = FALSE; + U08 pending_index = 0; + + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( confirmRequests[ i ].requestID == request_id ) + { + status = confirmRequests[ i ].status; + if ( CONFIRMATION_REQUEST_STATUS_PENDING != status) + { + // Send UI clear + if ( CONFIRMATION_REQUEST_STATUS_TIMEOUT == confirmRequests[ i ].status ) + { + sendConfirmationRequest( confirmRequests[ i ].requestID, GENERIC_CONFIRM_CMD_TIMEOUT_CLOSE, 0 ); + } + else + { + sendConfirmationRequest( confirmRequests[ i ].requestID, GENERIC_CONFIRM_CMD_ACCEPT_CLOSE, 0 ); + } + + // Clear the confirmation request, it is done and consumed + confirmRequests[ i ].requestID = GENERIC_CONFIRM_ID_NONE; + confirmRequests[ i ].requestType = GENERIC_CONFIRM_CMD_REQUEST_OPEN; + confirmRequests[ i ].timeStamp = 0; + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_UNUSED; + } + } + else if ( CONFIRMATION_REQUEST_STATUS_PENDING == confirmRequests[ i ].status ) + { + if ( TRUE == pending ) + { + // Is this newer than other pending request? + if ( confirmRequests[ i ].timeStamp > confirmRequests[ pending_index ].timeStamp ) + { + pending_index = i; + pending = TRUE; + } + } + else + { + pending_index = i; + pending = TRUE; + } + } + } + if ( ( CONFIRMATION_REQUEST_STATUS_PENDING != status ) && ( TRUE == pending ) ) + { + // Last confirmation cleared, pending request must be resent to UI + sendConfirmationRequest( confirmRequests[ pending_index ].requestID, confirmRequests[ pending_index ].requestType, 0 ); + } + + return status; +} + +/*********************************************************************//** + * @brief + * The setConfirmationRequestStatus function sets the status of a confirmation request + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] status. + * @param request ID + * @param new status + * @return CONFIRMATION_REQUEST_STATUS_T + *************************************************************************/ +void setConfirmationRequestStatus( GENERIC_CONFIRM_ID_T request_id, CONFIRMATION_REQUEST_STATUS_T status ) +{ + U08 i; + + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( confirmRequests[ i ].requestID == request_id ) + { + confirmRequests[ i ].status = status; + break; + } + } +} + +/*********************************************************************//** + * @brief + * The addConfirmationRequest function sends a confirmation request to UI + * @details Inputs: confirmRequests[] + * @details Outputs: confirmRequests[] new added. + * @param request_id - confirm id / type + * @param request_type - confirm command + * @return request ID - will be non-zero if added + *************************************************************************/ +GENERIC_CONFIRM_ID_T addConfirmationRequest( GENERIC_CONFIRM_ID_T request_id, GENERIC_CONFIRM_COMMAND_T request_type, U32 reject_reason ) +{ + U08 i; + GENERIC_CONFIRM_ID_T new_id = GENERIC_CONFIRM_ID_NONE; + + for ( i = 0; i < NUM_CONFIRM_REQUESTS; i++ ) + { + if ( confirmRequests[ i ].status == CONFIRMATION_REQUEST_STATUS_UNUSED ) + { + // Save the confirmation request info + confirmRequests[ i ].requestID = request_id; + confirmRequests[ i ].requestType = request_type; + confirmRequests[ i ].timeStamp = getMSTimerCount(); + confirmRequests[ i ].status = CONFIRMATION_REQUEST_STATUS_PENDING; + new_id = request_id; + sendConfirmationRequest( request_id, request_type, reject_reason ); + + break; + } + } + + return new_id; +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/