Listing 1The interrupt handler for DeviceNet messages copies the message from the 82527 into a buffer, saves the length, and frees the 82527 for the next message. The run time is 100 µs.
#define CAN_BASE 0xA000
UCHAR global_CAN_buf[10];
UINT global_event;
// Handles receipt of incoming DeviceNet messages
// The three dots are required in C++ mode
void interrupt far can_isr(...)
{
UCHAR i, int_source, addr, mailbox, length;
int_source = peekb(CAN_BASE, 0x5F); // read interrupt source
if ((int_source < 3) || (int_source > 7)) return;
mailbox = int_source - 2;
for (i=0; i < 10; i++) global_CAN_buf[i] = 0;
// compute address of config register in mailbox of interest
addr = 6 + (mailbox << 4); // multiply by 16
length = peekb(CAN_BASE, addr); // read message length
length = length >> 4;
global_CAN_buf[9] = length; // save message length
for (i=0; i < length; i++){ // move message from 82527
addr++;
global_CAN_buf[i] = peekb(CAN_BASE, addr);
}
addr = 1 + (mailbox << 4); // point to control 1 reg.
pokeb(CAN_BASE, addr, 0x55); // clear INT_PENDING bit
addr--; // point to control 0 reg.
pokeb(CAN_BASE, addr, 0xFD); // clear NEWDAT
global_event |= 0x0001 << mailbox; // set bit in global_event
outp(0x20,0x20); // nonspecific EOI
}