mirror of
https://github.com/arduino/Arduino.git
synced 2024-12-01 12:24:14 +01:00
[sam] Refactoring API for SPI library
This commit is contained in:
parent
0e0c18ed73
commit
9a5be09f06
@ -10,75 +10,71 @@
|
|||||||
|
|
||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
|
|
||||||
SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void), uint32_t *_ss) :
|
SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)) :
|
||||||
spi(_spi), id(_id), initCb(_initCb)
|
spi(_spi), id(_id), initCb(_initCb)
|
||||||
{
|
{
|
||||||
for (int i=0; i<SPI_CHANNELS_NUM; i++)
|
|
||||||
ssPins[i] = _ss[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::begin() {
|
|
||||||
initCb();
|
initCb();
|
||||||
|
|
||||||
// Set CS on NPCS3
|
|
||||||
SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS);
|
SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS);
|
||||||
SPI_Enable(spi);
|
SPI_Enable(spi);
|
||||||
setClockDivider(1);
|
setClockDivider(1);
|
||||||
setDataMode(SPI_MODE0);
|
setDataMode(SPI_MODE0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::addSlave(uint8_t _channel) {
|
void SPIClass::begin(uint8_t _pin) {
|
||||||
uint32_t pin = ssPins[_channel];
|
if (_pin == 0)
|
||||||
if (pin == 0)
|
|
||||||
return;
|
return;
|
||||||
PIO_Configure(g_APinDescription[pin].pPort,
|
PIO_Configure(g_APinDescription[_pin].pPort,
|
||||||
g_APinDescription[pin].ulPinType,
|
g_APinDescription[_pin].ulPinType,
|
||||||
g_APinDescription[pin].ulPin,
|
g_APinDescription[_pin].ulPin,
|
||||||
g_APinDescription[pin].ulPinConfiguration);
|
g_APinDescription[_pin].ulPinConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::end() {
|
void SPIClass::end() {
|
||||||
SPI_Disable(spi);
|
SPI_Disable(spi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::setBitOrder(uint8_t bitOrder) {
|
//void SPIClass::setBitOrder(uint8_t bitOrder) {
|
||||||
setBitOrder(bitOrder, 0);
|
// setBitOrder(bitOrder, 0);
|
||||||
setBitOrder(bitOrder, 1);
|
// setBitOrder(bitOrder, 1);
|
||||||
setBitOrder(bitOrder, 2);
|
// setBitOrder(bitOrder, 2);
|
||||||
setBitOrder(bitOrder, 3);
|
// setBitOrder(bitOrder, 3);
|
||||||
}
|
//}
|
||||||
|
|
||||||
void SPIClass::setBitOrder(uint8_t bitOrder, uint8_t _channel) {
|
//void SPIClass::setBitOrder(uint8_t bitOrder, uint8_t _channel) {
|
||||||
// Not supported
|
// // Not supported
|
||||||
}
|
//}
|
||||||
|
|
||||||
void SPIClass::setDataMode(uint8_t _mode) {
|
void SPIClass::setDataMode(uint8_t _mode) {
|
||||||
setDataMode(_mode, 0);
|
setDataMode(PIN_SPI_SS0, _mode);
|
||||||
setDataMode(_mode, 1);
|
setDataMode(PIN_SPI_SS1, _mode);
|
||||||
setDataMode(_mode, 2);
|
setDataMode(PIN_SPI_SS2, _mode);
|
||||||
setDataMode(_mode, 3);
|
setDataMode(PIN_SPI_SS3, _mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::setDataMode(uint8_t _mode, uint8_t _channel) {
|
void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) {
|
||||||
|
uint32_t _channel = SPI_PIN_TO_SPI_CHANNEL(_pin);
|
||||||
mode[_channel] = _mode | SPI_CSR_CSAAT;
|
mode[_channel] = _mode | SPI_CSR_CSAAT;
|
||||||
SPI_ConfigureNPCS(spi, _channel, mode[_channel] | SPI_CSR_SCBR(divider[_channel]));
|
SPI_ConfigureNPCS(spi, _channel, mode[_channel] | SPI_CSR_SCBR(divider[_channel]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::setClockDivider(uint8_t _divider) {
|
void SPIClass::setClockDivider(uint8_t _divider) {
|
||||||
setClockDivider(_divider, 0);
|
setClockDivider(PIN_SPI_SS0, _divider);
|
||||||
setClockDivider(_divider, 1);
|
setClockDivider(PIN_SPI_SS1, _divider);
|
||||||
setClockDivider(_divider, 2);
|
setClockDivider(PIN_SPI_SS2, _divider);
|
||||||
setClockDivider(_divider, 3);
|
setClockDivider(PIN_SPI_SS3, _divider);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIClass::setClockDivider(uint8_t _divider, uint8_t _channel) {
|
void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) {
|
||||||
|
uint32_t _channel = SPI_PIN_TO_SPI_CHANNEL(_pin);
|
||||||
divider[_channel] = _divider;
|
divider[_channel] = _divider;
|
||||||
SPI_ConfigureNPCS(spi, _channel, mode[_channel] | SPI_CSR_SCBR(divider[_channel]));
|
SPI_ConfigureNPCS(spi, _channel, mode[_channel] | SPI_CSR_SCBR(divider[_channel]));
|
||||||
}
|
}
|
||||||
|
|
||||||
byte SPIClass::transfer(byte _data, uint8_t _channel, bool _last) {
|
byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
|
||||||
|
uint32_t _channel = SPI_PIN_TO_SPI_CHANNEL(_pin);
|
||||||
uint32_t d = _data | SPI_PCS(_channel);
|
uint32_t d = _data | SPI_PCS(_channel);
|
||||||
if (_last)
|
if (_mode == SPI_LAST)
|
||||||
d |= SPI_TDR_LASTXFER;
|
d |= SPI_TDR_LASTXFER;
|
||||||
|
|
||||||
// SPI_Write(spi, _channel, _data);
|
// SPI_Write(spi, _channel, _data);
|
||||||
@ -117,12 +113,5 @@ static void SPI_0_Init(void) {
|
|||||||
g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
|
g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SPI_0_SS[] = {
|
SPIClass SPI(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init);
|
||||||
PIN_SPI_SS0,
|
|
||||||
PIN_SPI_SS1,
|
|
||||||
PIN_SPI_SS2,
|
|
||||||
PIN_SPI_SS3
|
|
||||||
};
|
|
||||||
|
|
||||||
SPIClass SPI_0(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init, SPI_0_SS);
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,42 +19,45 @@
|
|||||||
#define SPI_MODE2 0x03
|
#define SPI_MODE2 0x03
|
||||||
#define SPI_MODE3 0x01
|
#define SPI_MODE3 0x01
|
||||||
|
|
||||||
|
enum SPITransferMode {
|
||||||
|
SPI_CONTINUE,
|
||||||
|
SPI_LAST
|
||||||
|
};
|
||||||
|
|
||||||
class SPIClass {
|
class SPIClass {
|
||||||
public:
|
public:
|
||||||
SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void), uint32_t *_ss);
|
SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void));
|
||||||
|
|
||||||
byte transfer(byte _data, uint8_t _channel = 0, bool _last = true);
|
byte transfer(byte _channel, uint8_t _data, SPITransferMode _mode = SPI_LAST);
|
||||||
|
|
||||||
// SPI Configuration methods
|
// SPI Configuration methods
|
||||||
|
|
||||||
void attachInterrupt(void);
|
void attachInterrupt(void);
|
||||||
void detachInterrupt(void);
|
void detachInterrupt(void);
|
||||||
|
|
||||||
void begin(void);
|
void begin(uint8_t _channel);
|
||||||
void addSlave(uint8_t _channel);
|
|
||||||
void end(void);
|
void end(void);
|
||||||
|
|
||||||
// These methods sets the same parameters on all channels
|
// These methods sets the same parameters on all channels
|
||||||
void setBitOrder(uint8_t);
|
//void setBitOrder(uint8_t);
|
||||||
void setDataMode(uint8_t);
|
void setDataMode(uint8_t);
|
||||||
void setClockDivider(uint8_t);
|
void setClockDivider(uint8_t);
|
||||||
|
|
||||||
// These methods sets a parameter on a single channel
|
// These methods sets a parameter on a single channel
|
||||||
void setBitOrder(uint8_t, uint8_t _channel);
|
// void setBitOrder(uint8_t _channel, uint8_t);
|
||||||
void setDataMode(uint8_t, uint8_t _channel);
|
void setDataMode(uint8_t _channel, uint8_t);
|
||||||
void setClockDivider(uint8_t, uint8_t _channel);
|
void setClockDivider(uint8_t _channel, uint8_t);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Spi *spi;
|
Spi *spi;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint32_t divider[SPI_CHANNELS_NUM];
|
uint32_t divider[SPI_CHANNELS_NUM];
|
||||||
uint32_t mode[SPI_CHANNELS_NUM];
|
uint32_t mode[SPI_CHANNELS_NUM];
|
||||||
uint32_t ssPins[SPI_CHANNELS_NUM];
|
|
||||||
void (*initCb)(void);
|
void (*initCb)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if SPI_INTERFACES_COUNT > 0
|
#if SPI_INTERFACES_COUNT > 0
|
||||||
extern SPIClass SPI_0;
|
extern SPIClass SPI;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,38 +1,34 @@
|
|||||||
|
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
#define FLASH_SPI_CHAN 3
|
// Flash memory is connected on SPI pin SS3
|
||||||
|
#define FLASH PIN_SPI_SS3
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial1.begin(9600);
|
Serial.begin(9600);
|
||||||
SPI_0.begin();
|
SPI.begin(FLASH);
|
||||||
SPI_0.addSlave(FLASH_SPI_CHAN);
|
SPI.setClockDivider(2); // We are too fast with 1
|
||||||
SPI_0.setClockDivider(2); // We are too fast with 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
Serial1.println("Sending 'Identify' cmd to flash => 9F");
|
Serial.println("Sending 'Identify' cmd to flash => 9F");
|
||||||
|
|
||||||
// Send cmd and receive response on the same transaction
|
// Send "identify" command (9f) and receive response
|
||||||
// Parameter "false" keeps the SS pin active
|
// on the same SPI transaction. Parameter SPI_CONTINUE
|
||||||
SPI_0.transfer(0x9f, FLASH_SPI_CHAN, false);
|
// keeps the SS pin active.
|
||||||
char a1 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false);
|
SPI.transfer(FLASH, 0x9f, SPI_CONTINUE);
|
||||||
char a2 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false);
|
char a1 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
|
||||||
char a3 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false);
|
char a2 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
|
||||||
char a4 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false);
|
char a3 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
|
||||||
char a5 = SPI_0.transfer(0x00, FLASH_SPI_CHAN);
|
char a4 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
|
||||||
|
char a5 = SPI.transfer(FLASH, 0x00);
|
||||||
|
|
||||||
Serial1.print("Received signature: ");
|
// Print response over serial port
|
||||||
Serial1.print(a1, HEX);
|
Serial.print("Received signature: ");
|
||||||
Serial1.print(" ");
|
Serial.print(a1, HEX);
|
||||||
Serial1.print(a2, HEX);
|
Serial.print(a2, HEX);
|
||||||
Serial1.print(" ");
|
Serial.print(a3, HEX);
|
||||||
Serial1.print(a3, HEX);
|
Serial.print(a4, HEX);
|
||||||
Serial1.print(" ");
|
Serial.println(a5, HEX);
|
||||||
Serial1.print(a4, HEX);
|
|
||||||
Serial1.print(" ");
|
|
||||||
Serial1.print(a5, HEX);
|
|
||||||
Serial1.println();
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,16 +6,15 @@
|
|||||||
# Datatypes (KEYWORD1)
|
# Datatypes (KEYWORD1)
|
||||||
#######################################
|
#######################################
|
||||||
|
|
||||||
SPI_0 KEYWORD1
|
SPI KEYWORD1
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Methods and Functions (KEYWORD2)
|
# Methods and Functions (KEYWORD2)
|
||||||
#######################################
|
#######################################
|
||||||
begin KEYWORD2
|
begin KEYWORD2
|
||||||
addSlave KEYWORD2
|
|
||||||
end KEYWORD2
|
end KEYWORD2
|
||||||
transfer KEYWORD2
|
transfer KEYWORD2
|
||||||
setBitOrder KEYWORD2
|
#setBitOrder KEYWORD2
|
||||||
setDataMode KEYWORD2
|
setDataMode KEYWORD2
|
||||||
setClockDivider KEYWORD2
|
setClockDivider KEYWORD2
|
||||||
|
|
||||||
@ -23,7 +22,10 @@ setClockDivider KEYWORD2
|
|||||||
#######################################
|
#######################################
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
||||||
#######################################
|
#######################################
|
||||||
SPI_MODE0 LITERAL1
|
SPI_MODE0 LITERAL1
|
||||||
SPI_MODE1 LITERAL1
|
SPI_MODE1 LITERAL1
|
||||||
SPI_MODE2 LITERAL1
|
SPI_MODE2 LITERAL1
|
||||||
SPI_MODE3 LITERAL1
|
SPI_MODE3 LITERAL1
|
||||||
|
|
||||||
|
SPI_CONTINUE LITERAL1
|
||||||
|
SPI_LAST LITERAL1
|
||||||
|
@ -92,6 +92,7 @@ extern "C"{
|
|||||||
#define PIN_SPI_MOSI (75u)
|
#define PIN_SPI_MOSI (75u)
|
||||||
#define PIN_SPI_MISO (74u)
|
#define PIN_SPI_MISO (74u)
|
||||||
#define PIN_SPI_SCK (76u)
|
#define PIN_SPI_SCK (76u)
|
||||||
|
#define SPI_PIN_TO_SPI_CHANNEL(x) (x==PIN_SPI_SS0 ? 0 : (x==PIN_SPI_SS1 ? 1 : (x==PIN_SPI_SS2 ? 2 : 3)))
|
||||||
|
|
||||||
static const uint8_t SS = PIN_SPI_SS0 ;
|
static const uint8_t SS = PIN_SPI_SS0 ;
|
||||||
static const uint8_t SS1 = PIN_SPI_SS1 ;
|
static const uint8_t SS1 = PIN_SPI_SS1 ;
|
||||||
|
Loading…
Reference in New Issue
Block a user