Experimenting further with this issue I'm now having some results (both good and bad). I managed to use this code that uses the SAM3X SPI instead of Arduino's SPI (if I got this right) to write some bytes to a couple of shift registers to light up some LEDs. This is the code that works
#define USE_ARDUINO_SPI_LIBRARY 0
#define USE_NATIVE_SAM3X_SPI 1
#define CS 10
#define SPI_RATE 21
#define SPI_BUFF_SIZE 2
uint8_t rx_buffer[SPI_BUFF_SIZE];
uint8_t tx_buffer[SPI_BUFF_SIZE];
void setup() {
pinMode(CS,OUTPUT);
digitalWrite(CS,HIGH);
spiBegin();
spiInit(SPI_RATE);
for(int i = 0; i < SPI_BUFF_SIZE; i++)
tx_buffer[i] = 0x00;
}
void loop() {
for(int i = 0; i < SPI_BUFF_SIZE; i ++){
for(int j = 0; j < 8; j++){
tx_buffer[i] ^= (byte) pow(2, j);
digitalWrite(CS, LOW);
spiSend(tx_buffer, SPI_BUFF_SIZE);
digitalWrite(CS,HIGH);
delay(200);
tx_buffer[i] = 0x00;
}
}
}
I even managed to send data from Pure Data to Arduino and control the LEDs by combining the code above with code given from Nick Gammon. This is the code
#define USE_ARDUINO_SPI_LIBRARY 0
#define USE_NATIVE_SAM3X_SPI 1
#define CS 10
#define SPI_RATE 21
#define SPI_BUFF_SIZE 2
uint8_t rx_buffer[SPI_BUFF_SIZE];
uint8_t tx_buffer[SPI_BUFF_SIZE];
const unsigned int MAX_INPUT = 10;
const byte maxLEDs = SPI_BUFF_SIZE * 8;
void refreshLEDs()
{
digitalWrite(CS, LOW);
spiSend(tx_buffer, SPI_BUFF_SIZE);
digitalWrite(CS,HIGH);
}
void process_data (char * data)
{
// C: clear all bits
switch (toupper (data [0]))
{
case 'C':
{
for (int i = 0; i < SPI_BUFF_SIZE; i++)
tx_buffer[i] = 0;
refreshLEDs ();
return;
}
// S: set all bits
case 'S':
{
for (int i = 0; i < SPI_BUFF_SIZE; i++)
tx_buffer[i] = 0xFF;
refreshLEDs ();
return;
}
// I: invert all bits
case 'I':
{
for (int i = 0; i < SPI_BUFF_SIZE; i++)
tx_buffer[i] ^= 0xFF;
refreshLEDs ();
return;
}
} // end of switch
// otherwise: nnx
// where nn is 1 to 89 and x is 0 for off, or 1 for on
// convert first 2 digits to the LED number
byte led = (data[0] - '0') * 10 + (data[1] - '0');
// convert third digit to state (0 = off)
byte state = data[2] - '0'; // 0 = off, otherwise on
if (led > maxLEDs) // if LED number is greater than total LEDs, do nothing
{
return;
}
led--; // make zero relative
// divide by 8 to work out which chip
byte chip = led / 8; // which chip
// remainder is bit number
byte bit = 1 << (led % 8);
// turn bit on or off
if (state)
tx_buffer[chip] |= bit;
else
tx_buffer[chip] &= ~ bit;
refreshLEDs ();
} // end of process_data
void setup() {
pinMode(CS,OUTPUT);
digitalWrite(CS,HIGH);
spiBegin();
spiInit(SPI_RATE);
for(int i = 0; i < SPI_BUFF_SIZE; i++)
tx_buffer[i] = 0x00;
refreshLEDs();
Serial.begin(115200);
}
void loop() {
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;
if (Serial.available () > 0)
{
char inByte = Serial.read ();
switch (inByte)
{
case '\n': // end of text
input_line [input_pos] = 0; // terminating null byte
// terminator reached! process input_line here ...
process_data (input_line);
// reset buffer for next time
input_pos = 0;
break;
case '\r': // discard carriage return
break;
default:
// keep adding if not full ... allow for terminating null byte
if (input_pos < (MAX_INPUT - 1))
input_line [input_pos++] = inByte;
break;
} // end of switch
} // end of incoming data
}
But trying to read buttons from shift registers simply doesn't work. I came up with this code
#define USE_ARDUINO_SPI_LIBRARY 0
#define USE_NATIVE_SAM3X_SPI 1
#define CS 10
#define SPI_RATE 21
#define SPI_BUFF_SIZE 2
uint8_t rx_buffer[SPI_BUFF_SIZE];
uint8_t tx_buffer[SPI_BUFF_SIZE];
byte butArray[3] = { 0 };
void refreshInput()
{
digitalWrite(CS, LOW);
digitalWrite(CS, HIGH);
spiRec(rx_buffer, SPI_BUFF_SIZE);
}
void setup() {
pinMode(CS,OUTPUT);
digitalWrite(CS,HIGH);
spiBegin();
spiInit(SPI_RATE);
Serial.begin(115200);
}
void loop() {
butArray[0] = 0xc0; // this byte is necessary so that Pd understands that this is the beginning of the data stream
refreshInput();
for(int i = 0; i < SPI_BUFF_SIZE; i ++)
butArray[i + 1] = rx_buffer[i];
Serial.write(butArray, 3);
}
which to my understanding has the same philosophy as the first code of this post. The code compiles and uploads, but again, when I try to open the serial port, Pure Data hangs and I get the message "watchdog: signaling pd..." repeatedly.
Can someone point out what I'm doing wrong here?
Another thing I don't understand is how to manage is the CS pin, which in both cases is set to 10. With Arduino Uno, the CS (referred to as SS - Slave Select) is indeed pin 10, but that's used for the shift out registers, whereas for the shift in registers I was using pin 9 (taken from Gammon's tutorials as well), which is independent of the SPI (right?). Can I use pin 9 as the latch pin for shifting bits in?
Just a reminder, all this happens on a Udoo board (which has an embedded Arduino Due), and the functions used in the pieces of code above are taken from here DUEZoo/dmaspi.ino at master · manitou48/DUEZoo · GitHub copied from line 37 and below.