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); }
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; }
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; }