Files
ESP8266lib/io/SoftSPI.h

233 lines
4.9 KiB
C++

#ifndef SOFTSPI_H
#define SOFTSPI_H
//#include "IO.h"
#include "fastGPIO.h"
// wemos D1 mini
#define SPI_CS_OUTPUT GPIO15_OUTPUT_SET
#define SPI_MOSI_OUTPUT GPIO13_OUTPUT_SET
#define SPI_MISO_INPUT GPIO12_INPUT_SET
#define SPI_MISO_NO_PULLUP GPIO12_INPUT_PULLUP_UNSET
#define SPI_CLK_OUTPUT GPIO14_OUTPUT_SET
#define SPI_CS_LO GPIO15_L
#define SPI_CS_HI GPIO15_H
#define SPI_CLK_LO GPIO14_L
#define SPI_CLK_HI GPIO14_H
#define SPI_MOSI_LO GPIO13_L
#define SPI_MOSI_HI GPIO13_H
#define SPI_MISO_READ GPIO12_IN
#define SPI_FAST
class SoftSPI {
// MTDI GPIO12 MISO (DIN) D6
// MTCK GPIO13 MOSI (DOUT) D7
// MTMS GPIO14 CLOCK D5
// MTDO GPIO15 CS / SS D8
// #define PIN_CLK 14
// #define PIN_MISO 12
// #define PIN_MOSI 13
// #define BIT(nr) (1 << 0)
public:
SoftSPI() {
// NOT CALLED!
// CALL INIT() manually!
}
void init() const {
SPI_MISO_INPUT; SPI_MISO_NO_PULLUP; // D6: MISO
SPI_MOSI_OUTPUT; // D7: MOSI
SPI_CLK_OUTPUT; // D5: CLK
SPI_CS_OUTPUT; // D8: CS
}
inline void chipSelect() const {
clkLo();
wait();
csLo();
waitLong();
}
inline void chipDeselect() const {
clkLo();
wait();
csHi();
wait();
}
inline void csLo() const { SPI_CS_LO; } // D8
inline void csHi() const { SPI_CS_HI; } // D8
inline void clkLo() const { SPI_CLK_LO; } // D5
inline void clkHi() const { SPI_CLK_HI; } // D5
inline bool getMISO() const {return SPI_MISO_READ;} // D6
/** read 16 bits */
inline uint16_t readWord() const {
return
(readBit() << 15) |
(readBit() << 14) |
(readBit() << 13) |
(readBit() << 12) |
(readBit() << 11) |
(readBit() << 10) |
(readBit() << 9) |
(readBit() << 8) |
(readBit() << 7) |
(readBit() << 6) |
(readBit() << 5) |
(readBit() << 4) |
(readBit() << 3) |
(readBit() << 2) |
(readBit() << 1) |
(readBit() << 0);
}
/** read 8 bits */
inline uint8_t readByte() const {
return
(readBit() << 7) |
(readBit() << 6) |
(readBit() << 5) |
(readBit() << 4) |
(readBit() << 3) |
(readBit() << 2) |
(readBit() << 1) |
(readBit() << 0);
}
inline void writeWord(const uint16_t word) const {
writeBit(word & BIT(15));
writeBit(word & BIT(14));
writeBit(word & BIT(13));
writeBit(word & BIT(12));
writeBit(word & BIT(11));
writeBit(word & BIT(10));
writeBit(word & BIT( 9));
writeBit(word & BIT( 8));
writeBit(word & BIT( 7));
writeBit(word & BIT( 6));
writeBit(word & BIT( 5));
writeBit(word & BIT( 4));
writeBit(word & BIT( 3));
writeBit(word & BIT( 2));
writeBit(word & BIT( 1));
writeBit(word & BIT( 0));
}
inline void writeByte(const uint8_t byte) const {
writeBit(byte & BIT( 7));
writeBit(byte & BIT( 6));
writeBit(byte & BIT( 5));
writeBit(byte & BIT( 4));
writeBit(byte & BIT( 3));
writeBit(byte & BIT( 2));
writeBit(byte & BIT( 1));
writeBit(byte & BIT( 0));
}
inline uint16 readWriteWord(const uint16_t word) const {
return
(readWriteBit(word & BIT(15)) << 15) |
(readWriteBit(word & BIT(14)) << 14) |
(readWriteBit(word & BIT(13)) << 13) |
(readWriteBit(word & BIT(12)) << 12) |
(readWriteBit(word & BIT(11)) << 11) |
(readWriteBit(word & BIT(10)) << 10) |
(readWriteBit(word & BIT( 9)) << 9) |
(readWriteBit(word & BIT( 8)) << 8) |
(readWriteBit(word & BIT( 7)) << 7) |
(readWriteBit(word & BIT( 6)) << 6) |
(readWriteBit(word & BIT( 5)) << 5) |
(readWriteBit(word & BIT( 4)) << 4) |
(readWriteBit(word & BIT( 3)) << 3) |
(readWriteBit(word & BIT( 2)) << 2) |
(readWriteBit(word & BIT( 1)) << 1) |
(readWriteBit(word & BIT( 0)) << 0);
}
inline uint8 readWriteByte(const uint8_t byte) const {
return
(readWriteBit(byte & BIT( 7)) << 7) |
(readWriteBit(byte & BIT( 6)) << 6) |
(readWriteBit(byte & BIT( 5)) << 5) |
(readWriteBit(byte & BIT( 4)) << 4) |
(readWriteBit(byte & BIT( 3)) << 3) |
(readWriteBit(byte & BIT( 2)) << 2) |
(readWriteBit(byte & BIT( 1)) << 1) |
(readWriteBit(byte & BIT( 0)) << 0);
}
private:
inline uint8_t readWriteBit(const bool out) const {
if(out) {SPI_MOSI_HI;} else {SPI_MOSI_LO;}
wait();
clkHi();
wait();
const bool inp = getMISO();
wait();
clkLo();
wait();
return (inp) ? 1 : 0;
}
/** write one bit to the bus */
inline void writeBit(const bool out) const {
if(out) {SPI_MOSI_HI;} else {SPI_MOSI_LO;}
wait();
clkHi();
wait();
clkLo();
wait();
}
/** read one bit from the bus */
inline uint8_t readBit() const {
clkHi();
wait();
const bool val = getMISO();
wait();
clkLo();
wait();
return (val) ? 1 : 0;
}
#ifdef SPI_FAST
inline void wait() const {
__asm__ __volatile__("nop");
}
inline void waitLong() const {
os_delay_us(1);
}
#else
inline void wait() const {
os_delay_us(2);
}
inline void waitLong() const {
os_delay_us(50);
}
#endif
};
#endif // SOFTSPI_H