コード例 #1
0
ファイル: Can_Hw.c プロジェクト: SushMJ/gainos-tk
/**
 * ISR for CAN. Normal Tx operation
 *
 * @param unit CAN controller number( from 0 )
 */
static void Can_TxIsr(int unit) {
  CAN_HW_t *canHw= GetController(unit);
  const Can_ControllerConfigType *canHwConfig= CAN_GET_CONTROLLER_CONFIG(Can_Global.channelMap[unit]);
  Can_UnitType *canUnit = CAN_GET_PRIVATE_DATA(unit);
  const Can_HardwareObjectType *hohObj;

  // Loop over all the Hoh's
  hohObj= canHwConfig->Can_Hoh;
  --hohObj;
  do {
	++hohObj;

	if (hohObj->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT)
	{
		CanIf_TxConfirmation(canUnit->swPduHandle);

		canUnit->swPduHandle = 0;  // Is this really necessary ??

		// Clear Tx interrupt
        CAN_ClearITPendingBit(canHw,CAN_IT_RQCP0);
        CAN_ClearITPendingBit(canHw,CAN_IT_RQCP1);
        CAN_ClearITPendingBit(canHw,CAN_IT_RQCP2);
	}
  } while ( !hohObj->Can_EOL);
}
コード例 #2
0
ファイル: Can_Hw.c プロジェクト: SushMJ/gainos-tk
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);
}
コード例 #3
0
ファイル: Can_Hw.c プロジェクト: SushMJ/gainos-tk
/**
 * Hardware error ISR for CAN
 *
 * @param unit CAN controller number( from 0 )
 */
static void Can_ErrIsr( int unit ) {
  CAN_HW_t *canHw = GetController(unit);
  Can_UnitType *canUnit = CAN_GET_PRIVATE_DATA(unit);
  Can_Arc_ErrorType err;
  err.R = 0;

  // Check wake up
  if(SET == CAN_GetITStatus(canHw, CAN_IT_WKU)){
	  Can_WakeIsr(unit);
	  CAN_ClearITPendingBit(canHw, CAN_IT_WKU);
  }

  if(SET == CAN_GetITStatus(canHw, CAN_IT_BOF)){
	canUnit->stats.boffCnt++;
	CanIf_ControllerBusOff(unit);
	Can_SetControllerMode(unit, CAN_T_STOP); // CANIF272

	Can_AbortTx( canHw, canUnit ); // CANIF273

	// Clear int
	CAN_ClearITPendingBit(canHw, CAN_IT_BOF);
  }

  if (err.R != 0)
  {
	  CanIf_Arc_Error( unit, err );
  }
}
コード例 #4
0
ファイル: Can.c プロジェクト: paduc77/gainos
EXPORT void Can_InitController(uint8 Controller,const Can_ControllerConfigType* Config)
{
	Can_UnitType *canUnit;
	StatusType ercd;
	canUnit = CAN_GET_PRIVATE_DATA(Controller);
#if(CAN_DEV_ERROR_DETECT == STD_ON)
	if(CAN_UNINIT == Can_Global.driverState)
	{
		Det_ReportError(MODULE_ID_CAN,0,CAN_INITCONTROLLER_SERVICE_ID,CAN_E_UNINIT);
		return;
	}
	if(NULL == Config)
	{
		Det_ReportError(MODULE_ID_CAN,0,CAN_INITCONTROLLER_SERVICE_ID,CAN_E_PARAM_POINTER);
		return;
	}
	if(Controller >= CAN_CONTROLLER_CNT)
	{
		Det_ReportError(MODULE_ID_CAN,0,CAN_INITCONTROLLER_SERVICE_ID,CAN_E_PARAM_CONTROLLER);
		return;
	}
	if(canUnit->state!=CANIF_CS_STOPPED)
	{
		Det_ReportError(MODULE_ID_CAN,0,CAN_INITCONTROLLER_SERVICE_ID,CAN_E_TRANSITION);
		return;
	}
#endif
	ercd = Can_Hw_InitController(Controller,Config);
	if(ercd != E_OK)
	{
		return;
	}
	canUnit->state = CANIF_CS_STOPPED;
	Can_EnableControllerInterrupts(Controller);
}
コード例 #5
0
ファイル: Can.c プロジェクト: paduc77/gainos
// Unitialize the module
EXPORT void Can_DeInit()
{
  Can_UnitType *canUnit;
  int configId;
  const Can_ControllerConfigType *canHwConfig;
  uint32 ctlrId;

  for (configId=0; configId < CAN_CTRL_CONFIG_CNT; configId++) {
    canHwConfig = CAN_GET_CONTROLLER_CONFIG(configId);
    ctlrId = canHwConfig->CanControllerId;

    canUnit = CAN_GET_PRIVATE_DATA(ctlrId);
    canUnit->state = CANIF_CS_UNINIT;

    Can_DisableControllerInterrupts(ctlrId);

    canUnit->lock_cnt = 0;

    // Clear stats
    memset(&canUnit->stats, 0, sizeof(Can_StatisticsType));
  }

  Can_Global.config = NULL;
  Can_Global.driverState = CAN_UNINIT;

  return;
}
コード例 #6
0
ファイル: Can.c プロジェクト: paduc77/gainos
/* ####################### FUNCTIONs ########################### */
EXPORT void Can_Init(const Can_ConfigType* Config)
{
	  Can_UnitType *canUnit;
	  const Can_ControllerConfigType *canHwConfig;
	  const Can_HardwareObjectType* hoh;
	  uint8 ctlrId;
	  int configId;
#if(CAN_DEV_ERROR_DETECT == STD_ON)
	if(CAN_UNINIT != Can_Global.driverState)
	{
		Det_ReportError(MODULE_ID_CAN,0,CAN_INIT_SERVICE_ID,CAN_E_TRANSITION);
		return;
	}
	if(NULL == Config)
	{
		Det_ReportError(MODULE_ID_CAN,0,CAN_INIT_SERVICE_ID,CAN_E_PARAM_POINTER);
		return;
	}
#endif
	/* save config */
	Can_Global.config = Config;
	Can_Global.driverState = CAN_READY;

	Can_Hw_Init(Config);

	for (configId=0; configId < CAN_CTRL_CONFIG_CNT; configId++)
	{
		canHwConfig = CAN_GET_CONTROLLER_CONFIG(configId);
		ctlrId = canHwConfig->CanControllerId;

		// Assign the configuration channel used later..
		Can_Global.channelMap[ctlrId] = configId;
		Can_Global.configured |= (1<<ctlrId);

		canUnit = CAN_GET_PRIVATE_DATA(ctlrId);
		canUnit->state = CANIF_CS_STOPPED;

		canUnit->lock_cnt = 0;

		// Clear stats
		memset(&canUnit->stats, 0, sizeof(Can_StatisticsType));
		//This can be done by CanIf
	    //Can_InitController(ctlrId, canHwConfig);

	    // Loop through all Hohs and map them into the HTHMap
	    hoh = canHwConfig->Can_Hoh;
	    hoh--;
		do
		{
		    hoh++;
			if (hoh->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT)
			{
				Can_Global.CanHTHMap[hoh->CanObjectId].CanControllerRef = canHwConfig->CanControllerId;
				Can_Global.CanHTHMap[hoh->CanObjectId].CanHOHRef = hoh;
			}
		} while (!hoh->Can_EOL);
	}
}
コード例 #7
0
ファイル: Can_Hw.c プロジェクト: SushMJ/gainos-tk
EXPORT Can_ReturnType Can_Hw_Write( Can_HwHandleType/* Can_HTHType */ hth, const Can_PduType *pduInfo ) {
	  Can_ReturnType rv = CAN_OK;
	  CAN_HW_t *canHw;
	  const Can_HardwareObjectType *hohObj;
	  const Can_ControllerConfigType *canHwConfig;
	  uint32 controller;
	  imask_t state;

	  hohObj = Can_FindHoh(hth, &controller);
	  if (hohObj == NULL)
	    return CAN_NOT_OK;

	  Can_UnitType *canUnit = CAN_GET_PRIVATE_DATA(controller);

	  canHw = GetController(controller);
	  Irq_Save(state);

	  CanTxMsg TxMessage;

	  TxMessage.RTR=CAN_RTR_DATA;
	  TxMessage.DLC=pduInfo->length;

	  memcpy(TxMessage.Data, pduInfo->sdu, pduInfo->length);

	  if (hohObj->CanIdType == CAN_ID_TYPE_EXTENDED) {
		TxMessage.IDE=CAN_ID_EXT;
		TxMessage.ExtId=pduInfo->id;
	  } else {
		TxMessage.IDE=CAN_ID_STD;
		TxMessage.StdId=pduInfo->id;
	  }

	  // check for any free box
	  if(CAN_Transmit(canHw,&TxMessage) != CAN_NO_MB) {
	    canHwConfig = CAN_GET_CONTROLLER_CONFIG(Can_Global.channelMap[controller]);

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

		// Increment statistics
		canUnit->stats.txSuccessCnt++;

	    // Store pdu handle in unit to be used by TxConfirmation
	    canUnit->swPduHandle = pduInfo->swPduHandle;
	  } else {
	    rv = CAN_BUSY;
	  }
	  Irq_Restore(state);

	  return rv;
}
コード例 #8
0
ファイル: Can_Hw.c プロジェクト: SushMJ/gainos-tk
/**
 * ISR for CAN. Normal Rx/operation
 *
 * @param unit CAN controller number( from 0 )
 */
static void Can_RxIsr(int unit) {

  CAN_HW_t *canHw= GetController(unit);
  const Can_ControllerConfigType *canHwConfig= CAN_GET_CONTROLLER_CONFIG(Can_Global.channelMap[unit]);
  Can_UnitType *canUnit = CAN_GET_PRIVATE_DATA(unit);
  const Can_HardwareObjectType *hohObj;

  CanRxMsg RxMessage;

  RxMessage.StdId=0x00;
  RxMessage.ExtId=0x00;
  RxMessage.IDE=0;
  RxMessage.DLC=0;
  RxMessage.FMI=0;
  RxMessage.Data[0]=0x00;
  RxMessage.Data[1]=0x00;
  CAN_Receive(canHw,CAN_FIFO0, &RxMessage);

  // Loop over all the Hoh's
  hohObj= canHwConfig->Can_Hoh;
  --hohObj;
  do {
	++hohObj;

	if (hohObj->CanObjectType == CAN_OBJECT_TYPE_RECEIVE)
	{
	    Can_IdType id=0;

	    // According to autosar MSB shuould be set if extended
		if (RxMessage.IDE != CAN_ID_STD) {
		  id = RxMessage.ExtId;
		  id |= 0x80000000;
		} else {
		  id = RxMessage.StdId;
		}

		CanIf_RxIndication(hohObj->CanObjectId,
									id,
									RxMessage.DLC,
									(uint8 *)&RxMessage.Data[0] ); // Next layer will copy

		// Increment statistics
		canUnit->stats.rxSuccessCnt++;
	}
  } while ( !hohObj->Can_EOL);
}
コード例 #9
0
ファイル: Can_Hw.c プロジェクト: SushMJ/gainos-tk
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;
}
コード例 #10
0
ファイル: Can_Hw.c プロジェクト: SushMJ/gainos-tk
EXPORT Can_ReturnType Can_Hw_SetControllerMode(uint8 controller,Can_StateTransitionType transition)
{
	  imask_t state;
	  CAN_HW_t *canHw;
	  Can_ReturnType rv = CAN_OK;

	  Can_UnitType *canUnit = CAN_GET_PRIVATE_DATA(controller);

	  VALIDATE( (canUnit->state!=CANIF_CS_UNINIT), 0x3, CAN_E_UNINIT );
	  canHw = GetController(controller);

	  switch(transition )
	  {
	  case CAN_T_START:
	    canUnit->state = CANIF_CS_STARTED;
	    Irq_Save(state);
	    if (canUnit->lock_cnt == 0){   // REQ CAN196
	      Can_EnableControllerInterrupts(controller);
	    }
	    Irq_Restore(state);
	    break;
	  case CAN_T_WAKEUP:
		VALIDATE(canUnit->state == CANIF_CS_SLEEP, 0x3, CAN_E_TRANSITION);
		CAN_WakeUp(canHw);
		canUnit->state = CANIF_CS_STOPPED;
		break;
	  case CAN_T_SLEEP:  //CAN258, CAN290
	    // Should be reported to DEM but DET is the next best
	    VALIDATE(canUnit->state == CANIF_CS_STOPPED, 0x3, CAN_E_TRANSITION);
	    CAN_Sleep(canHw);
	    canUnit->state = CANIF_CS_SLEEP;
		break;
	  case CAN_T_STOP:
	    // Stop
	    canUnit->state = CANIF_CS_STOPPED;
	    Can_AbortTx( canHw, canUnit ); // CANIF282
	    break;
	  default:
	    // Should be reported to DEM but DET is the next best
	    VALIDATE(canUnit->state == CANIF_CS_STOPPED, 0x3, CAN_E_TRANSITION);
	    break;
	  }

	  return rv;
}
コード例 #11
0
ファイル: Can_Hw.c プロジェクト: SushMJ/gainos-tk
EXPORT Std_ReturnType Can_Hw_InitController(uint8 controller,const Can_ControllerConfigType* config)
{
	  CAN_HW_t *canHw;
	  uint8_t tq;
	  uint8_t tqSync;
	  uint8_t tq1;
	  uint8_t tq2;
	  uint32_t clock;
	  Can_UnitType *canUnit;
	  uint8 cId = controller;
	  const Can_ControllerConfigType *canHwConfig;
	  const Can_HardwareObjectType *hohObj;


	  canUnit = CAN_GET_PRIVATE_DATA(controller);

	  canHw = GetController(cId);
	  canHwConfig = CAN_GET_CONTROLLER_CONFIG(Can_Global.channelMap[cId]);

	  // Start this baby up
	  CAN_DeInit(canHw);

	  /* CAN filter init. We set up two filters - one for the master (CAN1) and
	   * one for the slave (CAN2)
	   *
	   * CAN_SlaveStartBank(n) denotes which filter is the first of the slave.
	   *
	   * The filter registers reside in CAN1 and is shared to CAN2, so we only need
	   * to set up this once.
	   */

	  // We let all frames in and do the filtering in software.
	  CAN_FilterInitTypeDef  CAN_FilterInitStructure;
	  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
	  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
	  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
	  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
	  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
	  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
	  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
	  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;

	  // Init filter 0 (CAN1/master)
	  CAN_FilterInitStructure.CAN_FilterNumber=0;
	  CAN_FilterInit(&CAN_FilterInitStructure);

	  // Init filter 1 (CAN2/slave)
	  CAN_FilterInitStructure.CAN_FilterNumber=1;
	  CAN_FilterInit(&CAN_FilterInitStructure);

	  // Set which filter to use for CAN2.
	  CAN_SlaveStartBank(1);

	  // acceptance filters
	   hohObj = canHwConfig->Can_Hoh;
	   --hohObj;
	   do {
		 ++hohObj;
	     if (hohObj->CanObjectType == CAN_OBJECT_TYPE_RECEIVE)
	     {
	    	 // TODO Hw filtering
	     }
	   }while( !hohObj->Can_EOL );

	  // Clock calucation
	  // -------------------------------------------------------------------
	  //
	  // * 1 TQ = Sclk period( also called SCK )
	  // * Ftq = Fcanclk / ( PRESDIV + 1 ) = Sclk
	  //   ( Fcanclk can come from crystal or from the peripheral dividers )
	  //
	  // -->
	  // TQ = 1/Ftq = (PRESDIV+1)/Fcanclk --> PRESDIV = (TQ * Fcanclk - 1 )
	  // TQ is between 8 and 25
	  clock = McuE_GetSystemClock()/2;

	  tqSync = config->CanControllerPropSeg + 1;
	  tq1 = config->CanControllerSeg1 + 1;
	  tq2 = config->CanControllerSeg2 + 1;
	  tq = tqSync + tq1 + tq2;

	  CAN_InitTypeDef        CAN_InitStructure;
	  CAN_StructInit(&CAN_InitStructure);

	  /* CAN cell init */
	  CAN_InitStructure.CAN_TTCM=DISABLE;
	  CAN_InitStructure.CAN_ABOM=ENABLE;
	  CAN_InitStructure.CAN_AWUM=ENABLE;
	  CAN_InitStructure.CAN_NART=DISABLE;
	  CAN_InitStructure.CAN_RFLM=DISABLE;
	  CAN_InitStructure.CAN_TXFP=DISABLE;
	  if(config->Can_Loopback){
		  CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
	  }else{
		  CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
	  }

	  CAN_InitStructure.CAN_SJW=config->CanControllerPropSeg;
	  CAN_InitStructure.CAN_BS1=config->CanControllerSeg1;
	  CAN_InitStructure.CAN_BS2=config->CanControllerSeg2;
	  CAN_InitStructure.CAN_Prescaler= clock/(config->CanControllerBaudRate*1000*tq);

	  if(CANINITOK != CAN_Init(canHw,&CAN_InitStructure))
	  {
		return E_NOT_OK;
	  }

	  canUnit->state = CANIF_CS_STOPPED;
	  Can_EnableControllerInterrupts(cId);

	  return E_OK;
}