📄 drvcan.c
字号:
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* Copyright(c) 2009 Nuvoton Technology Corp. All rights reserved. */
/* */
/*---------------------------------------------------------------------------------------------------------*/
#include <stdio.h>
/*---------------------------------------------------------------------------------------------------------*/
/* Includes of headers */
/*---------------------------------------------------------------------------------------------------------*/
#include "DrvCAN.h"
#include "DrvSYS.h"
#include "NUC1xx.h"
/* Private function prototypes -----------------------------------------------*/
static uint32_t GetFreeIF(void);
/* Private functions ---------------------------------------------------------*/
static STR_CAN_CALLBACK_T CANHandler = {0};
//#define DEBUG_PRINTF printf
#define DEBUG_PRINTF(...)
/*---------------------------------------------------------------------------------------------------------*/
/* CAN0 ISR */
/*---------------------------------------------------------------------------------------------------------*/
void CAN0_IRQHandler(void)
{
uint8_t u8IIDRstatus;
if(CAN->u32IIDR == 0x8000) /* Check Status Interrupt Flag (Error status Int and Status change Int) */
{
/**************************/
/* Status Change interrupt*/
/**************************/
if(CAN->STATUS.RXOK == 1)
{
CAN->STATUS.RXOK = 0; /* Clear Rx Ok status*/
DEBUG_PRINTF("RX OK INT\n") ;
if (CANHandler.RxOkCallBackFn)
{
CANHandler.RxOkCallBackFn(0);
}
}
if(CAN->STATUS.TXOK == 1)
{
CAN->STATUS.TXOK = 0; /* Clear Tx Ok status*/
DEBUG_PRINTF("TX OK INT\n") ;
if (CANHandler.TxOkCallBackFn)
{
CANHandler.TxOkCallBackFn(0);
}
}
/**************************/
/* Error Status interrupt */
/**************************/
if(CAN->STATUS.EWARN==1)
{
DEBUG_PRINTF("EWARN INT\n") ;
if (CANHandler.ErrorWarningCallBackFn)
{
CANHandler.ErrorWarningCallBackFn(0);
}
}
if(CAN->STATUS.BOFF==1)
{
DEBUG_PRINTF("BOFF INT\n") ;
if (CANHandler.BusOffCallBackFn)
{
CANHandler.BusOffCallBackFn(0);
}
}
}
else if ((CAN->u32IIDR)!=0)
{
DEBUG_PRINTF("=> Interrupt Pointer = %d\n",CAN->u32IIDR -1);
u8IIDRstatus = CAN->u32IIDR;
if (CANHandler.MessageCallBackFn)
{
CANHandler.MessageCallBackFn(u8IIDRstatus);
}
DrvCAN_ClrIntPnd((CAN->u32IIDR) -1 ); /* Clear Interrupt Pending */
}
else if(CAN->u32WU_STATUS==1)
{
DEBUG_PRINTF("Wake up\n");
CAN->u32WU_STATUS = 0; /* Write '0' to clear */
if (CANHandler.WakeupCallBackFn)
{
CANHandler.WakeupCallBackFn(0);
}
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: GetFreeIF */
/* */
/* Parameter: */
/* None */
/* Returns: */
/* 0: IF0 is free 1: IF1 is free 2: No IF is free */
/* Description: */
/* Searchs the first free message interface, starting from 0. */
/*---------------------------------------------------------------------------------------------------------*/
static uint32_t GetFreeIF(void)
{
if (CAN->sMsgObj[0].CREQ.BUSY == 0)
return 0;
else if (CAN->sMsgObj[1].CREQ.BUSY == 0)
return 1;
else
return 2;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvCAN_GetCANBitRate */
/* */
/* Parameter: */
/* None */
/* Returns: */
/* Current Bit-Rate (kilo bit per second) */
/* Description: */
/* Return current CAN bitrate according to the user bit-timing parameter settings */
/*---------------------------------------------------------------------------------------------------------*/
int32_t DrvCAN_GetCANBitRate(void)
{
uint8_t u8Tseg1,u8Tseg2;
uint32_t u32Bpr;
u8Tseg1 = CAN->BTIME.TSEG1;
u8Tseg2 = CAN->BTIME.TSEG2;
u32Bpr = (CAN->BTIME.BRP) | (CAN->BRPE.BPRE <<6);
return (DrvSYS_GetHCLKFreq()/(u32Bpr+1)/(u8Tseg1 + u8Tseg2 + 3))/1000;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvCAN_Init */
/* */
/* Parameter: */
/* None */
/* Returns: */
/* None */
/* Description: */
/* The function is used to reset and Initializes CAN IP */
/*---------------------------------------------------------------------------------------------------------*/
void DrvCAN_Init(void)
{
/* Enable CAN0 Clock and Reset it */
SYSCLK->APBCLK.CAN0_EN =1;
SYS->IPRSTC2.CAN0_RST =1;
SYS->IPRSTC2.CAN0_RST =0;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvCAN_Close */
/* */
/* Parameter: */
/* None */
/* Returns: */
/* None */
/* Description: */
/* Reset and clear all CAN control and disable CAN IP */
/*---------------------------------------------------------------------------------------------------------*/
void DrvCAN_Close(void)
{
/* Clear Install callback function pointer */
CANHandler.MessageCallBackFn = NULL;
CANHandler.RxOkCallBackFn = NULL;
CANHandler.TxOkCallBackFn = NULL;
CANHandler.ErrorWarningCallBackFn = NULL;
CANHandler.BusOffCallBackFn = NULL;
CANHandler.WakeupCallBackFn = NULL;
/* Disable CAN0 Clock and Reset it */
SYS->IPRSTC2.CAN0_RST =1;
SYS->IPRSTC2.CAN0_RST =0;
SYSCLK->APBCLK.CAN0_EN =0;
}
/*---------------------------------------------------------------------------------------------------------*/
/* Function: DrvCAN_Open */
/* */
/* Parameter: */
/* u32kbps: The target CAN kilo bit rate per second. */
/* The range of u32kbps is 1~1000KHz */
/* Returns: */
/* E_DRVCAN_ERR_BITRATE : Set target bit-rate fail */
/* E_SUCCESS : Set target bit-rate successful */
/* Description: */
/* The function is used to set bus timing parameter according current clock and */
/* target bit-rate. */
/*---------------------------------------------------------------------------------------------------------*/
int32_t DrvCAN_Open(uint32_t u32kbps)
{
uint8_t u8Tseg1,u8Tseg2;
uint32_t u32Bpr;
uint32_t u32value;
DrvCAN_EnterInitMode();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -