Skip to content

Commit aef8a28

Browse files
committed
add SPI example
also fixes a pointer casting issue
1 parent e6210fc commit aef8a28

File tree

2 files changed

+139
-2
lines changed

2 files changed

+139
-2
lines changed
+136
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
// This file is subject to the terms and conditions defined in
3+
// file 'LICENSE.md', which is part of this source code package.
4+
*/
5+
6+
/*
7+
8+
SPI functionality is accessed via SPIClass objects or their children.
9+
On the Apollo3 the MbedSPI class inherits from the SPIClass class and
10+
provides the actual implemenation based on mbed-os SPI
11+
https://os.mbed.com/docs/mbed-os/v6.2/apis/spi.html
12+
13+
Apollo3 features 6 IOM peripherals that can each be configured as either
14+
SPI or I2C. Each IOM has only one set of pins that can be used. Check the
15+
board schematic or Apollo3 Blue datasheet to determine which IOM
16+
peripherals are available on your board. There are a few different ways
17+
to access these ports:
18+
- via pre-defined MbedSPI objects like SPI, SPI1 -> SPI5
19+
- declaring your own MbedSPI object using pins that correspond to the correct IOM
20+
21+
Once you have an MbedSPI object to work with you can use all the standard
22+
Arduino SPI API methods on it
23+
https://www.arduino.cc/en/reference/SPI
24+
25+
This example will use threads to organize SPI operations based on board
26+
capabilities. The test function will check that outgoing bytes are proerly
27+
detected on a loop-back wire.
28+
29+
Wiring:
30+
For each applicable SPI port:
31+
SDO <--> SDI
32+
CLK (Not Connected)
33+
34+
*/
35+
36+
#include "SPI.h"
37+
38+
// define SPI settings at which to test
39+
#define SPI_FREQ 10000000
40+
#define SPI_MODE SPI_MODE3
41+
#define SPI_ORDER MSBFIRST
42+
#define CS_PIN 0
43+
44+
#define SERIAL_PORT Serial
45+
46+
// define pins to create a custom SPI port
47+
// using mbed PinNames or Arduino pin numbers
48+
// (must be all pins from one IOM module)
49+
#define mySDI D25
50+
#define mySDO D28
51+
#define myCLK D27
52+
53+
MbedSPI mySPI(mySDI, mySDO, myCLK); // declare the custom MbedSPI object mySPI
54+
55+
// define a macro to aid testing
56+
#define TEST_SPI_PORT(P) SERIAL_PORT.printf("testing %s\n\ttime (ms): %d\n\tbyte transer: %s\n\tbuffer transfer: %s\n\n", #P, millis(), ((test_byte_transfer(P) == 0) ? "pass" : "fail"), ((test_buffer_transfer(P) == 0) ? "pass" : "fail"))
57+
58+
// this thread will test the pre-defined SPI object if it exists
59+
rtos::Thread spi_thread;
60+
void spi_thread_fn( void ){
61+
#if VARIANT_SPI_INTFCS > 0
62+
delay(100);
63+
SPI.begin();
64+
while(1){
65+
TEST_SPI_PORT(SPI);
66+
delay(500);
67+
}
68+
#endif
69+
}
70+
71+
// this thread tests the custom mySPI object
72+
extern "C" SPIName spi_get_peripheral_name(PinName mosi, PinName miso, PinName sclk); // this mbed internal function determines the IOM module number for a set of pins
73+
rtos::Thread myspi_thread;
74+
void myspi_thread_fn( void ){
75+
delay(300);
76+
SERIAL_PORT.printf("starting mySPI on IOM %d\n", spi_get_peripheral_name(mySDO, mySDI, myCLK));
77+
mySPI.begin();
78+
while(1){
79+
TEST_SPI_PORT(mySPI);
80+
delay(500);
81+
}
82+
}
83+
84+
int test_byte_transfer( SPIClass &spi ){
85+
uint8_t tx = random(1, 256);
86+
uint8_t rx = 0x00;
87+
spi.beginTransaction(SPISettings(SPI_FREQ, SPI_ORDER, SPI_MODE));
88+
rx = spi.transfer(tx);
89+
spi.endTransaction();
90+
if(rx != tx){
91+
return -1;
92+
}
93+
return 0;
94+
}
95+
96+
int test_buffer_transfer( SPIClass &spi ){
97+
const size_t len = 10;
98+
uint8_t tx_buff[len];
99+
uint8_t mirror[len];
100+
for(size_t idx = 0; idx < len; idx++){
101+
tx_buff[idx] = random(1, 256);
102+
mirror[idx] = tx_buff[idx];
103+
}
104+
spi.beginTransaction(SPISettings(SPI_FREQ, SPI_ORDER, SPI_MODE));
105+
spi.transfer(tx_buff, len);
106+
spi.endTransaction();
107+
bool mismatched = false;
108+
for(size_t idx = 0; idx < len; idx++){
109+
if(tx_buff[idx] != mirror[idx]){
110+
mismatched = true;
111+
}
112+
}
113+
if(mismatched){
114+
return -1;
115+
}
116+
return 0;
117+
}
118+
119+
void setup() {
120+
SERIAL_PORT.begin(115200);
121+
SERIAL_PORT.println("Apollo3 - Simple SPI");
122+
123+
pinMode(LED_BUILTIN, OUTPUT);
124+
pinMode(CS_PIN, OUTPUT);
125+
digitalWrite(CS_PIN, HIGH);
126+
127+
spi_thread.start(spi_thread_fn);
128+
myspi_thread.start(myspi_thread_fn);
129+
}
130+
131+
void loop() {
132+
digitalWrite(LED_BUILTIN, HIGH);
133+
delay(500);
134+
digitalWrite(LED_BUILTIN, LOW);
135+
delay(500);
136+
}

libraries/SPI/src/SPI.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ arduino::MbedSPI::MbedSPI(PinName miso, PinName mosi, PinName sck) : _miso(miso)
1616

1717
uint8_t arduino::MbedSPI::transfer(uint8_t data) {
1818
uint8_t ret;
19-
dev->write((const char*)&data, 1, (char*)&ret, 1);
19+
uint32_t tx = data;
20+
dev->write((const char*)&tx, 1, (char*)&ret, 1);
2021
return ret;
2122
}
2223

@@ -72,7 +73,7 @@ void arduino::MbedSPI::detachInterrupt() {
7273

7374
void arduino::MbedSPI::begin() {
7475
if(!dev){
75-
dev = new mbed::SPI((PinName)_mosi, (PinName)_miso, (PinName)_sck);
76+
dev = new mbed::SPI(_mosi, _miso, _sck);
7677
}
7778
}
7879

0 commit comments

Comments
 (0)