📄 can.c
字号:
/* Includes ------------------------------------------------------------------*/
#include "public.h"
/* Private variables ---------------------------------------------------------*/
volatile unsigned char Can_Page;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : CAN_Init
* Description : This routine configures the CAN cell and active it.
* Input : CAN_MasterCtrlReg (options of the CAN controller)
- CMCR_ABOM: Automatic bus-off management -> left
automatically by HW once 128 x 11 recessive bits,
- CMCR_AWUM: Automatic Wake-up mode,
- CMCR_NART: No Automatic Retransmission,
- CMCR_RFLM: Discard last message when FIFO full,
- CMCR_TXFP: Transmit order by FIFO -> Priority by the
request order or identifier of the message.
* Output : .
* Return : .
*******************************************************************************/
void CAN_Init(unsigned char CAN_MasterCtrlReg)
{
/* Abort the pending transmit requests */
CAN_FPSR = CAN_TXMB0_PG;
CAN_MCSR |= MCSR_ABRQ;
CAN_FPSR = CAN_TXMB1_PG;
CAN_MCSR |= MCSR_ABRQ;
CAN_FPSR = CAN_TXMB2_PG;
CAN_MCSR |= MCSR_ABRQ;
CAN_MCR |= CMCR_INRQ; /* Request initialisation */
while ( !(CAN_MSR & CMSR_INAK) ); /* Wait until acknowledged */
/*
Clear Transmit mailbox empty interrupts (RQCP 0 & 1 & 2) and therefore
clear TXOK 0 & 1 & 2 bits
*/
CAN_TSR |= CTSR_RQCP0 | CTSR_RQCP1 | CTSR_RQCP2;
/* Release the Receive FIFO -> clear FMP bits and FULL bit */
while(CAN_RFR & CRFR_FMP01)
{
CAN_RFR = CRFR_RFOM;
}
/* Clear the FIFO Overrun (FOVR) bit */
CAN_RFR |= CRFR_FOVR;
/* Clear Wake-up pending interrupt */
CAN_MSR = CMSR_WKUI;
/* ABOM - /NART - TXFP */
CAN_MCR |= CAN_MasterCtrlReg;
/* Filter initialization */
/* Deactivate all filters */
CAN_FPSR = CAN_CTRL_PG ;
CAN_FCR1 = 0x00;
CAN_FCR2 = 0x00;
CAN_FCR3 = 0x00;
/* Filter 0, 1, 2, 3 in Identifier/Mask mode */
CAN_FMR1 = 0x00;
/* Filter 4, 5 in Identifier/Mask mode */
CAN_FMR2 = 0x00;
/* Select filter 0:1 Page */
CAN_FPSR = CAN_FILTER01_PG;
/* All ID values are accepted */
CAN_FxR0 = 0x00;
CAN_FxR1 = 0x00;
CAN_FxR2 = 0x00;
CAN_FxR3 = 0x00;
CAN_FxR4 = 0x00;
CAN_FxR5 = 0x00;
CAN_FxR6 = 0x00;
CAN_FxR7 = 0x00;
CAN_FPSR = CAN_CTRL_PG ;
/* Filter 0 active in 1 x 32-bit registers */
CAN_FCR1 = 0x07;
/* Configure bit timing */
CAN_FPSR = CAN_CTRL_PG;
CAN_BTR1 = CAN_CBTR0_REGISTER; // see can.h for modification of
CAN_BTR2 = CAN_CBTR1_REGISTER; // bit timing parameters.
CAN_DGR |= CDGR_3TX; /* 3 Tx mailboxes */
CAN_MCR &= ~CMCR_INRQ; /* Leave the Init mode */
while ( (CAN_MSR & CMSR_INAK) ); /* Wait until acknowledged */
}
/*******************************************************************************
* Function Name : CAN_Sleep
* Description : This routine puts the CAN to bed.
* Input : .
* Output : .
* Return : .
*******************************************************************************/
void CAN_Sleep(void)
{
CAN_MCR |= CMCR_SLEEP; /* Set Sleep mode */
while( !(CAN_MSR & CMSR_SLAK) ); /* Wait for Sleep acknowledge */
}
/*******************************************************************************
* Function Name : CAN_WakeUp
* Description : This routine wakes the CAN up.
* Input : .
* Output : .
* Return : .
*******************************************************************************/
void CAN_WakeUp(void)
{
CAN_MCR &= ~CMCR_SLEEP; /* Leave Sleep mode */
while(CAN_MSR & CMSR_SLAK); /* Wait until slak bit cleared */
}
/*******************************************************************************
* Function Name : CAN_DiagMode
* Description : This routine sets the CAN in Loop-back and/or silent modes.
* Input : CAN_Mode (CDGR_LBKM, CDGR_SILM)
* Output : .
* Return : .
*******************************************************************************/
void CAN_EnableDiagMode(unsigned char CAN_Mode)
{
CAN_MCR |= CMCR_INRQ; /* Request initialisation */
while ( !(CAN_MSR & CMSR_INAK) ); /* Wait until acknowledged */
/* CAN modes */
CAN_DGR |= CAN_Mode;
CAN_MCR &= ~CMCR_INRQ; /* Leave the Init mode */
while ( (CAN_MSR & CMSR_INAK) ); /* Wait until acknowledged */
}
/*******************************************************************************
* Function Name : CAN_DisableDiagMode
* Description : This routine sets the CAN in Loop-back and/or silent modes.
* Input : CAN_Mode (CDGR_LBKM, CDGR_SILM)
* Output : .
* Return : .
*******************************************************************************/
void CAN_DisableDiagMode (void)
{
CAN_MCR |= CMCR_INRQ; /* Request initialisation */
while ( !(CAN_MSR & CMSR_INAK) ); /* Wait until acknowledged */
/* Disable Silent/Loop-back modes */
CAN_DGR &= ~(CDGR_LBKM | CDGR_SILM);
CAN_MCR &= ~CMCR_INRQ; /* Leave the Init mode */
while ( (CAN_MSR & CMSR_INAK) ); /* Wait until acknowledged */
}
/*******************************************************************************
* Function Name : CanMsgTransmit
* Description : This service initiates the transmission for the message
referenced by <txData>.
This service shall not be called when the CAN driver is in
stop or sleep mode.
* Input : txData - Pointer to structure which contains about CAN-Id,
CAN-DLC,CAN-Frame Data.
CAN-Frame Data[0] = Mailbox number (for debug)
* Output : .
* Return : KCANTXOK - Request is accepted by CAN driver.
KCANTXFAILED - Request is not accepted by CAN driver.
*******************************************************************************/
unsigned char CanMsgTransmit(tCanMsgOject *txData)
{
unsigned char idx, MailboxNumber;
if(CAN_TPR & CTPR_TME0) /* Mailbox 1 empty ? */
{
CAN_FPSR = CAN_TXMB0_PG;
MailboxNumber = 1;
}
else if(CAN_TPR & CTPR_TME1) /* Mailbox 2 empty ? */
{
CAN_FPSR = CAN_TXMB1_PG;
MailboxNumber = 2;
}
else if(CAN_TPR & CTPR_TME2) /* Mailbox 3 empty ? */
{
CAN_FPSR = CAN_TXMB2_PG;
MailboxNumber = 3;
}
else
{
return (KCANTXFAILED);
}
/* Transfert ID, DLC and Data in RAM to the right Mailbox */
CAN_MDLC = txData->dlc;
/* Mask used to clear IDE, RTR, ExtID [17:16] -> Only Std frames are used */
CAN_MIDR12 = (txData->stdid << 2) & 0x1FFC;
CAN_MIDR34 = txData->extid;
CAN_MDAR[0] = MailboxNumber;
for(idx = 1; idx < CAN_MDLC; idx++)
{
CAN_MDAR[idx] = txData->data[idx];
}
CAN_MCSR |= MCSR_TXRQ; /* Transmit Request */
return (KCANTXOK);
}
/*******************************************************************************
* Function Name : CanCanInterruptDisable
* Description : This routine disables all CAN interrupts.
* Input : .
* Output : .
* Return : .
*******************************************************************************/
void CanCanInterruptDisable (void)
{
CanSavePg();
CAN_IER = 0x00;
CAN_FPSR = CAN_CTRL_PG;
CAN_EIER = 0x00;
CanRestorePg();
}
/*******************************************************************************
* Function Name : CanCanInterruptRestore
* Description : This service restores all CAN interrupts.
* Input : .
* Output : .
* Return : .
*******************************************************************************/
void CanCanInterruptRestore (void)
{
CanSavePg();
CAN_IER = CIER_WKUIE | /* Wake-up Interrupt */
CIER_FOVIE | /* FIFO overrun Interrupt */
CIER_FFIE | /* FIFO Full Interrupt */
CIER_FMPIE | /* FIFO Message Pending Interrupt */
CIER_TMEIE; /* Transmit Mailbox Empty Interrupt */
CAN_FPSR = CAN_CTRL_PG;
CAN_EIER = CEIER_ERRIE| /* Error Interrupt */
CEIER_LECIE| /* Last Error Code Interrupt */
CEIER_BOFIE| /* Bus-Off Interrupt */
CEIER_EPVIE| /* Error Passive Interrupt */
CEIER_EWGIE; /* Error Warning Interrupt */
CanRestorePg();
}
/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -