[solved, kind of...]: SPI issue with shift registers on a Udoo board

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.