Skip to content

Add Sercom defs for SPI and Wire in variant #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Aug 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 27 additions & 3 deletions libraries/SPI/SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,20 @@

const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();

SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI)
SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad PadTx, SercomRXPad PadRx)
{
initialized = false;
assert(p_sercom != NULL);
_p_sercom = p_sercom;

// pins
_uc_pinMiso = uc_pinMISO;
_uc_pinSCK = uc_pinSCK;
_uc_pinMosi = uc_pinMOSI;

// SERCOM pads
_padTx=PadTx;
_padRx=PadRx;
}

void SPIClass::begin()
Expand Down Expand Up @@ -65,7 +70,7 @@ void SPIClass::config(SPISettings settings)
{
_p_sercom->disableSPI();

_p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, settings.bitOrder);
_p_sercom->initSPI(_padTx, _padRx, SPI_CHAR_SIZE_8_BITS, settings.bitOrder);
_p_sercom->initSPIClock(settings.dataMode, settings.clockFreq);

_p_sercom->enableSPI();
Expand Down Expand Up @@ -197,4 +202,23 @@ void SPIClass::detachInterrupt() {
// Should be disableInterrupt()
}

SPIClass SPI( &sercom4, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI );
#if SPI_INTERFACES_COUNT > 0

/* In case new variant doesn't define these macros,
* we put here the ones for Arduino Zero.
*
* These values should be different on some variants!
*
* The SPI PAD values can be found in cores/arduino/SERCOM.h:
* - SercomSpiTXPad
* - SercomRXPad
*/
#ifndef PERIPH_SPI
#define PERIPH_SPI sercom4
#define PAD_SPI_TX SPI_PAD_2_SCK_3
#define PAD_SPI_RX SERCOM_RX_PAD_0
#endif // PERIPH_SPI

SPIClass SPI( &PERIPH_SPI, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI, PAD_SPI_TX, PAD_SPI_RX );

#endif // SPI_INTERFACES_COUNT > 0
7 changes: 6 additions & 1 deletion libraries/SPI/SPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ class SPISettings {

class SPIClass {
public:
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI);
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad);


byte transfer(uint8_t data);
inline void transfer(void *buf, size_t count);
Expand Down Expand Up @@ -120,6 +121,10 @@ class SPIClass {
uint8_t _uc_pinMiso;
uint8_t _uc_pinMosi;
uint8_t _uc_pinSCK;

SercomSpiTXPad _padTx;
SercomRXPad _padRx;

bool initialized;
uint8_t interruptMode;
char interruptSave;
Expand Down
8 changes: 8 additions & 0 deletions libraries/SPI/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name=SPI
version=1.0
author=Jonathan BAUDIN, Thibaut VIARD, Arduino
maintainer=Arduino <info@arduino.cc>
sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. Specific implementation for Arduino Zero.
paragraph=
url=http://www.arduino.cc/en/Reference/SPI
architectures=samd
113 changes: 18 additions & 95 deletions libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ extern "C" {

#include "Wire.h"

TwoWire::TwoWire(SERCOM * s)
TwoWire::TwoWire(SERCOM * s, uint8_t pinSDA, uint8_t pinSCL)
{
this->sercom = s;
this->_uc_pinSDA=pinSDA;
this->_uc_pinSCL=pinSCL;
transmissionBegun = false;
}

Expand All @@ -37,8 +39,8 @@ void TwoWire::begin(void) {
sercom->initMasterWIRE(TWI_CLOCK);
sercom->enableWIRE();

pinPeripheral(PIN_WIRE_SDA, g_APinDescription[PIN_WIRE_SDA].ulPinType);
pinPeripheral(PIN_WIRE_SCL, g_APinDescription[PIN_WIRE_SCL].ulPinType);
pinPeripheral(_uc_pinSDA, g_APinDescription[_uc_pinSDA].ulPinType);
pinPeripheral(_uc_pinSCL, g_APinDescription[_uc_pinSCL].ulPinType);
}

void TwoWire::begin(uint8_t address) {
Expand Down Expand Up @@ -254,102 +256,23 @@ void TwoWire::onService(void)
}
}

/*
void TwoWire::onService(void)
{
// Retrieve interrupt status
uint32_t sr = TWI_GetStatus(twi);

if (status == SLAVE_IDLE && TWI_STATUS_SVACC(sr)) {
TWI_DisableIt(twi, TWI_IDR_SVACC);
TWI_EnableIt(twi, TWI_IER_RXRDY | TWI_IER_GACC | TWI_IER_NACK
| TWI_IER_EOSACC | TWI_IER_SCL_WS | TWI_IER_TXCOMP);

srvBufferLength = 0;
srvBufferIndex = 0;

// Detect if we should go into RECV or SEND status
// SVREAD==1 means *master* reading -> SLAVE_SEND
if (!TWI_STATUS_SVREAD(sr)) {
status = SLAVE_RECV;
} else {
status = SLAVE_SEND;

// Alert calling program to generate a response ASAP
if (onRequestCallback)
onRequestCallback();
else
// create a default 1-byte response
write((uint8_t) 0);
}
}

if (status != SLAVE_IDLE) {
if (TWI_STATUS_TXCOMP(sr) && TWI_STATUS_EOSACC(sr)) {
if (status == SLAVE_RECV && onReceiveCallback) {
// Copy data into rxBuffer
// (allows to receive another packet while the
// user program reads actual data)
for (uint8_t i = 0; i < srvBufferLength; ++i)
rxBuffer[i] = srvBuffer[i];
rxBufferIndex = 0;
rxBufferLength = srvBufferLength;

// Alert calling program
onReceiveCallback( rxBufferLength);
}
#if WIRE_INTERFACES_COUNT > 0

// Transfer completed
TWI_EnableIt(twi, TWI_SR_SVACC);
TWI_DisableIt(twi, TWI_IDR_RXRDY | TWI_IDR_GACC | TWI_IDR_NACK
| TWI_IDR_EOSACC | TWI_IDR_SCL_WS | TWI_IER_TXCOMP);
status = SLAVE_IDLE;
}
}
/* In case new variant doesn't define these macros,
* we put here the ones for Arduino Zero.
*
* These values should be different on some variants!
*/

if (status == SLAVE_RECV) {
if (TWI_STATUS_RXRDY(sr)) {
if (srvBufferLength < BUFFER_LENGTH)
srvBuffer[srvBufferLength++] = TWI_ReadByte(twi);
}
}
#ifndef PERIPH_WIRE
# define PERIPH_WIRE sercom3
# define WIRE_IT_HANDLER SERCOM3_Handler
#endif // PERIPH_WIRE

if (status == SLAVE_SEND) {
if (TWI_STATUS_TXRDY(sr) && !TWI_STATUS_NACK(sr)) {
uint8_t c = 'x';
if (srvBufferIndex < srvBufferLength)
c = srvBuffer[srvBufferIndex++];
TWI_WriteByte(twi, c);
}
}
}
*/
TwoWire Wire(&PERIPH_WIRE, PIN_WIRE_SDA, PIN_WIRE_SCL);

#if WIRE_INTERFACES_COUNT > 0
/*static void Wire_Init(void) {
pmc_enable_periph_clk(WIRE_INTERFACE_ID);
PIO_Configure(
g_APinDescription[PIN_WIRE_SDA].pPort,
g_APinDescription[PIN_WIRE_SDA].ulPinType,
g_APinDescription[PIN_WIRE_SDA].ulPin,
g_APinDescription[PIN_WIRE_SDA].ulPinConfiguration);
PIO_Configure(
g_APinDescription[PIN_WIRE_SCL].pPort,
g_APinDescription[PIN_WIRE_SCL].ulPinType,
g_APinDescription[PIN_WIRE_SCL].ulPin,
g_APinDescription[PIN_WIRE_SCL].ulPinConfiguration);

NVIC_DisableIRQ(WIRE_ISR_ID);
NVIC_ClearPendingIRQ(WIRE_ISR_ID);
NVIC_SetPriority(WIRE_ISR_ID, 0);
NVIC_EnableIRQ(WIRE_ISR_ID);
}*/


TwoWire Wire(&sercom3);

void SERCOM3_Handler(void) {
void WIRE_IT_HANDLER(void) {
Wire.onService();
}

#endif
#endif // WIRE_INTERFACES_COUNT > 0
5 changes: 4 additions & 1 deletion libraries/Wire/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
class TwoWire : public Stream
{
public:
TwoWire(SERCOM *s);
TwoWire(SERCOM *s, uint8_t pinSDA, uint8_t pinSCL);
void begin();
void begin(uint8_t);
void setClock(uint32_t); // dummy function
Expand Down Expand Up @@ -59,6 +59,9 @@ class TwoWire : public Stream

private:
SERCOM * sercom;
uint8_t _uc_pinSDA;
uint8_t _uc_pinSCL;

bool transmissionBegun;

// RX Buffer
Expand Down
9 changes: 9 additions & 0 deletions libraries/Wire/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=Wire
version=1.0
author=Jonathan BAUDIN, Thibaut VIARD, Arduino
maintainer=Arduino <info@arduino.cc>
sentence=Allows the communication between devices or sensors connected via Two Wire Interface Bus. Specific implementation for Arduino Zero.
paragraph=
url=http://www.arduino.cc/en/Reference/Wire
architectures=samd

5 changes: 5 additions & 0 deletions variants/arduino_zero/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ static const uint8_t ATN = PIN_ATN;
#define PIN_SPI_MISO (22u)
#define PIN_SPI_MOSI (23u)
#define PIN_SPI_SCK (24u)
#define PERIPH_SPI sercom4
#define PAD_SPI_TX SPI_PAD_2_SCK_3
#define PAD_SPI_RX SERCOM_RX_PAD_0

static const uint8_t SS = PIN_A2 ; // SERCOM4 last PAD is present on A2 but HW SS isn't used. Set here only for reference.
static const uint8_t MOSI = PIN_SPI_MOSI ;
Expand All @@ -142,6 +145,8 @@ static const uint8_t SCK = PIN_SPI_SCK ;

#define PIN_WIRE_SDA (20u)
#define PIN_WIRE_SCL (21u)
#define PERIPH_WIRE sercom3
#define WIRE_IT_HANDLER SERCOM3_Handler

/*
* USB
Expand Down