1
0
mirror of https://github.com/arduino/Arduino.git synced 2024-11-29 10:24:12 +01:00

[sam] Refactoring API for SPI library

This commit is contained in:
Cristian Maglie 2012-05-18 01:30:54 +02:00
parent 0e0c18ed73
commit 9a5be09f06
5 changed files with 77 additions and 86 deletions

View File

@ -10,75 +10,71 @@
#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)
{
for (int i=0; i<SPI_CHANNELS_NUM; i++)
ssPins[i] = _ss[i];
}
void SPIClass::begin() {
initCb();
// Set CS on NPCS3
SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS);
SPI_Enable(spi);
setClockDivider(1);
setDataMode(SPI_MODE0);
}
void SPIClass::addSlave(uint8_t _channel) {
uint32_t pin = ssPins[_channel];
if (pin == 0)
void SPIClass::begin(uint8_t _pin) {
if (_pin == 0)
return;
PIO_Configure(g_APinDescription[pin].pPort,
g_APinDescription[pin].ulPinType,
g_APinDescription[pin].ulPin,
g_APinDescription[pin].ulPinConfiguration);
PIO_Configure(g_APinDescription[_pin].pPort,
g_APinDescription[_pin].ulPinType,
g_APinDescription[_pin].ulPin,
g_APinDescription[_pin].ulPinConfiguration);
}
void SPIClass::end() {
SPI_Disable(spi);
}
void SPIClass::setBitOrder(uint8_t bitOrder) {
setBitOrder(bitOrder, 0);
setBitOrder(bitOrder, 1);
setBitOrder(bitOrder, 2);
setBitOrder(bitOrder, 3);
}
//void SPIClass::setBitOrder(uint8_t bitOrder) {
// setBitOrder(bitOrder, 0);
// setBitOrder(bitOrder, 1);
// setBitOrder(bitOrder, 2);
// setBitOrder(bitOrder, 3);
//}
void SPIClass::setBitOrder(uint8_t bitOrder, uint8_t _channel) {
// Not supported
}
//void SPIClass::setBitOrder(uint8_t bitOrder, uint8_t _channel) {
// // Not supported
//}
void SPIClass::setDataMode(uint8_t _mode) {
setDataMode(_mode, 0);
setDataMode(_mode, 1);
setDataMode(_mode, 2);
setDataMode(_mode, 3);
setDataMode(PIN_SPI_SS0, _mode);
setDataMode(PIN_SPI_SS1, _mode);
setDataMode(PIN_SPI_SS2, _mode);
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;
SPI_ConfigureNPCS(spi, _channel, mode[_channel] | SPI_CSR_SCBR(divider[_channel]));
}
void SPIClass::setClockDivider(uint8_t _divider) {
setClockDivider(_divider, 0);
setClockDivider(_divider, 1);
setClockDivider(_divider, 2);
setClockDivider(_divider, 3);
setClockDivider(PIN_SPI_SS0, _divider);
setClockDivider(PIN_SPI_SS1, _divider);
setClockDivider(PIN_SPI_SS2, _divider);
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;
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);
if (_last)
if (_mode == SPI_LAST)
d |= SPI_TDR_LASTXFER;
// SPI_Write(spi, _channel, _data);
@ -117,12 +113,5 @@ static void SPI_0_Init(void) {
g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
}
uint32_t SPI_0_SS[] = {
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);
SPIClass SPI(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init);
#endif

View File

@ -19,42 +19,45 @@
#define SPI_MODE2 0x03
#define SPI_MODE3 0x01
enum SPITransferMode {
SPI_CONTINUE,
SPI_LAST
};
class SPIClass {
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
void attachInterrupt(void);
void detachInterrupt(void);
void begin(void);
void addSlave(uint8_t _channel);
void begin(uint8_t _channel);
void end(void);
// These methods sets the same parameters on all channels
void setBitOrder(uint8_t);
//void setBitOrder(uint8_t);
void setDataMode(uint8_t);
void setClockDivider(uint8_t);
// These methods sets a parameter on a single channel
void setBitOrder(uint8_t, uint8_t _channel);
void setDataMode(uint8_t, uint8_t _channel);
void setClockDivider(uint8_t, uint8_t _channel);
// void setBitOrder(uint8_t _channel, uint8_t);
void setDataMode(uint8_t _channel, uint8_t);
void setClockDivider(uint8_t _channel, uint8_t);
private:
Spi *spi;
uint32_t id;
uint32_t divider[SPI_CHANNELS_NUM];
uint32_t mode[SPI_CHANNELS_NUM];
uint32_t ssPins[SPI_CHANNELS_NUM];
void (*initCb)(void);
};
#if SPI_INTERFACES_COUNT > 0
extern SPIClass SPI_0;
extern SPIClass SPI;
#endif
#endif

View File

@ -1,38 +1,34 @@
#include <SPI.h>
#define FLASH_SPI_CHAN 3
// Flash memory is connected on SPI pin SS3
#define FLASH PIN_SPI_SS3
void setup() {
Serial1.begin(9600);
SPI_0.begin();
SPI_0.addSlave(FLASH_SPI_CHAN);
SPI_0.setClockDivider(2); // We are too fast with 1
Serial.begin(9600);
SPI.begin(FLASH);
SPI.setClockDivider(2); // We are too fast with 1
}
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
// Parameter "false" keeps the SS pin active
SPI_0.transfer(0x9f, FLASH_SPI_CHAN, false);
char a1 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false);
char a2 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false);
char a3 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false);
char a4 = SPI_0.transfer(0x00, FLASH_SPI_CHAN, false);
char a5 = SPI_0.transfer(0x00, FLASH_SPI_CHAN);
// Send "identify" command (9f) and receive response
// on the same SPI transaction. Parameter SPI_CONTINUE
// keeps the SS pin active.
SPI.transfer(FLASH, 0x9f, SPI_CONTINUE);
char a1 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
char a2 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
char a3 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
char a4 = SPI.transfer(FLASH, 0x00, SPI_CONTINUE);
char a5 = SPI.transfer(FLASH, 0x00);
Serial1.print("Received signature: ");
Serial1.print(a1, HEX);
Serial1.print(" ");
Serial1.print(a2, HEX);
Serial1.print(" ");
Serial1.print(a3, HEX);
Serial1.print(" ");
Serial1.print(a4, HEX);
Serial1.print(" ");
Serial1.print(a5, HEX);
Serial1.println();
// Print response over serial port
Serial.print("Received signature: ");
Serial.print(a1, HEX);
Serial.print(a2, HEX);
Serial.print(a3, HEX);
Serial.print(a4, HEX);
Serial.println(a5, HEX);
delay(1000);
}

View File

@ -6,16 +6,15 @@
# Datatypes (KEYWORD1)
#######################################
SPI_0 KEYWORD1
SPI KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
addSlave KEYWORD2
end KEYWORD2
transfer KEYWORD2
setBitOrder KEYWORD2
#setBitOrder KEYWORD2
setDataMode KEYWORD2
setClockDivider KEYWORD2
@ -23,7 +22,10 @@ setClockDivider KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
SPI_MODE0 LITERAL1
SPI_MODE1 LITERAL1
SPI_MODE2 LITERAL1
SPI_MODE3 LITERAL1
SPI_MODE0 LITERAL1
SPI_MODE1 LITERAL1
SPI_MODE2 LITERAL1
SPI_MODE3 LITERAL1
SPI_CONTINUE LITERAL1
SPI_LAST LITERAL1

View File

@ -92,6 +92,7 @@ extern "C"{
#define PIN_SPI_MOSI (75u)
#define PIN_SPI_MISO (74u)
#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 SS1 = PIN_SPI_SS1 ;