It's still a work in progess and a bit rough
//
// Acts as an SPI master
// Receives 3 bytes, CMD, ADDR_LO, ADDR_HI
// performs an action based on the CMD
// returns the results as a fourth byte
//
// Still very rough, a work in progress.
//
//#define RUNNING_ON_328
#define RUNNING_ON_2560
//#define VERSION_ASM
#define VERSION_C
#ifdef RUNNING_ON_328
#define ATMON_PORT_PIN_MOSI 3
#define ATMON_PORT_PIN_MISO 4
#define ATMON_PORT_PIN_SCK 5
#define ATMON_ARD_PIN_MOSI 11
#define ATMON_ARD_PIN_MISO 12
#define ATMON_ARD_PIN_SCK 13
#define ATMON_ARD_PIN_DEBUG 8
#endif
#ifdef RUNNING_ON_2560
#define ATMON_PORT_PIN_MOSI 2
#define ATMON_PORT_PIN_MISO 3
#define ATMON_PORT_PIN_SCK 1
#define ATMON_ARD_PIN_MOSI 51
#define ATMON_ARD_PIN_MISO 50
#define ATMON_ARD_PIN_SCK 52
#define ATMON_ARD_PIN_DEBUG 53
#endif
#define CMD_POLL 1
#define CMD_RD 2
#define CMD_WR 3
#define ACK 6
#define NAK 15
// known location to read from
byte test_byte = 0x23;
#ifdef VERSION_ASM
ISR (WDT_vect, ISR_NAKED) {
#include "d:\work\atmon\atmon\atmon_isr.s"
}
#endif
#ifdef VERSION_C
ISR (WDT_vect) {
volatile byte cmd = 0;
volatile byte addr_hi = 0;
volatile byte addr_lo = 0;
byte response;
byte *address;
int i;
asm ("wdr");
// get the command byte from other Arduino
for (i = 0; i < 8; i++) {
cmd <<= 1;
PORTB |= (1 << ATMON_PORT_PIN_SCK);
if (PINB & 1 << ATMON_PORT_PIN_MISO) {
cmd |= 1;
}
PORTB &= ~(1 << ATMON_PORT_PIN_SCK);
}
delayMicroseconds (5); // needed to allow the other Arduino some time to load another byte
// get the low address byte from other Arduino
for (i = 0; i < 8; i++) {
addr_lo <<= 1;
PORTB |= (1 << ATMON_PORT_PIN_SCK);
if (PINB & 1 << ATMON_PORT_PIN_MISO) {
addr_lo |= 1;
}
PORTB &= ~(1 << ATMON_PORT_PIN_SCK);
}
delayMicroseconds (5);
// get the high address byte from other Arduino
for (i = 0; i < 8; i++) {
addr_hi <<= 1;
PORTB |= (1 << ATMON_PORT_PIN_SCK);
if (PINB & 1 << ATMON_PORT_PIN_MISO) {
addr_hi |= 1;
}
PORTB &= ~(1 << ATMON_PORT_PIN_SCK);
}
address = (byte*)((addr_hi << 8) + addr_lo);
// action the command
switch (cmd) {
case CMD_POLL:
response = ACK;
break;
case CMD_RD:
response = *address;
break;
case CMD_WR:
response = ACK; // not implemented yet
break;
default:
response = NAK;
break;
}
// send response byte to other Arduino
for (i = 0; i < 8; i++) {
if ((response & 0x80) == 0)
PORTB &= ~(1 << ATMON_PORT_PIN_MOSI);
else
PORTB |= (1 << ATMON_PORT_PIN_MOSI);
PORTB |= (1 << ATMON_PORT_PIN_SCK);
response <<= 1;
PORTB &= ~(1 << ATMON_PORT_PIN_SCK);
}
}
#endif
void setup () {
WDTCSR = (1<<WDIE);
Serial.begin (115200);
pinMode(ATMON_ARD_PIN_MOSI, OUTPUT);
pinMode(ATMON_ARD_PIN_MISO, INPUT);
pinMode(ATMON_ARD_PIN_SCK, OUTPUT);
pinMode(ATMON_ARD_PIN_DEBUG,OUTPUT);
};
void loop () {
// pulse to allow measuring of the timeout from main code
PORTB |= (1);
PORTB &= ~(1);
};
I cleaned it up a bit, hopefully I didn't break anything while doing so.
Rob