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 0x3 //SPI_INT_HOLD_ENA
|
||||||
#define SPIE2IHEN_S 0 //SPI_INT_HOLD_ENA_S
|
#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
|
//SLC (DMA) Registers
|
||||||
#define SLCC0 ESP8266_REG(0xB00) //SLC_CONF0
|
#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).
|
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).
|
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
|
## SoftwareSerial
|
||||||
|
|
||||||
|
@ -22,6 +22,12 @@
|
|||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
#include "HardwareSerial.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 {
|
typedef union {
|
||||||
uint32_t regValue;
|
uint32_t regValue;
|
||||||
struct {
|
struct {
|
||||||
@ -35,12 +41,43 @@ typedef union {
|
|||||||
|
|
||||||
SPIClass::SPIClass() {
|
SPIClass::SPIClass() {
|
||||||
useHwCs = false;
|
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() {
|
void SPIClass::begin() {
|
||||||
pinMode(SCK, SPECIAL); ///< GPIO14
|
switch (pinSet) {
|
||||||
pinMode(MISO, SPECIAL); ///< GPIO12
|
case SPI_PINS_HSPI_OVERLAP:
|
||||||
pinMode(MOSI, SPECIAL); ///< GPIO13
|
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;
|
SPI1C = 0;
|
||||||
setFrequency(1000000); ///< 1MHz
|
setFrequency(1000000); ///< 1MHz
|
||||||
@ -50,24 +87,55 @@ void SPIClass::begin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::end() {
|
void SPIClass::end() {
|
||||||
pinMode(SCK, INPUT);
|
switch (pinSet) {
|
||||||
pinMode(MISO, INPUT);
|
case SPI_PINS_HSPI:
|
||||||
pinMode(MOSI, INPUT);
|
pinMode(SCK, INPUT);
|
||||||
if(useHwCs) {
|
pinMode(MISO, INPUT);
|
||||||
pinMode(SS, 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) {
|
void SPIClass::setHwCs(bool use) {
|
||||||
if(use) {
|
switch (pinSet) {
|
||||||
pinMode(SS, SPECIAL); ///< GPIO15
|
case SPI_PINS_HSPI:
|
||||||
SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
|
if (use) {
|
||||||
|
pinMode(SS, SPECIAL); ///< GPIO15
|
||||||
|
SPI1U |= (SPIUCSSETUP | SPIUCSHOLD);
|
||||||
} else {
|
} else {
|
||||||
if(useHwCs) {
|
if (useHwCs) {
|
||||||
pinMode(SS, INPUT);
|
pinMode(SS, INPUT);
|
||||||
SPI1U &= ~(SPIUCSSETUP | SPIUCSHOLD);
|
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;
|
useHwCs = use;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,7 +374,7 @@ void SPIClass::write32(uint32_t data, bool msb) {
|
|||||||
SPI1W0 = data;
|
SPI1W0 = data;
|
||||||
SPI1CMD |= SPIBUSY;
|
SPI1CMD |= SPIBUSY;
|
||||||
}
|
}
|
||||||
while(SPI1CMD & SPIBUSY) {}
|
while(SPI1CMD & SPIBUSY) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,6 +53,7 @@ public:
|
|||||||
class SPIClass {
|
class SPIClass {
|
||||||
public:
|
public:
|
||||||
SPIClass();
|
SPIClass();
|
||||||
|
bool pins(int8_t sck, int8_t miso, int8_t mosi, int8_t ss);
|
||||||
void begin();
|
void begin();
|
||||||
void end();
|
void end();
|
||||||
void setHwCs(bool use);
|
void setHwCs(bool use);
|
||||||
@ -74,6 +75,7 @@ public:
|
|||||||
void endTransaction(void);
|
void endTransaction(void);
|
||||||
private:
|
private:
|
||||||
bool useHwCs;
|
bool useHwCs;
|
||||||
|
uint8_t pinSet;
|
||||||
void writeBytes_(uint8_t * data, uint8_t size);
|
void writeBytes_(uint8_t * data, uint8_t size);
|
||||||
void transferBytes_(uint8_t * out, uint8_t * in, uint8_t size);
|
void transferBytes_(uint8_t * out, uint8_t * in, uint8_t size);
|
||||||
inline void setDataBits(uint16_t bits);
|
inline void setDataBits(uint16_t bits);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user