I am finally getting back to CAN (Controller Area Networks). The article CAN 101: CAN Can Where Ethernet Does Not, ED Online 9131 was written last year. I am hoping the next one will not take that long. The forthcoming CAN article will take a look at higher-level CAN protocols.
This time around we take a look at the workings of the CAN controller, and more specifically, those used in Microchip's 8-bit PIC microcontrollers. These contain the Microchip ECAN (Enhanced CAN) controller that supports the CAN Rev. 2.0B standard at speeds up to 1 Mbit/s. ECAN supports 29-bit CAN identifiers, the usual 8-byte messages, three transmit buffers with individual prioritization, three receive buffers (actually two buffers and one assembly buffer), six 29-bit acceptance filter maps, two 29-bit filter acceptance masks, and receive message buffer prioritization. It can also handle 11-bit CAN identifiers.
Microchip has a range of CAN and LIN (Local Interconnect Network) demo kits. I took a look at the CAN-LIN 2 kit (see Fig. 1). The board contains three sockets for two 28-pin/40-pin CAN-equipped PICs and a 16-pin LIN-equipped PIC. The two CAN sockets are connected to socketed CAN driver chips and a 9-pin connector. There is a 3-pin LIN header. Each PIC CAN controller has its own socketed clock chip.
The board has plenty of test points, patch area, and built-in peripheral devices like status LEDs, potentiometers, and buttons. These can be used with the sample applications or your own custom applications. Overall, the board is extremely flexible.
Chips can be programmed and then plugged in, or you can develop in place using a pair of Microchip MPLAB ICD 2 units (see Fig. 2). You can actually get along with just one ICD, but if you are trying to debug CAN communication code then a pair definitely makes the job easier. I was able to watch how both chips were communicating when using two units by setting breakpoints before the first device sent a message and in the second device after it received the message.
The kit's CD contains all the software necessary to get started, including the LIN slave assembler code. LIN nodes are not designed to be very sophisticated. In many cases, the same code can be used to set and poll I/O pins.
The CD does not contain any autostart support, so I had to explore its contents manually. For the most part, it contains a collection of PDF files that describe the board, chips, and software. Source code is provided for everything and the chips on the board come preprogrammed with this code. It was easy to reprogram the PIC chips with the original applications after trying my own modifications.
The first thing to check out is the User's Guide. It addresses board setup, the CANKing software, and how to reprogram the PIC microcontrollers with the original software.
Microchip's ICD 2 installation CD comes with the ICD 2 package that is not part of the CAN-LIN 2 kit. This installation is much different. Pop the CD into a Windows PC and run through the usual windowed installation process. The ICD 2 is a USB device that is automatically recognized when it's plugged in. It connects to the CAN-LIN kit board via a short telephone-style cable.
I had no trouble using either the ICD 2 or the CAN-LIN kit, but I have used Microchip products in the past. I was able to test sample code within an hour. For those new to PICs, reserve a day because you need to understand the PIC architecture and how to use the MPLAB software. The MPLAB IDE instruction set simulator lets you experiment without modifying the CAN-LIN kit processors.
One part of the CAN-LIN kit that is indispensable is Kvaser's CANKing software (see Fig. 3). This software is a Windows-based CAN diagnostic tool that works with the demo software initially installed on the PIC micros. It lets you monitor CAN traffic. It's designed to run on the PIC18F458, but there needs to be only one of these on the network. The tool can be used with CAN networks that incorporate other kinds of CAN devices, although you will need to make sure that the CANKing-related messages do not conflict with the messages being used on the CAN bus.
CANKing utilizes templates for configuration. CANKing also lets you control the messages that it will log, so it is possible to isolate the traffic for a particular part of an application instead of having to deal with all the CAN traffic. This ability to capture traffic is similar to the features found in Ethernet scanners and commercial CAN bus scanners. CANKing won't put the latter out of business, as CANKing is not designed to handle large amounts of traffic. But it is more than sufficient as a development tool for PIC microcontrollers. Kvaser and others provide more robust CAN monitoring tools.
CANKing has a plethora of windows, but each is easy to understand and use. It essentially provides a windowed interface into the ECAN controller. CANKing also provides useful statistics on CAN bus traffic. CANKing does have some windows specifically for the CAN-LIN board. It provides access to the LEDs, switches, pots, and the PWM output from the PIC.
For those looking for the part of the article covering the CAN controller versus the CAN-LIN key, you have finally found it.
Microchip's ECAN (see Fig. 4) is specific to its PIC controllers, but its general operation is very similar to other vendor's CAN controller implementations. This overview should be useful for understanding other controllers when examining competitor's CAN-enabled microcontrollers.
The ECAN consists of three major components: the protocol engine, the transmitter, and the receiver. The transmitter and receiver operate independently of each other. The protocol engine handles all the data link and physical layer support, including error handling and CRC processing.
Essentially, an application needs to first configure the transmitter and receiver. It can then put messages in an empty transmit buffer to be sent, and extract received messages from the receiver. Polling or interrupts can be used to keep messages flowing through the system. The rest is a matter of details.
We'll take a look at the transmitter first since it's less complex than the receiver.
The transmitter consists of three identical message buffers. Each can handle 8 bytes of data and has a set of configuration registers to control where the message is sent. As noted in the prior CAN article, a message identifier is more of a description of its contents rather than a node address. This will become more apparent when we take a look at the receiver section. Four bytes of the interface are used for the 29-bit identifier. Each buffer also has a priority associated with it. The highest priority buffer will be sent when possible. This priority is independent of the priority enforced by the CAN protocol on the bus that is related to the identifier.
That is pretty much it for the transmit side. Set up the priority and address, fill in the data, wait for the message to be sent, and check if it was acknowledged.
Now for the more interesting part-the receiver. The receiver has a pair of receive buffers, another buffer where incoming data is processed, a host of configuration registers, and the acceptance processing registers. The latter identifies what messages will be received by the controller. This is important because messages are acknowledged when they are received unless the controller is set to monitor mode, in which case it is just looking at the information being sent on the CAN bus.
One a message has been received, it is placed into an empty receive buffer. The application must remove the messages before they are overwritten. This can occur if both buffers are full and the priority of an incoming message is higher than those in the buffers. This allows the controller to accept the latest high-priority message. Dropped messages are noted, but not their identifier.
In a general sense, the receiver operation is relatively simple. Set up the receiver (more on this later) and remove messages that have been received. It is essentially the converse of the transmitter operation, except that the identifier and data are read instead of written.
Now for the hard part-the acceptance process. Note: there is no difference in terms of operation between standard 11-bit mode and the extended 29-bit mode. The latter simply requires more bytes to be shoved around.
Taking a closer look, you see that the two receive buffers are actually independent of each other. Both has a single acceptance mask. One buffer (RBX0) has two acceptance filters and the other (RBX1) has four. There is a priority associated with the buffers, with RBX0 being more important. If RBX0 accepts a message, then the message will not be considered by RBX1 even if the acceptance criteria for RBX1 matches the just received message identifier.
Now for the details of acceptance. First, you start with the received message identifier. Next, the identifier is compared against the filter register contents. Each bit comparison will either match or not. Assume for the moment that a match is represented by a 0 and no match is a 1. The result is then ANDed with the acceptance mask. The message is accepted if the result in all bits is 0. If the controller is receiving messages, then it will be acknowledged after the data and CRC have been accepted and verified. The accepted message is then placed into the appropriate receive buffer where it can be read by the application. The following shows some standard 11-bit identifier comparisons.
Failure: (result not zero) Message identifier 001 1010 0000 Acceptance filter 100 1010 0000 Compare result 101 0000 0000 Acceptance mask 111 1111 0000 ANDed result 101 0000 0000 Success: (result zero) Message identifier 101 1100 0001 Acceptance filter 101 1100 1010 Compare result 000 0000 1011 Acceptance mask 111 1111 0000 ANDed result 000 0000 0000
These examples only show an acceptance mask that ignores the four least significant bits (left-most bit is most significant in this example). In the first case, two bits are different from the acceptance filter. In the second there are three bits, but they are in the section ignored by the acceptance mask. For RBX0, two checks are made since it has two acceptance filters. All the comparisons are done in hardware and in parallel so the process is actually very fast.
We will forego an extensive discussion of CAN identifier allocation. There are a variety of ways to do it based upon the kind of applications being used on the CAN network. In the simplest case, each device would have a unique identifier and the acceptance mask would be all 1s. Alternatively, the masked portion (ignored) could be a function code that indicates what the data is or what is should be used for. Yet another alternative would use the mask portion as an identifier where the associated response should be sent. As you can see, there can be quite a number of variations.
In any case, the full CAN identifier of a received message is retained so an application can process the identifier and the data as required.
Acceptance filter and mask settings are normally configured when the microcontroller boots. They are rarely changed unless the application does some unusual things, such as monitor the bus or pick up the job of another device when a failure is detected.
Microchip's controller also supports features such as time stamping. This allows the hardware to keep track of when a message was received. This can be important for time-critical applications in which an action or response is based on the time a command is received or when the time between two messages is significant.
That is pretty much it for CAN controllers. It is not worth going down into the bit fields of the registers used to control Microchip's ECAN until you get into the actual job of programming. In fact, much of it may be hidden if you use templates, higher-level C APIs, or run-time libraries. Still, it's useful to understand what the hardware is doing and what it is capable of.
The kit comes with a number of application notes, and there are even more on Microchip's website. One that caught my eye was the bootloader note (AN247). It shows how to implement bootloader support in a PIC microcontroller so one CAN-equipped microcontroller can program another.
More specifically, a CAN-equipped PIC boots a CAN block-loader program that is never overwritten. It submits a request on the CAN network for a boot program. Another CAN node responds by sending the program. Although this node could be any microcontroller, Microchip obviously only supplies sample code for their own chips.
Sounds simple. It is, but there is a lot more to that job for two reasons. First, CAN's small packet size means most applications will not fit into a single message. Multiple messages are required. In fact, the protocol is a bit complex, so it can handle actions like erasing memory. Second, there can be priority and loading issues as the boot operation will typically occur while the network is being used for other operations. CAN's limited bandwidth means properly sharing this bandwidth will be an issue.
The application note and source code handle most of the details. It is possible to reduce or enhance the functionality. The code is written so many options can be enabled conditionally. It is worth checking out, as it also provides a mechanism to do in-system upgrades.
The only fault I can find with the CAN-LIN kit is the sample applications are not numerous enough. Luckily, the Microchip website has additional information.
CAN is a relatively easy interface to utilize. It's very flexible and robust. It may not be as fast as Ethernet, but in many ways it is more effective in control applications. I can definitely recommend the CAN-LIN kits as a great way to check out CAN and to evaluate PIC microcontrollers.