Software SPI on A0 (sck),A1 (miso), A2 (mosi)
// sw_spi.h
#include "Arduino.h"
#ifndef sw_spi_h
#define sw_spi_h
void nokia_spiSetup(void);
uint8_t nokia_spiRec(void);
void nokia_spiSend(uint8_t data);
#endif // sw_spi_h
// sw_spi.cpp
#include "Sd2PinMap.h"
#include "sw_spi.h"
#define SPI_SCK_PIN A0 //14 // A0 PC0
#define SPI_MISO_PIN A1 //15 // A1 PC1
#define SPI_MOSI_PIN A2 //16 // A2 PC2
/** nop to tune soft SPI timing */
#define nop asm volatile ("nop\n\t")
#define SPI_WAIT {nop;}
void nokia_spiSetup(void)
{
setPinMode(SPI_SCK_PIN, OUTPUT);
setPinMode(SPI_MISO_PIN, INPUT);
setPinMode(SPI_MOSI_PIN, OUTPUT);
}
uint8_t nokia_spiRec(void)
{
uint8_t data = 0;
// no interrupts during byte receive - about 8 us
cli();
// output pin high - like sending 0XFF
fastDigitalWrite(SPI_MOSI_PIN, HIGH);
for (uint8_t i = 0; i < 8; i++) {
fastDigitalWrite(SPI_SCK_PIN, HIGH);
// adjust so SCK is nice
nop;
nop;
data <<= 1;
if (fastDigitalRead(SPI_MISO_PIN)) data |= 1;
fastDigitalWrite(SPI_SCK_PIN, LOW);
}
// enable interrupts
sei();
return data;
}
void nokia_spiSend(uint8_t data)
{
// no interrupts during byte send - about 8 us
cli();
for (uint8_t i = 0; i < 8; i++) {
fastDigitalWrite(SPI_SCK_PIN, LOW);
SPI_WAIT;
fastDigitalWrite(SPI_MOSI_PIN, data & 0X80);
SPI_WAIT;
data <<= 1;
fastDigitalWrite(SPI_SCK_PIN, HIGH);
SPI_WAIT;
}
// hold SCK high for a few ns
nop;
nop;
nop;
nop;
fastDigitalWrite(SPI_SCK_PIN, LOW);
// enable interrupts
sei();
}
The examples Nick provides for SPI slave mode are much tidier than mine.
Cheers,
Jack