cover

Advantech CAN Card Driver Manual

Supporting Card List:

PCL-841 Card

PCM-3680 Card

PCI-1680 Card

MIC-3680 Card

UNO-2052 CAN Controller

Web: http://www.advantech.com

e-mail: info@advantech.com

Copyright ©2003-2004, Advantech Co., Ltd. All rights reserved.


Introduction

The Advantech CAN cards are special purpose communication card that brings the Control Area Network to your PC. With the built-in CAN controller, the Advantech CAN cards provide bus arbitration and error detection with automatic transmission repeat function. This drastically avoids data loss and ensures system reliability. The on-board CAN controllers are located at different positions in the memory. You can run both CAN controllers at the same time, independently. The Advantech CAN cards operate at baud rates up to 1 Mbps and can be installed directly into the expansion slot of your PC.

Control Area Network

The CAN (Control Area Network) is a serial bus system especially suited for networking "intelligent" I/O devices as well as sensors and actuators within a machine or plant. Characterized by its multi-master protocol, real-time capability, error correction, high noise immunity, and the existence of many different silicon components, the CAN serial bus system, originally developed by Bosch for use in automobiles, is increasingly being used in industrial automation.

Direct memory mapping

The Advantech CAN cards are assigned with memory address, which allows direct access to the CAN controller. This is the simplest and fastest way to program any board in a PC because the board is regarded as standard RAM.

Optical Isolation Protection

On-board optical isolators protect your PC and equipment against damage from ground loops, increasing system reliability in harsh environments.


PCL-841 & PCM-3680

Features

  • Operates two separate CAN networks at the same time
  • High speed transmission up to 1 Mbps
  • 16 MHz CAN controller frequency
  • Takes a 4 KB address space, 40 base address adjustable in steps from C800H up to EF00H
  • Optical isolation protection of 1000 VDC ensures system reliability
  • Wide IRQ selection for each port includes: IRQ3, 4, 5, 6, 7, 9, 10, 11, 12, 15
  • LED indicates Transmit/Receive status on each port
  • Direct memory mapping enables speedy access to the CAN controllers
  • C library and examples included

Specifications

Ports: 2

CAN controller: SJA-1000

CAN transceiver: 82C250

Signal support: CAN-L, CAN-H

Memory address: From C800H to EF00H

IRQ: 3, 4, 5, 6, 7, 9, 10, 11, 12, 15

Isolation voltage: 1000 VDC

Power consumption: +5 V @ 400 mA typical, 950 mA max.

Connectors: Dual DB-9 male connectors

Operating temperature: 32 to 1 22˚ F (0 to 50˚C)

Dimensions: 7.25" x 4. 13" (18.4 x 10.5 cm)

Shipping weight: 0.9 lb (0.4 kg)

PCI-1680 & UNO-2052 & MIC-3680

Specifications

Bus interface: PCI bus spec. 2.2 compliant

Two independent CAN network operation (V2.0 A,B)

Communication controller: SJA1000

CAN transceiver:82C250

16MHz CAN controller frequency

Speed ( bps ): Up to 1Mbps programmable transfer rate

Connector: Dual DB-9 male connectors (for PCI-1680UP, it's DB25(F), and include a DB25 to Two standard DB9(M) cable)

Operating Temperature: 0 ~ 60℃

Storage Temperature: -25 ~ 85℃

Operating Humidity: 5 ~ 95% Relative Humidity, non-condensing


installation

Hardware Installation

Initial inspection

We have carefully inspected the Advantech CAN card mechanically and electrically before shipping. It should be free of marks and scratches and in perfect working order upon receipt. As you unpack the card, check it for signs of shipping damage (damaged box, scratches, dents, etc.). If it is damaged or it fails to meet specifications, notify our service department or your local representative immediately. Also notify the carrier. Retain the shipping carton and packing material for inspection by the carrier. After inspection we will make arrangements to repair or replace the unit. When you handle the CAN card, remove it from its protective packaging by grasping the rear metal panel. Keep the anti-vibration packing. Whenever you remove the card from the PC, store it in this package for protection.

Warning! Modern electronic devices are very sensitive to damage from static electricity. Ground yourself before you touch the card. We recommend that you use a grounded wrist strap and place the card on a static dissipative mat whenever you work with it. At the very least, touch the back of the grounded chassis of the system unit (metal) before you handle the board. Avoid contact with materials that hold a static charge, such as styrofoam. Do not touch the exposed circuit connectors.

Jumper and switch locations of PCL 841

Jumper & Switch Locations of PCM 3680


installation

PCL-841 & PCM-3680 Card configuration

The PCL-841(or PCM-3680) has two ports, each with one jumper. The jumpers set the IRQ for the ports, which can be configured separately. A DIP switch sets the memory base address for each port. The following chart shows the function of the jumper and the switches (see the previous page for jumper and switch locations).

Switch and jumper functions
CAN controllers
JP1 Port 1
JP2 Port 2
Memory base address
SW1 Port 1, Port 2

Default settings

Port 1 is set for COM1 (IRQ=12, Memory address=DA00:0000).

Port 2 is set for COM2 (IRQ=15, Memory address=DA00:0200).

If you need to change these settings, see the following sections.

Otherwise, you can simply install the card. Note that you will need to disable your CPU card's on-board COM ports, if any, or set them to alternate addresses/IRQs.

Interrupt (IRQ) setup (JP1 and JP2)

Jumpers JP1 and JP2 set the interrupts for Port 1 and Port 2, respectively. You can choose any IRQ from 3 to 15, except 8, 13 and 14. When you choose IRQs, make sure they are not used for other cards in the system. The following figures show the card's default settings.

Memory base address (SW1)

The memory base address for the PCL-841(or PCM-3680), which requires 4 KB of address space, is made up of the memory segment and its associated offset. The address for the memory segment is set through SW1, a six position DIP switch. You can choose any base address from C800 to EF00. The following table shows the DIP switch settings and the corresponding base addresses.

Memory address configuration (SW1)
Address/DIP switch | A12 | A13 | A14 | A15 | A16 |
C800H | on | on | on | off | on | on
C900H | off | on | on | off | on | on
CA00H | on | off | on | off | on | on
CB00H | off | off | on | off | on | on
CC00H | on | on | off | off | on | on
CD00H | off | on | off | off | on | on
CE00H | on | off | off | off | on | on
CF00H | off | off | off | off | on | on
D000H | on | on | on | on | off | on
D100H | off | on | on | on | off | on
D200H | on | off | on | on | off | on
D300H | off | off | on | on | off | on
D400H | on | on | off | on | off | on
D500H | off | on | off | on | off | on
D600H | on | off | off | on | off | on
D700H | off | off | off | on | off | on
D800H | on | on | on | off | off | on
D900H | off | on | on | off | off | on
DA00H | on | off | on | off | off | on
DB00H | off | off | on | off | off | on
DC00H | on | on | off | off | off | on
DD00H | off | on | off | off | off | on
DE00H | on | off | off | off | off | on
DF00H | off | off | off | off | off | on
E000H | on | on | on | on | on | off
E100H | off | on | on | on | on | off
E200H | on | off | on | on | on | off
E300H | off | off | on | on | on | off
E400H | on | on | off | on | on | off
E500H | off | on | off | on | on | off
E600H | on | off | off | on | on | off
E700H | off | off | off | on | on | off
E800H | on | on | on | off | on | off
E900H | off | on | on | off | on | off
EA00H | on | off | on | off | on | off
EB00H | off | off | on | off | on | off
EC00H | on | on | off | off | on | off
ED00H | off | on | off | off | on | off
EE00H | on | off | off | off | on | off
EF00H | off | off | off | off | on | off

Memory area

Once the memory segment for the base address is selected, the offset will be automatically assigned for Port 1, Port 2, and hardware reset. The following table shows the base addresses of the CAN controllers.

Base address (hex) | CAN controller
base:0000h - base:00FFh | Basic- Port 1
base:0100h - base:01FFh | HW reset Basic - Port 1
base:0200h - base:02FFh | Basic- Port 2
base:0300h - base:03FFh | HW reset Basic - Port 2
base:0400h - base:0FFFh | Not used


softwareprogramming

Software Programming Library functions

Quick reference table

The following table lists the available functions and their corresponding syntax and descriptions.

Function | Syntax (in C) | Description | Product Support List
 |  |  | PCL-841/PCM-3680 | PCI-1680/MIC-3680/UNO-2052
1 | CANCheckEvent() | Check event status from kernel-mode and clear event. | Yes | Yes
2 | CANEnableEvent() | Enable or disable the event mechanism. | Yes | Yes
3 | CANEnableMessageint() | Select the data transmit interrupt. | Yes | No
4 | CANEnableRxInt() | Enable the receive interrupt. | Yes | Yes
5 | CANGetArbitrationLostCatchMsgEx() | Get arbitrate lost catch information | Yes | No
6 | CANGetBaudRate() | Get the card baud rate. | Yes | Yes
7 | CANGetControllerErrorCodeEx() | Get Controller error code. | Yes | No
8 | CANGetErrorMessage() | Get error message. | Yes | Yes
9 | CANGetEventName() | Queries and get Can port's event name. | Yes | Yes
10 | CANGetProtocolType() | Get the card current protocol type. | Yes | Yes
11 | CANHwReset() | Reset the hardware. | Yes | Yes
12 | CANInit() | Controls CAN port settings. | Yes | Yes
13 | CANInpb() | Inputs a byte data from the specified address on CAN card. | Yes | No
14 | CANOutpb() | Outputs a byte data to the specified address on CAN card. | Yes | No
15 | CANPortClose() | Release settings, close port. | Yes | Yes
16 | CANPortOpen | Open the CAN port. | Yes | Yes
17 | CANQueryID() | Query the message ID. | Yes | No
18 | CANQueryMsg() | Query the message ID. | Yes | No
19 | CANReadFile() | Reads data. | Yes | Yes
20 | CANReset() | Reset CAN port. | Yes | Yes
21 | CANSendMsg() | Sends message. | Yes | No
22 | CANSetAcp() | Send the card 2.0A protocol acceptance code. | Yes | Yes
23 | CANSetAcpEx() | Set the card 2.0B protocol acceptance code. | Yes | Yes
24 | CANSetBaud() | Set card baud rate. | Yes | Yes
25 | CANSetBufferPtr() | Set the data receive buffer | Yes | Yes
26 | CANSetCountPtr() | Set the counter of receive buffer. | Yes | Yes
27 | CANSetIntrMaskEx() | Set 2.0B protocol interrupt mask. | Yes | Yes
28 | CANSetNormal() | Set CAN card to normal mode. | Yes | Yes
29 | CANSetOutCtrl() | Set the card out control register. | Yes | Yes
30 | CANSetProtocolType() | Set the card current protocol type. | Yes | Yes
31 | CANWaitForFIFOEvent() | Wait for the FIFO buffer event. | Yes | Yes
32 | CANWaitForID() | Wait for the message ID. | Yes | No
33 | CANWaitForMsg() | Queries and gets message from CAN bus. | Yes | No
34 | CANWakeUpEx() | Set CAN controller into sleep mode. | Yes | No
35 | CANWriteFile() | Send message | Yes | Yes
36 | CANGetAddress() | Returns a pointer or address of a variable. | Yes | Yes
37 | CANSelectDevice() | Show device list tree dialog box for select device's number. | Yes | Yes

Note: Function highlighted in yellow are not supported by PCI-1680, MIC-3680 and UNO-2052.


cancheckevent

LRESULT CANCheckEvent
(
    USHORT Port,
    DWORD Milliseconds
)

Purpose

Check event status from kernel-mode and clear event.

Parameters :

Name | Direction | Type | Range | Description
Port | Input | Unsigned Short | default | Specify the port number
Milliseconds | Input | DWORD | default | the interval that wait for the system event.

Return

SUCCESS if successful
EventTimeOut if wait for event time is out


canenableevent

LRESULT CANEnableEvent
(
    WORD Port,
    BOOL Enabled
)

Purpose

Enable or disable the event mechanism.

Parameters :

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number
Enabled | Input | BOOL | default | True if enabled. A related event is set by the user.

Return

SUCCESS if successful
CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANPortIsNotOpened if port is not opened


canenablemessaging

LRESULT CANEnableMessaging
(
    WORD Port,
    WORD Type,
    BOOL Enabled,
    HWND AppWnd
    UCHAR FAR *RcvBuf
)

The function is only for PCL-841 card and PCM-3680 card.

Purpose

Enable/Disable message passing from driver to user application at transmit data complete, receiving message or error occurring on CAN card. User can use these messages to take necessary actions. Please refer to MSDN for Windows message format. The message and parameters has showed following, the maximum client applications to receive the messages are 10.

Type Message | WParam | lParam
0 | WM_CANTRANSMITCOMPLETE | Port number no use
1 | WM_CANMESSAGE | Port number Pointer, point to the receiving buffer (RcvBuf)
2 | WM_CANERROR | Port number no use

Parameters :

Name | Direction | Type | Range | Description
Port | Input | Unsigned Short | default | Specify the port number
Type | Input | WORD | 0~2 | Specify the message is for transfer, receive or error Type = 0 is set for Transmit complete Type = 1 is set for Receive data Type = 2 is set for Error occurring
Enabled | Input | BOOL | default | Sets Enabled = FALSE, then driver will not send message to user application at receiving any message from CAN card. Sets Enabled = TRUE, then driver will send message to user application at receiving any message from CAN card.
AppWnd | Input | HWND | default | The application window handle that receives the messages from driver. This field is only used for Enabled = TRUE.
RcvBuf | Input | UCHAR FAR * | default | Receive buffer pointer for Receive message.

Return

SUCCESS if successful
CANInvalidInputParam if invalid input parameters
CANEnableMessagingFailed if enable messaging fail


CANEnableRxInt

LRESULT CANEnableRxInt
(
    WORD Port,
)

Purpose

If this function is called, the related port's receive interrupt bit will be set. So the system can be notified if the data arrived at the port.

Parameters :

Name | Direction | Type | Range | Description
Port | Input | Unsigned Short | default | Specify the port number

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANPortIsNotOpened if port is not opened


CANGetAddres

DWORD CANGetAddres
(
    LPVOID lpVoid
)

Purpose

This function is only used in Visual Basic. It returns a pointer or address of a variable.
Declare Function CANGetAddress Lib "adscan.dll" (lpVoid As Any) As Long

Parameters

Name | Direction | Type | Range | Description
lpVoid | Input | LPVOID | default | The variable name

Return

return the address of a variable.


CANGetArbitrationLostCatchMsgEx

LRESULT CANGetArbitrationLostCatchMsgEx
(
    WORD Port,
    LPT_ArbitrationLostCatch lpssArbLostCatch
)

The function is only for PCL-841 card and PCM-3680 card.

Purpose

Get arbitrate lost catch information.

Parameters

Name | Direction | Type | Range | Description
Port | Input | Unsigned Short | default | Specify the port number
lpssArbLostCatch | Output | LPT_ArbitrationLostCatch | default | stored the error code

NOTE: LPT_ArbitrationLostCatch’s structure is as follow,

typedef struct tag_PT_ArbitrationLostCatch
{
    WORD wLostCode; // Arbitration Lost code
    UCHAR uchErrorCode; // value of Arbitration Lost catch register
    UCHAR auchErrMsg[ 128 ];
} FAR* LPT_A} FAR* LPT_ArbitrationLostCatch;

Return

SUCCESS if successful

CANInvalidInputParam if invalid input parameters

CANResetFailed if CAN reset failed


CANGetBaudRate

LRESULT CANGetBaudRate
(
    WORD Port,
    WORD *wBaudRate
)

Purpose

Get the baud rate for CAN card from registry, this value was set in the Advantech Device Manager setup dialog box.

Parameters :

Name | Direction | Type | Range | Description
Port | Input | Unsigned Short | default | Specify the port number.
wBaudRate | Output | WORD * | default | The baud rate.

Return

SUCCESS if successful

returns a no zero value if unsuccessful


CANGetControllerErrorCodeEx

LRESULT CANGetControllerErrorCodeEx
(
    WORD Port,
    LPT_ErrorCodeCatch lpssErrorCodeCatch
)

The function is only for PCL-841 card and PCM-3680 card.

Purpose

Get CAN 2.0B controller error type.

Parameters

Name | Direction | Type | Range | Description
Port | Input | Unsigned Short | default | Specify the port number
lpssErrorCode Catch | Output | LPT_ErrorCodeCatch | default | Save the value of error code catch register and explain error code

Note: the LPT_ErrorCodeCatch's structure is as follow,

typedef struct tag_PT_ErrorCodeCatch
{
    WORD wErrorType; // error type
    WORD wDirection; // error direction
    WORD wErrorDesc; // error description code
    UCHAR uchErrorCode; // value of error catch register
    UCHAR auchErrMsg[ 128 ];
} FAR* LPT_ErrorCodeCatch;

Return

SUCCESS if successful
CANInvalidInputParam if invalid input parameters

CANResetFailed if CAN reset failed


CANGetErrorMessage

LRESULT CANGetErrorMessage
(
    LRESULT lError,
    PUCHAR puchErrMsg
)

Purpose

From return code of function to its really meaning.

Parameters :

Name | Direction | Type | Range | Description
lError | Input | LRESULT | default | the CAN error code
puchErrMsg | Output | PUCHAR | default | the error's really meaning

Return

SUCCESS if successful

CANInvalidInputParam if invalid input parameters

CANResetFailed if CAN reset failed

Example:

In this example we want to close the CAN port 0.

#include "canbus2.0.h"
main()
{
    LRESULT lCode;
    WORD m_Port=0;
    UCHAR auchTemp[ 128 ];
    string CanError;
    //do initialize works
    ......
    //transmit data
    ......
    //close the port
    lCode = CANPortClose( m_Port );
    CANGetErrorMessage( lCode, auchTemp );
    CanError = auchTemp;
    Printf("%s", CanError);
}


CANGetEventName

LRESULT CANGetEventName
(
    WORD Port,
    CHAR *EventName
)

Purpose

Queries and gets CAN port's event name.

Parameters :

Name | Direction | Type | Range | Description
Port | Input | Unsigned Short | default | Specify the port number
EventName | Output | CHAR * | default | Data buffer for Event Name.

Return

SUCCESS if successful

If unsuccessful, returns a no zero data.


CANGetProtocolType

LRESULT CANGetProtocolType
(
    WORD wPort,
    WORD *pwProtocolType
)

Purpose

Get the current data transmit protocol type (2.0A or 2.0B).

Parameters

Name | Direction | Type | Range | Description
Port | Input | Unsigned Short | default | Specify the port number
pwProtocolType | Output | WORD * | default | If the function is called successfully, this parameter will store the current data transmit protocol type (2.0A or 2.0B).

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANPortIsNotOpened if port is not opened


CANHwReset

LRESULT CANHwReset
(
    WORD Port
)

Purpose

Sets hardware reset Basic.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANHwResetFailed if sets hardware reset basic failed


CANInit

LRESULT CANInit
(
    WORD Port,
    WORD BTR0,
    WORD BTR1,
   UCHAR ucMask
)

Purpose

Initializes CAN cards

Set baud rate

Install interrupt service routine

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number
BTR0,BTR1 | Input | WORD | default | The baud rate must be coordinated with the CAN network.Only low bytes of the two parameters are written to the Bus Timing Register 0/1 on CAN card. For example, if you want to set baud rate = 250 K for DeviceNet Protocol, you have to set BTR0 = 0x01, and BTR1 = 0x1c.
ucMask | Input | UCHAR | default | The mask value for interrupt enable

Note: the ucMask's value is as follow,

Bit | Interrupt Type | Value | Function
7 | - | - | Reserved
6 | - | - | Reserved
5 | - | - | Reserved
4 | - | - | Reserved
3 | Overrun Interrupt Enable | 1 | enabled; if the data overrun bit is set, the card gives an overrun interrupt signal
 |  | 0 | disabled; the card gives no overrun interrupt signal
2 | Error Interrupt Enable | 1 | enabled; if the error or bus status change, the card gives an error interrupt signal
 |  | 0 | disabled; the card gives no error interrupt signal
1 | Transmit Interrupt Enable | 1 | enabled; when a message has been successfully transmitted or the transmit buffer is accessible again,the card gives a transmit interrupt signal to the user.
 |  | 0 | disabled; the card gives no transmit interrupt signal
0 | Receive Interrupt Enable | 1 | enabled; when a message has been received without errors, the card gives a receive interrupt signal to the user.
 |  | 0 | disabled; the card gives no transmit interrupt signal.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANInitFailed if CAN initialization failed


CANInpb

LRESULT CANInpb
(
    WORD Port,
    WORD Offset,
    UCHAR FAR *Data
)

Purpose

Inputs a byte data from the specified address on CAN card.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
Offset | Input | WORD | default | Specify the offset from the starting address of the mapped memory.
Data | Input | UCHAR FAR * | default | The storage for input data.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANInpbFailed if CAN read failed


CANOutpb

LRESULT CANOutpb
(
    WORD Port,
    WORD Offset,
    UCHAR Value
)

Purpose

Outputs a byte data to the specified address on CAN card.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number
Offset | Input | WORD | default | Specify the offset from the starting address of the mapped memory
Value | Output | UCHAR | default | Output value

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANOutpbFailed if CAN write failed


CANPortClose

LRESULT CANPortClose
(
    WORD wPort
)

Purpose

Close opened CAN port.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number

Return

SUCCESS if successful

If unsuccessful, returns a no zero data.


CANPortOpen

LRESULT CANPortOpen
(
    WORD wDevNum,
    WORD *wPort,
    WORD *wHostID,
    WORD *wBaudRate
)

Parameter

wDevNum (IN) | Device's number
wPort (IN) | Port's number, select the port you want to reset
Port = 0 | is set for PORT1
Port = 1 | is set for PORT2
wHostID | Port's host ID
wBaudRate | Port's Baud Rate

Function Description

Open CAN device driver

Open CAN port

Returns

Returns 0 if successful. If unsuccessful, returns an error code.

Possible Error Codes Returned

CANOpenFailed "CAN Open Failed"

Purpose

Open CAN port

Parameters

Name | Direction | Type | Range | Description
wDevNum | Input | WORD | default | Device's number
wPort | Output | WORD * | default | Specify the port number
wHostID | Output | WORD * | default | Port's host ID
wBaudRate | Output | WORD * | default | Port's Baud Rate

Return

SUCCESS if successful

CANOpenFailed if CAN open failed

Example:

int main()
{
    UINT m_DevNum = 0;
    UINT m_nPort;
    UINT m_nHostID;
    UINT m_nPreBaudRate;

    if (CANPortOpen(
        m_DevNum,
        (WORD *) &m_nPort,
        (WORD *) &m_nHostID,
        (WORD *) &m_nPreBaudRate) != SUCCESS)
    {
        printf("CAN Open failed!\n");
        return 0;
    }
    printf("Host ID=%d\n",m_nHostID);

}


CANQueryID

LRESULT CANQueryID
(
    WORD Port,
    BOOL FAR *Ready,
    UCHAR FAR *IDBuf
)

This function is only for PCL-841 card and PCM-3680 card.

Purpose

Queries and gets message ID from CAN bus.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number
Ready | Output | BOOL FAR * | default | Ready = FALSE if there is no message on CAN bus Ready = TRUE if driver gets message from CAN bus
IDBuf | Output | UCHAR FAR * | default | Used to store message ID.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANQueryMsgFailed if query message ID failed


CANQueryMsg

LRESULT CANQueryMsg
(
    WORD Port,
    BOOL FAR *Ready,
    UCHAR FAR *RcvBuf
)
This function is only for PCL-841 card and PCM-3680 card.

Purpose

Queries and gets message from CAN bus. This function allow user query message without enable receive interrupt. If user want receive data by interrupt mode, then he should use CANReadFile() function.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number
Ready | Output | BOOL FAR * | default | Ready = FALSE if there is no message on CAN bus Ready = TRUE if driver gets message from CAN bus.
RcvBuf | Output | UCHAR FAR * | default | Data buffer for receiving. This field is valid if Ready = TRUE. The minimum buffer length is 10 bytes. User program has to allocate this buffer by itself and pass its address to the driver.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANQueryMsgFailed if query message failed


CANReadFile

LRESULT CANReadFile
(
    WORD Port,
    DWORD NumNeeded,
    PVOID FAR RcvBuf,
    PDWORD pNumReturned
)

Purpose

Read the received data from receive buffer. This function allow user receive data by interrupt way.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number
NumNeeded | Input | DWORD | default | The message number that should be read from buffer
RcvBuf | OutPut | PVOID FAR | default | The receive buffer that the transmit data stored
pNumReturned | Output | PDWORD | default | If pNumReturned = 0, the function is called unsuccessful. Else its value is the received message number.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANPortIsNotOpened if port is not opened

Example:

#include "canbus2.0.h"
typedef struct
{
    UCHAR rtr;
    ULONG id;
    UCHAR dlen;
    UCHAR data[8];
} CAN_MSG_T;

main( )
{
    CAN_MSG_T msg;
    DWORD cbReturned = 0;
    int nLength;
    WORD m_wProtocolType;
    UINT m_Port;
    string m_RxBuf;
    // do some initiate works
    ......
    // read the data from receive buffer

if ( m_wProtocolType = = CANBUS_PROTOCOL_20A )
{
    CANReadFile( m_Port, 1, &msg, &cbReturned );
    if ( cbReturned )
    {
       m_RxID = msg.id;

       // get receive data length

       nLength = msg.dlen;
       if ( msg.dlen!= 0 )
       {
          printf( "%s", (PUCHAR)msg.data );
       }
    }
  }
}


CANReset

LRESULT CANReset
(
    WORD Port,
)

Purpose

Resets physical memory access if all ports are reset.

Resets CAN card if all ports are reset.

Reinstalls interrupt service routine for this port.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANResetFailed if CAN reset failed


CANSelectDevice

LRESULT CANSelectDevice
(
    HWND hCaller,
    BOOL GetModule,
    ULONG *DeviceNum,
    UCHAR *Description
)

Purpose

Show device list tree dialog box for select device's number.

Parameters

Name | Direction | Type | Range | Description
hCaller | Input | HWND (window handle) | Default | Specify the Windows handle that is calling this function.
GetModule | Input | BOOL | TRUE / FALSE | Specify the function to select module from registry list or not (TRUE to select module from registry list).
DeviceNum | Output | pointer to unsigned long | 0-65535 | Return the device number that was get by this function.
Description | Output | pointer to unsigned char | Default | Return the description of the device.

Return

If successful, then return 0.

If unsuccessful, then return 1.


CANSendMsg

LRESULT CANSendMsg
(
    WORD Port,
    UCHAR FAR *TxBuf,
    BOOL Wait
)

This function is only for PCL-841 card and PCM-3680 card.

Purpose

Sends message to CAN bus.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number
TxBuf | Input | UCHAR FAR * | default | Data buffer for transmission. The maximum buffer length is 10 bytes. The data format refers to the transmitting buffer in hardware manual of CAN.
Wait | Input | BOOL | default | Wait = FALSE, the CAN driver will return to caller process immediately no wait data transmit complete; Wait = TRUE, the CAN driver will return caller process until data transmit complete or time out occurring.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANPortIsNotOpened if port is not opened


CANSetAcp

LRESULT CANSetAcp
(
    WORD Port,
    WORD Acp,
    WORD Mask
)

Purpose

Sets acceptance code register and mask register. With the help of the acceptance filter the CAN controller is able to allow passing of received messages to the RX FIFO only when the identifier bits of the received message are equal to the predefined ones within the acceptance filter registers. The acceptance filter is defined by the acceptance code register (ACR) and the acceptance mask register (AMR).

Specifies the value of the 8 most significant bits of the identifier (ID 10 ... ID 3), this register can be accessed (read/write), if the reset request bit is set HIGH (present). When a message is received which passes the acceptance test and there is receive buffer space left, then the respective descriptor and data field are sequentially stored in the RXFIFO.

The acceptance code bits (AC.7 to AC.0) and the eight most significant bits of the message is identifier (ID.10 to ID.3) must be equal to those bit positions which are marked relevant by the acceptance mask bits (AM.7 to AM.0). If the conditions as described in the following equation are fulfilled, acceptance is given:

[(ID.10 to ID.3) =(AC.7 to AC.0)] ^(AM.7 to AM.0)=11111111

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number
Acp | Input | WORD | default | Acceptance code
Mask | Input | WORD | default | Acceptance Mask

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANSetAcpFailed if set acceptance or mask failed


CANSetAcpEx

LRESULT CANSetAcpEx
(
    WORD Port,
    LPT_FilterSetting lpssFilter
)

Purpose

Sets acceptance code register and mask register, its usage is the same as CANSetAcp()

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number
lpssFilter | Input | LPT_FilterSetting | default | the accept code and accept mask setting value.

Note: LPT_FilterSetting's structure is as follows:

typedef struct tag_PT_FilterSetting

{
    //filter type: 0 - two 2-bytes accept code and accept mask
    // 8 - a 4-bytes accept code and accept mask
    DWORD dwFilterType;
    UCHAR uchAcceptCode0;
    UCHAR uchAcceptCode1;
    UCHAR uchAcceptCode2;
    UCHAR uchAcceptCode3;
    UCHAR uchAcceptMask0;
    UCHAR uchAcceptMask1;
    UCHAR uchAcceptMask2;
    UCHAR uchAcceptMask3;
} FAR *LPT_FilterSetting;

Two different filter modes are selectable by dwFilterType:

  • Single filter mode (dwFilterType ＝ 8, PELICAN_SINGLE_FILTER)
  • Dual filter mode (dwFilterType ＝ 0, PELICAN_DOUBLE_FILTER).

Single filter configuration

In this filter configuration one long filter (4-bytes) could be defined. The bit correspondences between the filter bytes and the message bytes depend on the currently received frame format.

Standard frame: if a standard frame format message is received, the complete identifier including the RTR bit and the first two data bytes are used for acceptance filtering. Messages may also be accepted if there are no data bytes existing due to a set RTR bit or if there is none or only one data byte because of the corresponding data length code. For a successful reception of a message, all single bit comparisons have to signal acceptance.

Extended Frame: if an extended frame format message is received, the complete identifier including the RTR bit is used for acceptance filtering. For a successful reception of a message, allExtended Frame: if an extended frame format message is received, the complete identifier including the RTR bit is used for acceptance filtering. For a successful reception of a message, all single bit comparisons have to signal acceptance.

Dual filter configuration

In this filter configuration two short filters (2-bytes) can be defined. A received message is compared with both filters to decide, whether this message should be copied into the receive buffer or not. If at least one of the filters signals an acceptance, the received message becomes valid. The bit correspondences between the filter bytes and the message bytes depend on the currently received frame format.

Standard frame: if a standard frame message is received, the two defined filters are looking different. The first filter compares the complete standard identifier including the RTR bit and the first data byte of the message. The second filter justStandard frame: if a standard frame message is received, the two defined filters are looking different. The first filter compares the complete standard identifier including the RTR bit and the first data byte of the message. The second filter just compares the complete standard identifier including the RTR bit. For a successful reception of a message, all single bit comparisons of at least one complete filter have to signal acceptance. In case of a set RTR bit or a data length code of logic 0 no data byte is existing. Nevertheless a message may pass filter 1, if the first part up to the RTR bit signals acceptance. If no data byte filtering is required for filter 1, the four least significant bits of AMR1 and AMR3 have to be set to logic 1 (don't care). Then both filters are working identically using the standard identifier range including the RTR bit.

Extended frame: if an extended frame message is received, the two defined filters are looking identically. Both filters are comparing the first two bytes of the extended identifier range only. For a successful reception of a message, all single bit comparisons of at least one complete filter have to indicate acceptance.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANSetAcpFailed if set acceptance or mask failed


CANSetBaud

LRESULT CANSetBaud
(
   WORD Port,
   WORD BTR0,
   WORD BTR1
)

Purpose

Configures the baud rate for CAN card.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
BTR0, BTR1 | Input | WORD | default | The baud rate must be coordinated with the CAN network. Only low bytes of the two parameters are written to the Bus Timing Register 0/1 on CAN card.

Note: Follow the table below to configure baud rate for DeviceNet Protocol,

Baud Rate | BTR0 | BTR1
125k | 0x03 | 0x1c
250k | 0x01 | 0x1c
500k | 0x00 | 0x1c
800k | 0x00 | 0x07
1000k | 0x00 | 0x05

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANSetBaudFailed if set baud rate failed


CANSetBaud

LRESULT CANSetBufferPtr
(
    WORD Port,
    PVOID FAR pOutputBuffer,
    ULONG PackNum,
    BOOL FAR *Ready
)

Purpose

This function is used to lock a block of memory to receive the transmitted data. If user calls this function, the transmitted data will be automatically filled in the locked memory when the data arrived at the card port. The user only needs to read the memory to get the data. Compare to the CANReadFile and CANQueryMsg functions, this function is used to high speed data transmitting.

Parameters
Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
pOutputBuffer | Input | PVOID FAR | default | this pointer is set by caller, it points to the buffer that can receive transmit data
PackNum | Input | ULONG | default | the number of the message the caller wants to send.
Ready | Output | BOOL FAR * | default | this parameter will be set true if the function is successful called and the system allocate a buffer used to store received data.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANPortIsNotOpened if port is not opened

Example:

#include "canbus2.0.h"
typedef struct
{
    UCHAR rtr;
    ULONG id;
    UCHAR dlen;
    UCHAR data[8];
} CAN_MSG_T;
CAN_MSG_T * g_pData;

#define BUFFER_SIZE 10000 // want to receive 10000 messages
main( )
{
    BOOL bReady = FALSE;
    WORD wDataLen;
    WORD m_wProtocolType;
    ULONG g_Index;
    //do some initiate works
    ......
    //set receive buffer
    g_pData = ( PCAN_MSG_T )GlobalAlloc( GPTR, 10000*sizeof(CAN_MSG_T) );
    // lock the memory
    GlobalLock( g_pData );
    CANSetBufferPtr( m_nPort, g_pData, BUFFER_SIZE, &bReady );
    if ( !bReady )
       {
         printf("CAN set bufferptr error!");
       }
       CANSetCountPtr( m_nPort, &g_Index, &bReady );
    if ( !bReady )
       {
         printf ("CAN set CountPtr error!");
       }
    //do other works
    ......

    //read the received data
    CANWaitForFIFOEvent( nPort, INFINITE, &bReady); //wait the buffer half full
    Sleep(10);
    if ( bReady )
       {
         printf( " Receive Data Buffer half full!" );
         printf("Received data index = %d, g_Index);
         bReady=FALSE;
       }
    CANWaitForFIFOEvent( nPort, INFINITE, &bReady); //wait the buffer full
    if ( bReady )
       {
         printf( " Receive Data Finished! Below is Data:" );
           for ( int i = 0; i < 10000; i++ )
                 {
                   printf("RECV : ID = %u, Len = %u, %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH",
                   g_pData[i].id,
                   g_pData[i].dlen,
                   g_pData[i].data[0],
                   g_pData[i].data[1],
                   g_pData[i].data[2],
                   g_pData[i].data[3],
                   g_pData[i].data[4],
                   g_pData[i].data[5],
                   g_pData[i].data[6],
                   g_pData[i].data[7]);

                 }
        }

}


CANSetCountPtr

LRESULT CANSetCountPtr
(
    WORD Port,
    PULONG FAR pCountBuffer,
    BOOL FAR *Ready
)

Purpose

This function is used to lock a block of memory to count the transmitted data. If user calls this function, the transmitted data will be automatically counted by pCountBuffer when the data arrived at the card port. The user only needs to read the pCountBuffer to get the data index. This function is always used with CANSetBufferPtr.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
pCountBuffer | Input | PULONG FAR | default | this pointer is set by caller, it points to the buffer that can receive transmit data
Ready | Output | BOOL FAR * | default | this parameter will be set true if the function is successful called and the system allocate a counter used to index the received data.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANPortIsNotOpened if port is not opened


CANSetIntrMaskEx

LRESULT CANSetIntrMaskEx
(
    WORD Port,
    UCHAR uchInterruptMask
)

Purpose

Mask controller's interrupt of 2.0B protocol, its value is as follow:

Bit | Interrupt Type | Value | Function
7 | Bus error interrupt enable | 1 | enabled; if an bus error has been detected, the CAN controller requests the respective interrupt.
 |  | 0 | disabled
6 | Arbitration Lost Interrupt enable | 1 | enabled; if the CAN controller has lost arbitration, the respective interrupt is requested.
 |  | 0 | disabled
5 | Error Passive Interrupt enable | 1 | enabled; if the error status of the CAN controller changes from error active to error passive or vice versa, the respective interrupt is requested.
 |  | 0 | disabled
4 | Wake-Up Interrupt enable | 1 | enabled; if the sleeping CAN controller wakes up, the respective interrupt is requested.
 |  | 0 | disabled
3 | Data Overrun Interrupt enable | 1 | enabled; if the data overrun status bit is set , the CAN controller requests the respective interrupt.
 |  | 0 | disabled
2 | Error Warning Interrupt enable | 1 | enabled; if the error or bus status change, the CAN controller requests the respective interrupt.
 |  | 0 | disabled.
1 | Transmit Interrupt enable | 1 | enabled; when a message has been successfully transmitted or the transmit buffer is accessible again, the CAN controller requests the respective interrupt.
 |  | 0 | disabled
0 | Receive Interrupt enable | 1 | enabled; when the receive buffer status is "full", the CAN controller requests the respective interrupt.
 |  | 0 | disabled

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
uchInterruptMask | Input | UCHAR | default | the interrupt mask value

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANResetFailed if CAN reset failed


CANSetNormal

LRESULT CANSetNormal
(
    WORD Port,
)

Purpose

Sets CAN card to normal mode.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANSetNormalFailed if set normal mode failed


CANSetOutCtrl

LRESULT CANSetOutCtrl
(
    WORD Port,
    WORD OutCtrl
)

Purpose

Set the output control register.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
OutCtrl | Input | WORD | default | Output control type

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANSetOutCtrlFailed if set output control register failed


CANSetProtocolType

LRESULT CANSetProtocolType
(
    WORD Port,
    WORD wProtocolType
)

Purpose

Set the data transmit protocol type (2.0A or 2.0B).

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
wProtocolType | Input | WORD | default | This parameter will store the data transmit protocol type (2.0A or 2.0B) that user want to use. "0" represent 2.0A and "1" represent 2.0B

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANPortIsNotOpened if port is not opened

CANPortInitializedAlready if port is initialized already and current operation cannot completed


CANWaitForFIFOEvent

LRESULT CANWaitForFIFOEvent
(
    WORD Port,
    ULONG timeout,
    BOOL * bReady
)

Purpose

This function can notify whether the received buffer is half full. If the received buffer is half full the system will create an event, and the function can catch the event and the parameter "bReady" will be set true.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
timeout | Input | ULONG | default | This parameter specifies how long should the user wait for a system event, which can notify user the receive buffer is half full
bReady | Output | BOOL * | default | If received a system event, bReady will be set true, else it will be set false.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANTimeout if wait for event timeout

Example:

#include "windows.h"
#include "stdio.h"
#include "canbus2.0.h"

typedef struct
{
    UCHAR rtr; //Remote Transmit Request
    ULONG id;
    UCHAR dlen;
    UCHAR data[8];
} CAN_MSG_T, *PCAN_MSG_T;

PCAN_MSG_T g_pData;
ULONG g_Index = 0;

int main()

{
    UINT m_DevNum = 1;
    UINT m_nPort;
    UINT m_nHostID;
    UINT m_nPreBaudRate;
    BOOL bReady = FALSE;

    if (CANPortOpen)
        m_DevNum,
        (WORD *) &m_nPort,
        (WORD *) &m_nHostID,
        (WORD *) &m_nPreBaudRate) != SUCCESS)
    {
        printf("Open port failed!\n");
        return 0;
    }
    // do some initiate works
    ......

    if (CANSetNormal(m_nPort) != SUCCESS)
    {
        printf("Set normal failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    CANEnableRxInt( m_nPort ); //enable receive interrupt
    g_pData = ( PCAN_MSG_T )GlobalAlloc( GPTR, 100*sizeof(CAN_MSG_T) );
    if( g_pData == NULL )
    {
        printf("Out of memory!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    // lock the memory
    GlobalLock( g_pData );
    bReady = FALSE;
    CANSetBufferPtr( m_nPort, g_pData, 100, &bReady );// set the receive buffer

    if ( !bReady )
    {
        printf("CanSetBufferPtr failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    CANEnableEvent( m_nPort, TRUE ); //enable system event
    printf("Open port successful, Begin to receive data!\n");
    bReady = FALSE;
    CANWaitForFIFOEvent( m_nPort, INFINITE, &bReady);// wait for the messages

    if ( bReady )
    {
        printf("Receive Data Buffer half full: \n" );
        for (int i = 0; i < 50; i++ )
        {
            printf("RECV : ID = %u, Len = %u, %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH\n",
            g_pData[i].id,
            g_pData[i].dlen,
            g_pData[i].data[0],
            g_pData[i].data[1],
            g_pData[i].data[2],
            g_pData[i].data[3],
            g_pData[i].data[4],
            g_pData[i].data[5],
            g_pData[i].data[6],
            g_pData[i].data[7]);
        }
    }
    CANPortClose(m_nPort);
    return 0;
}


CANWaitForID

LRESULT CANWaitForID
(
    WORD Port,
    UCHAR FAR *IDBuf,
    ULONG uTimeValue
)

This function is only for PCL-841 card and PCM-3680 card.

Purpose

Queries and gets message from CAN bus.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
IDBuf | Output | UCHAR FAR * | default | Store the message ID
uTimeValue | Input | ULONG | default | Used to set waiting time.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANWaitForMsgIDFailed if Wait For Message Failed

CANTimeout if wait ID time out


CANWaitForMsg

LRESULT CANWaitForMsg
(
    WORD Port,
    UCHAR FAR *RcvBuf,
    ULONG timeout
)

The function is only for PCL-841 card and PCM-3680 card.

Purpose

Queries and gets message from CAN bus. When the receive buffer receive data the system will give out an event. The CANWaitForMsg() function will catch the event so that it can notify the user the transmit data arrived.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
RcvBuf | Output | UCHAR FAR * | default | Data buffer for receiving. The minimum buffer length is 10 bytes. User program has to allocate this buffer by itself and pass its address to the driver.
timeout | Input | ULONG | default | Used to set waiting message time

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANWaitForMsgFailed if wait for message failed

CANTimeout if waiting time out

Example:

#include "canbus2.0.h"
typedef struct
{
    UCHAR rtr;
    ULONG id;
    UCHAR dlen;
    UCHAR data[8];
} CAN_MSG_T;

CAN_MSG_T g_Data;

main( )
{
    BOOL bReady = FALSE;
    WORD wDataLen;
    WORD m_wProtocolType
    WORD m_Port;
    UINT m_TimeOut;
    //do some initiate works
    ......
    //read the received data
    if ( !CANWaitForMsg(m_Port, g_Data, m_TimeOut)) // Wait for CAN message
    {
        // Get ID
        m_RxID = g_Data.id;
        // get receive data length
        wDataLen = g_Data.dlen;
        if ( g_Data.dlen ! = 0 )
        {
            printf( "%s", (PUCHAR)g_Data.data );
        }
     }
     else
     {
        printf("Wait for message is time out!");
     }
 }


CANWakeUpEx

LRESULT CANWakeUpEx
(
    WORD Port,
    BOOL bWakeUp
)

The function is only for PCL-841 card and PCM-3680 card.

Purpose

This function can wake up the controller or make it sleep.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
bWakeUp | Input | BOOL | default | bWakeUp = FALSE, can controller begin to sleep; bWakeUp = TRUE, we wake up can controller.

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10


CANWriteFile

LRESULT CANWriteFile
(
    WORD Port,
    BOOL FAR *Ready,
    PVOID FAR SendBuf
)

Purpose

Send the data in the SendBuf. If success the "Ready" will be set as true. Compared with the function CANSendMsg(), this function is based on system software interrupt mechanism so the data transmit speed is higher.

Parameters

Name | Direction | Type | Range | Description
Port | Input | WORD | default | Specify the port number.
Ready | Output | BOOL FAR * | default | Indicate the caller whether the card is ready to send data
SendBuf | Input | PVOID FAR | default | The data buffer that store the transmitting data

Return

SUCCESS if successful

CANInvalidPortIndex if port index is invalid, must from 1 to 10

CANPortIsNotOpened if port is not opened

Example:

#include "canbus2.0.h"
typedef struct
{
    UCHAR rtr;
    ULONG id;
    UCHAR dlen;
    UCHAR data[8];
} CAN_MSG_T;

main( )
{
    CAN_MSG_T msg;
    BOOL bReady = FALSE;
    WORD m_wProtocolType;
    UINT m_Port;
    //do some initiate works
    ......
    //read the data from receive buffer
    if ( m_wProtocolType == CANBUS_PROTOCOL_20A )
    {
        //initialize the msg
        ......
        //call the function to send data
        CANWriteFile( m_Port, &bReady,(PVOID)&msg);
        if (!bReady)
        {
            printf("Transmit Data time out!");
        }
    }
}


Examples to use the library functions

In this section we will give examples on how to use the functions to transmit data.


The sending part

#include "windows.h"
#include "canbus2.0.h"
#include "stdio.h"

typedef struct
{
    UCHAR rtr; //Remote Transmit Request
    ULONG id;
    UCHAR dlen;
    UCHAR data[8];
} CAN_MSG_T, *PCAN_MSG_T;

int main()
{
    UINT m_DevNum = 0;
    UINT m_nBtr0 = 0x03;
    UINT m_nBtr1 = 0x1c; //baudrate = 125k
    UINT m_nAcpCode = 0;
    UINT m_nAcpMask = 0xff;
    UINT m_nOutCtrlCode = 250;
    UINT m_nIntMask = 0;
    UINT m_nPort;
    UINT m_nHostID;
    UINT m_nPreBaudRate;
    UINT i;
    CAN_MSG_T msg;
    BOOL bReady = FALSE;

    if (CANPortOpen) //open the CAN port
    m_DevNum,
    (WORD *)&m_nPort,
    (WORD *) &m_nHostID,
    (WORD *) &m_nPreBaudRate) != SUCCESS)
    {
        printf("Open port failed!\n");
        return 0;
    }
    if (CANInit)
    m_nPort,
    m_nBtr0,
    m_nBtr1,
    (UCHAR) m_nIntMask) != SUCCESS)
    {
        printf("Init can failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    if (CANSetOutCtrl)
    m_nPort,
    m_nOutCtrlCode) != SUCCESS)
    {
        printf("Set out ctrl failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    if (CANSetAcp)
    m_nPort,
    m_nAcpCode,
    m_nAcpMask) != SUCCESS)
    {
        printf("Set acp code failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    if (CANSetBaud)
    m_nPort,
    m_nBtr0,
    m_nBtr1) != SUCCESS)
    {
        printf("Set baudrate failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    if (CANSetNormal(m_nPort) != SUCCESS)
    {
        printf("Set normal failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    printf("Open port successful, Press any key to begin send data!\n");
    getchar();
    msg.id = 0x51;
    msg.rtr = 0;
    msg.dlen = 8;
    for(i=0;i<8;i++)
    {
        msg.data[i] = i;
    }
    for (i = 0; i < 100; i++)
    {
        CANWriteFile(m_nPort, (BOOL *)&bReady, (PVOID)&msg ); //send the data
        if ( !bReady )
        {
            printf("CanWriteFile failed!\n");
            CANPortClose(m_nPort);
            return 0;
        }
        else
        {
            printf("Send Count = %d\n", i+1);
            printf("SEND : ID = %u, Len = %u, %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH\n",
            msg.id,
            msg.dlen,
            msg.data[0],
            msg.data[1],
            msg.data[2],
            msg.data[3],
            msg.data[4],
            msg.data[5],
            msg.data[6],
            msg.data[7]);
        }
    }
    CANPortClose(m_nPort);
    return 0;
}


The receiving part

#include "windows.h"
#include "canbus2.0.h"
#include "stdio.h"
typedef struct
{
    UCHAR rtr; //Remote Transmit Request
    ULONG id;
    UCHAR dlen;
    UCHAR data[8];
} CAN_MSG_T, *PCAN_MSG_T;

PCAN_MSG_T g_pData;
ULONG g_Index = 0;

int main()
{
    UINT m_DevNum = 1;
    UINT m_nBtr0 = 0x03;
    UINT m_nBtr1 = 0x1c; //baudrate = 125k
    UINT m_nAcpCode = 0;
    UINT m_nAcpMask = 0xff;
    UINT m_nOutCtrlCode = 250;
    UINT m_nIntMask = 0;
    UINT m_nPort;
    UINT m_nHostID;
    UINT m_nPreBaudRate;
    BOOL bReady = FALSE;
    if (CANPortOpen)
    m_DevNum,
    (WORD *)&m_nPort,
    (WORD *) &m_nHostID,
    (WORD *) &m_nPreBaudRate) != SUCCESS)
    {
        printf("Open port failed!\n");
        return 0;
    }
    if (CANInit)
    m_nPort,
    m_nBtr0,
    m_nBtr1,
    (UCHAR) m_nIntMask) != SUCCESS)
    {
        printf("Init can failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    if (CANSetOutCtrl)
    m_nPort,
    m_nOutCtrlCode) != SUCCESS)
    {
        printf("Set out ctrl failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    if (CANSetAcp)
    m_nPort,
    m_nAcpCode,
    m_nAcpMask) != SUCCESS)
    {
        printf("Set acp code failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    if (CANSetBaud)
    m_nPort,
    m_nBtr0,
    m_nBtr1) != SUCCESS)
    {
        printf("Set baudrate failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    if (CANSetNormal(m_nPort) != SUCCESS)
    {
        printf("Set normal failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    CANEnableRxInt( m_nPort ); //enable receive interrupt
    g_pData = ( PCAN_MSG_T )GlobalAlloc( GPTR, 100*sizeof(CAN_MSG_T) );
    if( g_pData == NULL )
    {
        printf("Out of memory!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    // lock the memory
    GlobalLock( g_pData );
    bReady = FALSE;
    CANSetBufferPtr( m_nPort, g_pData, 100, &bReady );// set the receive buffer
    if ( !bReady )
    {
        printf("CanSetBufferPtr failed!\n");
        CANPortClose(m_nPort);
        return 0;
    }
    CANEnableEvent( m_nPort, TRUE ); //enable system event
    printf("Open port successful, Begin to receive data!\n");
    bReady = FALSE;
    CANWaitForFIFOEvent( m_nPort, INFINITE, &bReady);// wait for the messages
    if ( bReady )
    {
        printf("Receive Data Buffer half full!\n" );
    }
    bReady = FALSE;
    CANWaitForFIFOEvent( m_nPort, INFINITE, &bReady);
    if ( bReady )
    {
        printf( "Receive Data Finished!Below is data:\n");
        for (int i = 0; i < 100; i++ )
    {
        printf("RECV : ID = %u, Len = %u, %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH %2.2XH\n",
        g_pData[i].id,
        g_pData[i].dlen,
        g_pData[i].data[0],
        g_pData[i].data[1],
        g_pData[i].data[2],
        g_pData[i].data[3],
        g_pData[i].data[4],
        g_pData[i].data[5],
        g_pData[i].data[6],
        g_pData[i].data[7]);
    }
}
CANPortClose(m_nPort);
return 0;
}


Examples Support List and Description

In the DAS CD, we provide some examples to demonstrate how to use the CAN cards. You can use them to test your cards. Also, you can develop your programs base on the programs we offer.

Here are the list of some examples written in Visual C++, Visual Basic, Delphi or Borland C++ Build.

Examples Name | Description | VC | VB | Delphi | BCB
CANMEx | Demo send and receive message between two ports. | √ | √ | √ | √
RECV | Demo receive message use interrupt function. It must be used with SEND. | √ | √ | √ | √
SEND | Demo send message use interrupt function. It must be used with RECV. | √ | √ | √ | √

Here are the list of examples and supported cards.

Cards | Examples Support List
PCL-841 | CANMEx | RECV & SEND
PCM-3680 | CANMEx | RECV & SEND
PCI-1680 | CANMEx | RECV & SEND
MIC-3680 | CANMEx | RECV & SEND
UNO-2052 | CANMEx | RECV & SEND

CANMEx example:

This demo is fit for sending (or receiving) a spot of messages between two CAN ports.

Item 1: Lists the basic information of the opened port.

Item 2: Provides two communication protocols, CAN 2.0A and CAN 2.0B.

Item 3: Be used for sending CAN messages. ID range is from 0 to 2,048 under CAN2.0A protocol, from 0 to 536,870,912 under CAN2.0B protocol.

Item 4: Be used for receiving CAN messages. 'Remote Frame' and 'Standard Frame' check boxes are read-only to display the status of received messages.

RECV example:

RECV and SEND are fit for sending (or receiving) a mass of messages between two CAN ports. When this demo receives 10,000 messages, some of the messages (No.1, 100, 200, 300, etc) will be displayed in the list box. Then you can compare the data with SEND.

Item 1: The total number of received messages. Click 'Clear Count' button to clear it.

Item 2: The number of receiving messages, which may increase automatically when receiving messages.

SEND example:

When this demo sends 10,000 messages, some of the messages (No.1, 100, 200, 300, etc) will be displayed in the list box.

Item 1: The number of messages will be sent after clicking 'Start' button.

Item 2: The number of sent messages, which may increase automatically when sending messages.


The API calling sequence

The following two graphs give the API functions calling flow of CAN PCL-841 driver, including 2.0A protocol and 2.0B protocol. It is recommend that you'd better follow the functions calling sequence, but you can also select your own functions flow if needed.


The API calling sequence

Wiring

Pin assignments

The following figure shows the pin assignments for the card's DB-9 connectors.

Termination resistor setup

Terminal resistors are factory installed to allow for impedance matching. These resistors can be enabled by utilizing jumpers number 9 and 10 (shown below). Jumper 9 enables the terminal resistor for port one, while jumper number 10 enables the terminal resistor for port two. The value of the resistor should equal the characteristic impedance of the signal wires (approximately 120 Q).

The following figure shows resistor placements.


CAN signal wiring

The CAN standard supports half-duplex communication. It means that just two wires are used to transmit and receive data.

Wiring connections are as follows:
The card DTE (male DB=9) |  | Terminal DTE
Pin | Signal | Signal
7 | CAN-H | CAN-H
3 | GND | GND
2 | CAN-L | CAN-L


APPENDIX A

Register structure

This appendix gives a brief description of the CAN controller registers. For more detailed information, please refer to the Stand-aloneC~4N-eontmller Data Book from Philips Semiconductors Micro controller Products.


CAN controller address allocation

Philips PCX82C200 CAN controller：

BasicCAN Mode:

PeliCAN Mode:


Register Description

Control Register (CR)

The Control Register is used to change the behavior of the PCX82C200. Control bits may be set or reset by the attached micro controller, which uses the Control Register as a read write memory.

Command Register (CMR)

A command bit initiates an action within the transfer layer of the PCX82C200. If a read access is performed to this address, the byte 11111111 (binary) is returned.

Status Register (SR)

The Status Register reflects the status of the PCX82C200 bus controller. The Status Register appears to the micro controller as a read-only memory.

Interrupt Register (IR)

The Interrupt Register allows identification of an interrupt source. When one or more of this register's bits are set, the INT pin is activated. All bits are reset by the PCX82C200 after this register is read by the micro controller. This register appears to the micro controller as a read-only memory.

Acceptance Code Register (ACR)

The Acceptance Code Register is part of the acceptance filter of the PCX82C200. This register can be accessed (read write) if the Reset Request bit is set HIGH (present). When a message which passes the acceptance test is received and if there is an empty Receive Buffer, the respective Descriptor and Data Field are sequentially stored in this empty buffer. In case there is no empty Receive Buffer, the Data Overrun bit is set HIGH (overrun).

Acceptance Mask Register (AMR)

The Acceptance Mask Register is part of the acceptance filter of the PCX82C200. This register can be accessed (read write) if the Reset Request bit is set HIGH (present). The Acceptance Mask Register classifies the corresponding bits of the acceptance code as "relevant" or "don't care" for acceptance filtering.

Bus Timing Register 0 (BTR0)

The Bus Timing Register 0 defines the values of the Baud Rate Prescaler (BRP) and the Synchronization Jump Width (SJW). This register can be accessed (read write) if the Reset Request bit is set HIGH (present).

Bus Timing Register 1 (BTR1)

The Bus Timing Register 1 defines the length of the bit period the location of the sample point, and the number of samples to be taken at each sample point. This register can be accessed (read write) if the Reset Request bit is set HIGH (present).

Output Control Register (OCR)

The Output Control Register allows, under software control, the setup of different driver configurations. This register may be accessed (read write) if the Reset Request bit is set HIGH (present).

Test Register (TR)

The Test Register is used only for production testing.

Transmit Buffer

The Transmit Buffer stores a message from the micro controller to be transmitted by the PCX82C200. It is subdivided into the Descriptor and Data Field. The Transmit Buffer can be written to and read from by the micro controller.

Receive Buffer

The layout of the Receive Buffer and the individual bytes correspond to the definitions given for the Transmit Buffer layout, except that the addresses start at 20 instead of 10.


Error Code Table

APPENDIX B

Error Code Table:

Error Code (Decimal) | Descriptions
2000 | CAN Port Is Not Opened
2001 | CAN Invalid Frame Format
2002 | CAN Invalid Port Index
2003 | CAN Incompatible Protocol
2004 | CAN Controller In Reset Mode
2005 | CAN Controller In Work Mode
2006 | CAN Invalid Data Length
2007 | CAN Bus Error
2008 | CAN Time Out
2009 | CAN Invalid Parameter
2010 | CAN Data Not Ready
2011 | CAN Bus Closed
2012 | CAN Open Event Failed
2013 | CAN Create Device Failed
2014 | CAN Port Opened Already
2015 | CAN Query Registry Failed
2016 | CAN Map Memory Failed
2017 | CAN Port Is Not Initialized
2018 | CAN Port Initialized Already
2019 | CAN Setup Port Failed
2020 | CAN Create Thread Failed (CE only)
2021 | CAN Close Thread Failed (CE only)
2022 | CAN Create Event Failed (CE only)
2023 | CAN HWReset Failed (CE only)
2024 | CAN Connect Interrupt Failed (CE only)