📄 lpc177x_8x_can.c
字号:
{
/* Transmit Channel 3 is available */
/* Write frame informations and frame data into its CANxTFI3,
* CANxTID3, CANxTDA3, CANxTDB3 register */
pCan->TFI3 &= ~0x000F0000;
pCan->TFI3 |= (CAN_Msg->len) << 16;
if(CAN_Msg->type == REMOTE_FRAME)
{
pCan->TFI3 |= (1 << 30); //set bit RTR
}
else
{
pCan->TFI3 &= ~(1 << 30);
}
if(CAN_Msg->format == EXT_ID_FORMAT)
{
pCan->TFI3 |= (1 << 31); //set bit FF
}
else
{
pCan->TFI3 &= ~(1 << 31);
}
/* Write CAN ID*/
pCan->TID3 = CAN_Msg->id;
/*Write first 4 data bytes*/
data = (CAN_Msg->dataA[0]) | (((CAN_Msg->dataA[1])) << 8) | ((CAN_Msg->dataA[2]) << 16) | ((CAN_Msg->dataA[3]) << 24);
pCan->TDA3 = data;
/*Write second 4 data bytes*/
data = (CAN_Msg->dataB[0]) | (((CAN_Msg->dataB[1])) << 8) | ((CAN_Msg->dataB[2]) << 16) | ((CAN_Msg->dataB[3]) << 24);
pCan->TDB3 = data;
/*Write transmission request*/
pCan->CMR = 0x81;
return SUCCESS;
}
else
{
return ERROR;
}
}
/********************************************************************//**
* @brief Receive message data
* @param[in] canId The Id of the expected CAN component
*
* @param[in] CAN_Msg point to the CAN_MSG_Type Struct, it will contain received
* message information such as: ID, DLC, RTR, ID Format
* @return Status:
* - SUCCESS: receive message successfully
* - ERROR: receive message unsuccessfully
*********************************************************************/
Status CAN_ReceiveMsg (uint8_t canId, CAN_MSG_Type *CAN_Msg)
{
LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId);
uint32_t data;
//check status of Receive Buffer
if((pCan->SR &0x00000001))
{
/* Receive message is available */
/* Read frame informations */
CAN_Msg->format = (uint8_t)(((pCan->RFS) & 0x80000000) >> 31);
CAN_Msg->type = (uint8_t)(((pCan->RFS) & 0x40000000) >> 30);
CAN_Msg->len = (uint8_t)(((pCan->RFS) & 0x000F0000) >> 16);
/* Read CAN message identifier */
CAN_Msg->id = pCan->RID;
/* Read the data if received message was DATA FRAME */
if (CAN_Msg->type == DATA_FRAME)
{
/* Read first 4 data bytes */
data = pCan->RDA;
*((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
*((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00) >> 8;;
*((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000) >> 16;
*((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000) >> 24;
/* Read second 4 data bytes */
data = pCan->RDB;
*((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
*((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00) >> 8;
*((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000) >> 16;
*((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000) >> 24;
/*release receive buffer*/
pCan->CMR = 0x04;
}
else
{
/* Received Frame is a Remote Frame, not have data, we just receive
* message information only */
pCan->CMR = 0x04; /*release receive buffer*/
return SUCCESS;
}
}
else
{
// no receive message available
return ERROR;
}
return SUCCESS;
}
/********************************************************************//**
* @brief Receive FullCAN Object
* @param[in] CANAFx: CAN Acceptance Filter register, should be: LPC_CANAF
* @param[in] CAN_Msg point to the CAN_MSG_Type Struct, it will contain received
* message information such as: ID, DLC, RTR, ID Format
* @return CAN_ERROR, could be:
* - CAN_FULL_OBJ_NOT_RCV: FullCAN Object is not be received
* - CAN_OK: Received FullCAN Object successful
*
*********************************************************************/
CAN_ERROR FCAN_ReadObj (CAN_MSG_Type *CAN_Msg)
{
uint32_t *pSrc, data;
uint32_t interrut_word, msg_idx, test_bit, head_idx, tail_idx;
interrut_word = 0;
if (LPC_CANAF->FCANIC0 != 0)
{
interrut_word = LPC_CANAF->FCANIC0;
head_idx = 0;
tail_idx = 31;
}
else if (LPC_CANAF->FCANIC1 != 0)
{
interrut_word = LPC_CANAF->FCANIC1;
head_idx = 32;
tail_idx = 63;
}
if (interrut_word != 0)
{
/* Detect for interrupt pending */
msg_idx = 0;
for (msg_idx = head_idx; msg_idx <= tail_idx; msg_idx++)
{
test_bit = interrut_word & 0x1;
interrut_word = interrut_word >> 1;
if (test_bit)
{
pSrc = (uint32_t *) (LPC_CANAF->ENDofTable + LPC_CANAF_RAM_BASE + msg_idx * 12);
/* Has been finished updating the content */
if ((*pSrc & 0x03000000L) == 0x03000000L)
{
/*clear semaphore*/
*pSrc &= 0xFCFFFFFF;
/*Set to DatA*/
pSrc++;
/* Copy to dest buf */
data = *pSrc;
*((uint8_t *) &CAN_Msg->dataA[0])= data & 0x000000FF;
*((uint8_t *) &CAN_Msg->dataA[1])= (data & 0x0000FF00) >> 8;
*((uint8_t *) &CAN_Msg->dataA[2])= (data & 0x00FF0000) >> 16;
*((uint8_t *) &CAN_Msg->dataA[3])= (data & 0xFF000000) >> 24;
/*Set to DatB*/
pSrc++;
/* Copy to dest buf */
data = *pSrc;
*((uint8_t *) &CAN_Msg->dataB[0])= data & 0x000000FF;
*((uint8_t *) &CAN_Msg->dataB[1])= (data & 0x0000FF00) >> 8;
*((uint8_t *) &CAN_Msg->dataB[2])= (data & 0x00FF0000) >> 16;
*((uint8_t *) &CAN_Msg->dataB[3])= (data & 0xFF000000) >> 24;
/*Back to Dat1*/
pSrc -= 2;
CAN_Msg->id = *pSrc & 0x7FF;
CAN_Msg->len = (uint8_t) (*pSrc >> 16) & 0x0F;
CAN_Msg->format = 0; //FullCAN Object ID always is 11-bit value
CAN_Msg->type = (uint8_t)(*pSrc >> 30) &0x01;
/*Re-read semaphore*/
if ((*pSrc & 0x03000000L) == 0)
{
return CAN_OK;
}
}
}
}
}
return CAN_FULL_OBJ_NOT_RCV;
}
/********************************************************************//**
* @brief Get CAN Control Status
* @param[in] canId The Id of the expected CAN component
*
* @param[in] arg: type of CAN status to get from CAN status register
* Should be:
* - CANCTRL_GLOBAL_STS: CAN Global Status
* - CANCTRL_INT_CAP: CAN Interrupt and Capture
* - CANCTRL_ERR_WRN: CAN Error Warning Limit
* - CANCTRL_STS: CAN Control Status
* @return Current Control Status that you want to get value
*********************************************************************/
uint32_t CAN_GetCTRLStatus (uint8_t canId, CAN_CTRL_STS_Type arg)
{
LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId);
switch (arg)
{
case CANCTRL_GLOBAL_STS:
return pCan->GSR;
case CANCTRL_INT_CAP:
return pCan->ICR;
case CANCTRL_ERR_WRN:
return pCan->EWL;
default: // CANCTRL_STS
return pCan->SR;
}
}
/********************************************************************//**
* @brief Get CAN Central Status
* @param[in] CANCRx point to LPC_CANCR_TypeDef, should be: LPC_CANCR
* @param[in] arg: type of CAN status to get from CAN Central status register
* Should be:
* - CANCR_TX_STS: Central CAN Tx Status
* - CANCR_RX_STS: Central CAN Rx Status
* - CANCR_MS: Central CAN Miscellaneous Status
* @return Current Central Status that you want to get value
*********************************************************************/
uint32_t CAN_GetCRStatus (CAN_CR_STS_Type arg)
{
switch (arg)
{
case CANCR_TX_STS:
return LPC_CANCR->TxSR;
case CANCR_RX_STS:
return LPC_CANCR->RxSR;
default: // CANCR_MS
return LPC_CANCR->MSR;
}
}
/********************************************************************//**
* @brief Enable/Disable CAN Interrupt
* @param[in] canId The Id of the expected CAN component
*
* @param[in] arg: type of CAN interrupt that you want to enable/disable
* Should be:
* - CANINT_RIE: CAN Receiver Interrupt Enable
* - CANINT_TIE1: CAN Transmit Interrupt Enable
* - CANINT_EIE: CAN Error Warning Interrupt Enable
* - CANINT_DOIE: CAN Data Overrun Interrupt Enable
* - CANINT_WUIE: CAN Wake-Up Interrupt Enable
* - CANINT_EPIE: CAN Error Passive Interrupt Enable
* - CANINT_ALIE: CAN Arbitration Lost Interrupt Enable
* - CANINT_BEIE: CAN Bus Error Interrupt Enable
* - CANINT_IDIE: CAN ID Ready Interrupt Enable
* - CANINT_TIE2: CAN Transmit Interrupt Enable for Buffer2
* - CANINT_TIE3: CAN Transmit Interrupt Enable for Buffer3
* - CANINT_FCE: FullCAN Interrupt Enable
* @param[in] NewState: New state of this function, should be:
* - ENABLE
* - DISABLE
* @return none
*********************************************************************/
void CAN_IRQCmd (uint8_t canId, CAN_INT_EN_Type arg, FunctionalState NewState)
{
LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId);
if(NewState == ENABLE)
{
if(arg == CANINT_FCE)
{
LPC_CANAF->AFMR = 0x01;
LPC_CANAF->FCANIE = 0x01;
LPC_CANAF->AFMR = 0x04;
}
else
pCan->IER |= (1 << arg);
}
else
{
if(arg == CANINT_FCE)
{
LPC_CANAF->AFMR = 0x01;
LPC_CANAF->FCANIE = 0x01;
LPC_CANAF->AFMR = 0x00;
}
else
pCan->IER &= ~(1 << arg);
}
}
/********************************************************************//**
* @brief Setting Acceptance Filter mode
* @param[in] CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF
* @param[in] AFMode: type of AF mode that you want to set, should be:
* - CAN_NORMAL: Normal mode
* - CAN_ACC_OFF: Acceptance Filter Off Mode
* - CAN_ACC_BP: Acceptance Fileter Bypass Mode
* - CAN_EFCAN: FullCAN Mode Enhancement
* @return none
*********************************************************************/
void CAN_SetAFMode (CAN_AFMODE_Type AFMode)
{
switch(AFMode)
{
case CAN_NORMAL:
LPC_CANAF->AFMR = 0x00;
break;
case CAN_ACC_OFF:
LPC_CANAF->AFMR = 0x01;
break;
case CAN_ACC_BP:
LPC_CANAF->AFMR = 0x02;
break;
case CAN_EFCAN:
LPC_CANAF->AFMR = 0x04;
break;
}
}
/********************************************************************//**
* @brief Enable/Disable CAN Mode
* @param[in] canId The Id of the expected CAN component
*
* @param[in] mode: type of CAN mode that you want to enable/disable, should be:
* - CAN_OPERATING_MODE: Normal Operating Mode
* - CAN_RESET_MODE: Reset Mode
* - CAN_LISTENONLY_MODE: Listen Only Mode
* - CAN_SELFTEST_MODE: Self Test Mode
* - CAN_TXPRIORITY_MODE: Transmit Priority Mode
* - CAN_SLEEP_MODE: Sleep Mode
* - CAN_RXPOLARITY_MODE: Receive Polarity Mode
* - CAN_TEST_MODE: Test Mode
* @param[in] NewState: New State of this function, should be:
* - ENABLE
* - DISABLE
* @return none
*********************************************************************/
void CAN_ModeConfig(uint8_t canId, CAN_MODE_Type mode, FunctionalState NewState)
{
LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId);
switch(mode)
{
case CAN_OPERATING_MODE:
pCan->MOD = 0x00;
break;
case CAN_RESET_MODE:
if(NewState == ENABLE)
pCan->MOD |= CAN_MOD_RM;
else
pCan->MOD &= ~CAN_MOD_RM;
break;
case CAN_LISTENONLY_MODE:
pCan->MOD |=CAN_MOD_RM;//Enter Reset mode
if(NewState == ENABLE)
pCan->MOD |= CAN_MOD_LOM;
else
pCan->MOD &= ~ CAN_MOD_LOM;
pCan->MOD &= ~ CAN_MOD_RM;//Release Reset mode
break;
case CAN_SELFTEST_MODE:
pCan->MOD |= CAN_MOD_RM;//Enter Reset mode
if(NewState == ENABLE)
pCan->MOD |= CAN_MOD_STM;
else
pCan->MOD &= ~ CAN_MOD_STM;
pCan->MOD &= ~ CAN_MOD_RM;//Release Reset mode
break;
case CAN_TXPRIORITY_MODE:
if(NewState == ENABLE)
pCan->MOD |= CAN_MOD_TPM;
else
pCan->MOD &= ~ CAN_MOD_TPM;
break;
case CAN_SLEEP_MODE:
if(NewState == ENABLE)
pCan->MOD |= CAN_MOD_SM;
else
pCan->MOD &= ~ CAN_MOD_SM;
break;
case CAN_RXPOLARITY_MODE:
if(NewState == ENABLE)
pCan->MOD |= CAN_MOD_RPM;
else
pCan->MOD &= ~ CAN_MOD_RPM;
break;
case CAN_TEST_MODE:
if(NewState == ENABLE)
pCan->MOD |= CAN_MOD_TM;
else
pCan->MOD &= ~ CAN_MOD_TM;
break;
}
}
/*********************************************************************//**
* @brief Set CAN command request
* @param[in] canId The Id of the expected CAN component
*
* @param[in] CMRType command request type, should be:
* - CAN_CMR_TR: Transmission request
* - CAN_CMR_AT: Abort Transmission request
* - CAN_CMR_RRB: Release Receive Buffer request
* - CAN_CMR_CDO: Clear Data Overrun request
* - CAN_CMR_SRR: Self Reception request
* - CAN_CMR_STB1: Select Tx Buffer 1 request
* - CAN_CMR_STB2: Select Tx Buffer 2 request
* - CAN_CMR_STB3: Select Tx Buffer 3 request
* @return CANICR (CAN interrupt and Capture register) value
**********************************************************************/
void CAN_SetCommand(uint8_t canId, uint32_t CMRType)
{
LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId);
pCan->CMR |= CMRType;
}
/*********************************************************************//**
* @brief Get CAN interrupt status
* @param[in] canId The Id of the expected CAN component
*
* @return CANICR (CAN interrupt and Capture register) value
**********************************************************************/
uint32_t CAN_IntGetStatus(uint8_t canId)
{
LPC_CAN_TypeDef* pCan = CAN_GetPointer(canId);
return pCan->ICR;
}
/*********************************************************************//**
* @brief Check if FullCAN interrupt enable or not
* @param[in] CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF
* @return IntStatus, could be:
* - SET: if FullCAN interrupt is enable
* - RESET: if FullCAN interrupt is disable
**********************************************************************/
IntStatus CAN_FullCANIntGetStatus (void)
{
if (LPC_CANAF->FCANIE)
return SET;
return RESET;
}
/*********************************************************************//**
* @brief Get value of FullCAN interrupt and capture register
* @param[in] CANAFx point to LPC_CANAF_TypeDef object, should be: LPC_CANAF
* @param[in] type: FullCAN IC type, should be:
* - FULLCAN_IC0: FullCAN Interrupt Capture 0
* - FULLCAN_IC1: FullCAN Interrupt Capture 1
* @return FCANIC0 or FCANIC1 (FullCAN interrupt and Capture register) value
**********************************************************************/
uint32_t CAN_FullCANPendGetStatus(FullCAN_IC_Type type)
{
if (type == FULLCAN_IC0)
return LPC_CANAF->FCANIC0;
return LPC_CANAF->FCANIC1;
}
/* End of Public Variables ---------------------------------------------------------- */
/**
* @}
*/
/**
* @}
*/
/* --------------------------------- End Of File ------------------------------ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -