📄 can.c
字号:
/*----------------------------------------------------------------------------
* A R T X - C A N
*----------------------------------------------------------------------------
* Name: CAN.c
* Purpose: CAN Generic Driver
* Rev.: V0.11a / september-15-2005
*----------------------------------------------------------------------------
* This code is part of the ARTX-ARM kernel package of Keil Software.
* Copyright (c) 2004-2005 Keil Software. All rights reserved.
*---------------------------------------------------------------------------*/
#include <ARTX.h> /* ARTX kernel functions & defines */
#include <LPC21xx.h> /* LPC21xx definitions */
#include "CAN_cfg.h" /* CAN Configuration */
#include "CAN.h" /* CAN Generic functions & defines */
#include "CAN_hw.h" /* CAN hw specific functions & defines */
/* Declare memory pool for CAN messages, both transmit and receive */
CAN_msgpool_declare(CAN_mpool,CAN_CTRL_MAX_NUM*(CAN_No_SendObjects+CAN_No_ReceiveObjects));
/* Declare mailbox, for CAN transmit messages */
mbx_arr_declare(MBX_tx_ctrl,CAN_CTRL_MAX_NUM,CAN_No_SendObjects);
/* Declare mailbox, for CAN receive messages */
mbx_arr_declare(MBX_rx_ctrl,CAN_CTRL_MAX_NUM,CAN_No_ReceiveObjects);
/* Flags signaling writing to CAN hardware */
U8 wr_to_CAN_hw[CAN_CTRL_MAX_NUM];
/*----------------------------------------------------------------------------
* CAN ARTX Generic Driver Functions
*----------------------------------------------------------------------------
* Functions implemented in this module:
* CAN_ERROR CAN_mem_init (void);
* CAN_ERROR CAN_setup (void)
* CAN_ERROR CAN_init (U32 ctrl, U32 baudrate)
* CAN_ERROR CAN_start (U32 ctrl)
* static CAN_ERROR CAN_push (U32 ctrl, CAN_msg *msg, U16 timeout)
* CAN_ERROR CAN_send (U32 ctrl, CAN_msg *msg, U16 timeout)
* CAN_ERROR CAN_request (U32 ctrl, CAN_msg *msg, U16 timeout)
* static CAN_ERROR CAN_pull (U32 ctrl, CAN_msg *msg, U16 timeout)
* CAN_ERROR CAN_receive (U32 ctrl, CAN_msg *msg, U16 timeout)
* CAN_ERROR CAN_rx_object (U32 ctrl, U32 ch, U32 id, CAN_FORMAT format)
* CAN_ERROR CAN_tx_object (U32 ctrl, U32 ch, U32 id, CAN_FORMAT format)
*---------------------------------------------------------------------------*/
/*--------------------------- CAN_init --------------------------------------
*
* The first time this function is called initialize the memory pool for
* CAN messages and setup CAN controllers hardware
*
* Initialize mailboxes for CAN messages and initialize CAN controller
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* baudrate: Baudrate
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_init (U32 ctrl, U32 baudrate) {
static U8 first_run_flag = 0;
CAN_ERROR error_code;
U32 ctrl0 = ctrl-1; /* Controller index 0 .. x-1 */
/* When function is called for the first time it will initialize and setup
all of the resources that are common to CAN functionality */
if (first_run_flag == 0) {
first_run_flag = 1;
if (_init_box (CAN_mpool, sizeof(CAN_mpool), sizeof(CAN_msg)) == 1)
return CAN_MEM_POOL_INIT_ERROR;
error_code = CAN_hw_setup ();
if (error_code != CAN_OK)
return error_code;
}
os_mbx_init (MBX_tx_ctrl[ctrl0], sizeof(MBX_tx_ctrl[ctrl0]));
os_mbx_init (MBX_rx_ctrl[ctrl0], sizeof(MBX_rx_ctrl[ctrl0]));
return (CAN_hw_init (ctrl, baudrate));
}
/*--------------------------- CAN_start -------------------------------------
*
* Start CAN controller (enable it to participate on CAN network)
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_start (U32 ctrl) {
return (CAN_hw_start (ctrl));
}
/*--------------------------- CAN_push --------------------------------------
*
* Send CAN_msg if hardware is free for sending, otherwise push message to
* message queue to be sent when hardware becomes free
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer to CAN message to be sent
* timeout: Timeout value for message sending
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
static CAN_ERROR CAN_push (U32 ctrl, CAN_msg *msg, U16 timeout) {
CAN_msg *ptrmsg;
U32 ctrl0 = ctrl-1; /* Controller index 0 .. x-1 */
if (CAN_hw_tx_empty (ctrl) == 0) { /* Transmit hardware free for sending */
wr_to_CAN_hw[ctrl0] = 1; /* Writing to transmit hardware */
CAN_hw_wr (ctrl, msg); /* Send message */
wr_to_CAN_hw[ctrl0] = 0; /* Writing to transmit hardware finished */
}
else { /* If hardware for sending is busy */
/* Write the message to send mailbox if there is room for it */
ptrmsg = _alloc_box (CAN_mpool);
if (ptrmsg != NULL)
*ptrmsg = *msg;
/* If message hasn't been received but timeout expired, deallocate memory*/
if (os_mbx_send (MBX_tx_ctrl[ctrl0], ptrmsg, timeout) == OS_R_TMO) {
if (_free_box (CAN_mpool, ptrmsg) == 1)
return CAN_DEALLOC_MEM_ERROR;
return CAN_TIMEOUT_ERROR;
}
else
return CAN_ALLOC_MEM_ERROR;
}
return CAN_OK;
}
/*--------------------------- CAN_send --------------------------------------
*
* Send DATA FRAME message, see CAN_push function comment
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer to CAN message to be sent
* timeout: Timeout value for message sending
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_send (U32 ctrl, CAN_msg *msg, U16 timeout) {
msg->type = DATA_FRAME;
return (CAN_push (ctrl, msg, timeout));
}
/*--------------------------- CAN_request -----------------------------------
*
* Send REMOTE FRAME message, see CAN_push function comment
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer to CAN message to be sent
* timeout: Timeout value for message sending
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_request (U32 ctrl, CAN_msg *msg, U16 timeout) {
msg->type = REMOTE_FRAME;
return (CAN_push (ctrl, msg, timeout));
}
/*--------------------------- CAN_pull --------------------------------------
*
* Pull first received and unread CAN_msg from receiving message queue
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer where CAN message will be read
* timeout: Timeout value for message receiving
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
static CAN_ERROR CAN_pull (U32 ctrl, CAN_msg *msg, U16 timeout) {
CAN_msg *ptrmsg;
U32 ctrl0 = ctrl-1; /* Controller index 0 .. x-1 */
/* Wait for received message in mailbox */
if (os_mbx_wait (MBX_rx_ctrl[ctrl0], &ptrmsg, timeout) == OS_R_TMO)
return CAN_TIMEOUT_ERROR;
/* Copy received message from mailbox to address given in function parameter msg */
*msg = *ptrmsg;
/* Free box where message was kept */
if (_free_box (CAN_mpool, ptrmsg) == 1)
return CAN_DEALLOC_MEM_ERROR;
return CAN_OK;
}
/*--------------------------- CAN_receive -----------------------------------
*
* Read received message, see CAN_pull function comment
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer where CAN message will be read
* timeout: Timeout value for message receiving
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_receive (U32 ctrl, CAN_msg *msg, U16 timeout) {
return (CAN_pull (ctrl, msg, timeout));
}
/*--------------------------- CAN_rx_object ---------------------------------
*
* Enable reception of messages on specified controller and channel with
* specified identifier
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* ch: Channel for message reception
* id: CAN message identifier
* CAN_FORMAT: Format of CAN identifier (standard or extended)
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_rx_object (U32 ctrl, U32 ch, U32 id, CAN_FORMAT format) {
return (CAN_hw_rx_object (ctrl, ch, id, format));
}
/*--------------------------- CAN_tx_object ---------------------------------
*
* Enable transmission of messages on specified controller and channel with
* specified identifier
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* ch: Channel for message transmission
* id: CAN message identifier
* CAN_FORMAT: Format of CAN identifier (standard or extended)
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_tx_object (U32 ctrl, U32 ch, U32 id, CAN_FORMAT format) {
return (CAN_hw_tx_object (ctrl, ch, id, format));
}
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -