// inslude the SPI library:
// ssh root@ yourYunsName.local 'telnet localhost 6571'
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>
#include <SPI.h>
// set pin 10 as the slave select for the digital pot:
const int slaveSelectPin = 10;
void setup()
{
// Serial.begin(9600);
Bridge.begin();
Console.begin();
// Wait for Console port to connect
while (!Console);
Console.println("Hi, what's your name?");
// set the slaveSelectPin as an output:
pinMode (10, OUTPUT);
// SPI.setClockDivider(SPI_CLOCK_DIV2);
// SPI.setDataMode(SPI_MODE0);
digitalWrite(10, HIGH);
// initialize SPI:
SPI.begin();
}
void loop()
{
int i, j;
do{
Console.println("spi transfer");
digitalWrite(10, LOW);
i = SPI.transfer(0x55);
Console.println(i);
i = SPI.transfer(0x01);
Console.println(i);
digitalWrite(10, HIGH);
delay(1000);
}
while(1);
}
void digitalPotWrite(int address, int value) {
// take the SS pin low to select the chip:
digitalWrite(slaveSelectPin, LOW);
// send in the address and value via SPI:
SPI.transfer(address);
SPI.transfer(value);
// take the SS pin high to de-select the chip:
digitalWrite(slaveSelectPin, HIGH);
}
#include <t3spi.h>
//Initialize T3SPI class as SPI_SLAVE
T3SPI SPI_SLAVE;
//The number of integers per data packet
//MUST be the same as defined on the MASTER device
#define dataLength 2
//Initialize the arrays for incoming data
volatile uint8_t data[dataLength] = {};
//volatile uint16_t data[dataLength] = {};
//Initialize the arrays for outgoing data
volatile uint8_t returnData[dataLength] = {};
//volatile uint16_t returnData[dataLength] = {};
void setup(){
Serial.begin(115200);
//Begin SPI in SLAVE (SCK pin, MOSI pin, MISO pin, CS pin)
SPI_SLAVE.begin_SLAVE(SCK, MOSI, MISO, CS0);
//Set the CTAR0_SLAVE0 (Frame Size, SPI Mode)
SPI_SLAVE.setCTAR_SLAVE(8, SPI_MODE0);
//SPI_SLAVE.setCTAR_SLAVE(16, SPI_MODE0);
//SPI_SLAVE
//Enable the SPI0 Interrupt
NVIC_ENABLE_IRQ(IRQ_SPI0);
//Poputlate the array of outgoing data
for (int i=0; i<dataLength; i++){
returnData[i]=0x55;}
}
void loop()
{
//Capture the time before receiving data
if (SPI_SLAVE.dataPointer==0 && SPI_SLAVE.packetCT==0){
SPI_SLAVE.timeStamp1=micros();}
//Capture the time when transfer is done
if (SPI_SLAVE.packetCT==1){
SPI_SLAVE.timeStamp2=micros();
//Print data received & data sent
for (int i=0; i<dataLength; i++){
Serial.print("data[");
Serial.print(i);
Serial.print("]: ");
Serial.print(data[i]);
Serial.print(" returnData[");
Serial.print(i);
Serial.print("]: ");
Serial.println(returnData[i]);
Serial.flush();}
//Print statistics for the previous transfer
SPI_SLAVE.printStatistics(dataLength);
//Reset the packet count
SPI_SLAVE.packetCT=0;}
}
//Interrupt Service Routine to handle incoming data
void spi0_isr(void)
{
//Function to handle data
SPI_SLAVE.rxtx8 (data, returnData, dataLength);
//SPI_SLAVE.rxtx16(data, returnData, dataLength);
}
All the code is pretty simple, but it's odd with the CS line and I am sure it's working but just not 100% sure. If I connect the CS line to Yun pin 10 I can see the SPI transfer and it's transferring data . If the CS is un-connected I still get SPI transfer and if SPI is held high (5v) there is no SPI transfer. I would have expected it only to work with the CS connected to YUN GPIO CS, as this would trigger the SPI ISR and then SPI transfer. But, the SPI seems to be working on may be CLK? I need to get a new scope, then I can try to decode the CS & CLK lines.
This setup works okay with Teensy 3.1 and Yun.
Can the ibrary be used at higher speed than 24 MHZ ?
Probably not. I believe it's the max (and that's very fast)
On another note, Paul, is there any chance of SPI slave support on the core SPI library any time soon?
So the library works, according to several people who have downloaded it. Here are the major issues:
...
2) the data being off a few indexes, or, the data from the master is not aligned to the data in the slave.
...So, when you say you halt the spi before clearing the fifo, do you only do it once during the initialization phase? I assume you aren't halting before popping data from the fifo?
void T3SPI::rxtx16(volatile uint16_t *dataIN, volatile uint16_t *dataOUT, int length){
dataIN[dataPointer] = SPI0_POPR;
dataPointer++;
if (dataPointer == length){
dataPointer=0;
packetCT++;}
SPI0_PUSHR_SLAVE = dataOUT[dataPointer];
SPI0_SR |= SPI_SR_RFDF;
}
void T3SPI::rxtx16(volatile uint16_t *dataIN, volatile uint16_t *dataOUT, int length){
dataIN[dataPointer] = SPI0_POPR;
SPI0_PUSHR_SLAVE = dataOUT[dataPointer];
dataPointer++;
if (dataPointer == length){
dataPointer=0;
packetCT++;}
SPI0_SR |= SPI_SR_RFDF;
}
oid T3SPI::rxtx16(volatile uint16_t *dataIN, volatile uint16_t *dataOUT, int length){
dataIN[dataPointer] = SPI0_POPR;
dataPointer++;
if (dataPointer == length){
dataPointer=0;
packetCT++;
delay(2);
}
SPI0_PUSHR_SLAVE = dataOUT[dataPointer];
SPI0_SR |= SPI_SR_RFDF;
}
SPI0_PUSHR_SLAVE = dataOUT[dataPointer];
SPI0_PUSHR_SLAVE = dataOUT[0];
#include <Arduino.h>
#include "mk20dx128.h"
#include "core_pins.h"
#include "stdintextended.h"
#define SPI_START() (SPI0_MCR &= ~SPI_MCR_HALT & ~SPI_MCR_MDIS)
#define SPI_STOP() (SPI0_MCR |= SPI_MCR_HALT | SPI_MCR_MDIS)
void SPIPrintConfig(void);
u8 SPIRead(void);
void setup()
{
delay(3000); // Allow time for the serial connection to be established following reset/programming
Serial.begin(115200);
SIM_SCGC6 |= SIM_SCGC6_SPI0; // enable clock to SPI.
SPI_STOP();
CORE_PIN13_CONFIG = PORT_PCR_MUX(2);
CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
CORE_PIN10_CONFIG = PORT_PCR_MUX(2);
// Slave mode
SPI0_MCR &= ~SPI_MCR_MSTR;
// SPI0_CTAR0_SLAVE config
SPI0_CTAR0_SLAVE = 0;
// Frame Size
SPI0_CTAR0_SLAVE |= SPI_CTAR_FMSZ(7);
// Clock Polarity
SPI0_CTAR0_SLAVE &= ~SPI_CTAR_CPOL;
// Clock Phase
SPI0_CTAR0_SLAVE &= ~SPI_CTAR_CPHA;
// Clear RX FIFO
SPI0_MCR |= SPI_MCR_CLR_RXF;
// Clear TX FIFO
SPI0_MCR |= SPI_MCR_CLR_TXF;
// Disable TX FIFO
SPI0_MCR |= SPI_MCR_DIS_TXF;
// Disable RX FIFO
SPI0_MCR |= SPI_MCR_DIS_RXF;
SPI_START();
SPIPrintConfig();
}
void loop()
{
u8 rxData;
while(1)
{
rxData = SPIRead();
Serial.print("RX = ");
Serial.print(rxData, HEX);
Serial.println();
}
}
u8 SPIRead(void)
{
u8 rxData = 0xAA;
SPI0_SR |= SPI_SR_TCF;
SPI0_PUSHR_SLAVE = 0xFF;
while ((SPI0_SR & SPI_SR_TCF) == 0)
{
}
rxData = (u8)SPI0_POPR;
return rxData;
}
void SPIPrintConfig(void)
{
uint32_t CTAR=0;
Serial.println("SPIO STATUS");
Serial.println();
Serial.println(" 33222222222211111111110000000000");
Serial.println(" 10987654321098765432109876543210");
Serial.println(" --------------------------------");
Serial.print("SPIO_MCR: ");
for (unsigned int mask = 0x80000000; mask; mask >>= 1)
{
Serial.print(mask&SPI0_MCR?'1':'0');
}
Serial.println();
Serial.print("SPIO_CTAR_SLAVE: ");
CTAR = SPI0_CTAR0_SLAVE;
for (unsigned int mask = 0x80000000; mask; mask >>= 1)
{
Serial.print(mask&CTAR?'1':'0');
}
Serial.println();
Serial.print("SPI0_SR: ");
for (unsigned int mask = 0x80000000; mask; mask >>= 1)
{
Serial.print(mask&SPI0_SR?'1':'0');
}
Serial.println();
Serial.print("SPI0_RSER: ");
for (unsigned int mask = 0x80000000; mask; mask >>= 1)
{
Serial.print(mask&SPI0_RSER?'1':'0');
}
Serial.println();
Serial.println();
Serial.println();
}