aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2011-04-28 13:52:58 -0400
committerMarti Bolivar <mbolivar@leaflabs.com>2011-04-28 14:23:30 -0400
commit77f707d7b87fce284945fc9fe21c824c18c4c93d (patch)
tree02daf36e8ac1a44218bd4cc309de44cee420cdbc /examples
parentc9da002f0833c7e4b5a156b67c0c8915056856af (diff)
SPI refactor.
Still a polling driver, but the libmaple proper interface exposes enough that users enable the various interrupts and define their own IRQ handlers if they feel like it. Wirish HardwareSPI interface was largely redone; it's more like the Arduino implementation now, although there are some differences when I didn't like their API. The old methods are still there, but are deprecated and slated for deletion in 0.1.0. New board-specific values: BOARD_NR_SPI, BOARD_SPIx_NSS_PIN, BOARD_SPIx_MOSI_PIN, BOARD_SPIx_MISO_PIN, and BOARD_SPIx_SCK_PIN, for x from 1 to BOARD_NR_SPI. Documentation was updated appropriately.
Diffstat (limited to 'examples')
-rw-r--r--examples/test-spi-roundtrip.cpp197
1 files changed, 197 insertions, 0 deletions
diff --git a/examples/test-spi-roundtrip.cpp b/examples/test-spi-roundtrip.cpp
new file mode 100644
index 0000000..257303b
--- /dev/null
+++ b/examples/test-spi-roundtrip.cpp
@@ -0,0 +1,197 @@
+/*
+ * Polling SPI loopback test.
+ *
+ * Bob is nowhere to be found, so Alice decides to talk to herself.
+ *
+ * Instructions: Connect SPI2 (Alice) to herself (i.e., MISO to MOSI).
+ * Connect to Alice via Serial2 at 115200 baud. Press any key to start.
+ *
+ * Alice will talk to herself for a little while. The sketch will
+ * report if Alice can't hear anything she says. She'll then start
+ * talking forever at various frequencies, bit orders, and modes. Use
+ * an oscilloscope to make sure she's not trying to lie about any of
+ * those things.
+ *
+ * This file is released into the public domain.
+ *
+ * Author: Marti Bolivar <mbolivar@leaflabs.com>
+ */
+
+#include "wirish.h"
+
+HardwareSPI alice(2);
+
+#define NFREQS 8
+const SPIFrequency spi_freqs[] = {
+ SPI_140_625KHZ,
+ SPI_281_250KHZ,
+ SPI_562_500KHZ,
+ SPI_1_125MHZ,
+ SPI_2_25MHZ,
+ SPI_4_5MHZ,
+ SPI_9MHZ,
+ SPI_18MHZ,
+};
+
+#define TEST_BUF_SIZE 10
+uint8 test_buf[TEST_BUF_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+void bad_assert(const char* file, int line, const char* exp) {
+ Serial2.println();
+ Serial2.print("ERROR: FAILED ASSERT(");
+ Serial2.print(exp);
+ Serial2.print("): ");
+ Serial2.print(file);
+ Serial2.print(": ");
+ Serial2.println(line);
+ throb();
+}
+
+#undef ASSERT
+#define ASSERT(exp) \
+ if (exp) { \
+ } else { \
+ bad_assert(__FILE__, __LINE__, #exp); \
+ }
+
+void haveConversation(uint32 bitOrder);
+void soliloquies(uint32 bitOrder);
+
+void setup() {
+ pinMode(BOARD_LED_PIN, OUTPUT);
+ Serial2.begin(115200);
+ Serial2.println();
+ Serial2.print("** SPI test ready. Press any key to start.");
+ while (!Serial2.available())
+ ;
+ Serial2.read();
+}
+
+void loop() {
+ Serial2.println("** Having a conversation, MSB first");
+ haveConversation(MSBFIRST);
+
+ Serial2.println("** Having a conversation, LSB first");
+ haveConversation(LSBFIRST);
+
+ Serial2.println();
+ Serial2.println("*** All done! It looks like everything worked.");
+ Serial2.println();
+
+ Serial2.println("** Alice will now wax eloquent in various styles. "
+ "Press any key for the next configuration.");
+ soliloquies(MSBFIRST);
+ soliloquies(LSBFIRST);
+
+ while (true)
+ ;
+}
+
+void printFrequencyString(SPIFrequency frequency);
+void chat(SPIFrequency frequency, uint32 bitOrder, uint32 mode);
+
+void haveConversation(uint32 bitOrder) {
+ for (int f = 0; f < NFREQS; f++) {
+ for (int mode = 0; mode < 4; mode++) {
+ chat(spi_freqs[f], bitOrder, mode);
+ delay(10);
+ }
+ }
+}
+
+void chat(SPIFrequency frequency, uint32 bitOrder, uint32 mode) {
+ Serial2.print("Having a chat.\tFrequency: ");
+ printFrequencyString(frequency);
+ Serial2.print(",\tbitOrder: ");
+ Serial2.print(bitOrder == MSBFIRST ? "MSB" : "LSB");
+ Serial2.print(",\tmode: ");
+ Serial2.print(mode);
+ Serial2.print(".");
+
+ Serial2.print(" [1] ");
+ alice.begin(frequency, bitOrder, mode);
+
+ Serial2.print(" [2] ");
+ uint32 txed = 0;
+ while (txed < TEST_BUF_SIZE) {
+ ASSERT(alice.transfer(test_buf[txed]) == test_buf[txed]);
+ txed++;
+ }
+
+ Serial2.print(" [3] ");
+ alice.end();
+
+ Serial2.println(" ok.");
+}
+
+void soliloquy(SPIFrequency freq, uint32 bitOrder, uint32 mode);
+
+void soliloquies(uint32 bitOrder) {
+ for (int f = 0; f < NFREQS; f++) {
+ for (int mode = 0; mode < 4; mode++) {
+ soliloquy(spi_freqs[f], bitOrder, mode);
+ }
+ }
+}
+
+void soliloquy(SPIFrequency frequency, uint32 bitOrder, uint32 mode) {
+ const uint8 repeat = 0xAE;
+ Serial2.print("Alice is giving a soliloquy (repeating 0x");
+ Serial2.print(repeat, HEX);
+ Serial2.print("). Frequency: ");
+ printFrequencyString(frequency);
+ Serial2.print(", bitOrder: ");
+ Serial2.print(bitOrder == MSBFIRST ? "big-endian" : "little-endian");
+ Serial2.print(", SPI mode: ");
+ Serial2.println(mode);
+
+ alice.begin(frequency, bitOrder, mode);
+ while (!Serial2.available()) {
+ alice.write(repeat);
+ delayMicroseconds(200);
+ }
+ Serial2.read();
+}
+
+void printFrequencyString(SPIFrequency frequency) {
+ switch (frequency) {
+ case SPI_18MHZ:
+ Serial2.print("18 MHz");
+ break;
+ case SPI_9MHZ:
+ Serial2.print("9 MHz");
+ break;
+ case SPI_4_5MHZ:
+ Serial2.print("4.5 MHz");
+ break;
+ case SPI_2_25MHZ:
+ Serial2.print("2.25 MHZ");
+ break;
+ case SPI_1_125MHZ:
+ Serial2.print("1.125 MHz");
+ break;
+ case SPI_562_500KHZ:
+ Serial2.print("562.500 KHz");
+ break;
+ case SPI_281_250KHZ:
+ Serial2.print("281.250 KHz");
+ break;
+ case SPI_140_625KHZ:
+ Serial2.print("140.625 KHz");
+ break;
+ }
+}
+
+// Force init to be called *first*, i.e. before static object allocation.
+// Otherwise, statically allocated objects that need libmaple may fail.
+__attribute__((constructor)) void premain() {
+ init();
+}
+
+int main(void) {
+ setup();
+ while (true) {
+ loop();
+ }
+ return 0;
+}