Esempio n. 1
0
/**
 * 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);
}
/**
 * Function that finds the Hoh( HardwareObjectHandle ) from a Hth
 * A HTH may connect to one or several HOH's. Just find the first one.
 *
 * @param hth The transmit handle
 * @returns Ptr to the Hoh
 */
LOCAL const Can_HardwareObjectType * Can_FindHoh( Can_Arc_HTHType hth , uint32* controller)
{
    const Can_HardwareObjectType *hohObj;
    const Can_ObjectHOHMapType *map;
    const Can_ControllerConfigType *canHwConfig;

    map = &Can_Global.CanHTHMap[hth];
#if(CAN_DEV_ERROR_DETECT == STD_ON)
    // Verify that this is the correct map
    if (map->CanHOHRef->CanObjectId != hth)
    {
        Det_ReportError(MODULE_ID_CAN, 0, CAN_WRITE_SERVICE_ID, CAN_E_PARAM_HANDLE);
    }
#endif
    canHwConfig= CAN_GET_CONTROLLER_CONFIG(Can_Global.channelMap[map->CanControllerRef]);

    hohObj = map->CanHOHRef;

    // Verify that this is the correct Hoh type
    if ( hohObj->CanObjectType == CAN_OBJECT_TYPE_TRANSMIT)
    {
        *controller = map->CanControllerRef;
        return hohObj;
    }
#if(CAN_DEV_ERROR_DETECT == STD_ON)
    Det_ReportError(MODULE_ID_CAN, 0, CAN_WRITE_SERVICE_ID, CAN_E_PARAM_HANDLE);
#endif
    return NULL;
}
Esempio n. 3
0
File: Can.c Progetto: 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;
}
Esempio n. 4
0
File: Can.c Progetto: 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);
	}
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
/**
 * 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);
}
Esempio n. 7
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
EXPORT void Can_Hw_Init(const Can_ConfigType* Config)
{
	int configId;
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef  GPIO_InitStructure;
	const Can_ControllerConfigType *canHwConfig;
    
    /* All CAN ISR use the same priority */
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    
	for (configId=0; configId < CAN_CTRL_CONFIG_CNT; configId++)
	{
		canHwConfig = CAN_GET_CONTROLLER_CONFIG(configId);
		// Note!
		// Could install handlers depending on HW objects to trap more errors
		// in configuration
		switch( canHwConfig->CanControllerId ) {
		#ifndef STM32F10X_CL
		case CAN_CTRL_1:
        {
			INSTALL_HANDLERS(Can_1, CAN1_SCE_IRQn, USB_LP_CAN1_RX0_IRQn, USB_HP_CAN1_TX_IRQn);
            
            /* GPIO clock enable */
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOD, ENABLE);
            /* CAN1 Periph clock enable */
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
            
            /* Configure CAN pin: RX */
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//GPIO_Pin_CAN_RX;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
            GPIO_Init(GPIOD, &GPIO_InitStructure);
  
            /* Configure CAN pin: TX */
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//GPIO_Pin_CAN_TX;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(GPIOD, &GPIO_InitStructure);
            /* USE PD0 -->Rx  PD1 -->Tx*/
            GPIO_PinRemapConfig(GPIO_Remap2_CAN1 , ENABLE);
            
            /* Enable CAN1 SCE interrupt IRQ */
            NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
            NVIC_Init(&NVIC_InitStructure);            
            /* Enable CAN1 RX0 interrupt IRQ channel */
            NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
            NVIC_Init(&NVIC_InitStructure);
            /* Enable CAN1 TX interrupt IRQ channel */
            NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_TX0_IRQn;
            NVIC_Init(&NVIC_InitStructure);            
            break;
        }
		#else
		case CAN_CTRL_1:
        {
			INSTALL_HANDLERS(Can_1, CAN1_SCE_IRQn, CAN1_RX0_IRQn, CAN1_TX_IRQn);
            
            /* GPIO clock enable */
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOD, ENABLE);
            /* CAN1 Periph clock enable */
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);            

            /* Configure CAN pin: RX */
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//GPIO_Pin_CAN_RX;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
            GPIO_Init(GPIOD, &GPIO_InitStructure);
  
            /* Configure CAN pin: TX */
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;//GPIO_Pin_CAN_TX;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(GPIOD, &GPIO_InitStructure);
            /* USE PD0 -->Rx  PD1 -->Tx*/
            GPIO_PinRemapConfig(GPIO_Remap2_CAN1 , ENABLE);
            
            /* Enable CAN1 SCE interrupt IRQ */
            NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
            NVIC_Init(&NVIC_InitStructure);            
            /* Enable CAN1 RX0 interrupt IRQ channel */
            NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
            NVIC_Init(&NVIC_InitStructure);
            /* Enable CAN1 TX interrupt IRQ channel */
            NVIC_InitStructure.NVIC_IRQChannel = CAN1_TX_IRQn;
            NVIC_Init(&NVIC_InitStructure);                     
            break;
        }
		case CAN_CTRL_2:
        {
			INSTALL_HANDLERS(Can_2, CAN2_SCE_IRQn, CAN2_RX0_IRQn, CAN2_TX_IRQn);
            
            /* GPIO clock enable */
            RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOB, ENABLE);
            /* CAN2 Periph clock enable */
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);            
            
            /* Configure CAN pin: RX */
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//GPIO_Pin_CAN_RX;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
            GPIO_Init(GPIOB, &GPIO_InitStructure);
  
            /* Configure CAN pin: TX */
            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//GPIO_Pin_CAN_TX;
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(GPIOB, &GPIO_InitStructure);
            /* USE PB5 -->Rx  PB6 -->Tx*/
            GPIO_PinRemapConfig(GPIO_Remap_CAN2 , ENABLE);
            
            /* Enable CAN2 SCE interrupt IRQ */
            NVIC_InitStructure.NVIC_IRQChannel = CAN2_SCE_IRQn;
            NVIC_Init(&NVIC_InitStructure);
            /* Enable CAN2 RX0 interrupt IRQ channel */
            NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
            NVIC_Init(&NVIC_InitStructure);
            /* Enable CAN2 TX interrupt IRQ channel */
            NVIC_InitStructure.NVIC_IRQChannel = CAN2_TX_IRQn;
            NVIC_Init(&NVIC_InitStructure);                 
            break;
        }
		#endif
			default:
				AR_ASSERT(0);
		}
	}
	return;
}