Go Down

Topic: Continuous SPI for multiple bytes (Read 2761 times) previous topic - next topic

mcleung

#15
Apr 02, 2014, 03:22 pm Last Edit: Apr 02, 2014, 03:25 pm by mcleung Reason: 1
Yes, my CS goes low and back high, it's just off the frame. I'm using the CS down slope to trigger my scope.
Here is an updated copy of my code (working) for those in the future who may run into this problem also.

My next step is to remind myself how to do direct port manipulation for the CS LOW/HIGH, as there is a long delay before / after the actual transfer before the CS pin flips.
IIRC should be something like PORTD = PORTD & 0b00100000 ....
Anyhow, I don't need help on that, I can figure it out :)

Code: [Select]
/*
* SPI Communication via Arduino, version 2.0 using DMA
* Send via USB Serial
* Used for programming/Interfacing with LM96570
*
* DMASPI obtained from
* https://github.com/manitou48/DUEZoo/blob/master/dmaspi.ino
*
* Author: Michael, 2014
* mcleung@uwaterloo.ca
*/

// dmaspi   from SdFat lib

#define USE_ARDUINO_SPI_LIBRARY 0
#define  USE_NATIVE_SAM3X_SPI 1

// #include <SPI.h>
#define USE_ARDUINO_SPI_LIBRARY 0
#define USE_NATIVE_SAM3X_SPI 1

#define CS 10
#define SPI_RATE 2 // 84 / SPI_RATE = 42 MHz

// Save Words to write to chip
#define SPI_BUFF_SIZE 9
uint8_t rx_buffer[SPI_BUFF_SIZE]; // Not used
uint8_t tx_buffer[SPI_BUFF_SIZE];

void setup()
{
 // Set up Serial communication (Computer)
 Serial.begin(115200);
 Serial.println("Initialisation Started");
 pinMode(CS,OUTPUT);
 digitalWrite(CS,HIGH);
 spiBegin();
 spiInit(SPI_RATE);
 
 Serial.println("Initialisation Completed");
}


void loop() {
 if (Serial.available()) {
   serialRead();
 }
}

/*
 SerialEvent occurs whenever a new data comes in the
hardware serial RX.  This routine is run between each
time loop() runs, so using delay inside loop can delay
response.  Multiple bytes of data may be available.
*/
void serialRead() {
 Serial.println("    "); // Unknown why it's required
 tx_buffer[0]=Serial.read();
 tx_buffer[1]=Serial.read();
 tx_buffer[2]=Serial.read();
 tx_buffer[3]=Serial.read();
 tx_buffer[4]=Serial.read();
 tx_buffer[5]=Serial.read();
 tx_buffer[6]=Serial.read();
 tx_buffer[7]=Serial.read();
 tx_buffer[8]=Serial.read();
 //Serial.print("READ");
 //Word1 = Serial.parseInt();
 //Serial.print("READSUCESS");
 digitalWrite(CS,LOW);
 spiSend(tx_buffer,SPI_BUFF_SIZE);
 digitalWrite(CS,HIGH);

 // Return 1 so computer knows that Arduino is ready to recieve next command
 delay(1000);
 Serial.print("1");
 //Serial.print("DONE");

 // Clear unsused bytes from the buffer
 // This should only occur from transmission errors
 byte dummy;
 while(Serial.available() > 0) {
   dummy = Serial.read();
 }
}


And then the DMA SPI part, copied word for word, starting from line 37.
I can't post the entire part as I'm over the character limit.
https://github.com/manitou48/DUEZoo/blob/master/dmaspi.ino

Code: [Select]
// SPI functions
//==============================================================================
#if USE_ARDUINO_SPI_LIBRARY
#include <SPI.h>

dlloyd

Quote
My next step is to remind myself how to do direct port manipulation for the CS LOW/HIGH, as there is a long delay before / after the actual transfer before the CS pin flips.
IIRC should be something like PORTD = PORTD & 0b00100000 ....


There is a digitalWriteDirect function (from another thread) that I think is about 9X faster...

Code: [Select]
// example: digitalWriteDirect(10, HIGH)
inline void digitalWriteDirect(int pin, boolean val){
  if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
  else    g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}

mcleung

Right, because PORTD is for the Uno/Mega...
Thanks!

Go Up