www.beck-ipc.com

@CHIP-RTOS C Library V2.06 - CAN API


CAN_Send

Queue a CAN message for transmission.

int CAN_Send (  unsigned int port_idx,

unsigned int channel,
const CAN_MSG far *msg );

Parameters

port_idx

CAN port specifier:   CAN0_PORT = 0, or CAN1_PORT = 1

channel

Transmit register specifier:
    CAN_TX1 = 0
    CAN_TX2 = 1
    CAN_TX3 = 2

or when operating in CAN_TX_PRIORITY_QUEUES mode:
    CAN_TX_NORMAL = 0
    CAN_TX_HIGH = 1
    (2 works same as CAN_TX_HIGH here)

msg

Pointer to a CAN_MSG data structure holding contents of CAN message to be transmitted, set by caller.

Return Value

Error code -
CAN_EC_SUCCESS = 0:   Success, message has been transferred into specified transmit queue.
CAN_EC_INVALID_PARAMS = -1:   port_idx, filter_idx invalid or NULL msg pointer.
CAN_EC_PORT_NOT_OPENED = -3:  Port has not been opened. CAN_EC_NO_BUF_SPACE = -5:   Transmit queue for this output channel is full, message not accepted.

Comments

Three different modes of operation are available for the CAN transmission, selected at the CAN_Open_Port API call:

  1. Default mode

    This mode uses three transmit software FIFO queues, where each FIFO feeds a specific hardware transmit register.   The size of each FIFO is configurable.

  2. CAN_TX_PRIORITY_QUEUES Mode

    This mode is selected by setting the CAN_TX_PRIORITY_QUEUES bit in the CAN_CONFIG structure's Mode word.   In this mode two transmit FIFO's are used, one with normal priority and one with high priority.   The size of the normal priority queue is specified by the Tx_Q_Size[CAN_TX_NORMAL] value in the CAN_PORT_INIT structure at the CAN_Open_Port call.   The high priority queue size is specified here with the Tx_Q_Size[CAN_TX_HIGH] value.


  3. CAN_TXQ1_DRIVES_ALL Mode

    This mode is selected by setting the CAN_TXQ1_DRIVES_ALL bit in the CAN_CONFIG structure's Mode word.   In this mode, a single queue feeds more than one of the hardware transmit registers.   If a queue size of zero is specified for channels CAN_TX2 and CAN_TX3, then the respective hardware transmit registers will be fed from the common FIFO.   If both the Tx_Q_Size[CAN_TX2] and Tx_Q_Size[CAN_TX3] values in the CAN_PORT_INIT structure are zero when CAN_Open_Port is called, then the single FIFO whose size was specified by Tx_Q_Size[CAN_TX1] drives all three hardware transmit channels.

Comments General to All Operation Modes

The CAN_Send() function either places the provided CAN message directly into the hardware register when there is no message currently pending output already in this register, or into the software ring buffer queue.   When no more space is available in the output queue, an error code CAN_EC_NO_BUF_SPACE is returned and no operation is performed.

The driver feeds the output queues into the hardware transmit registers in an interrupt driven fashion.   The hardware prioritizes the three transmit registers based on "first recessive bit" logic, similar to that used for normal CAN bus arbitration.   However in this case, the "arbitration" is performed internally prior to presentation of the outgoing CAN message on the bus.   This priorization mechanism can lead to transmission which is not done in FIFO order for the operational modes which drive more than one hardware transmit register from a single FIFO.

Inside this API the interrupts are masked for a short period and then re-enabled.   This function is reentrant.

Comments on Default Mode

The CAN driver provides three queues for outgoing CAN messages.   Each queue is fed into one of the three hardware transmit registers provided by the CAN device.

The output queues can be loaded with this API prior to enabling the respective hardware transmit register.   In this case no output from this channel will occur until the channel is enabled with the appropriate channel enable command to the CAN_Control() function.

Comments on CAN_TX_PRIORITY_QUEUES Mode

The CAN_TX_PRIORITY_QUEUES option bit in the CAN_CONFIG Mode word selects this mode.   CAN messages from the CAN_TX_NORMAL queue will only be loaded into the CAN hardware transmit registers when the CAN_TX_HIGH queue is empty.   The CAN messages in the CAN_TX_HIGH queue are higher priority and will be loaded before those in the CAN_TX_NORMAL queue.

When using this CAN_Send() API, the channel parameter is used to specify either the normal (CAN_TX_NORMAL) or high (CAN_TX_HIGH) priority queues.

Note that when this API is called with channel set to CAN_TX_HIGH, any CAN messages from the CAN_TX_NORMAL queue which have already been loaded into the hardware registers will remain there.   Consequently, it can happen that pending CAN messages from the CAN_TX_NORMAL queue that have already been loaded into one of the three hardware transmit registers may be transmitted after calling this API with a CAN_TX_HIGH message and before this higher priority message is loaded into the transmit registers by the CAN driver.   The new high priority message will only be loaded when one of the three transmit registers becomes available (empty).

Once loaded into the hardware register, the CAN message recessive bit prioritization logic is used by hardware to select among the three transmit registers.   This too may lead to messages from the normal priority queue being transmitted ahead of a high priority CAN message, if the high priority queue's message does not have a high priority CAN message ID (low number).   For applications where this behavior is not tolerable, you might consider disabling all but one of the transmit registers.   However, this may lead to performance problems so should be avoided when possible.   The queues will drain through what ever transmit registers have been enabled.

Comments on CAN_TXQ1_DRIVES_ALL Mode

This mode is selected by setting the CAN_TXQ1_DRIVES_ALL option bit in the CAN_CONFIG Mode word.   (The CAN_TX_PRIORITY_QUEUES bit must be zero.)   In this mode the hardware transmit registers CAN_TX2 and/or CAN_TX3 can be driven from the CAN_TX1 FIFO by specifying zero sizes for the CAN_TX2 and/or CAN_TX3 software FIFO's.

Example #1:


    CAN_PORT_INIT init ;
    init.Config.Mode = CAN_TXQ1_DRIVES_ALL ;
    init.Tx_Q_Size[CAN_TX1] = 20 ;
    init.Tx_Q_Size[CAN_TX2] = 5 ;
    init.Tx_Q_Size[CAN_TX3] = 0 ;

These settings would cause TX1 and TX3 hardware transmit registers to both be driven from the 20 message CAN_TX1 FIFO.   The TX2 hardware transmit register is connected to its private 5 message queue.

Example #2:

    CAN_PORT_INIT init ;
    init.Config.Mode = CAN_TXQ1_DRIVES_ALL ;
    init.Tx_Q_Size[CAN_TX1] = 20 ;
    init.Tx_Q_Size[CAN_TX2] = 0 ;
    init.Tx_Q_Size[CAN_TX3] = 0 ;

These settings would cause all three hardware transmit registers to be filled from the 20 message CAN_TX1 FIFO.

When the CAN_TXQ1_DRIVES_ALL option is used to drive more than one hardware transmit register from the first software transmit FIFO, the CAN transmissions may not necessarily come out in FIFO order.   This is due to the CAN bus arbitration based on CAN label performed within the CAN port device's set of transmit registers.   A typical scenerio would be that the CAN driver software takes three CAN messages from the send FIFO and places these into the three hardware transmit registers.   Then the hardware transmit arbitration logic selects the CAN message among these three with the lowest CAN ID for transmission.

When the CAN_TXQ1_DRIVES_ALL option is used to drive CAN_TX2 and CAN_TX3 transmit registers, calling this CAN_Send() API with the channel argument set to either CAN_TX2 or CAN_TX3 performs nearly the same operation as CAN_TX1.   In the case where the provided CAN message is placed in the single send FIFO, the functionality is identical.   When the FIFO and specified transmit register are empty, there is a slight difference.   In this case the channel argument specifies which hardware transmit registers is loaded.

See Also

RTOS API

This library function uses a dynamic link to reach the service offered by RTOS software interrupt.

Supported since or modified in @CHIP-RTOS version

    SC12SC13SC11SC1x3
    n/an/an/aV1.07

Supported by @CHIP-RTOS C Library since version

    CLIB
    V2.01

This API List
List of C Libraries
@CHIP-RTOS Main Index


End of document