hi everyone
Seasons greetings
I hoping someone might be able to help me I'll try to keep it short. (Honestly ;-) )
I've been working with this excellent code https://forum.pjrc.com/threads/27651-SPI-DMA-slave-problem
I'm trying to integrate it into a synth Osc Filter Vca project. It involves the use of currently 3 x Teensy 3.2
I'm trying to use each teensy to try and spread the processing of Osscilators Filters etc whilst maintaing a high sample rate. Everything is interrupt driven at 23uS
Here is a Picture which shows the current configuration.
I started off with just 2 Teensy's one used as a oscillator and one as a filter to spread the code
Using a variation of the code i can have 4 + oscillator on Teensy 1 with spare code headroom which then SPi's using DMA to Teensy 2 to filter a single oscillator therefore
I can add any number of filter Teensys one for each voice giving me the ability to do true polyphonic. (It works great )
So now what i'm trying to achieve (If its at all possible) is to have the filter Teensy receive from the Oscillator then process through filter code. and send out to Teensy 3.
This obviously involves Switching from being a slave to being a master all within 23uS
The code that follows is for the Filter Teensy. (without the filter code itself 10uS ) I've moved thing round from the original code and have got to a position where in the main ISR if i change
" SlaveOrMaster = 0;//If you change this to 1 we transmit if 0 then we receive" it works as either Master or Slave. Utilising Clocks on both pin 14 and 13.
But one of the problems is if i move the SPI TRANSMIT SETUP_in the setup
into the masterSPI void it really not happy. So I'm wondering if its really possible for a Teensy to be both Master and Slave. I apologise if my approach seems a bit like hitting everything with a hammer to get it to work.
But i'm un tutored so normally have shall we say a unique approach.
If i could even get a clue if its possible that would be great
If i could get any hints that would be marvellous
If anyone has any other ideas on an alternative approach
I'm currently of the opionion it might not be possible and may have to resort to using the DAC on the Filter Teensy and then use ADC to get it into the 3rd Teensy for processing
If you got this far thanks for reading and Merry Christmas
A very old man
Seasons greetings
I hoping someone might be able to help me I'll try to keep it short. (Honestly ;-) )
I've been working with this excellent code https://forum.pjrc.com/threads/27651-SPI-DMA-slave-problem
I'm trying to integrate it into a synth Osc Filter Vca project. It involves the use of currently 3 x Teensy 3.2
I'm trying to use each teensy to try and spread the processing of Osscilators Filters etc whilst maintaing a high sample rate. Everything is interrupt driven at 23uS
Here is a Picture which shows the current configuration.
I started off with just 2 Teensy's one used as a oscillator and one as a filter to spread the code
Using a variation of the code i can have 4 + oscillator on Teensy 1 with spare code headroom which then SPi's using DMA to Teensy 2 to filter a single oscillator therefore
I can add any number of filter Teensys one for each voice giving me the ability to do true polyphonic. (It works great )
So now what i'm trying to achieve (If its at all possible) is to have the filter Teensy receive from the Oscillator then process through filter code. and send out to Teensy 3.
This obviously involves Switching from being a slave to being a master all within 23uS
The code that follows is for the Filter Teensy. (without the filter code itself 10uS ) I've moved thing round from the original code and have got to a position where in the main ISR if i change
" SlaveOrMaster = 0;//If you change this to 1 we transmit if 0 then we receive" it works as either Master or Slave. Utilising Clocks on both pin 14 and 13.
But one of the problems is if i move the SPI TRANSMIT SETUP_in the setup
into the masterSPI void it really not happy. So I'm wondering if its really possible for a Teensy to be both Master and Slave. I apologise if my approach seems a bit like hitting everything with a hammer to get it to work.
But i'm un tutored so normally have shall we say a unique approach.
If i could even get a clue if its possible that would be great
If i could get any hints that would be marvellous
If anyone has any other ideas on an alternative approach
I'm currently of the opionion it might not be possible and may have to resort to using the DAC on the Filter Teensy and then use ADC to get it into the 3rd Teensy for processing
If you got this far thanks for reading and Merry Christmas
A very old man
Code:
#include <TimerOne.h>
#define MasterNDAT 1
#define SlaveNDAT 8
#define SPI_CLOCK (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(48 / 5) * ((1+1)/2) = 9.8 MHz
uint16_t xx[MasterNDAT];//Master
uint16_t yy[SlaveNDAT];//Slave
volatile uint16_t printme;
volatile long testData = 0;
volatile int SlaveOrMaster = 0;
int SlaveISRclock = 5;
int MasterISRclock = 4;
void setup() {
pinMode (SlaveISRclock , INPUT);//ISR driven from Teensy 1
pinMode (MasterISRclock , OUTPUT);//ISR driving Teensy 3
// ______________SPI TRANSMIT SETUP________
SIM_SCGC6 |= SIM_SCGC6_SPI0;//Transmit Setup
CORE_PIN2_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2); // Master Setup SRE slew rate enable
CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2); // Master Setup DSE drive strength enable
CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(2);//Master Setup this is transmit pin
//ISR driven from Teensy 1
attachInterrupt(SlaveISRclock, mainISR, RISING);
}
void loop() {
Serial.println (printme); delay (80);//TestPrint
}//eo void loop
void mainISR() {
SlaveOrMaster = 0;
//Slave 8 Channels
if (SlaveOrMaster == 0) {
slaveSPI();
printme = (yy[7]);
analogWrite(A14, printme); //Just for testing
}
//_____________________________________________________________________
// Put code here to Receive Data on Channel 7 Process then send out to Tennsy 3
//_____________________________________________________________________
SlaveOrMaster = 0;//If you change this to 1 we transmit if 0 then we receive
//Master 1 Channel
if (SlaveOrMaster == 1) {
digitalWriteFast (MasterISRclock, HIGH);
masterSPI(testData++);
digitalWriteFast (MasterISRclock, LOW);
if (testData > 9999) {
testData = 0; //Test data reset
}
}
} //EO MainISR
void masterSPI(uint16_t data0) {
int ii;
for ( ii = 0; ii < MasterNDAT; ii++) {
xx[0] = data0; //this is data out Master
}
KINETISK_SPI0.MCR = SPI_MCR_MSTR;//Master
KINETISK_SPI0.CTAR0 = SPI_CLOCK | //Master
SPI_CTAR_FMSZ(15) | //Master
SPI_CTAR_PCSSCK(0) | //Master
SPI_CTAR_PASC(0) | //Master
SPI_CTAR_PDT(0) | //Master
SPI_CTAR_CSSCK(0) | //Master
SPI_CTAR_ASC(0) | //Master
SPI_CTAR_DT(0); //Master
// start SPI
KINETISK_SPI0.RSER = SPI_RSER_TFFF_DIRS | SPI_RSER_TFFF_RE ;//Master fifo fill flag to DMA
KINETISK_SPI0.MCR |= SPI_MCR_MSTR;
// set transmit
DMA_TCD0_DADDR = &SPI0_PUSHR;
DMA_TCD0_DOFF = 0;
DMA_TCD0_DLASTSGA = 0;
DMA_TCD0_ATTR = 1 << 8 | 1;
DMA_TCD0_NBYTES_MLNO = 2;
DMA_TCD0_SADDR = xx;
DMA_TCD0_SOFF = 2;
DMA_TCD0_SLAST = -2 * MasterNDAT;
DMA_TCD0_CITER_ELINKNO = DMA_TCD0_BITER_ELINKNO = MasterNDAT;
DMA_TCD0_CSR = DMA_TCD_CSR_INTMAJOR | DMA_TCD_CSR_DREQ;
DMAMUX0_CHCFG0 = DMAMUX_SOURCE_SPI0_TX | DMAMUX_ENABLE;
//start DMA
DMA_SERQ = 0;
NVIC_ENABLE_IRQ(IRQ_DMA_CH0);//enable SPI ISR
}//eo masterSPI
///ISR for Master
void dma_ch0_isr(void)
{
DMA_CINT = 0;
DMA_CDNE = 0;
}
void slaveSPI(void)
{
SIM_SCGC6 |= SIM_SCGC6_DMAMUX;//Slave Setup
SIM_SCGC7 |= SIM_SCGC7_DMA; //Slave Setup
DMA_CR = 0;////Slave Setup
CORE_PIN2_CONFIG = PORT_PCR_MUX(2); ////Slave Setup
CORE_PIN14_CONFIG = PORT_PCR_MUX(2); ////Slave Setup clock
CORE_PIN8_CONFIG = PORT_PCR_MUX(2);//This is the data recieve pin
//added from recieve was in void
SPI0_CTAR0_SLAVE = SPI_CTAR_FMSZ(15);
//spi SETUP
KINETISK_SPI0.MCR |= SPI_MCR_CLR_TXF;
// start SPI
KINETISK_SPI0.RSER = SPI_RSER_RFDF_DIRS | SPI_RSER_RFDF_RE; // receive fifo drain flag to DMA
KINETISK_SPI0.MCR = 0;
// set receive
DMA_TCD1_SADDR = &SPI0_POPR;
DMA_TCD1_SOFF = 0;
DMA_TCD1_SLAST = 0;
DMA_TCD1_ATTR = 1 << 8 | 1;
DMA_TCD1_NBYTES_MLNO = 2;
DMA_TCD1_DADDR = yy;
DMA_TCD1_DOFF = 2;
DMA_TCD1_DLASTSGA = -2 * SlaveNDAT;
DMA_TCD1_CITER_ELINKNO = DMA_TCD1_BITER_ELINKNO = SlaveNDAT;
DMA_TCD1_CSR = DMA_TCD_CSR_INTMAJOR | DMA_TCD_CSR_DREQ;
DMAMUX0_CHCFG1 = DMAMUX_DISABLE;
DMAMUX0_CHCFG1 = DMAMUX_SOURCE_SPI0_RX | DMAMUX_ENABLE;
//Enable IRQ
DMA_SERQ = 1;
NVIC_ENABLE_IRQ(IRQ_DMA_CH1);
}// eo slaveSPI
///ISR for Slave
void dma_ch1_isr(void)
{ DMA_CINT = 1;
DMA_CDNE = 1;
SPI0_MCR |= SPI_MCR_HALT | SPI_MCR_MDIS;
}