Nov 17

In order to develop the higher level RoboCAN protocol I will need two devices that are connected to the CAN bus. One is the ATDVK90CAN1 board and the other one is a PC using the CANUSB interface. When the drivers are installed a series of demo programs is installed as well including the source code. These demo programs show how to interface with a DLL called canusbdrv.dll which provides the basic functions to send and receive frames using the CANUSB interface.

I’m using Delphi 2005 as my development environment for Windows applications. Opening and compiling the SDIAPP stored in the C:\Program Files\LAWICEL\CANUSB\examples\Delphi2005 folder works, however when executing the code it crashes when I press the openbutton. I wonder if it truly is so difficult to build code that works…

Some debugging later I find that the string used for receiving the version is too small for storing the version. Below is the modified code (the bold parts):

procedure TSDIAppForm.BtnOpenClick(Sender: TObject);
Var VerText : String[255];
begin
  CANUSBOpen(”, CAN_BAUD_500K, CANUSB_ACCEPTANCE_CODE_ALL, CANUSB_ACCEPTANCE_MASK_ALL, CANUSB_FLAG_TIMESTAMP);
  CANUSBVersionInfo(@VerText[0]);
  Label1.Caption := VerText;
  BtnOpen.Enabled := False;
  BtnClose.Enabled := True;
  BtnStatus.Enabled := True;
  BtnWrite.Enabled := True;
  Timer1.Enabled := True;
end;

Next to this, I changed the address used for sending frames to $310 so it works with the code running so far on the ATDVK90CAN1 board. Now at least it does not crash, however when pressing the write button I see that a frame is received with 1 data byte (correct) but it shows two… Some more debugging shows that the loop to show the received data contains another bug as well… Below the modified code (the bold parts). 

procedure TSDIAppForm.Timer1Timer(Sender: TObject);
Var
  CANMessage: CANmsg;
  DummyStr: String;
  tmp: Integer;
begin
  if (CANUSBRead(CANMessage) = ERROR_CANUSB_OK) then
   begin
     DummyStr := Format(‘ID = %x,’, [CANMessage.id]);
     DummyStr := DummyStr + Format(‘ LEN = %d, DATA = ‘, [CANMessage.len]);

     tmp := 0;
     while (tmp < CANMessage.len) do
       begin
         DummyStr := DummyStr + Format(‘ %2x’, [CANMessage.data[tmp]]);
         Inc (tmp);
       end;

     Label3.Caption := DummyStr;
   end
end;

procedure TSDIAppForm.BtnWriteClick(Sender: TObject);
Var CANMessage: CANmsg;
begin
  CANMessage.id := $310;
  CANMessage.flags := 0;
  CANMessage.len := 2;
  CANMessage.data[0] := $55;
  CANMessage.data[1] := $AA;
  CANUSBWrite(CANMessage);
end;

At least it seems the ddl is working so I will use this dll to develop a RoboCAN monitor application.

Nov 16

Next to the priority of the messages, also some though should go into the library that implements the protocol.

Sending a single frame will require about 110 bits on the CAN bus. Using a 500kbps speed this will take 220us limiting the total amount of frames to 4500 frames per second. Question to answer is if it is necessary to buffer multiple outgoing commands or is it enough to buffer one command and report back to the application it has been send before another command can be send. Based on the 4500 frames per second and assuming that an average command will require 3 frames (2 for the command, 1 for receiving the acknowledgement) it means transferring the command will take a bit less than 1ms.

But what if other higher priority devices are on the bus transferring data? What is they decide to transfer larger amounts of data? If the send command function would only return when it has completed this would be a problem, however the transfer is already interrupt based. So the send command function can return directly allowing the application to continue. Before a new command can be send a verify must be done if the previous was already send. If not, than there are again two options: than wait in the send command or return with an error code. From an application point of view, most cases you want to wait before continuing. Also in most cases the command will result in data being send back that than must be processed. But the difficulty lies within the most.

Best approach here is to pass an additional parameter to the send command that indicates when to return: directly or when the acknowledgement has been received. If the previous command has not been send, than it overrules the parameter and wait until the previous command has been send. In both cases a time out must be implemented on the maximum time allowed to wait before the previous has been send and a timeout must be implemented how long it can wait for a response. Next to a level of retrying of course.

The send command will return a status like OK, timeout, bus error and so on. Applications can than make the send command part of an if structure that is only execute when the send command was successful. If the option is selected so it return without waiting for the acknowledge, than it will return also with the OK status (if indeed it was executed OK). After this other actions can take place, if a t a certain time the application wants to check if the data actually has been send the global status field can be tested to see if it already has been send or that the acknowledge has been received.

In this assumption there is one part missing, when a command is received from another device it must be acknowledged by sending dummy data or the actual data that was requested. Since the process of receiving data is interrupt based the moment in time that data must be send is not defined. It can be just at the moment that the application also want to send a command. Or even worse, the command received might require some measurements that some time before a response can be send. Since the application is not processing incoming commands at that time there sure will be a timeout on the sender side which will “think” the transmission failed and it will retry.

Hmmm. This means any incoming command must be acknowledged for received, not for processed. When the application finally has time to process incoming requests than it send out the formal response (if needed). The problem of acknowledging data on time might also be encountered when a higher priority device decides to start communicating. It might be that these two items already use one of the reserved bits: the acknowledgement bit. By using this bit acknowledge frames will have a higher priority over the bus than command frames. Since the acknowledgement frame is only 1 frame long (potentially no data at all) this does not have a big impact on transferring larger commands but it prevent retries.

As a result, the 29 bits of the priority field are used as indicated below:

  • b28:          0=interrupt packet, 1=normal packet
  • b27:          0=acknowledgement packet, 1=command packet
  • b26..b24:  Reserved, should be 0b011 by default
  • b23..b17:  Address of receiver, 0×7F is lowest priority, 0×00 is highest priority device
  • b16..b10:  Address of sender, 0×7F is lowest priority, 0×00 is highest priority device
  • b9..b5:      Packet number, 0×00 is packet 1, 0×1F is last possible packet 32
  • b4..b0:      Total number of packets, 0×00 is 1 packet, 0×1F is maximum amount of 32 packages

The function that will handle incoming frames will than also be responsible for sending the acknowledge frame when a full command is received. After this, the command can be placed in a buffer and a flag can be set in the overall status that a new command has been received. This buffer needs to be able to hold several commands, it must also be able to handle several incoming commands at the same time. For example, when a command exists out of 6 frames it can be that after receiving frame 3 a new command is received from a higher priority device. Than in theory it is possible than the lower priority sender does not get an acknowledge and retries making the partially received command obsolete.

A single command can exists of 32 frames. This would require housekeeping if all frames have been received before a command is acknowledged. The sender can make sure that all frames are send in the right order, so 1 out of 3, 2 out of 3 and finally 3 out of 3. When the last one is received, the receiver can store it in the incoming command buffer and send an acknowledge frame to the sender. If reception is interrupted by a higher priority device and a timeout on the sender is triggered to resend the command, the receiver will suddenly receive 1 out of 3 again. At that moment, all previously received data from that sender can be ignored and deleted.

While processing an incoming frame the MOB is disabled, since it might take some time to process the MOB there must be more MOB’s monitoring the bus for incoming frames. This again presents a problem since this can mean that frame 3 out of 3 is processed before 2 out of 3 since the first one can be received in a lower number MOB and as a result is processed earlier if two frames have arrived before the processing starts. The solution for this problem can be a 32 bit wide variable in which each bit indicates if a frame has arrived. Only when all bits are 1 that should be 1 for matching the total number of frames than the command can be acknowledged.

The buffer that holds the incoming commands can be a simple list of “x” commands each claiming 255 bytes of possible data. In an embedded system were RAM is limited this should not be done, also the chance that all commands actually have 255 bytes of data is very limited. Instead, a linear FIFO buffer can be used that holds all received commands in a circular buffer. The receive function must claim the number of bytes in the buffer when the first frame of a new command is received. The amount of bytes is a sum of:

  • 4 bytes for storing the bit pattern to detect if all frames are received
  • 1 byte for the address of the sender
  • 1 byte for the command
  • 1 byte for storing the amount of data bytes
  • n bytes for storing the data

The circular buffer holds two pointers, one is pointing to the first free memory location and used for receiving commands and one is pointing to the first received command and used for reading. Since multiple commands can be received in parallel a function will be needed to claim memory (and so advance the incoming pointer) and return the original buffer location. When memory was claimed but the frame was canceled than it should be made invalid so that when data is read from the buffer this frame is skipped.

In order to read data, the first thing to do is to see if all frames are received. This can be done by checking if the number of frames to be received are reported as 1 in the first 4 bytes. However, an easier way is to check if all 4 bytes are 0xFF. If not, all frames are not received yet. That leaves the problem of how to detect if the received command has been aborted and so should be ignored and the memory released. This could be done by clearing all 4 bytes, this pattern is never used since the moment the first frame of a new command comes in one of the 32 bits (in most cases the first) will be set to one directly when the memory is allocated on the buffer.

Sending the acknowledgement frame can be done using a seperate MOB, since the acknowledgement frames have a higher priority than command frames there is no need for a second MOB.

The function that sends commands can indeed send frame by frame until all data is send. Than a timer needs to be started after which it can wait for an acknowledgement frame to be received. There is a timer available in the CAN controller, this can be used here since only one command is send at the time. When the acknowledgement frame arrives the senders address can be compared with the original to address. If they match, success can be reported. When the timer expires the whole command must be resend. It is possible here that just when the timer expires and the resend start the acknowledgment frame comes in. In that case it must be ignored. If after x (3?) retries the command still is not acknowledged than it is time to stop the transfer and report an error. If at that time a new command is send to another device to report a non-responsive device it is in theory possible that just at that moment (before or during sending of the new command) the acknowledgement still comes in. Since it is too late, it should be ignored as well. So there is only a specific time window that acknowledgement frames are used and at that moment they whould match the last used to address. 

Above results in:

  • 1 MOB for sending commands only to make sure frames are send in the right order
  • 1 MOB for receiving acknowledgements, only one needed since it will wait with sending the next command until this command is acknowledged
  • x MOB’s for receiving incomming commands. The number depends a bit on how much code is required for storing the incoming data compared with the time needed for receiving a new frame.
  • 1 MOB for sending acknowledgements

Time to stop now and think about it for some hours before implementation starts.

Nov 16

On top of the basic CAN interface I will add a communication layer that allows devices to send each other commands. I will call this communication layer RoboCAN and will use it in all my robots (at least that is my intention while writing this).

The amount of data that is part of the command should not be limited to the standard 8 data bytes that can be stored in a single CAN frame. Next to this there is a set of basic commands that each device must support, from example GetStatus. In most cases the sender want to be sure the command has been received so any command send must be acknowledged by the receiver. This acknowledgement is only required when a command is received for sending data. When a command is received for receiving data the acknowledgement is the response itself. This response does not have to be acknowledged by the original sender, if this sender did not get the response it will repeat the original request again.

In order to support sending a command to a device it will be necessary to give each device an unique identifier. A device only needs to respond to commands send to it, not to commands send to other devices. The unique ID can be stored in the priority field of the frame. The benefit of this is that the priority filtering mechanism can be used which reduces the software overhead of the device application. A second benefit is that this automatically provides a priority mechanism between the devices. On a busy bus, messages send to a device with a lower identifier value will have higher priority and other data will (temporarily) be put on hold.

Big question to solve it how to handle the transport of data block larger than 8 data bytes? In principle this can be solved by storing in the data fields something like frame x out of y frames. This presents some problems. For one, next to the command it will consume 3 out of the 8 bytes available, so a relative large overhead. Next to this, if the application send two commands directly after each other, how will the receiving device know which frame is part of which command? If an error occurs during transmission of a frame it will be resend, but at that moment another message can have higher priority, the sending order does not have to match the receiving order (like in HTTP). This would require a “command ID”, so consuming in total 4 bytes out of the 8. We can reduce this overhead by limiting the maximum to 16 frames, so x out of y frames can be packed in a single byte. The same can not be done for the command, I guess complex devices will have more than 16 commands. For the command ID it can be done but there is no other byte available to combine it with.

The priority field of a frame is 11 or 29 bits (CAN rev A or B). Using the 11 bits this would mean 2048 devices on the bus. I guess this is a bit much, perhaps we can use a range of priorities per device. For example, limiting the number of devices on the bus to 127 (7 bits) gives us 4 bits per device, so 16 “addresses” per device. Next, in the driver an implementation can be made that commands are queued, a new command can be send before the previous has been finished but is placed on hold in the driver until the previous command is fully handled. The 16 addresses can not be used for commands since 16 commands is not enough. For sending multiple frames for data this might be different.

The CAN controller itself provides an additional priority structure. When one or more MOB’s are enabled and the bus is free the CAN controller will first check if MOB0 is enabled. If not, than MOB1 and so on. So, if a command needs 3 frames for sending it’s data it can be placed in MOB0, 1 and 2. Only when MOB0 has been successfully transferred MOB1 will be send. However, this does not guarantee that the frame send by MOB0 has been received by the device. It is possible that the CAN controller was disable for a while on the receiving device, as a result it receives the frame send by MOB1 and MOB2 only (in that order). MOB0 frame is gone forever.

This does however provide a benefit, the order of frames can be controlled making the x in x out of y obsolete. The receiving device will receive part 2 out of 3 first, it thinks this is part 1 out of 3, since the other 2 parts have not been received yet it does not send an acknowledgement. Than comes part 3 out of 3, this is received as part 2 out of 3. Again no acknowledgement which triggers a timeout on the sender. The sender will than resend the whole message and than it goes wrong because part 1 out of 3 is received as part 3 out of 3…. Hmmm, this would require again the command ID allowing the device to see a new command is being send and so ignore all previous data.

While thinking about this, another problem is that when two devices start sending a command to the same device. Depending processing speed and the content of the data fields it can result than frame 1 is received from device 1 and frame 2 from device 2, theoretically using the same command ID. There is no way to differentiate between to senders, so the senders address must be part of the message somewhere. This also allows the receiver to send back the acknowledgement to the sender.

The problem of two senders in parallel can only be solved if each frame contains the sender of the frame. In total that means every frame should have:

  • The destination address
  • The senders address
  • Packet number
  • Total number of packets

This can also be done using a 29 bits long priority identifier in stead of the 11 bits. Above order can than also be used as priority information: A device with a higher priority gets data faster than with a lower priority. If two devices want to send data to it, the sender with a higher priority wins and the first packet is send before the last packet. Since the number of packets is always the same this has no impact.

Having more than 128 devices on the bus is not likely, so 14 bits will be required for the two address fields. This leaves 15 bits for the packet fields, also here 2 times 7 bits should be enough. As a result, 1 bit is free for which no function is defined yet. It might be a good idea to make this the most significant bit so it can be used later for even higher priority messages like alarm status or “interrupts”.

Since all required data for package transfer is now included in the priority field, all 8 data bytes are available for data. Except the command of course, so this is the first byte of the first frame. Also the total number of bytes that are included in the command (different than the number of packages) needs to be included, this will be the second byte of the first frame. As a result, there are 256 possible commands that each can include 255 bytes of data. Small calculation, since there are 7 bits to indicate the number of packages so a maximum of 127 packages. In total this allows us to send (127*8)-2=1014 bytes of data which is more than the 255 bytes previously mentioned.

If the limit would remain 255 bytes, the maximum amount of frames would be (255+2)/8=32.125 so 33. This would require 6 bits for storing the amount of packages instead of the previously indicated 7. This leaves 3 bits reserved for future use. Since the amount of packages will always be 1 (or more) the bit pattern 0b000000 can be used as well to indicate packet 1. When using 6 bits for the amount of packages this means we can send 32 packages, so (32*8)-2=254 bytes of data. The maximum was 255 (the value 0 is a valid number as well), so one bytes less might be a good compromise to save another 2 priority bits bring the total number of reserved bits to 5.

This brings up an interresting debate, if we limit the amount of devices to 6 bits so to 64 than we have 7 bits that can be used for storing the command and as such increase the maximum number of data bytes to 255. The advantage is that we can include the command in the priority, the dis-advantage is there is no reserved bits anymore. Is the command in priority higher than a sender? The sender can control this by itself, so the command should than be placed between “to address” and sender address making it possible for a lower priority device to interrupt a higher priority device with a higher priority command. Confused?

The only reason to do this is so (indeed) interrupt somebody. For this 1 bit should be enough. Secondly, each device must support a basic set of commands which than should remain constant in time, but the true priority can only be set during design time and can vary over projects. So this is not a smart thing to do. So the conclusion is we remain using 7 bits for the device addresses and using the first byte in the first packet as the command.

The interrupt feature is an interesting one, it is not a real time interrupt, but it will be beneficial to use the highest bit for this. If two high priority devices decide to exchange larger amount of data this can result in many frames before a lower priority device can actually report it is in panic mode… If used sparingly this adds value. Also here the interrupt of a higher priority device wins over an interrupt of a lower priority device, all very logic.

As a result, the 29 bits of the priority field are used as indicated below:

  • b28:          0=interrupt packet, 1=normal packet
  • b27..b24:  Reserved, should be 0b0011 by default
  • b23..b17:  Address of receiver, 0x7F is lowest priority, 0x00 is highest priority device
  • b16..b10:  Address of sender, 0x7F is lowest priority, 0x00 is highest priority device
  • b9..b5:      Packet number, 0x00 is packet 1, 0x1F is last possible packet 32
  • b4..b0:      Total number of packets, 0x00 is 1 packet, 0x1F is maximum amount of 32 packages

The reason for the 0b0011 pattern on the reserved bits is that this allows future expansions using a higher and a lower priority.

I will write a library that implements above to get some experience with this structure.

Nov 12

As previously already mentioned, I like to go into details to fully understand how things work. Also for working with the CAN protocol, I want to understand how this works and how the AT90CAN CAN controller supports the interface.

On the CD-ROM that comes with the ATDVK90CAN1 there is sample code including a simple CAN driver that allows you to send and receive a frame. Next to the fact the code is very cryptic and it is not interrupt driven I want to write my own low level code so I truly understand the CAN modules and can solve problems later on that are related to the CAN interface.

The first version of my code can be downloaded here, the most important part is the CAN.c unit. This version is purely to provide the basic level of sending and receiving frames and respond to the various interrupt sources of the CAN controller. If you want nothing more than the basics, this is a good start for generating your own code, I think I will add an extra layers so applications can simply read and write “data” to a specific device similar to the CANOpen protocol. I will not use the CANOpen protocol since it only accepts one master on the bus, I want every device to be a master.

The AT90CAN controller handles almost every task needed for sending and receiving frames. It can handle 14 frames in parallel, for this it uses 14 so called Message OBjects. Each object can be setup to receive or transmit a frame. If something goes wrong during transmission an error interrupt is triggered but all error handling is done by the MOB itself. It continues to retry until it is successful or it fails to many times as defined by the CAN protocol. At that moment the bus is automatically disabled for sending and/or receiving depending the error.

So all that is needed for sending a frame is to find the first available MOB that is not busy, fill in the message priority, the maximum of 8 data bytes and set the mode to sending. After this the CAN controller will do the rest as soon as the CAN interface is not used. When finished, it triggers an interrupt and automatically disables the MOB keeping it locked until the application manually frees it.

For reading a frame this works similar with the exception that now the base priority needs to be set in combination with a filter that sets a range around the base priority. When a frame is received, the filter is used to check if it should be passed to the application or not. If a specific bit in the filter is set to 1 that same bit in the received priority has to match the bit of the base priority. In case of a 0 in the filter the matching bit in the received priority is ignored. As examples:

To accept only message priority 0x317:

  • Base priority  = 011 0001 0111 b
  • Filter              = 111 1111 1111 b

To accept priority from 0x310 up to 0x317:

  • Base priority  = 011 0001 0xxx b
  • Filter              = 111 1111 1000 b

To accept all priority from 0x000 up to 0x7FF:

  • Base priority  = xxx  xxxx  xxxx b
  • Filter              = 000 0000 0000 b

Also here, when it receives a frame matching the base priority and filter it triggers an interrupt and automatically disables the MOB and waits for the application to read the message priority and received data. After this, the MOB can be freed or enabled again for reading using the same filter.

In total, very simple. The only complex part is initializing the CAN controller or actually setting up the required baud rate. The whole timing of receiving a single bit of a frame can be defined using three registers. Luck ally the most common settings for these registers in combination with the crystal frequency and the required baud rate are listed in chapter 19.12 of the specification.

The logic of my code is that each MOB can be used for any action (send or receive). When an action is required the first free MOB is found and assigned to this task, any action later on (like reading the data when it finished receiving) uses the assigned MOB. When it is no longer needed, it must be released so it can be used by a new action.

In order to test it, connect the CANUSB to the PC, use the cable to connect the CANUSB device to the ATDVK90CAN1 evaluation board. Start CAN Monitor Lite, click the Open CANUSB device button followed by the monitor button. Execute the code in AVR Studio 4 in combination with an AVR JTAGICE mkII JTAG interface. The LED’s on the evaluation board should all be off.

Fill in the value 0 in the CAN ID field of the message tab in CAN Monitor Lite. Press the send button, a green flash should be visible on the CANUSB device. If a red flash is shown as well (or continuous red) there is a CAN bus error, check the cable and make sure the application in the AT90CAN is running.

The LED’s on the evaluation board should not change to indicate a frame has been received. Reason for this is that both MOB’s (MonitorMOBOne and MonitorMOBTwo) that are reading will see the frame passing by but it does not pass the filter in both MOB’s. When you enter 310 in the CAN ID field and press the send button again a small green flash will be visible on the CANUSB and the LED’s on the evaluation board will display the value 1. In this case MonitorMOBTwo has received the frame and is enabled again after reading the data. A (modified) frame will be send by the AT90CAN as a response and CAN Monitor Lite will show the incomming frame. Sending priority 311 will also result in the same effect since it can pass through the filter of MonitorMOBTwo.

Sending priority 317 will also result in the same effect but now using MonitorMOBOne. After reading the data it is not renewed, so sending again priority 317 will not show an incomming frame.

The filter mechanism is very powerfull in combination with the 14 MOB’s. You can also setup two MOB’s using the same base priority and filter. This reduces the risk of missing the second frame if the first frame is not read yet. This is important to understand since there is no active acknowledgement of data, even the opposite, messages are just being dumped on the bus without caring if somebody does anything with it. This is something that the next layer on top of these basic commands must take care of.

Nov 1

The development kit of the AT90CAN controller and the CAN USB interface arrived earlier his week. In order to setup an development environment on a Windows XP machine, follow below steps:

Download and install AVR Studio 4(version 4.14, build 589 at the time of writing). This will create a folder c:\Program Files\Atmel with all files related to AVR Studio.

Download and install WinAVR, when it asks for the folder for installation, select the folder c:\Program Files\Atmel

Download and extract the ZIP file of the CAN USB FTDI drivers (Virtual COM Port and D2XX DLL). Then connect the CANUSB to an USB port. When Windows starts the Found New Hardware Wizard, do not allow it to connect to Windows Update, select the No, not this time option. Click Next and select the Install from a list or specific location option. Click Next and select the Search for the best driver in these location. Only check Include this location in the searchand select the folder the holds the unzipped drivers. After installation of the device drivers, Windows will start again the Found New Hardware Wizard. This is to install a virtual COM port for the CAN USB hardware. Repeat the exact same procedure as above so the device drivers from the ZIP file are loaded.

Download and install the CAN USB & Active X Driver, this installs demo applications and an DLL that is used for using the CAN USB in your own applications.

Download the executable of CAN Monitor Lite. You do not need to install it, it is an executable already. Store it somewhere in c:\Program Files and create a shortcut to the desktop in order to start it. This is an application that uses the above DLL and shows all CAN frames that are send over the bus. It also allows you to transmit a frame with the maximum of 8 data bytes. Since the CAN USB hardware is connected to the PC, start the application and select the CANUSB | Openmenu. If this does not give an error message and at the bottom it states CANUSB Version: xxxx followed with Opened and the bit rate than the whole chain is setup correctly. A second test is to press the send button at the bottom the send a frame (no need to change the default data), since there is no one to respond a red LED will light up on the CAN USB hardware. After selecting the CANUSB | Close menu this LED will dim again.

Download and extract the ZIP file with the AT90CAN128/64/32 Software Library and Examples. This contains (amongst others) the basic CAN library to send and receive frames.

All installation work is now done, it’s time to start connection the hardware starting with the CANUSB and the ATDVK90CAN1. For this a cable must be constructed, below image shows the pinout of both male SUB-D9 connectors.

A CAN bus must be terminated at the start and the end of the lines by connecting an 120 Ohm resistor between the CAN_H and CAN_L pins. Combining this and the possible option to add a third CAN device later, below schematic shows how to wire a cable. Please note that only on one connector the shield is connected to ground. If you connect all shields to ground you are creating a second path for the ground line other that the ground line of the power supplies. As a result, you create a huge antenna and can be guaranteed to received all kinds of noise that is available in the air.

Below an image of the cable assembly, the termination resistors are inside the connectors. Each cable segment is about 50cm, so in total the cable is 1 meter long.

I will not connect the ATDVK90CAN1 board yet but first will try if I can program it with the JTAG. Reading the manualand checking all jumper default settings I understand there is a default program in the AT90CAN that does something with the LED’s and the buttons. After connecting the power plug, applying 8V and setting the power switch in the on position the green power LED lights up. Pressing any of the navigation buttons however does not show anything.

To verify that the AT90CAN is running, I verify if 5V is available. That is the case. Than it might be that the AT90CAN is not programmed, for this the JTAG needs to be connected. When trying to insert the 10 pins JTAG header in the connector the ISP pins are in the way. The pictures are not clear in the manual, it might that they cut them away. I will not totally remove them, but cut away the top 2mm of every pin. After this, the JTAG can be connected.

After starting AVR Studio and selecting the Tools | Program AVR | Auto Connect menu option followed by selecting the AT90CAN128 and JTAG mode in the Main tab followed by a click on the Read Signature button I see that the AT90CAN is responding in the status area. That means the board is not defective, good. In the Fuses tab I see that the clock select is set to an 8MHz external oscillator, this matches the settings of the jumpers as well.

After reading the FLASH file from the AT90CAN, saving it to disk, closing the connect dialog and opening the HEX file, AVR Studio will create a project allowing me to execute this HEX file step by step. Executing the HEX file by stepping through the code using F10 I do not see execution that looks like the demo program, no input or output calls are made. It looks to be some kind of boot loader program instead.

Since the source code is listed in the manual, let’s try to compile this demo and execute it. Start a new project and select Atmel AVR Assembler as the project type. Select the JTAG ICE II as programmer and an AT90CAN128 as target. Copy the example code and press Assemble and Run. Now pressing the center button of the navigation keys shows an LED moving until you release the button. I will send a mail to ATMEL so they can correct this mistake, if they (or you) want they can download the project here.