mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-17 22:23:10 +03:00
SPI: added setBitOrder support; added end(pin) method.
This commit is contained in:
@ -42,8 +42,10 @@ extern "C"{
|
|||||||
#define SERIAL 0x0
|
#define SERIAL 0x0
|
||||||
#define DISPLAY 0x1
|
#define DISPLAY 0x1
|
||||||
|
|
||||||
#define LSBFIRST 0
|
enum BitOrder {
|
||||||
#define MSBFIRST 1
|
LSBFIRST = 0,
|
||||||
|
MSBFIRST = 1
|
||||||
|
};
|
||||||
|
|
||||||
#define CHANGE 1
|
#define CHANGE 1
|
||||||
#define FALLING 2
|
#define FALLING 2
|
||||||
|
@ -25,6 +25,7 @@ void SPIClass::begin() {
|
|||||||
// Default speed set to 4Mhz
|
// Default speed set to 4Mhz
|
||||||
setClockDivider(BOARD_SPI_DEFAULT_SS, 21);
|
setClockDivider(BOARD_SPI_DEFAULT_SS, 21);
|
||||||
setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0);
|
setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0);
|
||||||
|
setBitOrder(BOARD_SPI_DEFAULT_SS, MSBFIRST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::begin(uint8_t _pin) {
|
void SPIClass::begin(uint8_t _pin) {
|
||||||
@ -34,39 +35,50 @@ void SPIClass::begin(uint8_t _pin) {
|
|||||||
g_APinDescription[spiPin].ulPinType,
|
g_APinDescription[spiPin].ulPinType,
|
||||||
g_APinDescription[spiPin].ulPin,
|
g_APinDescription[spiPin].ulPin,
|
||||||
g_APinDescription[spiPin].ulPinConfiguration);
|
g_APinDescription[spiPin].ulPinConfiguration);
|
||||||
// Default speed set to 4Mhz
|
|
||||||
setClockDivider(_pin, 21);
|
// Default speed set to 500Khz
|
||||||
|
setClockDivider(_pin, 168);
|
||||||
setDataMode(_pin, SPI_MODE0);
|
setDataMode(_pin, SPI_MODE0);
|
||||||
|
setBitOrder(_pin, MSBFIRST);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPIClass::end(uint8_t _pin) {
|
||||||
|
uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
|
||||||
|
// Setting the pin as INPUT will disconnect it from SPI peripheral
|
||||||
|
pinMode(spiPin, INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::end() {
|
void SPIClass::end() {
|
||||||
SPI_Disable(spi);
|
SPI_Disable(spi);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void SPIClass::setBitOrder(uint8_t _bitOrder, uint8_t _channel) {
|
void SPIClass::setBitOrder(uint8_t _pin, BitOrder _bitOrder) {
|
||||||
// // Not supported
|
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
||||||
//}
|
bitOrder[ch] = _bitOrder;
|
||||||
|
}
|
||||||
|
|
||||||
void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) {
|
void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) {
|
||||||
uint32_t _channel = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
||||||
mode[_channel] = _mode | SPI_CSR_CSAAT;
|
mode[ch] = _mode | SPI_CSR_CSAAT;
|
||||||
// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
|
// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
|
||||||
// transfer. Some device needs that for working properly.
|
// transfer. Some device needs that for working properly.
|
||||||
SPI_ConfigureNPCS(spi, _channel, mode[_channel] | SPI_CSR_SCBR(divider[_channel]) | SPI_CSR_DLYBCT(10) | (32<<16));
|
SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) {
|
void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) {
|
||||||
uint32_t _channel = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
||||||
divider[_channel] = _divider;
|
divider[ch] = _divider;
|
||||||
// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
|
// SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
|
||||||
// transfer. Some device needs that for working properly.
|
// transfer. Some device needs that for working properly.
|
||||||
// SPI_ConfigureNPCS(spi, _channel, mode[_channel] | SPI_CSR_SCBR(divider[_channel]) | SPI_CSR_DLYBCT(1));
|
SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
|
||||||
SPI_ConfigureNPCS(spi, _channel, mode[_channel] | SPI_CSR_SCBR(divider[_channel]) | SPI_CSR_DLYBCT(10) | (32<<16));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
|
byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
|
||||||
uint32_t _channel = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
|
||||||
uint32_t d = _data | SPI_PCS(_channel);
|
// Reverse bit order
|
||||||
|
if (bitOrder[ch] == LSBFIRST)
|
||||||
|
_data = __REV(__RBIT(_data));
|
||||||
|
uint32_t d = _data | SPI_PCS(ch);
|
||||||
if (_mode == SPI_LAST)
|
if (_mode == SPI_LAST)
|
||||||
d |= SPI_TDR_LASTXFER;
|
d |= SPI_TDR_LASTXFER;
|
||||||
|
|
||||||
@ -79,6 +91,9 @@ byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
|
|||||||
while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
|
while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
|
||||||
;
|
;
|
||||||
d = spi->SPI_RDR;
|
d = spi->SPI_RDR;
|
||||||
|
// Reverse bit order
|
||||||
|
if (bitOrder[ch] == LSBFIRST)
|
||||||
|
d = __REV(__RBIT(d));
|
||||||
return d & 0xFF;
|
return d & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,23 +36,27 @@ class SPIClass {
|
|||||||
void attachInterrupt(void);
|
void attachInterrupt(void);
|
||||||
void detachInterrupt(void);
|
void detachInterrupt(void);
|
||||||
|
|
||||||
void begin(uint8_t _channel);
|
|
||||||
void begin(void);
|
void begin(void);
|
||||||
void end(void);
|
void end(void);
|
||||||
|
|
||||||
// These methods sets a parameter on a single pin
|
// Attach/Detach pin to/from SPI controller
|
||||||
//void setBitOrder(uint8_t _channel, uint8_t);
|
void begin(uint8_t _pin);
|
||||||
void setDataMode(uint8_t _channel, uint8_t);
|
void end(uint8_t _pin);
|
||||||
void setClockDivider(uint8_t _channel, uint8_t);
|
|
||||||
|
|
||||||
// These methods sets the same parameters but on default pin PIN_SPI_SS_DEFAULT
|
// These methods sets a parameter on a single pin
|
||||||
//void setBitOrder(uint8_t _order) { setBitOrder(PIN_SPI_SS_DEFAULT, _order); };
|
void setBitOrder(uint8_t _pin, BitOrder);
|
||||||
|
void setDataMode(uint8_t _pin, uint8_t);
|
||||||
|
void setClockDivider(uint8_t _pin, uint8_t);
|
||||||
|
|
||||||
|
// These methods sets the same parameters but on default pin BOARD_SPI_DEFAULT_SS
|
||||||
|
void setBitOrder(BitOrder _order) { setBitOrder(BOARD_SPI_DEFAULT_SS, _order); };
|
||||||
void setDataMode(uint8_t _mode) { setDataMode(BOARD_SPI_DEFAULT_SS, _mode); };
|
void setDataMode(uint8_t _mode) { setDataMode(BOARD_SPI_DEFAULT_SS, _mode); };
|
||||||
void setClockDivider(uint8_t _div) { setClockDivider(BOARD_SPI_DEFAULT_SS, _div); };
|
void setClockDivider(uint8_t _div) { setClockDivider(BOARD_SPI_DEFAULT_SS, _div); };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Spi *spi;
|
Spi *spi;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
BitOrder bitOrder[SPI_CHANNELS_NUM];
|
||||||
uint32_t divider[SPI_CHANNELS_NUM];
|
uint32_t divider[SPI_CHANNELS_NUM];
|
||||||
uint32_t mode[SPI_CHANNELS_NUM];
|
uint32_t mode[SPI_CHANNELS_NUM];
|
||||||
void (*initCb)(void);
|
void (*initCb)(void);
|
||||||
|
Reference in New Issue
Block a user