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