add fast software spi
This commit is contained in:
parent
d9b3d9a6d4
commit
0b1dbbd0e4
|
|
@ -46,6 +46,22 @@ Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin,
|
||||||
_sck = sckpin;
|
_sck = sckpin;
|
||||||
_miso = misopin;
|
_miso = misopin;
|
||||||
_mosi = mosipin;
|
_mosi = mosipin;
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
csPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(cspin));
|
||||||
|
csPinMask = digitalPinToBitMask(cspin);
|
||||||
|
if (mosipin != -1) {
|
||||||
|
mosiPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(mosipin));
|
||||||
|
mosiPinMask = digitalPinToBitMask(mosipin);
|
||||||
|
}
|
||||||
|
if (misopin != -1) {
|
||||||
|
misoPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(misopin));
|
||||||
|
misoPinMask = digitalPinToBitMask(misopin);
|
||||||
|
}
|
||||||
|
clkPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(sckpin));
|
||||||
|
clkPinMask = digitalPinToBitMask(sckpin);
|
||||||
|
#endif
|
||||||
|
|
||||||
_freq = freq;
|
_freq = freq;
|
||||||
_dataOrder = dataOrder;
|
_dataOrder = dataOrder;
|
||||||
_dataMode = dataMode;
|
_dataMode = dataMode;
|
||||||
|
|
@ -125,38 +141,89 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
|
||||||
reply <<= 1;
|
reply <<= 1;
|
||||||
if (_dataMode == SPI_MODE0 || _dataMode == SPI_MODE2) {
|
if (_dataMode == SPI_MODE0 || _dataMode == SPI_MODE2) {
|
||||||
if (_mosi != -1) {
|
if (_mosi != -1) {
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
digitalWrite(_mosi, send & (1 << b));
|
digitalWrite(_mosi, send & (1 << b));
|
||||||
|
#else
|
||||||
|
if (send & (1 << b))
|
||||||
|
*mosiPort |= mosiPinMask;
|
||||||
|
else
|
||||||
|
*mosiPort &= ~mosiPinMask;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
*clkPort |= clkPinMask; // Clock high
|
||||||
|
#else
|
||||||
digitalWrite(_sck, HIGH);
|
digitalWrite(_sck, HIGH);
|
||||||
if ((_miso != -1) && digitalRead(_miso)) {
|
#endif
|
||||||
reply |= 1;
|
|
||||||
|
if (_miso != -1) {
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
if (*misoPort & misoPinMask) {
|
||||||
|
#else
|
||||||
|
if (digitalRead(_miso)) {
|
||||||
|
#endif
|
||||||
|
reply |= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
*clkPort &= ~clkPinMask; // Clock low
|
||||||
|
#else
|
||||||
digitalWrite(_sck, LOW);
|
digitalWrite(_sck, LOW);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (_dataMode == SPI_MODE1 || _dataMode == SPI_MODE3) {
|
if (_dataMode == SPI_MODE1 || _dataMode == SPI_MODE3) {
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
*clkPort |= clkPinMask; // Clock high
|
||||||
|
#else
|
||||||
digitalWrite(_sck, HIGH);
|
digitalWrite(_sck, HIGH);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_mosi != -1) {
|
if (_mosi != -1) {
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
digitalWrite(_mosi, send & (1 << b));
|
digitalWrite(_mosi, send & (1 << b));
|
||||||
|
#else
|
||||||
|
if (send & (1 << b))
|
||||||
|
*mosiPort |= mosiPinMask;
|
||||||
|
else
|
||||||
|
*mosiPort &= ~mosiPinMask;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
*clkPort &= ~clkPinMask; // Clock low
|
||||||
|
#else
|
||||||
digitalWrite(_sck, LOW);
|
digitalWrite(_sck, LOW);
|
||||||
if ((_miso != -1) && digitalRead(_miso)) {
|
#endif
|
||||||
reply |= 1;
|
|
||||||
|
if (_miso != -1) {
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
if (*misoPort & misoPinMask) {
|
||||||
|
#else
|
||||||
|
if (digitalRead(_miso)) {
|
||||||
|
#endif
|
||||||
|
reply |= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serial.print(" : 0x"); Serial.print(reply, HEX);
|
// Serial.print(" : 0x"); Serial.print(reply, HEX);
|
||||||
if (_dataOrder == SPI_BITORDER_LSBFIRST) {
|
if (_miso != -1) {
|
||||||
// LSB is rare, if it happens we'll just flip the bits around for them
|
if (_dataOrder == SPI_BITORDER_LSBFIRST) {
|
||||||
uint8_t temp = 0;
|
// LSB is rare, if it happens we'll just flip the bits around for them
|
||||||
for (uint8_t b = 0; b < 8; b++) {
|
uint8_t temp = 0;
|
||||||
temp |= ((reply >> b) & 0x1) << (7 - b);
|
for (uint8_t b = 0; b < 8; b++) {
|
||||||
|
temp |= ((reply >> b) & 0x1) << (7 - b);
|
||||||
|
}
|
||||||
|
reply = temp;
|
||||||
}
|
}
|
||||||
reply = temp;
|
// Serial.print(" -> "); Serial.println(reply, HEX);
|
||||||
}
|
|
||||||
// Serial.print(" -> "); Serial.println(reply, HEX);
|
|
||||||
|
|
||||||
buffer[i] = reply;
|
buffer[i] = reply;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,27 @@ typedef enum _BitOrder {
|
||||||
#define SPI_BITORDER_LSBFIRST LSBFIRST
|
#define SPI_BITORDER_LSBFIRST LSBFIRST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__AVR__) || defined(TEENSYDUINO)
|
||||||
|
typedef volatile uint8_t BusIO_PortReg;
|
||||||
|
typedef uint8_t BusIO_PortMask;
|
||||||
|
#define BUSIO_USE_FAST_PINIO
|
||||||
|
|
||||||
|
#elif defined(ESP8266) || defined(ESP32) || defined(__SAM3X8E__) || \
|
||||||
|
defined(ARDUINO_ARCH_SAMD)
|
||||||
|
typedef volatile uint32_t BusIO_PortReg;
|
||||||
|
typedef uint32_t BusIO_PortMask;
|
||||||
|
#define BUSIO_USE_FAST_PINIO
|
||||||
|
|
||||||
|
#elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) && \
|
||||||
|
!defined(ARDUINO_ARCH_MBED)
|
||||||
|
typedef volatile uint32_t BusIO_PortReg;
|
||||||
|
typedef uint32_t BusIO_PortMask;
|
||||||
|
#define BUSIO_USE_FAST_PINIO
|
||||||
|
|
||||||
|
#else
|
||||||
|
#undef BUSIO_USE_FAST_PINIO
|
||||||
|
#endif
|
||||||
|
|
||||||
/**! The class which defines how we will talk to this device over SPI **/
|
/**! The class which defines how we will talk to this device over SPI **/
|
||||||
class Adafruit_SPIDevice {
|
class Adafruit_SPIDevice {
|
||||||
public:
|
public:
|
||||||
|
|
@ -62,6 +83,10 @@ private:
|
||||||
uint8_t _dataMode;
|
uint8_t _dataMode;
|
||||||
|
|
||||||
int8_t _cs, _sck, _mosi, _miso;
|
int8_t _cs, _sck, _mosi, _miso;
|
||||||
|
#ifdef BUSIO_USE_FAST_PINIO
|
||||||
|
BusIO_PortReg *mosiPort, *clkPort, *misoPort, *csPort;
|
||||||
|
BusIO_PortMask mosiPinMask, misoPinMask, clkPinMask, csPinMask;
|
||||||
|
#endif
|
||||||
bool _begun;
|
bool _begun;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue