Skip to content

Commit 2bb742a

Browse files
committed
Add support for SPI1 device to SPIClass
SPI1 can now be used (SPI1.begin()) to access the SPI device connected to the Arduino 101's on-board SPI flash device
1 parent 2bea587 commit 2bb742a

File tree

5 files changed

+72
-40
lines changed

5 files changed

+72
-40
lines changed

libraries/SPI/src/SPI.cpp

100644100755
+21-18
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,32 @@
1818
*/
1919
#include "SPI.h"
2020

21-
SPIClass SPI;
21+
SPIClass SPI(SPIDEV_1);
22+
SPIClass SPI1(SPIDEV_0);
2223

2324
void SPIClass::setClockDivider(uint8_t clockDiv)
2425
{
2526
/* disable controller */
26-
SPI1_M_REG_VAL(SPIEN) &= SPI_DISABLE;
27+
SPI_M_REG_VAL(spi_addr, SPIEN) &= SPI_DISABLE;
2728

2829
/* Set SPI Clock Divider */
29-
SPI1_M_REG_VAL(BAUDR) = clockDiv & SPI_CLOCK_MASK;
30+
SPI_M_REG_VAL(spi_addr, BAUDR) = clockDiv & SPI_CLOCK_MASK;
3031

3132
/* re-enable controller */
32-
SPI1_M_REG_VAL(SPIEN) |= SPI_ENABLE;
33+
SPI_M_REG_VAL(spi_addr, SPIEN) |= SPI_ENABLE;
3334
}
3435

3536
void SPIClass::setDataMode(uint8_t dataMode)
3637
{
3738
/* disable controller */
38-
SPI1_M_REG_VAL(SPIEN) &= SPI_DISABLE;
39+
SPI_M_REG_VAL(spi_addr, SPIEN) &= SPI_DISABLE;
3940

4041
/* Set frame size, bus mode and transfer mode */
41-
SPI1_M_REG_VAL(CTRL0) = (SPI1_M_REG_VAL(CTRL0) & ~(SPI_MODE_MASK)) | ((dataMode << SPI_MODE_SHIFT) & SPI_MODE_MASK);
42+
SPI_M_REG_VAL(spi_addr, CTRL0) = (SPI_M_REG_VAL(spi_addr, CTRL0)
43+
& ~(SPI_MODE_MASK)) | ((dataMode << SPI_MODE_SHIFT) & SPI_MODE_MASK);
4244

4345
/* re-enable controller */
44-
SPI1_M_REG_VAL(SPIEN) |= SPI_ENABLE;
46+
SPI_M_REG_VAL(spi_addr, SPIEN) |= SPI_ENABLE;
4547
}
4648

4749
void SPIClass::begin()
@@ -60,29 +62,30 @@ void SPIClass::begin()
6062

6163
// Set SS to high so a connected chip will be "deselected" by default
6264
// TODO - confirm that data register is updated even if pin is set as input
63-
digitalWrite(SS, HIGH);
65+
digitalWrite(ss_gpio, HIGH);
6466

6567
// When the SS pin is set as OUTPUT, it can be used as
6668
// a general purpose output port (it doesn't influence
6769
// SPI operations).
68-
pinMode(SS, OUTPUT);
70+
pinMode(ss_gpio, OUTPUT);
6971

7072
/* disable controller */
71-
SPI1_M_REG_VAL(SPIEN) &= SPI_DISABLE;
73+
SPI_M_REG_VAL(spi_addr, SPIEN) &= SPI_DISABLE;
7274

7375
/* Enable clock to peripheral */
74-
MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) |= ENABLE_SPI_MASTER_1;
76+
MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) |= enable_val;
7577

7678
/* Configure defaults for clock divider, frame size and data mode */
77-
SPI1_M_REG_VAL(BAUDR) = SPI_CLOCK_DIV4;
78-
SPI1_M_REG_VAL(CTRL0) = (frameSize << SPI_FSIZE_SHIFT) | (SPI_MODE0 << SPI_MODE_SHIFT);
79+
SPI_M_REG_VAL(spi_addr, BAUDR) = SPI_CLOCK_DIV4;
80+
SPI_M_REG_VAL(spi_addr, CTRL0) =
81+
(frameSize << SPI_FSIZE_SHIFT) | (SPI_MODE0 << SPI_MODE_SHIFT);
7982

8083
/* Disable interrupts */
81-
SPI1_M_REG_VAL(IMR) = SPI_DISABLE_INT;
8284
/* Enable at least one slave device (mandatory, though SS signals are unused) */
83-
SPI1_M_REG_VAL(SER) = 0x1;
85+
SPI_M_REG_VAL(spi_addr, IMR) = SPI_DISABLE_INT;
86+
SPI_M_REG_VAL(spi_addr, SER) = 0x1;
8487
/* Enable controller */
85-
SPI1_M_REG_VAL(SPIEN) |= SPI_ENABLE;
88+
SPI_M_REG_VAL(spi_addr, SPIEN) |= SPI_ENABLE;
8689

8790
/* Set SoC pin mux configuration */
8891
SET_PIN_MODE(g_APinDescription[MOSI].ulSocPin, SPI_MUX_MODE);
@@ -104,8 +107,8 @@ void SPIClass::end() {
104107
initialized--;
105108
// If there are no more references disable SPI
106109
if (!initialized) {
107-
SPI1_M_REG_VAL(SPIEN) &= SPI_DISABLE;
108-
MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) &= DISABLE_SPI_MASTER_1;
110+
SPI_M_REG_VAL(spi_addr, SPIEN) &= SPI_DISABLE;
111+
MMIO_REG_VAL(PERIPH_CLK_GATE_CTRL) &= disable_val;
109112
#ifdef SPI_TRANSACTION_MISMATCH_LED
110113
inTransactionFlag = 0;
111114
#endif

libraries/SPI/src/SPI.h

100644100755
+43-16
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
#define MSBFIRST 1
4747
#endif
4848

49+
#define SPI0_CS 21
50+
#define SPI1_CS SS
51+
52+
#define SPIDEV_0 0
53+
#define SPIDEV_1 1
4954
/* For Arduino Uno compatibility, divider values are doubled to provide equivalent clock rates
5055
* e.g. SPI_CLOCK_DIV4 will produce a 4MHz clock
5156
* The Intel Curie has a 32MHz base clock and a min divider of 2, so max SPI clock is 16MHz
@@ -63,6 +68,7 @@
6368
#define SPI_MODE2 0x02
6469
#define SPI_MODE3 0x03
6570

71+
#define NUM_SPIDEVS 2
6672
class SPISettings {
6773
public:
6874
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
@@ -86,7 +92,12 @@ class SPISettings {
8692

8793
class SPIClass {
8894
public:
89-
SPIClass(void) { initialized = 0; }
95+
SPIClass(int dev) {
96+
spi_addr = spidevs[dev][0];
97+
enable_val = spidevs[dev][1];
98+
disable_val = spidevs[dev][2];
99+
ss_gpio = spidevs[dev][3];
100+
}
90101

91102
// Initialize the SPI library
92103
void begin();
@@ -131,14 +142,14 @@ class SPIClass {
131142
#endif
132143

133144
/* disable controller */
134-
SPI1_M_REG_VAL(SPIEN) &= SPI_DISABLE;
145+
SPI_M_REG_VAL(spi_addr, SPIEN) &= SPI_DISABLE;
135146
/* Configure clock divider, frame size and data mode */
136-
SPI1_M_REG_VAL(BAUDR) = settings.baudr;
137-
SPI1_M_REG_VAL(CTRL0) = settings.ctrl0;
147+
SPI_M_REG_VAL(spi_addr, BAUDR) = settings.baudr;
148+
SPI_M_REG_VAL(spi_addr, CTRL0) = settings.ctrl0;
138149
frameSize = SPI_8_BIT;
139150
lsbFirst = settings.lsbFirst;
140151
/* Enable controller */
141-
SPI1_M_REG_VAL(SPIEN) |= SPI_ENABLE;
152+
SPI_M_REG_VAL(spi_addr, SPIEN) |= SPI_ENABLE;
142153
}
143154

144155
// Write to the SPI bus (MOSI pin) and also receive (MISO pin)
@@ -186,15 +197,15 @@ class SPIClass {
186197
uint32_t transferSize = SPI_FIFO_DEPTH > remaining ? remaining : SPI_FIFO_DEPTH;
187198
/* Fill the TX FIFO */
188199
for (uint32_t i = 0; i < transferSize; i++)
189-
SPI1_M_REG_VAL(DR) = *(p + i);
200+
SPI_M_REG_VAL(spi_addr, DR) = *(p + i);
190201
remaining -= transferSize;
191202
/* Wait for transfer to complete */
192-
while (SPI1_M_REG_VAL(SR) & SPI_STATUS_BUSY) ;
203+
while (SPI_M_REG_VAL(spi_addr, SR) & SPI_STATUS_BUSY) ;
193204
do {
194-
uint32_t rxLevel = SPI1_M_REG_VAL(RXFL);
205+
uint32_t rxLevel = SPI_M_REG_VAL(spi_addr, RXFL);
195206
/* Drain the RX FIFO */
196207
for (uint32_t i = 0; i < rxLevel; i++)
197-
*(p + i) = SPI1_M_REG_VAL(DR);
208+
*(p + i) = SPI_M_REG_VAL(spi_addr, DR);
198209
p += rxLevel;
199210
transferSize -= rxLevel;
200211
} while (transferSize);
@@ -248,6 +259,10 @@ class SPIClass {
248259
void setClockDivider(uint8_t clockDiv);
249260

250261
private:
262+
int ss_gpio;
263+
uint32_t spi_addr;
264+
uint32_t enable_val;
265+
uint32_t disable_val;
251266
uint32_t initialized;
252267
uint32_t interruptMode; // 0=none, 1-7=mask, 8=global
253268
uint32_t interruptMask[3]; // which interrupts to mask
@@ -260,26 +275,38 @@ class SPIClass {
260275
inline void setFrameSize(uint32_t size) {
261276
if (frameSize != size) {
262277
/* disable controller */
263-
SPI1_M_REG_VAL(SPIEN) &= SPI_DISABLE;
278+
SPI_M_REG_VAL(spi_addr, SPIEN) &= SPI_DISABLE;
264279
/* Configure new frame size */
265280
frameSize = size;
266-
SPI1_M_REG_VAL(CTRL0) = (SPI1_M_REG_VAL(CTRL0) & ~(SPI_FSIZE_MASK)) | ((frameSize << SPI_FSIZE_SHIFT) & SPI_FSIZE_MASK);
281+
SPI_M_REG_VAL(spi_addr, CTRL0) = (SPI_M_REG_VAL(spi_addr, CTRL0)
282+
& ~(SPI_FSIZE_MASK)) | ((frameSize << SPI_FSIZE_SHIFT)
283+
& SPI_FSIZE_MASK);
267284
/* Enable controller */
268-
SPI1_M_REG_VAL(SPIEN) |= SPI_ENABLE;
285+
SPI_M_REG_VAL(spi_addr, SPIEN) |= SPI_ENABLE;
269286
}
270287
}
271288

272289
inline uint32_t singleTransfer(uint32_t data) {
273290
/* Write to TX FIFO */
274-
SPI1_M_REG_VAL(DR) = data;
291+
SPI_M_REG_VAL(spi_addr, DR) = data;
275292
/* Wait for transfer to complete */
276-
while (SPI1_M_REG_VAL(SR) & SPI_STATUS_BUSY) ;
277-
while (SPI1_M_REG_VAL(RXFL) == 0) ;
293+
while (SPI_M_REG_VAL(spi_addr, SR) & SPI_STATUS_BUSY) ;
294+
while (SPI_M_REG_VAL(spi_addr, RXFL) == 0) ;
278295
/* Read from RX FIFO */
279-
return SPI1_M_REG_VAL(DR);
296+
return SPI_M_REG_VAL(spi_addr, DR);
280297
}
298+
299+
void init();
300+
void set_dev(int dev);
301+
int spidevs[NUM_SPIDEVS][4] =
302+
{
303+
/* base addr. Clk. enable value Clk. disable value SS GPIO */
304+
{(int)SOC_MST_SPI0_REGISTER_BASE, ENABLE_SPI_MASTER_0, DISABLE_SPI_MASTER_0, SPI0_CS},
305+
{(int)SOC_MST_SPI1_REGISTER_BASE, ENABLE_SPI_MASTER_1, DISABLE_SPI_MASTER_1, SPI1_CS}
306+
};
281307
};
282308

283309
extern SPIClass SPI;
310+
extern SPIClass SPI1;
284311

285312
#endif

libraries/SPI/src/SPI_registers.h

100644100755
+6-5
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@
2121

2222
#include "portable.h"
2323

24-
/* Macro to access SPI1 Master controller register offset */
25-
#define SPI1_M_REG_VAL(reg) \
26-
MMIO_REG_VAL_FROM_BASE(SOC_MST_SPI1_REGISTER_BASE, (reg))
24+
/* Macro to access SPI Master controller register offset */
25+
#define SPI_M_REG_VAL(base, reg) MMIO_REG_VAL_FROM_BASE(base, (reg))
2726

2827
/* SoC SPI device register offsets */
2928
#define CTRL0 (0x00) /* SoC SPI Control Register 1 */
@@ -55,8 +54,10 @@
5554

5655
#define SPI_FIFO_DEPTH (8UL)
5756

58-
#define ENABLE_SPI_MASTER_1 (0x1 << 15)
59-
#define DISABLE_SPI_MASTER_1 (~ENABLE_SPI_MASTER_1)
57+
#define ENABLE_SPI_MASTER_0 (0x1 << 14)
58+
#define DISABLE_SPI_MASTER_0 (~ENABLE_SPI_MASTER_0)
59+
#define ENABLE_SPI_MASTER_1 (0x1 << 15)
60+
#define DISABLE_SPI_MASTER_1 (~ENABLE_SPI_MASTER_1)
6061

6162
#define SPI_BASE_CLOCK (CLOCK_SPEED*1000*1000) /* CLOCK_SPEED in MHz */
6263

variants/arduino_101/pins_arduino.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#ifndef Pins_Arduino_h
2626
#define Pins_Arduino_h
2727

28-
#define NUM_DIGITAL_PINS 21
28+
#define NUM_DIGITAL_PINS 22
2929
#define NUM_ANALOG_INPUTS 6
3030
#define NUM_PWM 4
3131
#define NUM_UARTS 1

variants/arduino_101/variant.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ PinDescription g_APinDescription[]=
8383
{ 6, SS_GPIO_8B0, SS_GPIO, SS_GPIO_8B0_BASE_ADDR, 14, GPIO_MUX_MODE, INVALID, INVALID, 14, INPUT_MODE }, // Arduino IO18
8484
{ 1, SS_GPIO_8B0, SS_GPIO, SS_GPIO_8B0_BASE_ADDR, 9, GPIO_MUX_MODE, INVALID, INVALID, 9, INPUT_MODE }, // Arduino IO19
8585
{ 0, SS_GPIO_8B0, SS_GPIO, SS_GPIO_8B0_BASE_ADDR, 8, GPIO_MUX_MODE, INVALID, INVALID, INVALID, INPUT_MODE }, // Arduino IO20
86+
{ 24, SOC_GPIO_32, SOC_GPIO, SOC_GPIO_BASE_ADDR, 58, GPIO_MUX_MODE, INVALID, INVALID, INVALID, INPUT_MODE }, // Arduino IO21
8687

8788
} ;
8889

0 commit comments

Comments
 (0)