Last active
April 28, 2023 10:18
-
-
Save shaielc/e0937d68978b03b2544474b641328145 to your computer and use it in GitHub Desktop.
SlaveSPIClass_esp32_Arduino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<SlaveSPIClass.h> | |
int SlaveSPI::size = 0; | |
SlaveSPI** SlaveSPI::SlaveSPIVector = NULL; | |
void setupIntr(spi_slave_transaction_t * trans) | |
{ | |
for(int i=0 ; i<SlaveSPI::size;i++) | |
{ | |
if(SlaveSPI::SlaveSPIVector[i]->match(trans)) | |
SlaveSPI::SlaveSPIVector[i]->setup_intr(trans); | |
} | |
} | |
void transIntr(spi_slave_transaction_t * trans) | |
{ | |
for(int i=0 ; i<SlaveSPI::size;i++) | |
{ | |
if(SlaveSPI::SlaveSPIVector[i]->match(trans)) | |
SlaveSPI::SlaveSPIVector[i]->trans_intr(trans); | |
} | |
} | |
SlaveSPI::SlaveSPI() | |
{ | |
SlaveSPI** temp = new SlaveSPI * [size+1]; | |
for (int i=0;i<size;i++) | |
{ | |
temp[i]=SlaveSPIVector[i]; | |
} | |
temp[size] = this; | |
size++; | |
delete [] SlaveSPIVector; | |
SlaveSPIVector = temp; | |
buff = ""; | |
transBuffer = ""; | |
} | |
void SlaveSPI::begin(gpio_num_t so,gpio_num_t si,gpio_num_t sclk,gpio_num_t ss,size_t length,void(* ext)()) | |
{ | |
//should set to the minimum transaction length | |
t_size = length; | |
driver = new spi_slave_transaction_t{t_size * 8 , 0 , heap_caps_malloc(max(t_size,32), MALLOC_CAP_DMA), heap_caps_malloc(max(t_size,32), MALLOC_CAP_DMA),NULL}; | |
spi_bus_config_t buscfg={ | |
.mosi_io_num=si, | |
.miso_io_num=so, | |
.sclk_io_num=sclk | |
}; | |
gpio_set_pull_mode(sclk, GPIO_PULLUP_ONLY); | |
gpio_set_pull_mode(ss, GPIO_PULLUP_ONLY); | |
spi_slave_interface_config_t slvcfg={ss,0,1,0,setupIntr,transIntr};//check the IDF for further explenation | |
spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg,1); //DMA channel 1 | |
spi_slave_queue_trans(HSPI_HOST,driver,portMAX_DELAY);//ready for input (no transmit) | |
exter_intr =ext; | |
} | |
void SlaveSPI::setup_intr(spi_slave_transaction_t *trans) | |
{//called when the trans is set in the queue | |
//didn't find use for it in the end. | |
} | |
void SlaveSPI::trans_intr(spi_slave_transaction_t *trans) | |
{//called when the trans has finished | |
for(int i=0;i<(driver->trans_len/8);i++) | |
{ | |
buff += ((char*)driver->rx_buffer)[i]; | |
((char*) driver->rx_buffer)[i] = (char)0; | |
size++; | |
} | |
setDriver(); | |
exter_intr(); | |
} | |
void SlaveSPI::trans_queue(String& transmission){ | |
//used to queue data to transmit | |
for (int i=0;i<transmission.length();i++) | |
transBuffer += transmission[i]; | |
} | |
inline bool SlaveSPI::match(spi_slave_transaction_t * trans) | |
{ | |
return (this->driver == trans); | |
} | |
void SlaveSPI::setDriver() | |
{ | |
driver->user = NULL; | |
int i=0; | |
for(;i<(driver->trans_len/8)&&i<transBuffer.length();i++) | |
{ | |
((char*) driver->tx_buffer)[i] = transBuffer[i]; | |
} | |
transBuffer = &(transBuffer[i]); | |
driver->length=t_size*8; | |
driver->trans_len = 0; | |
spi_slave_queue_trans(HSPI_HOST,driver,portMAX_DELAY); | |
} | |
char SlaveSPI::read() | |
{ | |
char temp = buff[0]; | |
buff.remove(0,1); | |
size--; | |
return temp; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SLAVE_SPI_CLASS | |
#define SLAVE_SPI_CLASS | |
#include "Arduino.h" | |
#include "driver/spi_slave.h" | |
void setupIntr(spi_slave_transaction_t * trans); | |
void transIntr(spi_slave_transaction_t * trans); | |
class SlaveSPI | |
{ | |
static SlaveSPI** SlaveSPIVector; | |
static int size; | |
friend void setupIntr(spi_slave_transaction_t * trans); | |
friend void transIntr(spi_slave_transaction_t * trans); | |
String buff;//used to save incoming data | |
String transBuffer;//used to buffer outgoing data !not tested! | |
spi_slave_transaction_t * driver; | |
void (*exter_intr)();//interrupt at the end of transmission , if u need to do something at the end of each transmission | |
size_t t_size;//length of transaction buffer, (should be set to maximum transition size) | |
public: | |
SlaveSPI(); | |
int size; | |
void setup_intr(spi_slave_transaction_t *trans);//called when the trans is set in the queue | |
void trans_intr(spi_slave_transaction_t *trans);//called when the trans has finished | |
void begin(gpio_num_t so,gpio_num_t si,gpio_num_t sclk,gpio_num_t ss,size_t length=128,void(* ext)() = NULL); | |
void trans_queue(String& transmission);//used to queue data to transmit | |
inline char* operator[](int i){return (&buff[i]);} | |
inline void flush(){buff = "";size=0;} | |
inline bool match(spi_slave_transaction_t * trans); | |
void setDriver(); | |
char read(); | |
inline String* getBuff(){return &buff;} | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SlaveSPIClass.h> | |
#include <SPI.h> | |
#define MO 22 | |
#define MI 23 | |
#define MCLK 19 | |
#define MS 18 | |
#define SO 32 | |
#define SI 25 | |
#define SCLK 27 | |
#define SS 34 | |
SlaveSPI slave; | |
SPIClass master(VSPI); | |
void test(); | |
void setup() { | |
Serial.begin(115200); | |
// put your setup code here, to run once: | |
master.begin(MCLK,MI,MO); | |
slave.begin((gpio_num_t)SO,(gpio_num_t)SI,(gpio_num_t)SCLK,(gpio_num_t)SS,8,test);//seems to work with groups of 4 bytes | |
SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0)); | |
pinMode(MS,OUTPUT); | |
} | |
String txt = ""; | |
String cmd =""; | |
void loop() { | |
// put your main code here, to run repeatedly: | |
if(slave.getBuff()->length()&&digitalRead(SS)==HIGH) | |
{ | |
while(slave.getBuff()->length()) | |
txt+=slave.read(); | |
Serial.println("slave input:"); | |
Serial.println(txt); | |
} | |
while(Serial.available()) | |
{ | |
cmd +=(char) Serial.read(); | |
} | |
while(txt.length()>0) | |
{ | |
slave.trans_queue(txt); | |
Serial.println("slave output:"); | |
Serial.println(txt); | |
txt =""; | |
} | |
while(cmd.length()>0) | |
{ | |
Serial.println("input:"); | |
Serial.println(cmd); | |
Serial.println("Master input:"); | |
digitalWrite(MS,LOW); | |
for(int i=0;i<cmd.length();i++) | |
{ | |
cmd[i] = master.transfer(cmd[i]); //ERROR : gives the transmitted data <<1 | |
} | |
digitalWrite(MS,HIGH); | |
for(int i=0;i<cmd.length();i++) | |
Serial.print(cmd[i],HEX); | |
cmd =""; | |
} | |
} | |
void test() | |
{ | |
//Serial.println("test"); | |
//Serial.println(slave[0]); | |
} | |
I am using platform IO, and after implementing all the fixes above, I cannot compile:
My error is inline 29 of .cpp file: tx_buffer = (uint8_t *)heap_caps_malloc(max(max_buffer_size, 32), SPI_MALLOC_CAP);
the error is: no instance of max(size_t,int)
any help or suggestions?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I feel like something else is wrong with
size
andsize_
.Fix #3
It does not make sense that an instance value is used in the constructor
SlaveSPI::SlaveSPI()
becausesize
is only used to affect the static memberSlaveSPIVector
.SlaveSPIClass.cpp @ lines 20 to 33: replace every
size
withSlaveSPI::size_
.Possible fix
The instance's
size
is not explicitly initialized. It looks like a buffer count. It should probably be initialized to 0 in the member initialization part of the constructor. The default value is to be checked.EDIT #1
Yes! My fixes #1 to #3 made it work somehow! I was receiving nothing at all without the fix #3. Now I'm receiving a corrupted message but at least I have a correct piece of it.