From cde4c963c999e57c03b30bb03423deabbbd8b5e0 Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Tue, 5 Jul 2016 18:25:11 +0300 Subject: [PATCH 1/2] Initial SPI Slave implementation and examples --- .../SPISlave_Master/SPISlave_Master.ino | 101 ++++++++++++++ .../SPISlave_SafeMaster.ino | 106 +++++++++++++++ .../examples/SPISlave_Test/SPISlave_Test.ino | 71 ++++++++++ libraries/SPISlave/keywords.txt | 25 ++++ libraries/SPISlave/library.properties | 9 ++ libraries/SPISlave/src/SPISlave.cpp | 83 ++++++++++++ libraries/SPISlave/src/SPISlave.h | 67 +++++++++ libraries/SPISlave/src/hspi_slave.c | 127 ++++++++++++++++++ libraries/SPISlave/src/hspi_slave.h | 41 ++++++ 9 files changed, 630 insertions(+) create mode 100644 libraries/SPISlave/examples/SPISlave_Master/SPISlave_Master.ino create mode 100644 libraries/SPISlave/examples/SPISlave_SafeMaster/SPISlave_SafeMaster.ino create mode 100644 libraries/SPISlave/examples/SPISlave_Test/SPISlave_Test.ino create mode 100644 libraries/SPISlave/keywords.txt create mode 100644 libraries/SPISlave/library.properties create mode 100644 libraries/SPISlave/src/SPISlave.cpp create mode 100644 libraries/SPISlave/src/SPISlave.h create mode 100644 libraries/SPISlave/src/hspi_slave.c create mode 100644 libraries/SPISlave/src/hspi_slave.h diff --git a/libraries/SPISlave/examples/SPISlave_Master/SPISlave_Master.ino b/libraries/SPISlave/examples/SPISlave_Master/SPISlave_Master.ino new file mode 100644 index 0000000000..903bed54fe --- /dev/null +++ b/libraries/SPISlave/examples/SPISlave_Master/SPISlave_Master.ino @@ -0,0 +1,101 @@ +/* + SPI Master Demo Sketch + Connect the SPI Master device to the following pins on the esp8266: + + GPIO NodeMCU Name | Uno + =================================== + 15 D8 SS | D10 + 13 D7 MOSI | D11 + 12 D6 MISO | D12 + 14 D5 SCK | D13 + + Note: If the ESP is booting at a moment when the SPI Master has the Select line HIGH (deselected) + the ESP8266 WILL FAIL to boot! + See SPISlave_SafeMaster example for possible workaround + +*/ +#include + +class ESPMaster { + private: + uint8_t _ss_pin; + + public: + ESPMaster(uint8_t pin):_ss_pin(pin){} + void begin(){ + pinMode(_ss_pin, OUTPUT); + digitalWrite(_ss_pin, HIGH); + } + + uint32_t readStatus(){ + digitalWrite(_ss_pin, LOW); + SPI.transfer(0x04); + uint32_t status = (SPI.transfer(0) | ((uint32_t)(SPI.transfer(0)) << 8) | ((uint32_t)(SPI.transfer(0)) << 16) | ((uint32_t)(SPI.transfer(0)) << 24)); + digitalWrite(_ss_pin, HIGH); + return status; + } + + void writeStatus(uint32_t status){ + digitalWrite(_ss_pin, LOW); + SPI.transfer(0x01); + SPI.transfer(status & 0xFF); + SPI.transfer((status >> 8) & 0xFF); + SPI.transfer((status >> 16) & 0xFF); + SPI.transfer((status >> 24) & 0xFF); + digitalWrite(_ss_pin, HIGH); + } + + void readData(uint8_t * data){ + digitalWrite(_ss_pin, LOW); + SPI.transfer(0x03); + SPI.transfer(0x00); + for(uint8_t i=0; i<32; i++) data[i] = SPI.transfer(0); + digitalWrite(_ss_pin, HIGH); + } + + void writeData(uint8_t * data, size_t len){ + uint8_t i=0; + digitalWrite(_ss_pin, LOW); + SPI.transfer(0x02); + SPI.transfer(0x00); + while(len-- && i < 32) SPI.transfer(data[i++]); + while(i++ < 32) SPI.transfer(0); + digitalWrite(_ss_pin, HIGH); + } + + String readData(){ + char data[33]; + data[32] = 0; + readData((uint8_t *)data); + return String(data); + } + + void writeData(const char * data){ + writeData((uint8_t *)data, strlen(data)); + } +}; + +ESPMaster esp(SS); + +void send(const char * message){ + Serial.print("Master: "); + Serial.println(message); + esp.writeData(message); + delay(10); + Serial.print("Slave: "); + Serial.println(esp.readData()); + Serial.println(); +} + +void setup() { + Serial.begin(115200); + SPI.begin(); + esp.begin(); + delay(1000); + send("Hello Slave!"); +} + +void loop(){ + delay(1000); + send("Are you alive?"); +} diff --git a/libraries/SPISlave/examples/SPISlave_SafeMaster/SPISlave_SafeMaster.ino b/libraries/SPISlave/examples/SPISlave_SafeMaster/SPISlave_SafeMaster.ino new file mode 100644 index 0000000000..ef94f7490d --- /dev/null +++ b/libraries/SPISlave/examples/SPISlave_SafeMaster/SPISlave_SafeMaster.ino @@ -0,0 +1,106 @@ +/* + SPI Safe Master Demo Sketch + Connect the SPI Master device to the following pins on the esp8266: + + GPIO NodeMCU Name | Uno + =================================== + 15 D8 SS | D10 + 13 D7 MOSI | D11 + 12 D6 MISO | D12 + 14 D5 SCK | D13 + + Note: If the ESP is booting at a moment when the SPI Master has the Select line HIGH (deselected) + the ESP8266 WILL FAIL to boot! + This sketch tries to go around this issue by only pulsing the Slave Select line to reset the command + and keeping the line LOW all other time. + +*/ +#include + +class ESPSafeMaster { + private: + uint8_t _ss_pin; + void _pulseSS(){ + digitalWrite(_ss_pin, HIGH); + delayMicroseconds(5); + digitalWrite(_ss_pin, LOW); + } + public: + ESPSafeMaster(uint8_t pin):_ss_pin(pin){} + void begin(){ + pinMode(_ss_pin, OUTPUT); + _pulseSS(); + } + + uint32_t readStatus(){ + _pulseSS(); + SPI.transfer(0x04); + uint32_t status = (SPI.transfer(0) | ((uint32_t)(SPI.transfer(0)) << 8) | ((uint32_t)(SPI.transfer(0)) << 16) | ((uint32_t)(SPI.transfer(0)) << 24)); + _pulseSS(); + return status; + } + + void writeStatus(uint32_t status){ + _pulseSS(); + SPI.transfer(0x01); + SPI.transfer(status & 0xFF); + SPI.transfer((status >> 8) & 0xFF); + SPI.transfer((status >> 16) & 0xFF); + SPI.transfer((status >> 24) & 0xFF); + _pulseSS(); + } + + void readData(uint8_t * data){ + _pulseSS(); + SPI.transfer(0x03); + SPI.transfer(0x00); + for(uint8_t i=0; i<32; i++) data[i] = SPI.transfer(0); + _pulseSS(); + } + + void writeData(uint8_t * data, size_t len){ + uint8_t i=0; + _pulseSS(); + SPI.transfer(0x02); + SPI.transfer(0x00); + while(len-- && i < 32) SPI.transfer(data[i++]); + while(i++ < 32) SPI.transfer(0); + _pulseSS(); + } + + String readData(){ + char data[33]; + data[32] = 0; + readData((uint8_t *)data); + return String(data); + } + + void writeData(const char * data){ + writeData((uint8_t *)data, strlen(data)); + } +}; + +ESPSafeMaster esp(SS); + +void send(const char * message){ + Serial.print("Master: "); + Serial.println(message); + esp.writeData(message); + delay(10); + Serial.print("Slave: "); + Serial.println(esp.readData()); + Serial.println(); +} + +void setup() { + Serial.begin(115200); + SPI.begin(); + esp.begin(); + delay(1000); + send("Hello Slave!"); +} + +void loop(){ + delay(1000); + send("Are you alive?"); +} diff --git a/libraries/SPISlave/examples/SPISlave_Test/SPISlave_Test.ino b/libraries/SPISlave/examples/SPISlave_Test/SPISlave_Test.ino new file mode 100644 index 0000000000..8f9ee6ba6c --- /dev/null +++ b/libraries/SPISlave/examples/SPISlave_Test/SPISlave_Test.ino @@ -0,0 +1,71 @@ +/* + SPI Slave Demo Sketch + Connect the SPI Master device to the following pins on the esp8266: + + GPIO NodeMCU Name | Uno + =================================== + 15 D8 SS | D10 + 13 D7 MOSI | D11 + 12 D6 MISO | D12 + 14 D5 SCK | D13 + + Note: If the ESP is booting at a moment when the SPI Master has the Select line HIGH (deselected) + the ESP8266 WILL FAIL to boot! + See SPISlave_SafeMaster example for possible workaround + +*/ + +#include "SPISlave.h" + +void setup() { + Serial.begin(115200); + Serial.setDebugOutput(true); + + // data has been received from the master. Beware that len is always 32 + // and the buffer is autofilled with zeroes if data is less than 32 bytes long + // It's up to the user to implement protocol for handling data length + SPISlave.onData([](uint8_t * data, size_t len){ + String message = String((char *)data); + if(message.equals("Hello Slave!")){ + SPISlave.setData("Hello Master!"); + } else if(message.equals("Are you alive?")){ + char answer[33]; + sprintf(answer,"Alive for %u seconds!", millis() / 1000); + SPISlave.setData(answer); + } else { + SPISlave.setData("Say what?"); + } + Serial.printf("Question: %s\n", (char *)data); + }); + + // The master has read out outgoing data buffer + // that buffer can be set with SPISlave.setData + SPISlave.onDataSent([](){ + Serial.println("Answer Sent"); + }); + + // status has been received from the master. + // The status register is a special register that bot the slave and the master can write to and read from. + // Can be used to exchange small data or status information + SPISlave.onStatus([](uint32_t data){ + Serial.printf("Status: %u\n", data); + SPISlave.setStatus(millis()); //set next status + }); + + // The master has read the status register + SPISlave.onStatusSent([](){ + Serial.println("Status Sent"); + }); + + // Setup SPI Slave registers and pins + SPISlave.begin(); + + // Set the status register (if the master reads it, it will read this value) + SPISlave.setStatus(millis()); + + // Sets the data registers. Limited to 32 bytes at a time. + // SPISlave.setData(uint8_t * data, size_t len); is also available with the same limitation + SPISlave.setData("Ask me a question!"); +} + +void loop() {} diff --git a/libraries/SPISlave/keywords.txt b/libraries/SPISlave/keywords.txt new file mode 100644 index 0000000000..dfa7974fbf --- /dev/null +++ b/libraries/SPISlave/keywords.txt @@ -0,0 +1,25 @@ +####################################### +# Syntax Coloring Map SPI Slave +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +SPISlave KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +setData KEYWORD2 +setStatus KEYWORD2 +onData KEYWORD2 +onDataSent KEYWORD2 +onStatus KEYWORD2 +onStatusSent KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/SPISlave/library.properties b/libraries/SPISlave/library.properties new file mode 100644 index 0000000000..fdbd70ceaf --- /dev/null +++ b/libraries/SPISlave/library.properties @@ -0,0 +1,9 @@ +name=SPISlave +version=1.0 +author=Arduino +maintainer=Arduino +sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. +paragraph= +category=Signal Input/Output +url=http://arduino.cc/en/Reference/SPI +architectures=esp8266 diff --git a/libraries/SPISlave/src/SPISlave.cpp b/libraries/SPISlave/src/SPISlave.cpp new file mode 100644 index 0000000000..8344fbe66d --- /dev/null +++ b/libraries/SPISlave/src/SPISlave.cpp @@ -0,0 +1,83 @@ +/* + SPISlave library for esp8266 + + Copyright (c) 2015 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "SPISlave.h" +extern "C" { + #include "hspi_slave.h" +} + +void SPISlaveClass::_data_rx(uint8_t * data, uint8_t len){ + if(_data_cb) + _data_cb(data, len); +} +void SPISlaveClass::_status_rx(uint32_t data){ + if(_status_cb) + _status_cb(data); +} +void SPISlaveClass::_data_tx(void){ + if(_data_sent_cb) + _data_sent_cb(); +} +void SPISlaveClass::_status_tx(void){ + if(_status_sent_cb) + _status_sent_cb(); +} +void SPISlaveClass::_s_data_rx(void *arg, uint8_t * data, uint8_t len){ + reinterpret_cast(arg)->_data_rx(data,len); +} +void SPISlaveClass::_s_status_rx(void *arg, uint32_t data){ + reinterpret_cast(arg)->_status_rx(data); +} +void SPISlaveClass::_s_data_tx(void *arg){ + reinterpret_cast(arg)->_data_tx(); +} +void SPISlaveClass::_s_status_tx(void *arg){ + reinterpret_cast(arg)->_status_tx(); +} + +void SPISlaveClass::begin(){ + hspi_slave_onData(&_s_data_rx); + hspi_slave_onDataSent(&_s_data_tx); + hspi_slave_onStatus(&_s_status_rx); + hspi_slave_onStatusSent(&_s_status_tx); + hspi_slave_begin(4, this); +} +void SPISlaveClass::setData(uint8_t * data, size_t len){ + if(len > 32) + len = 32; + hspi_slave_setData(data, len); +} +void SPISlaveClass::setStatus(uint32_t status){ + hspi_slave_setStatus(status); +} +void SPISlaveClass::onData(SpiSlaveDataHandler cb){ + _data_cb = cb; +} +void SPISlaveClass::onDataSent(SpiSlaveSentHandler cb){ + _data_sent_cb = cb; +} +void SPISlaveClass::onStatus(SpiSlaveStatusHandler cb){ + _status_cb = cb; +} +void SPISlaveClass::onStatusSent(SpiSlaveSentHandler cb){ + _status_sent_cb = cb; +} + +SPISlaveClass SPISlave; diff --git a/libraries/SPISlave/src/SPISlave.h b/libraries/SPISlave/src/SPISlave.h new file mode 100644 index 0000000000..81caeeff52 --- /dev/null +++ b/libraries/SPISlave/src/SPISlave.h @@ -0,0 +1,67 @@ +/* + SPISlave library for esp8266 + + Copyright (c) 2015 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef _SPISLAVE_H_INCLUDED +#define _SPISLAVE_H_INCLUDED + +#include "Arduino.h" +#include + +typedef std::function SpiSlaveDataHandler; +typedef std::function SpiSlaveStatusHandler; +typedef std::function SpiSlaveSentHandler; + +class SPISlaveClass { + protected: + SpiSlaveDataHandler _data_cb; + SpiSlaveStatusHandler _status_cb; + SpiSlaveSentHandler _data_sent_cb; + SpiSlaveSentHandler _status_sent_cb; + void _data_rx(uint8_t * data, uint8_t len); + void _status_rx(uint32_t data); + void _data_tx(void); + void _status_tx(void); + static void _s_data_rx(void *arg, uint8_t * data, uint8_t len); + static void _s_status_rx(void *arg, uint32_t data); + static void _s_data_tx(void *arg); + static void _s_status_tx(void *arg); + public: + SPISlaveClass() + : _data_cb(NULL) + , _status_cb(NULL) + , _data_sent_cb(NULL) + , _status_sent_cb(NULL) + {} + ~SPISlaveClass(){} + void begin(); + void setData(uint8_t * data, size_t len); + void setData(const char * data){ + setData((uint8_t *)data, strlen(data)); + } + void setStatus(uint32_t status); + void onData(SpiSlaveDataHandler cb); + void onDataSent(SpiSlaveSentHandler cb); + void onStatus(SpiSlaveStatusHandler cb); + void onStatusSent(SpiSlaveSentHandler cb); +}; + +extern SPISlaveClass SPISlave; + +#endif diff --git a/libraries/SPISlave/src/hspi_slave.c b/libraries/SPISlave/src/hspi_slave.c new file mode 100644 index 0000000000..0547e78918 --- /dev/null +++ b/libraries/SPISlave/src/hspi_slave.c @@ -0,0 +1,127 @@ +/* + SPISlave library for esp8266 + + Copyright (c) 2015 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "hspi_slave.h" +#include "esp8266_peri.h" +#include "ets_sys.h" + +static void (*_hspi_slave_rx_data_cb)(void * arg, uint8_t * data, uint8_t len) = NULL; +static void (*_hspi_slave_tx_data_cb)(void * arg) = NULL; +static void (*_hspi_slave_rx_status_cb)(void * arg, uint32_t data) = NULL; +static void (*_hspi_slave_tx_status_cb)(void * arg) = NULL; +static uint8_t _hspi_slave_buffer[33]; + +void ICACHE_RAM_ATTR _hspi_slave_isr_handler(void *arg){ + uint32_t status; + uint32_t istatus; + + istatus = SPIIR; + + if(istatus & (1 << SPII1)){ //SPI1 ISR + status = SPI1S; + SPI1S &= ~(0x3E0);//disable interrupts + SPI1S |= SPISSRES;//reset + SPI1S &= ~(0x1F);//clear interrupts + SPI1S |= (0x3E0);//enable interrupts + + if((status & SPISRBIS) != 0 && (_hspi_slave_tx_data_cb)) + _hspi_slave_tx_data_cb(arg); + if((status & SPISRSIS) != 0 && (_hspi_slave_tx_status_cb)) + _hspi_slave_tx_status_cb(arg); + if((status & SPISWSIS) != 0 && (_hspi_slave_rx_status_cb)){ + uint32_t s = SPI1WS; + _hspi_slave_rx_status_cb(arg, s); + } + if((status & SPISWBIS) != 0 && (_hspi_slave_rx_data_cb)){ + uint8_t i; + uint32_t data; + uint8_t buffer[33]; + _hspi_slave_buffer[32] = 0; + for(i=0;i<8;i++){ + data=SPI1W(i); + _hspi_slave_buffer[i<<2] = data & 0xff; + _hspi_slave_buffer[(i<<2)+1] = (data >> 8) & 0xff; + _hspi_slave_buffer[(i<<2)+2] = (data >> 16) & 0xff; + _hspi_slave_buffer[(i<<2)+3] = (data >> 24) & 0xff; + } + _hspi_slave_rx_data_cb(arg, &_hspi_slave_buffer[0], 32); + } + } else if(istatus & (1 << SPII0)){ //SPI0 ISR + SPI0S &= ~(0x3ff);//clear SPI ISR + } else if(istatus & (1 << SPII2)){} //I2S ISR +} + +void hspi_slave_begin(uint8_t status_len, void * arg){ + status_len &= 7; + if(status_len > 4) status_len == 4;//max 32 bits + if(status_len == 0) status_len == 1;//min 8 bits + + pinMode(SS, SPECIAL); + pinMode(SCK, SPECIAL); + pinMode(MISO, SPECIAL); + pinMode(MOSI, SPECIAL); + + SPI1S = SPISE | SPISBE | 0x3E0; + SPI1U = SPIUMISOH | SPIUCOMMAND | SPIUSSE; + SPI1CLK = 0; + SPI1U2 = (7 << SPILCOMMAND); + SPI1S1 = (((status_len * 8) - 1) << SPIS1LSTA) | (0xff << SPIS1LBUF) | (7 << SPIS1LWBA) | (7 << SPIS1LRBA) | SPIS1RSTA; + SPI1P = (1 << 19); + SPI1CMD = SPIBUSY; + + ETS_SPI_INTR_ATTACH(_hspi_slave_isr_handler,arg); + ETS_SPI_INTR_ENABLE(); +} + +void hspi_slave_setStatus(uint32_t status){ + SPI1WS = status; +} + +void hspi_slave_setData(uint8_t *data, uint8_t len){ + uint8_t i; + uint32_t out = 0; + uint8_t bi = 0; + uint8_t wi = 8; + + for(i=0; i<32; i++){ + out |= (i Date: Tue, 5 Jul 2016 19:36:11 +0300 Subject: [PATCH 2/2] Update style and info --- .../SPISlave_Master/SPISlave_Master.ino | 137 ++++++++------ .../SPISlave_SafeMaster.ino | 146 ++++++++------- .../examples/SPISlave_Test/SPISlave_Test.ino | 85 ++++----- libraries/SPISlave/library.properties | 8 +- libraries/SPISlave/src/SPISlave.cpp | 128 +++++++------ libraries/SPISlave/src/SPISlave.h | 22 ++- libraries/SPISlave/src/hspi_slave.c | 176 ++++++++++-------- 7 files changed, 388 insertions(+), 314 deletions(-) diff --git a/libraries/SPISlave/examples/SPISlave_Master/SPISlave_Master.ino b/libraries/SPISlave/examples/SPISlave_Master/SPISlave_Master.ino index 903bed54fe..107467cc44 100644 --- a/libraries/SPISlave/examples/SPISlave_Master/SPISlave_Master.ino +++ b/libraries/SPISlave/examples/SPISlave_Master/SPISlave_Master.ino @@ -16,86 +16,103 @@ */ #include -class ESPMaster { - private: +class ESPMaster +{ +private: uint8_t _ss_pin; - public: - ESPMaster(uint8_t pin):_ss_pin(pin){} - void begin(){ - pinMode(_ss_pin, OUTPUT); - digitalWrite(_ss_pin, HIGH); +public: + ESPMaster(uint8_t pin):_ss_pin(pin) {} + void begin() + { + pinMode(_ss_pin, OUTPUT); + digitalWrite(_ss_pin, HIGH); } - - uint32_t readStatus(){ - digitalWrite(_ss_pin, LOW); - SPI.transfer(0x04); - uint32_t status = (SPI.transfer(0) | ((uint32_t)(SPI.transfer(0)) << 8) | ((uint32_t)(SPI.transfer(0)) << 16) | ((uint32_t)(SPI.transfer(0)) << 24)); - digitalWrite(_ss_pin, HIGH); - return status; + + uint32_t readStatus() + { + digitalWrite(_ss_pin, LOW); + SPI.transfer(0x04); + uint32_t status = (SPI.transfer(0) | ((uint32_t)(SPI.transfer(0)) << 8) | ((uint32_t)(SPI.transfer(0)) << 16) | ((uint32_t)(SPI.transfer(0)) << 24)); + digitalWrite(_ss_pin, HIGH); + return status; } - void writeStatus(uint32_t status){ - digitalWrite(_ss_pin, LOW); - SPI.transfer(0x01); - SPI.transfer(status & 0xFF); - SPI.transfer((status >> 8) & 0xFF); - SPI.transfer((status >> 16) & 0xFF); - SPI.transfer((status >> 24) & 0xFF); - digitalWrite(_ss_pin, HIGH); + void writeStatus(uint32_t status) + { + digitalWrite(_ss_pin, LOW); + SPI.transfer(0x01); + SPI.transfer(status & 0xFF); + SPI.transfer((status >> 8) & 0xFF); + SPI.transfer((status >> 16) & 0xFF); + SPI.transfer((status >> 24) & 0xFF); + digitalWrite(_ss_pin, HIGH); } - void readData(uint8_t * data){ - digitalWrite(_ss_pin, LOW); - SPI.transfer(0x03); - SPI.transfer(0x00); - for(uint8_t i=0; i<32; i++) data[i] = SPI.transfer(0); - digitalWrite(_ss_pin, HIGH); + void readData(uint8_t * data) + { + digitalWrite(_ss_pin, LOW); + SPI.transfer(0x03); + SPI.transfer(0x00); + for(uint8_t i=0; i<32; i++) { + data[i] = SPI.transfer(0); + } + digitalWrite(_ss_pin, HIGH); } - void writeData(uint8_t * data, size_t len){ - uint8_t i=0; - digitalWrite(_ss_pin, LOW); - SPI.transfer(0x02); - SPI.transfer(0x00); - while(len-- && i < 32) SPI.transfer(data[i++]); - while(i++ < 32) SPI.transfer(0); - digitalWrite(_ss_pin, HIGH); + void writeData(uint8_t * data, size_t len) + { + uint8_t i=0; + digitalWrite(_ss_pin, LOW); + SPI.transfer(0x02); + SPI.transfer(0x00); + while(len-- && i < 32) { + SPI.transfer(data[i++]); + } + while(i++ < 32) { + SPI.transfer(0); + } + digitalWrite(_ss_pin, HIGH); } - String readData(){ - char data[33]; - data[32] = 0; - readData((uint8_t *)data); - return String(data); + String readData() + { + char data[33]; + data[32] = 0; + readData((uint8_t *)data); + return String(data); } - void writeData(const char * data){ - writeData((uint8_t *)data, strlen(data)); + void writeData(const char * data) + { + writeData((uint8_t *)data, strlen(data)); } }; ESPMaster esp(SS); -void send(const char * message){ - Serial.print("Master: "); - Serial.println(message); - esp.writeData(message); - delay(10); - Serial.print("Slave: "); - Serial.println(esp.readData()); - Serial.println(); +void send(const char * message) +{ + Serial.print("Master: "); + Serial.println(message); + esp.writeData(message); + delay(10); + Serial.print("Slave: "); + Serial.println(esp.readData()); + Serial.println(); } -void setup() { - Serial.begin(115200); - SPI.begin(); - esp.begin(); - delay(1000); - send("Hello Slave!"); +void setup() +{ + Serial.begin(115200); + SPI.begin(); + esp.begin(); + delay(1000); + send("Hello Slave!"); } -void loop(){ - delay(1000); - send("Are you alive?"); +void loop() +{ + delay(1000); + send("Are you alive?"); } diff --git a/libraries/SPISlave/examples/SPISlave_SafeMaster/SPISlave_SafeMaster.ino b/libraries/SPISlave/examples/SPISlave_SafeMaster/SPISlave_SafeMaster.ino index ef94f7490d..6d3e55cd7b 100644 --- a/libraries/SPISlave/examples/SPISlave_SafeMaster/SPISlave_SafeMaster.ino +++ b/libraries/SPISlave/examples/SPISlave_SafeMaster/SPISlave_SafeMaster.ino @@ -17,90 +17,108 @@ */ #include -class ESPSafeMaster { - private: +class ESPSafeMaster +{ +private: uint8_t _ss_pin; - void _pulseSS(){ - digitalWrite(_ss_pin, HIGH); - delayMicroseconds(5); - digitalWrite(_ss_pin, LOW); + void _pulseSS() + { + digitalWrite(_ss_pin, HIGH); + delayMicroseconds(5); + digitalWrite(_ss_pin, LOW); } - public: - ESPSafeMaster(uint8_t pin):_ss_pin(pin){} - void begin(){ - pinMode(_ss_pin, OUTPUT); - _pulseSS(); +public: + ESPSafeMaster(uint8_t pin):_ss_pin(pin) {} + void begin() + { + pinMode(_ss_pin, OUTPUT); + _pulseSS(); } - - uint32_t readStatus(){ - _pulseSS(); - SPI.transfer(0x04); - uint32_t status = (SPI.transfer(0) | ((uint32_t)(SPI.transfer(0)) << 8) | ((uint32_t)(SPI.transfer(0)) << 16) | ((uint32_t)(SPI.transfer(0)) << 24)); - _pulseSS(); - return status; + + uint32_t readStatus() + { + _pulseSS(); + SPI.transfer(0x04); + uint32_t status = (SPI.transfer(0) | ((uint32_t)(SPI.transfer(0)) << 8) | ((uint32_t)(SPI.transfer(0)) << 16) | ((uint32_t)(SPI.transfer(0)) << 24)); + _pulseSS(); + return status; } - void writeStatus(uint32_t status){ - _pulseSS(); - SPI.transfer(0x01); - SPI.transfer(status & 0xFF); - SPI.transfer((status >> 8) & 0xFF); - SPI.transfer((status >> 16) & 0xFF); - SPI.transfer((status >> 24) & 0xFF); - _pulseSS(); + void writeStatus(uint32_t status) + { + _pulseSS(); + SPI.transfer(0x01); + SPI.transfer(status & 0xFF); + SPI.transfer((status >> 8) & 0xFF); + SPI.transfer((status >> 16) & 0xFF); + SPI.transfer((status >> 24) & 0xFF); + _pulseSS(); } - void readData(uint8_t * data){ - _pulseSS(); - SPI.transfer(0x03); - SPI.transfer(0x00); - for(uint8_t i=0; i<32; i++) data[i] = SPI.transfer(0); - _pulseSS(); + void readData(uint8_t * data) + { + _pulseSS(); + SPI.transfer(0x03); + SPI.transfer(0x00); + for(uint8_t i=0; i<32; i++) { + data[i] = SPI.transfer(0); + } + _pulseSS(); } - void writeData(uint8_t * data, size_t len){ - uint8_t i=0; - _pulseSS(); - SPI.transfer(0x02); - SPI.transfer(0x00); - while(len-- && i < 32) SPI.transfer(data[i++]); - while(i++ < 32) SPI.transfer(0); - _pulseSS(); + void writeData(uint8_t * data, size_t len) + { + uint8_t i=0; + _pulseSS(); + SPI.transfer(0x02); + SPI.transfer(0x00); + while(len-- && i < 32) { + SPI.transfer(data[i++]); + } + while(i++ < 32) { + SPI.transfer(0); + } + _pulseSS(); } - String readData(){ - char data[33]; - data[32] = 0; - readData((uint8_t *)data); - return String(data); + String readData() + { + char data[33]; + data[32] = 0; + readData((uint8_t *)data); + return String(data); } - void writeData(const char * data){ - writeData((uint8_t *)data, strlen(data)); + void writeData(const char * data) + { + writeData((uint8_t *)data, strlen(data)); } }; ESPSafeMaster esp(SS); -void send(const char * message){ - Serial.print("Master: "); - Serial.println(message); - esp.writeData(message); - delay(10); - Serial.print("Slave: "); - Serial.println(esp.readData()); - Serial.println(); +void send(const char * message) +{ + Serial.print("Master: "); + Serial.println(message); + esp.writeData(message); + delay(10); + Serial.print("Slave: "); + Serial.println(esp.readData()); + Serial.println(); } -void setup() { - Serial.begin(115200); - SPI.begin(); - esp.begin(); - delay(1000); - send("Hello Slave!"); +void setup() +{ + Serial.begin(115200); + SPI.begin(); + esp.begin(); + delay(1000); + send("Hello Slave!"); } -void loop(){ - delay(1000); - send("Are you alive?"); +void loop() +{ + delay(1000); + send("Are you alive?"); } diff --git a/libraries/SPISlave/examples/SPISlave_Test/SPISlave_Test.ino b/libraries/SPISlave/examples/SPISlave_Test/SPISlave_Test.ino index 8f9ee6ba6c..0f6a544bd8 100644 --- a/libraries/SPISlave/examples/SPISlave_Test/SPISlave_Test.ino +++ b/libraries/SPISlave/examples/SPISlave_Test/SPISlave_Test.ino @@ -17,55 +17,56 @@ #include "SPISlave.h" -void setup() { - Serial.begin(115200); - Serial.setDebugOutput(true); +void setup() +{ + Serial.begin(115200); + Serial.setDebugOutput(true); - // data has been received from the master. Beware that len is always 32 - // and the buffer is autofilled with zeroes if data is less than 32 bytes long - // It's up to the user to implement protocol for handling data length - SPISlave.onData([](uint8_t * data, size_t len){ - String message = String((char *)data); - if(message.equals("Hello Slave!")){ - SPISlave.setData("Hello Master!"); - } else if(message.equals("Are you alive?")){ - char answer[33]; - sprintf(answer,"Alive for %u seconds!", millis() / 1000); - SPISlave.setData(answer); - } else { - SPISlave.setData("Say what?"); - } - Serial.printf("Question: %s\n", (char *)data); - }); + // data has been received from the master. Beware that len is always 32 + // and the buffer is autofilled with zeroes if data is less than 32 bytes long + // It's up to the user to implement protocol for handling data length + SPISlave.onData([](uint8_t * data, size_t len) { + String message = String((char *)data); + if(message.equals("Hello Slave!")) { + SPISlave.setData("Hello Master!"); + } else if(message.equals("Are you alive?")) { + char answer[33]; + sprintf(answer,"Alive for %u seconds!", millis() / 1000); + SPISlave.setData(answer); + } else { + SPISlave.setData("Say what?"); + } + Serial.printf("Question: %s\n", (char *)data); + }); - // The master has read out outgoing data buffer - // that buffer can be set with SPISlave.setData - SPISlave.onDataSent([](){ - Serial.println("Answer Sent"); - }); + // The master has read out outgoing data buffer + // that buffer can be set with SPISlave.setData + SPISlave.onDataSent([]() { + Serial.println("Answer Sent"); + }); - // status has been received from the master. - // The status register is a special register that bot the slave and the master can write to and read from. - // Can be used to exchange small data or status information - SPISlave.onStatus([](uint32_t data){ - Serial.printf("Status: %u\n", data); - SPISlave.setStatus(millis()); //set next status - }); + // status has been received from the master. + // The status register is a special register that bot the slave and the master can write to and read from. + // Can be used to exchange small data or status information + SPISlave.onStatus([](uint32_t data) { + Serial.printf("Status: %u\n", data); + SPISlave.setStatus(millis()); //set next status + }); - // The master has read the status register - SPISlave.onStatusSent([](){ - Serial.println("Status Sent"); - }); + // The master has read the status register + SPISlave.onStatusSent([]() { + Serial.println("Status Sent"); + }); - // Setup SPI Slave registers and pins - SPISlave.begin(); + // Setup SPI Slave registers and pins + SPISlave.begin(); - // Set the status register (if the master reads it, it will read this value) - SPISlave.setStatus(millis()); + // Set the status register (if the master reads it, it will read this value) + SPISlave.setStatus(millis()); - // Sets the data registers. Limited to 32 bytes at a time. - // SPISlave.setData(uint8_t * data, size_t len); is also available with the same limitation - SPISlave.setData("Ask me a question!"); + // Sets the data registers. Limited to 32 bytes at a time. + // SPISlave.setData(uint8_t * data, size_t len); is also available with the same limitation + SPISlave.setData("Ask me a question!"); } void loop() {} diff --git a/libraries/SPISlave/library.properties b/libraries/SPISlave/library.properties index fdbd70ceaf..50d81f3fb8 100644 --- a/libraries/SPISlave/library.properties +++ b/libraries/SPISlave/library.properties @@ -1,9 +1,9 @@ name=SPISlave version=1.0 -author=Arduino -maintainer=Arduino -sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. +author=Hristo Gochkov +maintainer=Hristo Gochkov +sentence=SPI Slave library for ESP8266 paragraph= category=Signal Input/Output -url=http://arduino.cc/en/Reference/SPI +url= architectures=esp8266 diff --git a/libraries/SPISlave/src/SPISlave.cpp b/libraries/SPISlave/src/SPISlave.cpp index 8344fbe66d..0543557837 100644 --- a/libraries/SPISlave/src/SPISlave.cpp +++ b/libraries/SPISlave/src/SPISlave.cpp @@ -20,64 +20,84 @@ */ #include "SPISlave.h" extern "C" { - #include "hspi_slave.h" +#include "hspi_slave.h" } -void SPISlaveClass::_data_rx(uint8_t * data, uint8_t len){ - if(_data_cb) - _data_cb(data, len); -} -void SPISlaveClass::_status_rx(uint32_t data){ - if(_status_cb) - _status_cb(data); -} -void SPISlaveClass::_data_tx(void){ - if(_data_sent_cb) - _data_sent_cb(); -} -void SPISlaveClass::_status_tx(void){ - if(_status_sent_cb) - _status_sent_cb(); -} -void SPISlaveClass::_s_data_rx(void *arg, uint8_t * data, uint8_t len){ - reinterpret_cast(arg)->_data_rx(data,len); -} -void SPISlaveClass::_s_status_rx(void *arg, uint32_t data){ - reinterpret_cast(arg)->_status_rx(data); -} -void SPISlaveClass::_s_data_tx(void *arg){ - reinterpret_cast(arg)->_data_tx(); -} -void SPISlaveClass::_s_status_tx(void *arg){ - reinterpret_cast(arg)->_status_tx(); +void SPISlaveClass::_data_rx(uint8_t * data, uint8_t len) +{ + if(_data_cb) { + _data_cb(data, len); + } +} +void SPISlaveClass::_status_rx(uint32_t data) +{ + if(_status_cb) { + _status_cb(data); + } +} +void SPISlaveClass::_data_tx(void) +{ + if(_data_sent_cb) { + _data_sent_cb(); + } +} +void SPISlaveClass::_status_tx(void) +{ + if(_status_sent_cb) { + _status_sent_cb(); + } +} +void SPISlaveClass::_s_data_rx(void *arg, uint8_t * data, uint8_t len) +{ + reinterpret_cast(arg)->_data_rx(data,len); +} +void SPISlaveClass::_s_status_rx(void *arg, uint32_t data) +{ + reinterpret_cast(arg)->_status_rx(data); +} +void SPISlaveClass::_s_data_tx(void *arg) +{ + reinterpret_cast(arg)->_data_tx(); +} +void SPISlaveClass::_s_status_tx(void *arg) +{ + reinterpret_cast(arg)->_status_tx(); } -void SPISlaveClass::begin(){ - hspi_slave_onData(&_s_data_rx); - hspi_slave_onDataSent(&_s_data_tx); - hspi_slave_onStatus(&_s_status_rx); - hspi_slave_onStatusSent(&_s_status_tx); - hspi_slave_begin(4, this); -} -void SPISlaveClass::setData(uint8_t * data, size_t len){ - if(len > 32) - len = 32; - hspi_slave_setData(data, len); -} -void SPISlaveClass::setStatus(uint32_t status){ - hspi_slave_setStatus(status); -} -void SPISlaveClass::onData(SpiSlaveDataHandler cb){ - _data_cb = cb; -} -void SPISlaveClass::onDataSent(SpiSlaveSentHandler cb){ - _data_sent_cb = cb; -} -void SPISlaveClass::onStatus(SpiSlaveStatusHandler cb){ - _status_cb = cb; -} -void SPISlaveClass::onStatusSent(SpiSlaveSentHandler cb){ - _status_sent_cb = cb; +void SPISlaveClass::begin() +{ + hspi_slave_onData(&_s_data_rx); + hspi_slave_onDataSent(&_s_data_tx); + hspi_slave_onStatus(&_s_status_rx); + hspi_slave_onStatusSent(&_s_status_tx); + hspi_slave_begin(4, this); +} +void SPISlaveClass::setData(uint8_t * data, size_t len) +{ + if(len > 32) { + len = 32; + } + hspi_slave_setData(data, len); +} +void SPISlaveClass::setStatus(uint32_t status) +{ + hspi_slave_setStatus(status); +} +void SPISlaveClass::onData(SpiSlaveDataHandler cb) +{ + _data_cb = cb; +} +void SPISlaveClass::onDataSent(SpiSlaveSentHandler cb) +{ + _data_sent_cb = cb; +} +void SPISlaveClass::onStatus(SpiSlaveStatusHandler cb) +{ + _status_cb = cb; +} +void SPISlaveClass::onStatusSent(SpiSlaveSentHandler cb) +{ + _status_sent_cb = cb; } SPISlaveClass SPISlave; diff --git a/libraries/SPISlave/src/SPISlave.h b/libraries/SPISlave/src/SPISlave.h index 81caeeff52..5f9a566eba 100644 --- a/libraries/SPISlave/src/SPISlave.h +++ b/libraries/SPISlave/src/SPISlave.h @@ -28,8 +28,9 @@ typedef std::function SpiSlaveDataHandler; typedef std::function SpiSlaveStatusHandler; typedef std::function SpiSlaveSentHandler; -class SPISlaveClass { - protected: +class SPISlaveClass +{ +protected: SpiSlaveDataHandler _data_cb; SpiSlaveStatusHandler _status_cb; SpiSlaveSentHandler _data_sent_cb; @@ -42,18 +43,19 @@ class SPISlaveClass { static void _s_status_rx(void *arg, uint32_t data); static void _s_data_tx(void *arg); static void _s_status_tx(void *arg); - public: +public: SPISlaveClass() - : _data_cb(NULL) - , _status_cb(NULL) - , _data_sent_cb(NULL) - , _status_sent_cb(NULL) + : _data_cb(NULL) + , _status_cb(NULL) + , _data_sent_cb(NULL) + , _status_sent_cb(NULL) {} - ~SPISlaveClass(){} + ~SPISlaveClass() {} void begin(); void setData(uint8_t * data, size_t len); - void setData(const char * data){ - setData((uint8_t *)data, strlen(data)); + void setData(const char * data) + { + setData((uint8_t *)data, strlen(data)); } void setStatus(uint32_t status); void onData(SpiSlaveDataHandler cb); diff --git a/libraries/SPISlave/src/hspi_slave.c b/libraries/SPISlave/src/hspi_slave.c index 0547e78918..b3e0d6b5df 100644 --- a/libraries/SPISlave/src/hspi_slave.c +++ b/libraries/SPISlave/src/hspi_slave.c @@ -28,100 +28,116 @@ static void (*_hspi_slave_rx_status_cb)(void * arg, uint32_t data) = NULL; static void (*_hspi_slave_tx_status_cb)(void * arg) = NULL; static uint8_t _hspi_slave_buffer[33]; -void ICACHE_RAM_ATTR _hspi_slave_isr_handler(void *arg){ - uint32_t status; - uint32_t istatus; - - istatus = SPIIR; - - if(istatus & (1 << SPII1)){ //SPI1 ISR - status = SPI1S; - SPI1S &= ~(0x3E0);//disable interrupts - SPI1S |= SPISSRES;//reset - SPI1S &= ~(0x1F);//clear interrupts - SPI1S |= (0x3E0);//enable interrupts - - if((status & SPISRBIS) != 0 && (_hspi_slave_tx_data_cb)) - _hspi_slave_tx_data_cb(arg); - if((status & SPISRSIS) != 0 && (_hspi_slave_tx_status_cb)) - _hspi_slave_tx_status_cb(arg); - if((status & SPISWSIS) != 0 && (_hspi_slave_rx_status_cb)){ - uint32_t s = SPI1WS; - _hspi_slave_rx_status_cb(arg, s); +void ICACHE_RAM_ATTR _hspi_slave_isr_handler(void *arg) +{ + uint32_t status; + uint32_t istatus; + + istatus = SPIIR; + + if(istatus & (1 << SPII1)) { //SPI1 ISR + status = SPI1S; + SPI1S &= ~(0x3E0);//disable interrupts + SPI1S |= SPISSRES;//reset + SPI1S &= ~(0x1F);//clear interrupts + SPI1S |= (0x3E0);//enable interrupts + + if((status & SPISRBIS) != 0 && (_hspi_slave_tx_data_cb)) { + _hspi_slave_tx_data_cb(arg); + } + if((status & SPISRSIS) != 0 && (_hspi_slave_tx_status_cb)) { + _hspi_slave_tx_status_cb(arg); + } + if((status & SPISWSIS) != 0 && (_hspi_slave_rx_status_cb)) { + uint32_t s = SPI1WS; + _hspi_slave_rx_status_cb(arg, s); + } + if((status & SPISWBIS) != 0 && (_hspi_slave_rx_data_cb)) { + uint8_t i; + uint32_t data; + uint8_t buffer[33]; + _hspi_slave_buffer[32] = 0; + for(i=0; i<8; i++) { + data=SPI1W(i); + _hspi_slave_buffer[i<<2] = data & 0xff; + _hspi_slave_buffer[(i<<2)+1] = (data >> 8) & 0xff; + _hspi_slave_buffer[(i<<2)+2] = (data >> 16) & 0xff; + _hspi_slave_buffer[(i<<2)+3] = (data >> 24) & 0xff; + } + _hspi_slave_rx_data_cb(arg, &_hspi_slave_buffer[0], 32); + } + } else if(istatus & (1 << SPII0)) { //SPI0 ISR + SPI0S &= ~(0x3ff);//clear SPI ISR + } else if(istatus & (1 << SPII2)) {} //I2S ISR +} + +void hspi_slave_begin(uint8_t status_len, void * arg) +{ + status_len &= 7; + if(status_len > 4) { + status_len == 4; //max 32 bits } - if((status & SPISWBIS) != 0 && (_hspi_slave_rx_data_cb)){ - uint8_t i; - uint32_t data; - uint8_t buffer[33]; - _hspi_slave_buffer[32] = 0; - for(i=0;i<8;i++){ - data=SPI1W(i); - _hspi_slave_buffer[i<<2] = data & 0xff; - _hspi_slave_buffer[(i<<2)+1] = (data >> 8) & 0xff; - _hspi_slave_buffer[(i<<2)+2] = (data >> 16) & 0xff; - _hspi_slave_buffer[(i<<2)+3] = (data >> 24) & 0xff; - } - _hspi_slave_rx_data_cb(arg, &_hspi_slave_buffer[0], 32); + if(status_len == 0) { + status_len == 1; //min 8 bits } - } else if(istatus & (1 << SPII0)){ //SPI0 ISR - SPI0S &= ~(0x3ff);//clear SPI ISR - } else if(istatus & (1 << SPII2)){} //I2S ISR -} -void hspi_slave_begin(uint8_t status_len, void * arg){ - status_len &= 7; - if(status_len > 4) status_len == 4;//max 32 bits - if(status_len == 0) status_len == 1;//min 8 bits - - pinMode(SS, SPECIAL); - pinMode(SCK, SPECIAL); - pinMode(MISO, SPECIAL); - pinMode(MOSI, SPECIAL); - - SPI1S = SPISE | SPISBE | 0x3E0; - SPI1U = SPIUMISOH | SPIUCOMMAND | SPIUSSE; - SPI1CLK = 0; - SPI1U2 = (7 << SPILCOMMAND); - SPI1S1 = (((status_len * 8) - 1) << SPIS1LSTA) | (0xff << SPIS1LBUF) | (7 << SPIS1LWBA) | (7 << SPIS1LRBA) | SPIS1RSTA; - SPI1P = (1 << 19); - SPI1CMD = SPIBUSY; - - ETS_SPI_INTR_ATTACH(_hspi_slave_isr_handler,arg); - ETS_SPI_INTR_ENABLE(); + pinMode(SS, SPECIAL); + pinMode(SCK, SPECIAL); + pinMode(MISO, SPECIAL); + pinMode(MOSI, SPECIAL); + + SPI1S = SPISE | SPISBE | 0x3E0; + SPI1U = SPIUMISOH | SPIUCOMMAND | SPIUSSE; + SPI1CLK = 0; + SPI1U2 = (7 << SPILCOMMAND); + SPI1S1 = (((status_len * 8) - 1) << SPIS1LSTA) | (0xff << SPIS1LBUF) | (7 << SPIS1LWBA) | (7 << SPIS1LRBA) | SPIS1RSTA; + SPI1P = (1 << 19); + SPI1CMD = SPIBUSY; + + ETS_SPI_INTR_ATTACH(_hspi_slave_isr_handler,arg); + ETS_SPI_INTR_ENABLE(); } -void hspi_slave_setStatus(uint32_t status){ - SPI1WS = status; +void hspi_slave_setStatus(uint32_t status) +{ + SPI1WS = status; } -void hspi_slave_setData(uint8_t *data, uint8_t len){ - uint8_t i; - uint32_t out = 0; - uint8_t bi = 0; - uint8_t wi = 8; - - for(i=0; i<32; i++){ - out |= (i