Ejemplo n.º 1
0
void CanIf_ControllerBusOff(uint8 Controller)
{
  CanIf_Arc_ChannelIdType channel = 0xff;

  VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_UNINIT );

  for(int i = 0; i < CANIF_CHANNEL_CNT; i++)
  {
	  if(CanIf_ConfigPtr->Arc_ChannelToControllerMap[i] == Controller)
	  {
		  channel = i;
	  }
  }

  VALIDATE_NO_RV( Controller < CANIF_CHANNEL_CNT, CANIF_CONTROLLER_BUSOFF_ID, CANIF_E_PARAM_CONTROLLER );

  // According to figure 35 in canif spec this should be done in
  // Can driver but it is better to do it here
  CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);

  if (CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification != NULL)
  {
    CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification(channel);
  }
}
Ejemplo n.º 2
0
void CanIf_Arc_Error(uint8 Controller, Can_Arc_ErrorType Error)
{
  CanIf_Arc_ChannelIdType channel = 0xff;

  VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_ARCERROR_ID, CANIF_E_UNINIT );

  for(int i = 0; i < CANIF_CHANNEL_CNT; i++)
  {
	  if(CanIf_ConfigPtr->Arc_ChannelToControllerMap[i] == Controller)
	  {
		  channel = i;
	  }
  }

  VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_ARCERROR_ID, CANIF_E_PARAM_CONTROLLER );

  if (CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton != NULL)
  {
    CanIf_ConfigPtr->DispatchConfig->CanIfErrorNotificaton(Controller, Error);
  }

  // Special fix for restart of bus incase of general can error i.e. connection to CanSM
  if (CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification != NULL)
  {
    CanIf_ConfigPtr->DispatchConfig->CanIfBusOffNotification(channel);
  }
}
Ejemplo n.º 3
0
void CanIf_SetDynamicTxId(PduIdType CanTxPduId, Can_IdType CanId)
{
  CanIf_TxPduConfigType *txEntry;
  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_SETDYNAMICTX_ID, CANIF_E_UNINIT );

  // Get the controller from L-PDU handle
  txEntry = CanIf_FindTxPduEntry(CanTxPduId);

  if (txEntry == 0)
  {
    VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);
    return;
  }

  // Check that this is a dymanic PDU
  if (txEntry->CanIfCanTxPduType != CANIF_PDU_TYPE_DYNAMIC)
  {
    VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_INVALID_TXPDUID);
    return;
  }

  // Check that this is an extended or standard id
  if (((CanId & 0x80000000U) && (txEntry->CanIfTxPduIdCanIdType == CANIF_CAN_ID_TYPE_29)) ||
      (((CanId & 0x80000000U) == 0) && (txEntry->CanIfTxPduIdCanIdType == CANIF_CAN_ID_TYPE_11)))
  {
    // Update the CanID
    txEntry->CanIfCanTxPduIdCanId = CanId & 0x7FFFFFFFU;
  }
  else
  {
    // Inavlid Canid to configuration
    VALIDATE_NO_RV(FALSE, CANIF_SETDYNAMICTX_ID, CANIF_E_PARAM_CANID);
  }
}
Ejemplo n.º 4
0
void Fls_SetMode(MemIf_ModeType Mode) {

	VALIDATE_NO_RV( ( Fls_Global.status != MEMIF_UNINIT ), FLS_SET_MODE_ID, FLS_E_UNINIT);
	/** @req 3.1.5/FLS156 */
	VALIDATE_NO_RV( ( Fls_Global.status != MEMIF_BUSY ), FLS_SET_MODE_ID, FLS_E_BUSY);

	/** @req 3.1.5/FLS155 */
	Fls_Global.mode = Mode;
}
Ejemplo n.º 5
0
void Fls_SetMode(MemIf_ModeType Mode) {

	VALIDATE_NO_RV( ( Fls_Global.status != MEMIF_UNINIT ), FLS_SET_MODE_ID, FLS_E_UNINIT);
	/* @req SWS_Fls_00156 */
	VALIDATE_NO_RV( ( Fls_Global.status != MEMIF_BUSY ), FLS_SET_MODE_ID, FLS_E_BUSY);

	VALIDATE_NO_RV(((Mode == MEMIF_MODE_SLOW ) || (Mode == MEMIF_MODE_SLOW)), FLS_SET_MODE_ID, FLS_E_PARAM_POINTER);

	/* @req SWS_Fls_00155 */
	Fls_Global.mode = Mode;
}
Ejemplo n.º 6
0
void CanIf_CancelTxConfirmation(const Can_PduType *PduInfoPtr)
{
  VALIDATE(FALSE, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_NOK_NOSUPPORT);
  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_CANCELTXCONFIRMATION_ID, CANIF_E_UNINIT);
  VALIDATE_NO_RV(PduInfoPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);

  const CanIf_TxPduConfigType *entry =
    CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr;

  // Not supported

  // Did not find the PDU, something is wrong
  VALIDATE_NO_RV(FALSE, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);
}
Ejemplo n.º 7
0
void Fls_Init(const Fls_ConfigType *ConfigPtr) {
	/** @req FLS249 3.0 */
	/** @req FLS191 3.0 */
	/** @req FLS014 3.0 */
	/** @req FLS086 3.0 */
	/** @req FLS015 3.0 */
	/** !req FLS048 TODO, true?    */
	/** !req FLS271 NO_SUPPORT 3.0 */
	/** !req FLS325 NO_SUPPORT 4.0 */
	/** !req FLS326 NO_SUPPORT 4.0 */

	/** @req FLS268 */
	VALIDATE_NO_RV(Fls_Global.status!=MEMIF_BUSY,FLS_INIT_ID, FLS_E_BUSY );

	VALIDATE_CONFIG(ConfigPtr->FlsMaxReadFastMode != 0 );
	VALIDATE_CONFIG(ConfigPtr->FlsMaxReadNormalMode != 0 );
	VALIDATE_CONFIG(ConfigPtr->FlsMaxWriteFastMode != 0 );
	VALIDATE_CONFIG(ConfigPtr->FlsMaxWriteNormalMode != 0 );

	Fls_Global.status = MEMIF_UNINIT;
	Fls_Global.jobResultType = MEMIF_JOB_PENDING;
	// TODO: FLS_E_PARAM_CONFIG

	/** @req FLS191 */
	Fls_Global.config = ConfigPtr;

	Flash_Init();

	/** @req FLS016 3.0 *//** @req FLS323 4.0 *//** @req FLS324 4.0*/
	Fls_Global.status = MEMIF_IDLE;
	Fls_Global.jobResultType = MEMIF_JOB_OK;
	return;
}
Ejemplo n.º 8
0
EXPORT void Can_Hw_DisableControllerInterrupts(uint8 controller)
{
	  imask_t state;
	  Can_UnitType *canUnit;
	  CAN_HW_t *canHw;

	  canUnit = CAN_GET_PRIVATE_DATA(controller);

	  VALIDATE_NO_RV( (canUnit->state!=CANIF_CS_UNINIT), 0x4, CAN_E_UNINIT );

	  Irq_Save(state);
	  if(canUnit->lock_cnt > 0 )
	  {
	    // Interrupts already disabled
	    canUnit->lock_cnt++;
	    Irq_Restore(state);
	    return;
	  }
	  canUnit->lock_cnt++;
	  Irq_Restore(state);

	  /* Don't try to be intelligent, turn everything off */
	  canHw = GetController(controller);

	  /* Turn off the tx interrupt mailboxes */
	   CAN_ITConfig(canHw, CAN_IT_TME, DISABLE);

	   /* Turn off the bus off/tx warning/rx warning and error and rx  */
	   CAN_ITConfig(canHw, CAN_IT_FMP0 | CAN_IT_BOF | CAN_IT_ERR | CAN_IT_WKU, DISABLE);
}
Ejemplo n.º 9
0
void CanIf_PreInit_InitController(uint8 Controller, uint8 ConfigurationIndex){
	// We call this a CanIf channel. Hopefully makes it easier to follow.
	CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;

	VALIDATE_NO_RV(channel < CANIF_CHANNEL_CNT, CANIF_INIT_ID, CANIF_E_PARAM_CONTROLLER);
	VALIDATE_NO_RV(ConfigurationIndex < CANIF_CHANNEL_CONFIGURATION_CNT, CANIF_INIT_ID, CANIF_E_PARAM_POINTER);


	const CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(channel);
	// Validate that the configuration at the index match the right channel
	VALIDATE_NO_RV(CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfControllerIdRef == channel, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
	const Can_ControllerConfigType *canConfig = CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfInitControllerRef;
	// Validate that the CanIfControllerConfig points to configuration for the right Can Controller
	VALIDATE_NO_RV(canConfig->CanControllerId == canControllerId, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);

	Can_InitController(canControllerId, canConfig);
}
Ejemplo n.º 10
0
void CanIf_SetWakeupEvent(uint8 Controller)
{
	CanIf_Arc_ChannelIdType channel = 0xff;

	VALIDATE_NO_RV( CanIf_Global.initRun, CANIF_SETWAKEUPEVENT_ID, CANIF_E_UNINIT );

	for(int i = 0; i < CANIF_CHANNEL_CNT; i++)
	{
	  if(CanIf_ConfigPtr->Arc_ChannelToControllerMap[i] == Controller)
	  {
		  channel = i;
	  }
	}

	VALIDATE_NO_RV(FALSE, CANIF_SETWAKEUPEVENT_ID, CANIF_E_NOK_NOSUPPORT);
	VALIDATE_NO_RV( channel < CANIF_CHANNEL_CNT, CANIF_SETWAKEUPEVENT_ID, CANIF_E_PARAM_CONTROLLER );

	// Not supported
}
Ejemplo n.º 11
0
/*
 * Callback interface from driver
 */
void CanIf_TxConfirmation(PduIdType canTxPduId)
{
  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_TXCONFIRMATION_ID, CANIF_E_UNINIT)
  VALIDATE_NO_RV(canTxPduId < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanTXPduIds, CANIF_TXCONFIRMATION_ID, CANIF_E_PARAM_LPDU);

  const CanIf_TxPduConfigType* entry =
    &CanIf_ConfigPtr->InitConfig->CanIfTxPduConfigPtr[canTxPduId];

      if (entry->CanIfUserTxConfirmation != NULL)
      {
        CanIf_ChannelGetModeType mode;
        CanIf_GetPduMode(entry->CanIfCanTxPduHthRef->CanIfCanControllerIdRef, &mode);
        if ((mode == CANIF_GET_TX_ONLINE) || (mode == CANIF_GET_ONLINE)
            || (mode == CANIF_GET_OFFLINE_ACTIVE) || (mode == CANIF_GET_OFFLINE_ACTIVE_RX_ONLINE) )
        {
          entry->CanIfUserTxConfirmation(entry->CanIfTxPduId);  /* CANIF053 */
        }
      }
      return;
}
Ejemplo n.º 12
0
void Fls_GetVersionInfo( Std_VersionInfoType *VersioninfoPtr )
{
    /* @req SWS_Fls_00363 */
    VALIDATE_NO_RV( ( NULL != VersioninfoPtr ), FLS_GET_VERSION_INFO_ID, FLS_E_PARAM_POINTER);

    VersioninfoPtr->vendorID = FLS_VENDOR_ID;
    VersioninfoPtr->moduleID = FLS_MODULE_ID;
    VersioninfoPtr->sw_major_version = FLS_SW_MAJOR_VERSION;
    VersioninfoPtr->sw_minor_version = FLS_SW_MINOR_VERSION;
    VersioninfoPtr->sw_patch_version = FLS_SW_PATCH_VERSION;

}
Ejemplo n.º 13
0
void Fls_Init(const Fls_ConfigType *ConfigPtr) {
	/** @req SWS_Fls_00014 */
	/** @req SWS_Fls_00086 */
	/** @req SWS_Fls_00015 */
	/** !req SWS_Fls_00048 */
	/** !req SWS_Fls_00325 */
	/** !req SWS_Fls_00326 */

	/** @req SWS_Fls_00268 */
	VALIDATE_NO_RV(Fls_Global.status!=MEMIF_BUSY,FLS_INIT_ID, FLS_E_BUSY );

	VALIDATE_NO_RV((ConfigPtr != NULL), FLS_INIT_ID, FLS_E_PARAM_CONFIG);
	VALIDATE_NO_RV(ConfigPtr->FlsMaxReadFastMode != 0, FLS_INIT_ID, FLS_E_PARAM_CONFIG);
	VALIDATE_NO_RV(ConfigPtr->FlsMaxReadNormalMode != 0, FLS_INIT_ID, FLS_E_PARAM_CONFIG);
	VALIDATE_NO_RV(ConfigPtr->FlsMaxWriteFastMode != 0, FLS_INIT_ID, FLS_E_PARAM_CONFIG);
	VALIDATE_NO_RV(ConfigPtr->FlsMaxWriteNormalMode != 0, FLS_INIT_ID, FLS_E_PARAM_CONFIG);

	Fls_Global.status = MEMIF_UNINIT;
	Fls_Global.jobResultType = MEMIF_JOB_PENDING;

	/** @req SWS_Fls_00191 */
	Fls_Global.config = ConfigPtr;

	Flash_Init();

	/** @req SWS_Fls_00323 */
	/** @req SWS_Fls_00324 */
	Fls_Global.status = MEMIF_IDLE;
	Fls_Global.jobResultType = MEMIF_JOB_OK;
	return;
}
Ejemplo n.º 14
0
void CanIf_Init(const CanIf_ConfigType *ConfigPtr)
{
  VALIDATE_NO_RV(ConfigPtr != 0, CANIF_INIT_ID, CANIF_E_PARAM_POINTER); // Only PostBuild case supported

  CanIf_ConfigPtr = ConfigPtr;

  for (uint8 i = 0; i < CANIF_CHANNEL_CNT; i++)
  {
    CanIf_Global.channelData[i].ControllerMode = CANIF_CS_STOPPED;
    CanIf_Global.channelData[i].PduMode = CANIF_GET_OFFLINE;
    CanIf_PreInit_InitController(i, CanIf_ConfigPtr->Arc_ChannelDefaultConfIndex[i]);
  }


  CanIf_Global.initRun = TRUE;
}
Ejemplo n.º 15
0
/*
 * Controller :: CanIf_Arc_ChannelIdType (CanIf-specific id to abstract from Can driver/controllers)
 * ConfigurationIndex :: CanIf_Arc_ConfigurationIndexType
 */
void CanIf_InitController(uint8 Controller, uint8 ConfigurationIndex)
{
  // We call this a CanIf channel. Hopefully makes it easier to follow.
  CanIf_Arc_ChannelIdType channel = (CanIf_Arc_ChannelIdType) Controller;
  CanIf_ControllerModeType mode;

  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_INIT_CONTROLLER_ID, CANIF_E_UNINIT );
  VALIDATE_NO_RV(channel < CANIF_CHANNEL_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);
  VALIDATE_NO_RV(ConfigurationIndex < CANIF_CHANNEL_CONFIGURATION_CNT, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_POINTER);

  if (CanIf_GetControllerMode(channel, &mode) == E_OK)
  {
    if (mode == CANIF_CS_STARTED)
    {
      CanIf_SetControllerMode(channel, CANIF_CS_STOPPED); // CANIF092
    }
    else if (mode != CANIF_CS_STOPPED)
    {
      VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE); // CANIF092
    }
  }
  else
  {
    VALIDATE_NO_RV(FALSE, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER_MODE);
  }

  // CANIF293: ..Subsequently the CAN Interface calls the corresponding
  //             CAN Driver initialization services.

  // CANIF066: The CAN Interface has access to the CAN Driver configuration data. All
  // public CAN Driver configuration data are described in [8] Specification of CAN Driver.

  // Grab the configuration from the Can Controller
  const Can_ControllerConfigType *canConfig;
  const CanControllerIdType canControllerId = ARC_GET_CHANNEL_CONTROLLER(channel);

  // Validate that the configuration at the index match the right channel
  VALIDATE_NO_RV(CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfControllerIdRef == channel, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);

  canConfig = CanIf_ConfigPtr->ControllerConfig[ConfigurationIndex].CanIfInitControllerRef;

  // Validate that the CanIfControllerConfig points to configuration for the right Can Controller
  VALIDATE_NO_RV(canConfig->CanControllerId == canControllerId, CANIF_INIT_CONTROLLER_ID, CANIF_E_PARAM_CONTROLLER);

  Can_InitController(canControllerId, canConfig);

  // Set mode to stopped
  CanIf_SetControllerMode(channel, CANIF_CS_STOPPED);
}
Ejemplo n.º 16
0
EXPORT void Can_Hw_EnableControllerInterrupts( uint8 controller )
{
	 imask_t state;
	  Can_UnitType *canUnit;
	  CAN_HW_t *canHw;
	  const Can_ControllerConfigType *canHwConfig;

	  canUnit = CAN_GET_PRIVATE_DATA(controller);

	  VALIDATE_NO_RV( (canUnit->state!=CANIF_CS_UNINIT), 0x5, CAN_E_UNINIT );

	  Irq_Save(state);
	  if( canUnit->lock_cnt > 1 )
	  {
	    // IRQ should still be disabled so just decrement counter
	    canUnit->lock_cnt--;
	    Irq_Restore(state);
	    return;
	  } else if (canUnit->lock_cnt == 1)
	  {
	    canUnit->lock_cnt = 0;
	  }
	  Irq_Restore(state);

	  canHw = GetController(controller);

	  canHwConfig = CAN_GET_CONTROLLER_CONFIG(Can_Global.channelMap[controller]);

	   if( canHwConfig->CanRxProcessing == CAN_PROCESS_TYPE_INTERRUPT ) {
	     /* Turn on the rx interrupt */
	 	CAN_ITConfig(canHw, CAN_IT_FMP0, ENABLE);
	   }
	   if( canHwConfig->CanTxProcessing == CAN_PROCESS_TYPE_INTERRUPT ) {
	 	/* Turn on the tx interrupt mailboxes */
	   	CAN_ITConfig(canHw, CAN_IT_TME, ENABLE);
	   }

	   // BusOff here represents all errors and warnings
	   if( canHwConfig->CanBusOffProcessing == CAN_PROCESS_TYPE_INTERRUPT ) {
	 	/* Turn on the bus off/tx warning/rx warning and error and rx  */
	 	CAN_ITConfig(canHw, CAN_IT_BOF | CAN_IT_ERR | CAN_IT_WKU, ENABLE);
	   }

	   return;
}
Ejemplo n.º 17
0
//----- MAIN -----------------------------------------------------------------------------------------------------------------
void EcuM_MainFunction(void) {
	EcuM_WakeupSourceType wMask=0;
#if defined(USE_LDEBUG_PRINTF)
	static uint32 validationMask;
#endif
	static uint32 validationMaxTime;
	static uint32 pendingWkupMask = 0;

#if (ECUM_AR_VERSION < 40000)
	VALIDATE_NO_RV(EcuM_World.initiated, ECUM_MAINFUNCTION_ID, ECUM_E_UNINIT);
#else
	/* @req EcuMf0029 */
	if (!EcuM_World.initiated) {
		return;
	}
#endif

#if defined(USE_LDEBUG_PRINTF)
	{
	  static EcuM_StateType oldEcuMState = 0xff;
	  if( oldEcuMState != EcuM_World.current_state) {
	    DEBUG_ECUM_STATE(EcuM_World.current_state);
	    oldEcuMState = EcuM_World.current_state;
	  }
	}
#endif

	switch (EcuM_World.current_state) {
	case ECUM_STATE_APP_RUN:
		/* RUN II state */
		in_state_appRun();
		break;

	case ECUM_STATE_APP_POST_RUN:
		/* RUN III state */
		in_state_appPostRun();
		break;
	case ECUM_STATE_PREP_SHUTDOWN:
		in_state_prepShutdown();
		break;

	case ECUM_STATE_GO_OFF_ONE:
		in_state_goOffOne();
		break;

	case ECUM_STATE_GO_SLEEP:
	  /* 4 cases:
	   * 1. Wait for the NvM_WriteAll() - Stay in state
	   * 2. Timeout on NvM_WriteAll()   - go to ECUM_STATE_SLEEP (Scheduler is locked)
	   * 3. NvM_WriteAll() is done      - go to ECUM_STATE_SLEEP (Scheduler is locked)
	   * 4. Run request                 - Call NvM_CancelAll() and go to ECUM_STATE_WAKEUP_ONE.
	   */

	  in_state_goSleep();

	  if( EcuM_World.current_state != ECUM_STATE_SLEEP ) {
	    break;
	  }

	  /* Flow Through, Scheduler is Locked */
	  //lint -fallthrough MISRA 2004 Rule 15.2
	case ECUM_STATE_SLEEP:
		in_state_sleep();
		/* Flow Through, Scheduler is Locked */
		//lint -fallthrough MISRA 2004 Rule 15.2
	case ECUM_STATE_WAKEUP_ONE: {
		DEBUG_ECUM_STATE(EcuM_World.current_state);

		/*@req EcuMF2975 */

		Mcu_SetMode(EcuM_World.config->EcuMNormalMcuMode);

		wMask = EcuM_GetPendingWakeupEvents();

		DEBUG_ECUM_CALLOUT_W_ARG("EcuM_DisableWakeupSources", "0x%lx", (uint32) wMask);
		EcuM_DisableWakeupSources(wMask);

		/* @req EcuM2562 */   /* @req EcuMf2562 */
		EcuM_AL_DriverRestart(EcuM_World.config);

		EcuM_World.killAllRequest = false;	/* Enable run request again */

		(void)ReleaseResource(RES_SCHEDULER);

#if defined(USE_LDEBUG_PRINTF)
		validationMask = 0;
#endif
		validationMaxTime = 0;
		const EcuM_WakeupSourceConfigType *wkupCfgPtr;

		SetCurrentState(ECUM_STATE_WAKEUP_VALIDATION);

		/*-------------- ECUM_STATE_WAKEUP_VALIDATION -------------------- */

		DEBUG_ECUM_CALLOUT(ECUM_STR "EcuM_GetPendingWakeupEvents");
		pendingWkupMask = EcuM_GetPendingWakeupEvents();

		DEBUG_ECUM_CALLOUT_W_ARG("EcuM_StartWakeupSources", "0x%lx",(uint32) pendingWkupMask);

		EcuM_StartWakeupSources(pendingWkupMask);
		EcuM_World.validationTimer = 0;

		/* Calculate the validation timing , if any*/

		/* @req EcuMf2494 */
		/* @req EcuM2479 */  /* @req EcuMf2479 */

		for (int i = 0; i < ECUM_WKSOURCE_USER_CNT; i++) {
			wkupCfgPtr = &EcuM_World.config->EcuMWakeupSourceConfig[i];

			/* Can't validate something that is not pending */
			if (wMask & wkupCfgPtr->EcuMWakeupSourceId) {

				/* No validation timeout == ECUM_VALIDATION_TIMEOUT_ILL */
				if ((wkupCfgPtr->EcuMValidationTimeout
						!= ECUM_VALIDATION_TIMEOUT_ILL)
						&& (wMask & wkupCfgPtr->EcuMWakeupSourceId)) {
					/* Build a mask with the sources that need validation */
#if defined(USE_LDEBUG_PRINTF)
				    validationMask |= wkupCfgPtr->EcuMWakeupSourceId;
#endif
					/* Use one validation timeout, take the longest */
					validationMaxTime =
							MAX( wkupCfgPtr->EcuMValidationTimeout / ECUM_MAIN_FUNCTION_PERIOD,
							validationMaxTime);
					EcuM_World.validationTimer = validationMaxTime;
				} else {
					LDEBUG_PRINTF(ECUM_STR "No Validation for :0x%lx (EcuM_ValidateWakeupEvent() called)\n",
							(uint32) wkupCfgPtr->EcuMWakeupSourceId);

					/* Validate right away */
				/* @req EcuM2976 */  /* @req EcuMf2976 */
					EcuM_ValidateWakeupEvent(wkupCfgPtr->EcuMWakeupSourceId);
				}
			}
		}

		break;
	}

	case ECUM_STATE_WAKEUP_VALIDATION: {
		/* !req 3.1.5/EcuM2566 */
		boolean done = 0;

		if (EcuM_World.validationTimer != 0) {
			/*
			 * Call EcuM_CheckValidation() while all events have not been validated and
			 * timeout have not expired. The call to EcuM_CheckValidation(..) triggers a call
			 * to EcuM_ValidateWakeupEvent(..) from the driver when validated.
			 */

			/* Check validation for the events that do not match, ie not yet validated */
			DEBUG_ECUM_CALLOUT_W_ARG(
					"EcuM_CheckValidation",
					"0x%lx",
					(uint32)(EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask));

			EcuM_CheckValidation( EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask);
			/* !req EcuMf2495*/


			if (0 == (EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask)) {
				/* All events have been validated */
				done = 1;
			} else {
				LDEBUG_PRINTF( ECUM_STR "  Awaiting validation for mask: pending=%lx, expected=%lx\n",
								pendingWkupMask, validationMask);
				LDEBUG_PRINTF(ECUM_STR "  Validation Timer            : %lu\n", EcuM_World.validationTimer);
			}

		} else {
			uint32 notValidatedMask = EcuM_GetValidatedWakeupEvents() ^ pendingWkupMask;

			/* Stop wakeupSources that are not validated */
			if (notValidatedMask) {
				DEBUG_ECUM_CALLOUT_W_ARG("EcuM_StopWakeupSources", "0x%lx",
						(uint32) notValidatedMask);
				EcuM_StopWakeupSources(notValidatedMask);

#if defined(USE_BSWM)
				BswM_EcuM_CurrentWakeup(notValidatedMask, ECUM_WKSTATUS_EXPIRED);
#endif
			}
			done = 1;
		}

		/* @req 3.1.5/EcuM2710 */
		if (EcuM_World.validationTimer) {
			EcuM_World.validationTimer--;
		}

		if (done) {
#if defined(USE_COMM)
			const EcuM_WakeupSourceConfigType *wkupCfgPtr;
			uint32 validated = EcuM_GetValidatedWakeupEvents();

			for(int i=0;i<ECUM_WKSOURCE_USER_CNT;i++) {
				wkupCfgPtr = &EcuM_World.config->EcuMWakeupSourceConfig[i];

				/* Call wakeup indication for all validated events with a channel assigned */
				if ( (wkupCfgPtr->EcuMComMChannel != ECUM_COMM_CHANNEL_ILL) &&
						wkupCfgPtr->EcuMWakeupSourceId & validated ) {
					ComM_EcuM_WakeUpIndication(wkupCfgPtr->EcuMComMChannel);
				}
			}
#endif

			SetCurrentState(ECUM_STATE_WAKEUP_REACTION);
		}
		break;
	}

	case ECUM_STATE_WAKEUP_REACTION: {
		/*
		 * At this stage we want to know how to react to the wakeup, e.g. go
		 * back to RUN or SHUTDOWN, etc.
		 */
		EcuM_WakeupReactionType wReaction;

		wMask = EcuM_GetValidatedWakeupEvents();
		LDEBUG_PRINTF(ECUM_STR "EcuM_GetValidatedWakeupEvents() : %x\n", wMask);

		/* NOTE: We have skipped the TTII timer here */

		/* If the wakeup mask here is != 0 we have a validated wakeup event ->
		 * go back to RUN */
		wReaction = (0 == wMask) ? ECUM_WKACT_SHUTDOWN : ECUM_WKACT_RUN;
		wReaction = EcuM_OnWakeupReaction(wReaction);
		
		LDEBUG_PRINTF(ECUM_STR "Wakeup Reaction: %s\n", GetWakeupReactionAsString(wReaction));

		if (wReaction == ECUM_WKACT_RUN) {
			/* @req EcuMf2568 */
			SetCurrentState(ECUM_STATE_WAKEUP_TWO);
		} else {
			/* From figure 28 it seems that we should go to SHUTDOWN/GO SLEEP) again from wakeup
			 * not going up to RUN/RUN II state again. */
			/* @req EcuMf2711 */
			/* @req EcuMf2567 */
			SetCurrentState(ECUM_STATE_GO_SLEEP);
		}
		break;
	}

	case ECUM_STATE_WAKEUP_TWO:
#if defined(USE_DEM)
		Dem_Init();
#endif
		EcuM_enter_run_mode();
//		SetCurrentState(ECUM_STATE_APP_RUN);
		break;

	default:
		//IMPROVEMENT: Report error.
		break;
	}
}
Ejemplo n.º 18
0
void Fls_MainFunction(void) {
	/** @req SWS_Fls_00038 */

    static uint32 progressCntr = 0;
	uint32 flashStatus;
	sint32 result;
	uint8 eccError = 0;

	uint32 chunkSize;

	/** @req SWS_Fls_117 */
	VALIDATE_NO_RV(Fls_Global.status != MEMIF_UNINIT,FLS_MAIN_FUNCTION_ID, FLS_E_UNINIT );

	/** @req SWS_Fls_00039 */
	if ( Fls_Global.jobResultType == MEMIF_JOB_PENDING) {
		switch (Fls_Global.jobType) {
		case FLS_JOB_COMPARE:
		    /** @req SWS_Fls_00243 */

			// !req SWS_Fls_00154  Hardware error = FLS_E_COMPARE_FAILED
			// ( we are reading directly from flash so it makes no sense )
		    // Read ECC-error to clear it
		    Mcu_Arc_GetECCError(&eccError); /*lint !e934 Only used in this function  */

		    chunkSize = MIN( Fls_Global.length, Fls_Global.readChunkSize );

		    /** @req SWS_Fls_00244 */
		    /*lint -e{923} flashAddr set by AUTOSAR and it is justified to cast in this case */
			result = (sint32)memcmp((void *)Fls_Global.ramAddr,
					                (void *)Fls_Global.flashAddr, (size_t)chunkSize );

			Fls_Global.ramAddr = &Fls_Global.ramAddr[chunkSize];
			Fls_Global.flashAddr += chunkSize;
			Fls_Global.length -= chunkSize;

			Mcu_Arc_GetECCError(&eccError);  /*lint !e934 Only used in this function  */
			if( eccError > 0u ){
				readFail();
			} else {
				if( 0 != Fls_Global.length ) {
					if (result == 0) {
						Fls_Global.jobResultType = MEMIF_JOB_OK;
					} else {
						/* @req SWS_Fls_00200 */
						Fls_Global.jobResultType = MEMIF_BLOCK_INCONSISTENT;
					}
					Fls_Global.status = MEMIF_IDLE;
					Fls_Global.jobType = FLS_JOB_NONE;
				} else {
					/* Do nothing, wait for next loop */
				}
			}

			break;
		case FLS_JOB_ERASE: {

			flashStatus = Flash_CheckStatus(Fls_Global.config->FlsInfo, (uint32*)Fls_Global.flashAddr, Fls_Global.length ); /*lint !e923 Intended  */

			if (flashStatus == EE_OK ) {
				Fls_Global.jobResultType = MEMIF_JOB_OK;
				Fls_Global.jobType = FLS_JOB_NONE;
				Fls_Global.status = MEMIF_IDLE;
				FEE_JOB_END_NOTIFICATION();
			} else if (flashStatus == EE_INFO_HVOP_INPROGRESS) {
				/* Busy, Do nothing */
			} else {
				// Error
				eraseFail();
			}
			break;
		}
		case FLS_JOB_READ:
			/** @req SWS_Fls_00238 */
			/** @req SWS_Fls_00239 */

			// NOT implemented. Hardware error = FLS_E_READ_FAILED
			// ( we are reading directly from flash so it makes no sense )
			// Read ECC-error to clear it
			Mcu_Arc_GetECCError(&eccError); /*lint !e934 Only used in this function  */


			chunkSize = MIN( Fls_Global.length, Fls_Global.readChunkSize );

			memcpy( (void *)Fls_Global.ramAddr, (void *) Fls_Global.flashAddr, (size_t)chunkSize );  /*lint !e923 Inteded use  */

			Fls_Global.ramAddr += chunkSize; /*lint !e9016 Intended use */
			Fls_Global.flashAddr += chunkSize;
			Fls_Global.length -= chunkSize;

			Mcu_Arc_GetECCError(&eccError);  /*lint !e934 Only used in this function  */
			if( eccError > 0u ){
				readFail();
			} else {
				if( 0 == Fls_Global.length ) {
					Fls_Global.jobResultType = MEMIF_JOB_OK;
					Fls_Global.status = MEMIF_IDLE;
					Fls_Global.jobType = FLS_JOB_NONE;
					FEE_JOB_END_NOTIFICATION();
					LOG_STR("Fls_RP() OK\n");
				}
			}
			break;

		case FLS_JOB_WRITE:
		{
			/* We are writing in chunks. If we want to write 6 chunks in total but
			 * only 2 at a time:
			 *
			 * Call
			 *  #1   The Fls_Write
			 *  #2   Wait for Flash_CheckStatus(), Flash_ProgramPageStart().. function return
			 *      -> 1 verified write, 1 pending
			 *  #3  Wait for Flash_CheckStatus(), Flash_ProgramPageStart()
			 *      Wait for Flash_CheckStatus(), Flash_ProgramPageStart() .. function return
			 *      -> 3 verified writes, 1 pending
			 *  #4  Wait for Flash_CheckStatus(), Flash_ProgramPageStart()
			 *      Wait for Flash_CheckStatus(), Flash_ProgramPageStart() .. function return
			 *      -> 5 verified writes, 1 pending
			 *  #5  Wait for Flash_CheckStatus(), ...function return
			 *      -> 6 verified writes,
			 */

			uint32 bytesLeftToBeWritten = MIN(Fls_Global.flashWriteInfo.chunkSize, Fls_Global.flashWriteInfo.left);

		    do {
				flashStatus = Flash_CheckStatus(
										Fls_Global.config->FlsInfo,
										(uint32 *) Fls_Global.flashWriteInfo.pDest, /*lint !e923 Intended use */
										Fls_Global.flashWriteInfo.pLeft - Fls_Global.flashWriteInfo.left);

				if (flashStatus == EE_OK) {
				    progressCntr = 0;

					LOG_HEX1("Fls_CS() OK ",Fls_Global.flashWriteInfo.pDest);

					if (Fls_Global.flashWriteInfo.left == 0) {
						/* Done! */
						Fls_Global.jobResultType = MEMIF_JOB_OK;
						Fls_Global.status = MEMIF_IDLE;
						Fls_Global.jobType = FLS_JOB_NONE;
						FEE_JOB_END_NOTIFICATION();
						break;
					}

					/* Write more */
					Fls_Global.flashWriteInfo.pDest = Fls_Global.flashWriteInfo.dest;
					Fls_Global.flashWriteInfo.pLeft = Fls_Global.flashWriteInfo.left;

					/* Double word programming */
					LOG_HEX2("Fls_PP() ",Fls_Global.flashWriteInfo.dest," ", Fls_Global.flashWriteInfo.left);

					flashStatus = Flash_ProgramPageStart(
											Fls_Global.config->FlsInfo,
											&Fls_Global.flashWriteInfo.dest,
											&Fls_Global.flashWriteInfo.source,
											&Fls_Global.flashWriteInfo.left, NULL);
					if (flashStatus != EE_OK) {
						writeFail();
						break;  /*lint !e9011 Better readability this way */
					}
					else {
					    uint32 bytesWritten = Fls_Global.flashWriteInfo.pLeft - Fls_Global.flashWriteInfo.left;
					    bytesLeftToBeWritten = (bytesWritten > bytesLeftToBeWritten) ? 0u : (bytesLeftToBeWritten - bytesWritten);
					}

				} else if (flashStatus == EE_INFO_HVOP_INPROGRESS) {
					/* Wait for it */

				    // One return cycle takes approx ~130 instructions.
				    if (MAX_PROGRESS_CNTR < progressCntr) {
				        progressCntr = 0;
				        writeFail();
				        break; /*lint !e9011 Better readability this way */
				    }

				    progressCntr++;

				} else {
				    progressCntr = 0;
					writeFail();
					/* Nothing to do, quit loop */
					break;  /*lint !e9011 Better readability this way */
				}

			} while (bytesLeftToBeWritten > 0 );

			break;
		}
		case FLS_JOB_NONE:
			assert(FALSE);
			break;

		default:
		    break;
		} /* switch */

	}   /* if */
}
Ejemplo n.º 19
0
void CanIf_RxIndication(uint8 Hrh, Can_IdType CanId, uint8 CanDlc,
              const uint8 *CanSduPtr)
{
  VALIDATE_NO_RV(CanIf_Global.initRun, CANIF_RXINDICATION_ID, CANIF_E_UNINIT);
  VALIDATE_NO_RV(CanSduPtr != NULL, CANIF_RXINDICATION_ID, CANIF_E_PARAM_POINTER);

  /* Check PDU mode before continue processing */
  CanIf_ChannelGetModeType mode;
  CanIf_Arc_ChannelIdType channel = CanIf_Arc_FindHrhChannel( (Can_Arc_HRHType) Hrh);
  if (channel == -1)  // Invalid HRH
  {
    return;
  }

  if (CanIf_GetPduMode(channel, &mode) == E_OK)
  {
    if ( (mode == CANIF_GET_OFFLINE) || (mode == CANIF_GET_TX_ONLINE) ||
        (mode == CANIF_GET_OFFLINE_ACTIVE) )
    {
      // Receiver path is disabled so just drop it
      return;
    }
  }
  else
  {
    return;  // No mode so just return
  }

  const CanIf_RxPduConfigType *entry = CanIf_ConfigPtr->InitConfig->CanIfRxPduConfigPtr;

  /* Find the CAN id in the RxPduList */
  for (uint16 i = 0; i < CanIf_ConfigPtr->InitConfig->CanIfNumberOfCanRxPduIds; i++)
  {
    if (entry->CanIfCanRxPduHrhRef->CanIfHrhIdSymRef == Hrh)
    {
      // Software filtering
      if (entry->CanIfCanRxPduHrhRef->CanIfHrhType == CAN_ARC_HANDLE_TYPE_BASIC)
      {
        if (entry->CanIfCanRxPduHrhRef->CanIfSoftwareFilterHrh)
        {
          if (entry->CanIfSoftwareFilterType == CANIF_SOFTFILTER_TYPE_MASK)
          {
            if ((CanId & entry->CanIfCanRxPduCanIdMask ) ==
                ( entry->CanIfCanRxPduCanId & entry->CanIfCanRxPduCanIdMask))
            {
              // We found a pdu so call higher layers
            }
            else
            {
              entry++;
              continue; // Go to next entry
            }
          }
          else
          {
            DET_REPORTERROR(MODULE_ID_CAN, 0, CANIF_RXINDICATION_ID, CANIF_E_PARAM_HRH);
            continue; // Not a supported filter type, so just drop the frame
          }
        }
      }

#if (CANIF_DLC_CHECK == STD_ON)
      if (CanDlc < entry->CanIfCanRxPduDlc)
      {
        VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_DLC);
        return;
      }
#endif

      switch (entry->CanIfRxUserType)
      {
        case CANIF_USER_TYPE_CAN_SPECIAL:
        {
          ( (CanIf_FuncTypeCanSpecial)(entry->CanIfUserRxIndication) )(
            entry->CanIfCanRxPduHrhRef->CanIfCanControllerHrhIdRef,
            entry->CanIfCanRxPduId,
            CanSduPtr,
            CanDlc,
            CanId);

            return;
        }
        break;

        case CANIF_USER_TYPE_CAN_NM:
#if defined(USE_CANNM)
        	CanNm_RxIndication(entry->CanIfCanRxPduId,CanSduPtr);
        	return;
#endif
        	break;

        case CANIF_USER_TYPE_CAN_PDUR:
            // Send Can frame to PDU router
#if defined(USE_PDUR)
        	{
        		PduInfoType pduInfo;
        		pduInfo.SduLength = CanDlc;
        		pduInfo.SduDataPtr = (uint8 *)CanSduPtr;
            	PduR_CanIfRxIndication(entry->CanIfCanRxPduId,&pduInfo);
        	}
            return;
#endif
            break;

        case CANIF_USER_TYPE_CAN_TP:
          // Send Can frame to CAN TP
#if defined(USE_CANTP)
            {
        	    PduInfoType CanTpRxPdu;
        	    CanTpRxPdu.SduLength = CanDlc;
        	    CanTpRxPdu.SduDataPtr = (uint8 *)CanSduPtr;
                CanTp_RxIndication(entry->CanIfCanRxPduId, &CanTpRxPdu);
            }
            return;
#endif
            break;
        case CANIF_USER_TYPE_J1939TP:
          // Send Can frame to CAN TP
#if defined(USE_J1939TP)
            {
        	    PduInfoType J1939TpRxPdu;
        	    J1939TpRxPdu.SduLength = CanDlc;
        	    J1939TpRxPdu.SduDataPtr = (uint8 *)CanSduPtr;
        	    J1939Tp_RxIndication(entry->CanIfCanRxPduId, &J1939TpRxPdu);
            }
            return;
#endif
            break;            
      }
    }

    entry++;
  }

  // Did not find the PDU, something is wrong
  VALIDATE_NO_RV(FALSE, CANIF_RXINDICATION_ID, CANIF_E_PARAM_LPDU);
}
Ejemplo n.º 20
0
void Fls_MainFunction(void) {
	/** @req FLS255 */
	/** @req FLS266 */
	/** @req FLS038 */
	/** !req FLS040  No support for Fls_ConfigSetType.FlsMaxXXXX */
	/** !req FLS104 */
	/** !req FLS105 */
	/** !req FLS106 */
	/** !req FLS154 */
	/** !req FLS200 */
	/** !req FLS022 */
	/** !req FLS055 */
	/** !req FLS056 */
	/** !req FLS052 */
	/** !req FLS232 */
	/** !req FLS233 */
	/** !req FLS234 */
	/** !req FLS235 */
	/** !req FLS272 */
	/** !req FLS196 */



	uint32 flashStatus;
	int result;
	uint32 eccErrReg = 0;

	uint32 chunkSize;

	/** @req FLS117 */
	VALIDATE_NO_RV(Fls_Global.status != MEMIF_UNINIT,FLS_MAIN_FUNCTION_ID, FLS_E_UNINIT );

	/** @req FLS039 */
	if ( Fls_Global.jobResultType == MEMIF_JOB_PENDING) {
		switch (Fls_Global.jobType) {
		case FLS_JOB_COMPARE:
		    /** @req FLS243 */

			// NOT implemented. Hardware error = FLS_E_COMPARE_FAILED
			// ( we are reading directly from flash so it makes no sense )

			chunkSize = MIN( Fls_Global.length, Fls_Global.readChunkSize );

		    /** @req FLS244 */
			result = memcmp((void *)Fls_Global.ramAddr,
					        (void *)Fls_Global.flashAddr, chunkSize );

			Fls_Global.ramAddr += chunkSize;
			Fls_Global.flashAddr += chunkSize;
			Fls_Global.length -= chunkSize;

			McuE_GetECCError(&eccErrReg);
			if( eccErrReg & FLASH_NON_CORRECTABLE_ERROR ){
				fls_ReadFail();
			} else {
				if( 0 != Fls_Global.length ) {
					if (result == 0) {
						Fls_Global.jobResultType = MEMIF_JOB_OK;
					} else {
						Fls_Global.jobResultType = MEMIF_BLOCK_INCONSISTENT;
					}
					Fls_Global.status = MEMIF_IDLE;
					Fls_Global.jobType = FLS_JOB_NONE;
				} else {
					/* Do nothing, wait for next loop */
				}
			}

			break;
		case FLS_JOB_ERASE: {

			flashStatus = Flash_CheckStatus(Fls_Global.config->FlsInfo, (uint32_t *)Fls_Global.flashAddr, Fls_Global.length );

			if (flashStatus == EE_OK ) {
				Fls_Global.jobResultType = MEMIF_JOB_OK;
				Fls_Global.jobType = FLS_JOB_NONE;
				Fls_Global.status = MEMIF_IDLE;
				FEE_JOB_END_NOTIFICATION();
			} else if (flashStatus == EE_INFO_HVOP_INPROGRESS) {
				/* Busy, Do nothing */
			} else {
				// Error
				fls_EraseFail();
			}
            break;
		}
		case FLS_JOB_READ:
			/** @req FLS238 */
			/** @req FLS239 */

			// NOT implemented. Hardware error = FLS_E_READ_FAILED
			// ( we are reading directly from flash so it makes no sense )
			// Read ECC-error to clear it
			McuE_GetECCError(&eccErrReg);


			chunkSize = MIN( Fls_Global.length, Fls_Global.readChunkSize );

			memcpy( (void *)Fls_Global.ramAddr, (void *) Fls_Global.flashAddr, chunkSize );

			Fls_Global.ramAddr += chunkSize;
			Fls_Global.flashAddr += chunkSize;
			Fls_Global.length -= chunkSize;

			McuE_GetECCError(&eccErrReg);
			if( eccErrReg & FLASH_NON_CORRECTABLE_ERROR ){
				fls_ReadFail();
			} else {
				if( 0 == Fls_Global.length ) {
					Fls_Global.jobResultType = MEMIF_JOB_OK;
					Fls_Global.status = MEMIF_IDLE;
					Fls_Global.jobType = FLS_JOB_NONE;
					FEE_JOB_END_NOTIFICATION();
					LOG_STR("Fls_RP() OK\n");
				}
			}
			break;

		case FLS_JOB_WRITE:
		{
			/* We are writing in chunks. If we want to write 6 chunks in total but
			 * only 2 at a time:
			 *
			 * Call
			 *  #1   The Fls_Write
			 *  #2   Wait for Flash_CheckStatus(), Flash_ProgramPageStart().. function return
			 *      -> 1 verified write, 1 pending
			 *  #3  Wait for Flash_CheckStatus(), Flash_ProgramPageStart()
			 *      Wait for Flash_CheckStatus(), Flash_ProgramPageStart() .. function return
			 *      -> 3 verified writes, 1 pending
			 *  #4  Wait for Flash_CheckStatus(), Flash_ProgramPageStart()
			 *      Wait for Flash_CheckStatus(), Flash_ProgramPageStart() .. function return
			 *      -> 5 verified writes, 1 pending
			 *  #5  Wait for Flash_CheckStatus(), ...function return
			 *      -> 6 verified writes,
			 */



			int32_t chunkSize = MIN(Fls_Global.flashWriteInfo.chunkSize, Fls_Global.flashWriteInfo.left);

		    do {
				flashStatus = Flash_CheckStatus(
										Fls_Global.config->FlsInfo,
										(uint32_t *) Fls_Global.flashWriteInfo.pDest,
										Fls_Global.flashWriteInfo.pLeft - Fls_Global.flashWriteInfo.left);



				if (flashStatus == EE_OK) {

					LOG_HEX1("Fls_CS() OK ",Fls_Global.flashWriteInfo.pDest);

					if (Fls_Global.flashWriteInfo.left == 0) {
						/* Done! */
						Fls_Global.jobResultType = MEMIF_JOB_OK;
						Fls_Global.status = MEMIF_IDLE;
						Fls_Global.jobType = FLS_JOB_NONE;
						FEE_JOB_END_NOTIFICATION();
						break;
					}

					/* Write more */
					Fls_Global.flashWriteInfo.pDest = Fls_Global.flashWriteInfo.dest;
					Fls_Global.flashWriteInfo.pLeft = Fls_Global.flashWriteInfo.left;

					/* Double word programming */
					LOG_HEX2("Fls_PP() ",Fls_Global.flashWriteInfo.dest," ", Fls_Global.flashWriteInfo.left);

					flashStatus = Flash_ProgramPageStart(
											Fls_Global.config->FlsInfo,
											&Fls_Global.flashWriteInfo.dest,
											&Fls_Global.flashWriteInfo.source,
											&Fls_Global.flashWriteInfo.left, NULL);
					if (flashStatus != EE_OK) {
						fls_WriteFail();
						break;
					}

					chunkSize = chunkSize - (int32_t)(Fls_Global.flashWriteInfo.pLeft - Fls_Global.flashWriteInfo.left);

				} else if (flashStatus == EE_INFO_HVOP_INPROGRESS) {
					/* Wait for it */
				} else {
					fls_WriteFail();
					/* Nothing to do, quit loop */
					break;
				}

			} while (chunkSize > 0 );

			break;
		}
		case FLS_JOB_NONE:
			assert(0);
			break;

		default:
		    break;
		} /* switch */

	}   /* if */
}