mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-19 23:22:16 +03:00
Issue #1062: Implement support for HSPI overlap mode.
This commit is contained in:
parent
157698bef9
commit
af0f5ed956
@ -586,6 +586,10 @@ extern uint8_t esp8266_gpioToFn[16];
|
||||
#define SPIE2IHEN 0x3 //SPI_INT_HOLD_ENA
|
||||
#define SPIE2IHEN_S 0 //SPI_INT_HOLD_ENA_S
|
||||
|
||||
//SPI PIN (SPIxP)
|
||||
#define SPIPCS2DIS (1 << 2)
|
||||
#define SPIPCS1DIS (1 << 1)
|
||||
#define SPIPCS0DIS (1 << 0)
|
||||
|
||||
//SLC (DMA) Registers
|
||||
#define SLCC0 ESP8266_REG(0xB00) //SLC_CONF0
|
||||
|
@ -56,6 +56,28 @@ else they default to pins 4(SDA) and 5(SCL).
|
||||
|
||||
SPI library supports the entire Arduino SPI API including transactions, including setting phase (CPHA).
|
||||
Setting the Clock polarity (CPOL) is not supported, yet (SPI_MODE2 and SPI_MODE3 not working).
|
||||
The usual SPI pins are:
|
||||
|
||||
- `MOSI` = GPIO13
|
||||
- `MISO` = GPIO12
|
||||
- `SCLK` = GPIO14
|
||||
|
||||
There's an extended mode where you can swap the normal pins to the pin0 hardware pins.
|
||||
This is enabled by calling `SPI.pins(6, 7, 8, 0)` before the call to `SPI.begin()`. The pins would
|
||||
change to:
|
||||
|
||||
- `MOSI` = SD1
|
||||
- `MISO` = SD0
|
||||
- `SCLK` = CLK
|
||||
- `HWCS` = GPIO0
|
||||
|
||||
This mode shares the SPI pins with the controller that reads the program code from flash and is
|
||||
controlled by a hardware arbiter (the flash has always higher priority). For this mode the CS
|
||||
will be controlled by hardware as you can't handle the CS line with a GPIO, you never actually
|
||||
know when the arbiter is going to grant you access to the bus so you must let it handle CS
|
||||
automatically.
|
||||
|
||||
|
||||
|
||||
## SoftwareSerial
|
||||
|
||||
|
@ -22,6 +22,12 @@
|
||||
#include "SPI.h"
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
#define SPI_PINS_HSPI 0 // Normal HSPI mode (MISO = GPIO12, MOSI = GPIO13, SCLK = GPIO14);
|
||||
#define SPI_PINS_HSPI_OVERLAP 1 // HSPI Overllaped in spi0 pins (MISO = SD0, MOSI = SDD1, SCLK = CLK);
|
||||
|
||||
#define SPI_OVERLAP_SS 0
|
||||
|
||||
|
||||
typedef union {
|
||||
uint32_t regValue;
|
||||
struct {
|
||||
@ -35,12 +41,43 @@ typedef union {
|
||||
|
||||
SPIClass::SPIClass() {
|
||||
useHwCs = false;
|
||||
pinSet = SPI_PINS_HSPI;
|
||||
}
|
||||
|
||||
bool SPIClass::pins(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
|
||||
{
|
||||
if (sck == 6 &&
|
||||
miso == 7 &&
|
||||
mosi == 8 &&
|
||||
ss == 0) {
|
||||
pinSet = SPI_PINS_HSPI_OVERLAP;
|
||||
} else if (sck == 14 &&
|
||||
miso == 12 &&
|
||||
mosi == 13) {
|
||||
pinSet = SPI_PINS_HSPI;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SPIClass::begin() {
|
||||
pinMode(SCK, SPECIAL); ///< GPIO14
|
||||
pinMode(MISO, SPECIAL); ///< GPIO12
|
||||
pinMode(MOSI, SPECIAL); ///< GPIO13
|
||||
switch (pinSet) {
|
||||
case SPI_PINS_HSPI_OVERLAP:
|
||||
IOSWAP |= (1 << IOSWAP2CS);
|
||||
//SPI0E3 |= 0x1; This is in the MP3_DECODER example, but makes the WD kick in here.
|
||||
SPI1E3 |= 0x3;
|
||||
|
||||
setHwCs(true);
|
||||
break;
|
||||
case SPI_PINS_HSPI:
|
||||
default:
|
||||
pinMode(SCK, SPECIAL); ///< GPIO14
|
||||
pinMode(MISO, SPECIAL); ///< GPIO12
|
||||
pinMode(MOSI, SPECIAL); ///< GPIO13
|
||||
break;
|
||||
}
|
||||
|
||||
SPI1C = 0;
|
||||
setFrequency(1000000); ///< 1MHz
|
||||
@ -50,24 +87,55 @@ void SPIClass::begin() {
|
||||
}
|
||||
|
||||
void SPIClass::end() {
|
||||
pinMode(SCK, INPUT);
|
||||
pinMode(MISO, INPUT);
|
||||
pinMode(MOSI, INPUT);
|
||||
if(useHwCs) {
|
||||
pinMode(SS, INPUT);
|
||||
switch (pinSet) {
|
||||
case SPI_PINS_HSPI:
|
||||
pinMode(SCK, INPUT);
|
||||
pinMode(MISO, INPUT);
|
||||
pinMode(MOSI, INPUT);
|
||||
if (useHwCs) {
|
||||
pinMode(SS, INPUT);
|
||||
}
|
||||
break;
|
||||
case SPI_PINS_HSPI_OVERLAP:
|
||||
IOSWAP &= ~(1 << IOSWAP2CS);
|
||||
if (useHwCs) {
|
||||
SPI1P |= SPIPCS1DIS | SPIPCS0DIS | SPIPCS2DIS;
|
||||
pinMode(SPI_OVERLAP_SS, INPUT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SPIClass::setHwCs(bool use) {
|
||||
if(use) {
|
||||
pinMode(SS, SPECIAL); ///< GPIO15
|
||||
SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
|
||||
switch (pinSet) {
|
||||
case SPI_PINS_HSPI:
|
||||
if (use) {
|
||||
pinMode(SS, SPECIAL); ///< GPIO15
|
||||
SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
|
||||
} else {
|
||||
if(useHwCs) {
|
||||
pinMode(SS, INPUT);
|
||||
if (useHwCs) {
|
||||
pinMode(SS, INPUT);
|
||||
SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SPI_PINS_HSPI_OVERLAP:
|
||||
if (use) {
|
||||
pinMode(SPI_OVERLAP_SS, FUNCTION_1); // GPI0 to SPICS2 mode
|
||||
SPI1P &= ~SPIPCS2DIS;
|
||||
SPI1P |= SPIPCS1DIS | SPIPCS0DIS;
|
||||
SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
|
||||
}
|
||||
else {
|
||||
if (useHwCs) {
|
||||
pinMode(SPI_OVERLAP_SS, INPUT);
|
||||
SPI1P |= SPIPCS1DIS | SPIPCS0DIS | SPIPCS2DIS;
|
||||
SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
useHwCs = use;
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@ public:
|
||||
class SPIClass {
|
||||
public:
|
||||
SPIClass();
|
||||
bool pins(int8_t sck, int8_t miso, int8_t mosi, int8_t ss);
|
||||
void begin();
|
||||
void end();
|
||||
void setHwCs(bool use);
|
||||
@ -74,6 +75,7 @@ public:
|
||||
void endTransaction(void);
|
||||
private:
|
||||
bool useHwCs;
|
||||
uint8_t pinSet;
|
||||
void writeBytes_(uint8_t * data, uint8_t size);
|
||||
void transferBytes_(uint8_t * out, uint8_t * in, uint8_t size);
|
||||
inline void setDataBits(uint16_t bits);
|
||||
|
Loading…
x
Reference in New Issue
Block a user