Spififo

Status
Not open for further replies.

john-mike

Well-known member
Will SPIFIFO be able to work with multiple devices without doing begin() between them?

SPIFIFO seems to be taking less than 2u to send and receive two bytes.
SPI4Teensy3 and the SdFat code I've been using take just over 5us to do the same.
I'm trying to do a lot of SPI communication and wavetable synthesis inside an (approximately) audio rate timer so a couple of us are very important.

Here's the SPI code I lifted from SdFat. You just have to put a digitalWriteFast before and after spiSend or spiRec.

I'm using an external DAC as I need two channels along with an ADC and serial flash, which I've made a library for.
I haven't jumped to Audio.h as I've got a lot invested in the silly way I'm doing it.

Aaaand here's some code form this video I made when testing the internal DAC on the 3.1.

Code:
#include <SPIFIFO.h> 
int drymix,wetmix,dealy_in;
IntervalTimer timer0;
uint32_t j,todac;
long prev2,d,t;
static long LMSIZE =16;
uint32_t accumulator[9]={};
uint32_t increment[9]={};
uint16_t out[9]={};
uint32_t freq[9]={};
int waveindex[9]={};
byte tick;
int dds_rate=25;
long dds_tune;
int raw;

void setup() {

  SPIFIFO.begin(10,SPI_CLOCK_24MHz);
  timer0.begin(DDS, dds_rate);
  dds_tune=1/(dds_rate*.000001);
  analogWriteResolution(12);
  delay(100);
}


void DDS() 
{
  t=micros();

  n2f(0,500^j);
  int vt0 =  vtri_voice(0,512,255);
  n2f(1,1000&j);
  int vt1 =  vtri_voice(1,j,255);
  n2f(2,1200*j);
  int vt2 =  vtri_voice(2,j,128);
  n2f(3,250);
  int vt3 =  vtri_voice(3,j,255);
  n2f(4,125/2);
  int vt4 =  vtri_voice(4,j,255);
  n2f(5,3000&j);
  int vt5 =  vtri_voice(5,j,255);  

/*
  n2f(0,64|j);
  int vt0 =  vtri_voice(0,512,255);
  n2f(1,128|vt0);
  int vt1 =  vtri_voice(1,j,255);
  n2f(2,256|j);
  int vt2 =  vtri_voice(2,j,128);
  n2f(3,512|vt2);
  int vt3 =  vtri_voice(3,j,255);
  n2f(4,1024|vt3);
  int vt4 =  vtri_voice(4,j,128);
  n2f(5,6000/j);
  int vt5 =  vtri_voice(5,j,255);  
  */
   drymix=(vt0+vt1+vt2+vt3+vt4+vt5)>>3;

  // todac = (1 << 15) | (1 << 14) | (1<< 13) | (1 << 12) | ( outmix ); 
  // SPIFIFO.write16(todac);

      analogWrite(A14, drymix);
      

  d=micros()-t;


}

void loop() {

  if ((millis()-prev2)>5){
    j++;
    j%=1024;

    prev2=millis();
    Serial.print(d);       
    Serial.print( " " );
    Serial.println(drymix);       
  }

}



uint16_t vtri_voice(volatile byte vn, int16_t knee, byte amp){
  int16_t tempout;
  int waveamp=4095;
  int wavelength=1024;
  accumulator[vn] += increment[vn]; 
  waveindex[vn]=((accumulator[vn]) >> 22); 
  //   out[vn]= pgm_read_word(&tempout);  

  if (waveindex[vn]<knee){
    tempout=((waveindex[vn])*waveamp)/knee;
  }

  if (waveindex[vn]>=knee){
    tempout=((((waveindex[vn]-knee)*waveamp)/(wavelength-knee))*-1)+waveamp;
  }
  return  (tempout*amp)>>8;

} 

void n2f(byte n, long freq){
  increment[n] = ((65535*(freq))/(dds_tune))<<16 ; 

}

John-Mike
bleeplabs.com
 
Last edited:
There must have been something odd in my previous speed test code as when I tried SPIFIFO again it was considerably faster.

On the 3.0 it takes under 2.5us to change the CS and send and receive 2 bytes.
The 3.1 takes under 2.25.

Here's the unconnected test code. The speeds are similar when it's hooked up to a few DACs.

Code:
#include <SPIFIFO.h>
IntervalTimer timer0;
long prev2,d,t;

void setup() {
  timer0.begin(DDS, 25);
}


void DDS() 
{
int temp1=65000;
  t=micros();

  SPIFIFO.begin(9,SPI_CLOCK_24MHz);
  SPIFIFO.write16(temp1);
  int temp = SPIFIFO.read();

  SPIFIFO.begin(10,SPI_CLOCK_24MHz);
  SPIFIFO.write16(temp1);
  temp = SPIFIFO.read();

  SPIFIFO.begin(20,SPI_CLOCK_24MHz);
  SPIFIFO.write16(temp1);
  temp = SPIFIFO.read();

  SPIFIFO.begin(23,SPI_CLOCK_24MHz);
  SPIFIFO.write16(temp1);
  temp = SPIFIFO.read();

  d=micros()-t;
}

void loop() {

   // j++;
   // j%=1024;
   if ((millis()-prev2)>100){
    prev2=millis();
    Serial.println(d);       
    Serial.print( " " );

  }

}
 
Last edited:
Yes, a call to begin() is needed to switch to a different chip.

Maybe it ought to have a way to rapidly change to a different chip without affecting the other settings?
 
Status
Not open for further replies.
Back
Top