Skip to content

Commit ea3f807

Browse files
committed
Merge branch 'zero' of github.com:arduino/ArduinoZero into zero_servo
2 parents 1a08dd4 + f0e76f9 commit ea3f807

File tree

3 files changed

+118
-100
lines changed

3 files changed

+118
-100
lines changed

libraries/SPI/SPI.cpp

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/*
22
* SPI Master library for arduino.
33
* Copyright (c) 2014 Arduino.
4-
* based on Copyright (c) 2011 Cristian Maglie <[email protected]>.
54
*
65
* This file is free software; you can redistribute it and/or modify
76
* it under the terms of either the GNU General Public License version 2
@@ -16,8 +15,8 @@
1615

1716
SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI)
1817
{
19-
assert(p_sercom != NULL );
20-
_p_sercom = p_sercom;
18+
assert(p_sercom != NULL);
19+
_p_sercom = p_sercom;
2120

2221
_uc_pinMiso = uc_pinMISO;
2322
_uc_pinSCK = uc_pinSCK;
@@ -31,90 +30,95 @@ void SPIClass::begin()
3130
pinPeripheral(_uc_pinSCK, g_APinDescription[_uc_pinSCK].ulPinType);
3231
pinPeripheral(_uc_pinMosi, g_APinDescription[_uc_pinMosi].ulPinType);
3332

34-
// Default speed set to 4Mhz, SPI mode set to MODE 0 and Bit order set to MSB first.
35-
_p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, MSB_FIRST);
36-
_p_sercom->initSPIClock(SERCOM_SPI_MODE_0, 4000000);
33+
// Default speed set to 4Mhz, SPI mode set to MODE 0 and Bit order set to MSB first.
34+
_p_sercom->initSPI(SPI_PAD_2_SCK_3, SERCOM_RX_PAD_0, SPI_CHAR_SIZE_8_BITS, MSB_FIRST);
35+
_p_sercom->initSPIClock(SERCOM_SPI_MODE_0, 4000000);
3736

38-
_p_sercom->enableSPI();
37+
_p_sercom->enableSPI();
3938
}
4039

4140
void SPIClass::end()
4241
{
43-
_p_sercom->resetSPI();
42+
_p_sercom->resetSPI();
4443
}
4544

4645

4746
void SPIClass::usingInterrupt(uint8_t interruptNumber)
4847
{
49-
// XXX: TODO
48+
// XXX: TODO
5049
}
5150

5251
void SPIClass::beginTransaction(SPISettings settings)
5352
{
54-
// XXX: TODO
55-
setBitOrder(settings.bitOrder);
56-
setClockDivider(settings.clockDiv);
57-
setDataMode(settings.dataMode);
53+
// XXX: TODO
54+
setBitOrder(settings.bitOrder);
55+
setClockDivider(settings.clockDiv);
56+
setDataMode(settings.dataMode);
5857
}
5958

6059
void SPIClass::endTransaction(void)
6160
{
62-
// XXX: TODO
61+
// XXX: TODO
6362
}
6463

6564
void SPIClass::setBitOrder(BitOrder order)
6665
{
67-
if(order == LSBFIRST)
68-
_p_sercom->setDataOrderSPI(LSB_FIRST);
69-
else
70-
_p_sercom->setDataOrderSPI(MSB_FIRST);
66+
if (order == LSBFIRST) {
67+
_p_sercom->setDataOrderSPI(LSB_FIRST);
68+
} else {
69+
_p_sercom->setDataOrderSPI(MSB_FIRST);
70+
}
7171
}
7272

7373
void SPIClass::setDataMode(uint8_t mode)
7474
{
75-
switch(mode)
76-
{
77-
case SPI_MODE0:
78-
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_0);
79-
break;
80-
81-
case SPI_MODE1:
82-
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_1);
83-
break;
84-
85-
case SPI_MODE2:
86-
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_2);
87-
break;
88-
89-
case SPI_MODE3:
90-
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_3);
91-
break;
92-
93-
default:
94-
break;
95-
}
75+
switch (mode)
76+
{
77+
case SPI_MODE0:
78+
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_0);
79+
break;
80+
81+
case SPI_MODE1:
82+
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_1);
83+
break;
84+
85+
case SPI_MODE2:
86+
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_2);
87+
break;
88+
89+
case SPI_MODE3:
90+
_p_sercom->setClockModeSPI(SERCOM_SPI_MODE_3);
91+
break;
92+
93+
default:
94+
break;
95+
}
9696
}
9797

9898
void SPIClass::setClockDivider(uint8_t div)
9999
{
100-
_p_sercom->setBaudrateSPI(div);
100+
if (div < SPI_MIN_CLOCK_DIVIDER) {
101+
_p_sercom->setBaudrateSPI(SPI_MIN_CLOCK_DIVIDER);
102+
} else {
103+
_p_sercom->setBaudrateSPI(div);
104+
}
101105
}
102106

103107
byte SPIClass::transfer(uint8_t data)
104108
{
105-
//Writing the data
106-
_p_sercom->writeDataSPI(data);
109+
// Writing the data
110+
_p_sercom->writeDataSPI(data);
107111

108-
//Read data
109-
return _p_sercom->readDataSPI();
112+
// Read data
113+
return _p_sercom->readDataSPI();
110114
}
111115

112116
void SPIClass::attachInterrupt() {
113-
// Should be enableInterrupt()
117+
// Should be enableInterrupt()
114118
}
115119

116120
void SPIClass::detachInterrupt() {
117-
// Should be disableInterrupt()
121+
// Should be disableInterrupt()
118122
}
119123

120-
SPIClass SPI( &sercom4, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI ) ;
124+
SPIClass SPI( &sercom4, PIN_SPI_MISO, PIN_SPI_SCK, PIN_SPI_MOSI );

libraries/SPI/SPI.h

Lines changed: 65 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,75 +18,89 @@
1818
#define SPI_MODE2 0x03
1919
#define SPI_MODE3 0x01
2020

21+
#if defined(__SAMD21G18A__)
22+
// Even if not specified on the datasheet, the SAMD21G18A MCU
23+
// doesn't operate correctly with clock dividers lower than 4.
24+
// This allows a theoretical maximum SPI clock speed of 12Mhz
25+
#define SPI_MIN_CLOCK_DIVIDER 4
26+
// Other SAMD21xxxxx MCU may be affected as well
27+
#else
28+
#define SPI_MIN_CLOCK_DIVIDER 2
29+
#endif
30+
2131
class SPISettings {
2232
public:
23-
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
24-
if (__builtin_constant_p(clock)) {
25-
init_AlwaysInline(clock, bitOrder, dataMode);
26-
} else {
27-
init_MightInline(clock, bitOrder, dataMode);
28-
}
29-
}
30-
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
33+
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
34+
if (__builtin_constant_p(clock)) {
35+
init_AlwaysInline(clock, bitOrder, dataMode);
36+
} else {
37+
init_MightInline(clock, bitOrder, dataMode);
38+
}
39+
}
40+
41+
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
42+
3143
private:
32-
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
33-
init_AlwaysInline(clock, bitOrder, dataMode);
34-
}
35-
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
36-
uint8_t div;
37-
if (clock < (F_CPU / 255)) {
38-
div = 255;
39-
} else if (clock >= (F_CPU / 2)) {
40-
div = 2;
41-
} else {
42-
div = (F_CPU / (clock + 1)) + 1;
43-
}
44-
this->clockDiv = div;
45-
this->dataMode = dataMode;
46-
this->bitOrder = bitOrder;
47-
}
48-
uint8_t clockDiv, dataMode;
49-
BitOrder bitOrder;
50-
friend class SPIClass;
44+
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
45+
init_AlwaysInline(clock, bitOrder, dataMode);
46+
}
5147

48+
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
49+
uint8_t div;
50+
if (clock < (F_CPU / 255)) {
51+
div = 255;
52+
} else if (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER)) {
53+
div = SPI_MIN_CLOCK_DIVIDER;
54+
} else {
55+
div = (F_CPU / (clock + 1)) + 1;
56+
}
57+
this->clockDiv = div;
58+
this->dataMode = dataMode;
59+
this->bitOrder = bitOrder;
60+
}
61+
62+
uint8_t clockDiv, dataMode;
63+
BitOrder bitOrder;
64+
65+
friend class SPIClass;
5266
};
5367

5468
class SPIClass {
5569
public:
56-
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI);
70+
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI);
71+
72+
byte transfer(uint8_t data);
73+
inline void transfer(void *buf, size_t count);
5774

58-
byte transfer(uint8_t data);
59-
inline void transfer(void *buf, size_t count);
75+
// Transaction Functions
76+
void usingInterrupt(uint8_t interruptNumber);
77+
void beginTransaction(SPISettings settings);
78+
void endTransaction(void);
6079

61-
// Transaction Functions
62-
void usingInterrupt(uint8_t interruptNumber);
63-
void beginTransaction(SPISettings settings);
64-
void endTransaction(void);
80+
// SPI Configuration methods
81+
void attachInterrupt();
82+
void detachInterrupt();
6583

66-
// SPI Configuration methods
67-
void attachInterrupt();
68-
void detachInterrupt();
84+
void begin();
85+
void end();
6986

70-
void begin();
71-
void end();
72-
73-
void setBitOrder(BitOrder order);
74-
void setDataMode(uint8_t uc_mode);
75-
void setClockDivider(uint8_t uc_div);
87+
void setBitOrder(BitOrder order);
88+
void setDataMode(uint8_t uc_mode);
89+
void setClockDivider(uint8_t uc_div);
7690

7791
private:
78-
SERCOM *_p_sercom;
79-
uint8_t _uc_pinMiso;
80-
uint8_t _uc_pinMosi;
81-
uint8_t _uc_pinSCK;
92+
SERCOM *_p_sercom;
93+
uint8_t _uc_pinMiso;
94+
uint8_t _uc_pinMosi;
95+
uint8_t _uc_pinSCK;
8296
};
8397

8498
void SPIClass::transfer(void *buf, size_t count)
8599
{
86-
// TODO: Optimize for faster block-transfer
87-
uint8_t *buffer = reinterpret_cast<uint8_t *>(buf);
88-
for (size_t i=0; i<count; i++)
89-
buffer[i] = transfer(buffer[i]);
100+
// TODO: Optimize for faster block-transfer
101+
uint8_t *buffer = reinterpret_cast<uint8_t *>(buf);
102+
for (size_t i=0; i<count; i++)
103+
buffer[i] = transfer(buffer[i]);
90104
}
91105

92106
#if SPI_INTERFACES_COUNT > 0

platform.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ version=1.8.0
1111

1212
compiler.path={runtime.ide.path}/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/
1313
compiler.c.cmd=arm-none-eabi-gcc
14-
compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g -Os -W -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500
14+
compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g -Os -W -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD
1515
compiler.c.elf.cmd=arm-none-eabi-gcc
1616
compiler.c.elf.flags=-Os -Wl,--gc-sections -save-temps
1717
compiler.S.flags=-c -g -x assembler-with-cpp
1818
compiler.cpp.cmd=arm-none-eabi-g++
19-
compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g -Os -W -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions
19+
compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g -Os -W -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD
2020
compiler.ar.cmd=arm-none-eabi-ar
2121
compiler.ar.flags=rcs
2222
compiler.objcopy.cmd=arm-none-eabi-objcopy

0 commit comments

Comments
 (0)