#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