From dba5a9fe68ebb996eeee69fa9b573fe5a1561ce2 Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Thu, 16 Oct 2014 20:20:20 -0700 Subject: refactor: move test-style examples to ./tests --- examples/test-bkp.cpp | 80 --- examples/test-dac.cpp | 51 -- examples/test-fsmc.cpp | 122 ----- examples/test-print.cpp | 184 ------- examples/test-ring-buffer-insertion.cpp | 114 ---- examples/test-serial-flush.cpp | 38 -- examples/test-serialusb.cpp | 126 ----- examples/test-servo.cpp | 152 ------ examples/test-session.cpp | 938 -------------------------------- examples/test-spi-roundtrip.cpp | 192 ------- examples/test-systick.cpp | 49 -- examples/test-timers.cpp | 537 ------------------ examples/test-usart-dma.cpp | 211 ------- 13 files changed, 2794 deletions(-) delete mode 100644 examples/test-bkp.cpp delete mode 100644 examples/test-dac.cpp delete mode 100644 examples/test-fsmc.cpp delete mode 100644 examples/test-print.cpp delete mode 100644 examples/test-ring-buffer-insertion.cpp delete mode 100644 examples/test-serial-flush.cpp delete mode 100644 examples/test-serialusb.cpp delete mode 100644 examples/test-servo.cpp delete mode 100644 examples/test-session.cpp delete mode 100644 examples/test-spi-roundtrip.cpp delete mode 100644 examples/test-systick.cpp delete mode 100644 examples/test-timers.cpp delete mode 100644 examples/test-usart-dma.cpp (limited to 'examples') diff --git a/examples/test-bkp.cpp b/examples/test-bkp.cpp deleted file mode 100644 index 719cac7..0000000 --- a/examples/test-bkp.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include // for snprintf() - -#include -#include -#include - -void print_bkp_contents(); -void write_to_bkp(uint16 val); - -#define comm Serial2 - -void setup() { - pinMode(BOARD_BUTTON_PIN, INPUT); - - comm.begin(9600); - comm.println("*** Beginning BKP test"); - - comm.println("Init..."); - bkp_init(); - comm.println("Done."); - - print_bkp_contents(); - write_to_bkp(10); - print_bkp_contents(); - - comm.println("Enabling backup writes."); - bkp_enable_writes(); - write_to_bkp(20); - print_bkp_contents(); - - comm.println("Disabling backup writes."); - bkp_disable_writes(); - write_to_bkp(30); - print_bkp_contents(); - - comm.println("Done testing backup registers; press button to enable " - "independent watchdog (in order to cause a reset)."); - waitForButtonPress(0); - iwdg_init(IWDG_PRE_4, 1); - comm.println(); -} - -void loop() { -} - -void print_bkp_contents() { - comm.println("Backup data register contents:"); - char buf[100]; - for (int i = 1; i <= BKP_NR_DATA_REGS; i++) { - snprintf(buf, sizeof buf, "DR%d: %d ", i, bkp_read(i)); - comm.print(buf); - if (i % 5 == 0) comm.println(); - } - comm.println(); -} - -void write_to_bkp(uint16 val) { - comm.print("Attempting to write "); - comm.print(val); - comm.println(" to backup registers..."); - for (int i = 1; i <= BKP_NR_DATA_REGS; i++) { - bkp_write(i, val); - } - comm.println("Done."); -} - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - init(); - setup(); - - while (1) { - loop(); - } - return 0; -} - diff --git a/examples/test-dac.cpp b/examples/test-dac.cpp deleted file mode 100644 index af188cc..0000000 --- a/examples/test-dac.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Simple DAC test. - * - * Author: Marti Bolivar - * - * This file is released into the public domain. - */ - -#include -#include - -uint16 count = 0; - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); - digitalWrite(BOARD_LED_PIN, HIGH); - - Serial1.begin(9600); - Serial1.println("**** Beginning DAC test"); - - Serial1.print("Init... "); - dac_init(DAC, DAC_CH1 | DAC_CH2); - Serial1.println("Done."); -} - -void loop() { - toggleLED(); - delay(100); - - count += 100; - if (count > 4095) { - count = 0; - } - - dac_write_channel(DAC, 1, 4095 - count); - dac_write_channel(DAC, 2, count); -} - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} - diff --git a/examples/test-fsmc.cpp b/examples/test-fsmc.cpp deleted file mode 100644 index 1621317..0000000 --- a/examples/test-fsmc.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include // for ptrdiff_t - -#include -#include - -#ifndef BOARD_maple_native -#error "Sorry, this example only works on Maple Native." -#endif - -// Start of FSMC SRAM bank 1 -static uint16 *const sram_start = (uint16*)0x60000000; -// End of Maple Native SRAM chip address space (512K 16-bit words) -static uint16 *const sram_end = (uint16*)0x60100000; - -void test_single_write(void); -void test_all_addresses(void); - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); - digitalWrite(BOARD_LED_PIN, HIGH); - - SerialUSB.read(); - SerialUSB.println("*** Beginning RAM chip test"); - - test_single_write(); - test_all_addresses(); - - SerialUSB.println("Tests pass, finished."); - SerialUSB.println("***\n"); -} - -void loop() { -} - -void test_single_write() { - uint16 *ptr = sram_start; - uint16 tmp; - - SerialUSB.print("Writing 0x1234... "); - *ptr = 0x1234; - SerialUSB.println("Done."); - - SerialUSB.print("Reading... "); - tmp = *ptr; - SerialUSB.print("Done: 0x"); - SerialUSB.println(tmp, HEX); - - if (tmp != 0x1234) { - SerialUSB.println("Mismatch; abort."); - ASSERT(0); - } -} - -void test_all_addresses() { - uint32 start, end; - uint16 count = 0; - uint16 *ptr; - - SerialUSB.println("Now writing all memory addresses (unrolled loop)"); - start = micros(); - for (ptr = sram_start; ptr < sram_end;) { - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - *ptr++ = count++; - } - end = micros(); - SerialUSB.print("Done. Elapsed time (us): "); - SerialUSB.println(end - start); - - SerialUSB.println("Validating writes."); - for (ptr = sram_start, count = 0; ptr < sram_end; ptr++, count++) { - uint16 value = *ptr; - if (value != count) { - SerialUSB.print("mismatch: 0x"); - SerialUSB.print((uint32)ptr); - SerialUSB.print(" = 0x"); - SerialUSB.print(value, HEX); - SerialUSB.print(", should be 0x"); - SerialUSB.print(count, HEX); - SerialUSB.println("."); - ASSERT(0); - } - } - SerialUSB.println("Done; all writes seem valid."); - - ptrdiff_t nwrites = sram_end - sram_start; - double us_per_write = double(end-start) / double(nwrites); - SerialUSB.print("Number of writes = "); - SerialUSB.print(nwrites); - SerialUSB.print("; avg. time per write = "); - SerialUSB.print(us_per_write); - SerialUSB.print(" us ("); - SerialUSB.print(1 / us_per_write); - SerialUSB.println(" MHz)"); -} - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - - return 0; -} diff --git a/examples/test-print.cpp b/examples/test-print.cpp deleted file mode 100644 index bdc1894..0000000 --- a/examples/test-print.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * print-test.cpp - * - * Tests the various Print methods. (For USBSerial; assuming that - * writing a single character works, this should generalize to - * HardwareSerial). - * - * This file is released into the public domain. - */ - -#include -#undef min -#undef max - -// For snprintf() -#include -// The that comes with newlib is missing LLONG_MAX, etc. -#include - -using namespace std; - -#define BUF_SIZE 100 -char buf[BUF_SIZE]; - -void test_numbers(void); -void test_base_arithmetic(void); -void test_floating_point(void); - -void print_separator(void); - -void setup() { - while (!SerialUSB.available()) - continue; - SerialUSB.read(); -} - -void loop() { - SerialUSB.println("Testing Print methods."); - print_separator(); - - test_numbers(); - print_separator(); - - test_base_arithmetic(); - print_separator(); - - test_floating_point(); - print_separator(); - - SerialUSB.println("Test finished."); - while (true) { - continue; - } -} - -void test_numbers(void) { - SerialUSB.println("Numeric types:"); - - SerialUSB.print("unsigned char: "); - // prevent Print from treating it as an (extended) ASCII character: - SerialUSB.println((uint32)numeric_limits::max()); - - SerialUSB.print("int: "); - SerialUSB.print(numeric_limits::min()); - SerialUSB.print(" -- "); - SerialUSB.println(numeric_limits::max()); - - SerialUSB.print("unsigned int: "); - SerialUSB.print(numeric_limits::max()); - SerialUSB.println(); - - SerialUSB.print("long: "); - SerialUSB.print(numeric_limits::min()); - SerialUSB.print(" -- "); - SerialUSB.println(numeric_limits::max()); - - SerialUSB.print("long long: "); - SerialUSB.print(numeric_limits::min()); - SerialUSB.print(" -- "); - SerialUSB.println(numeric_limits::max()); - - SerialUSB.print("unsigned long long: "); - SerialUSB.println(numeric_limits::max()); -} - -void base_test(int base) { - SerialUSB.print("\tuint8: "); - SerialUSB.println(numeric_limits::max(), base); - SerialUSB.print("\tint: "); - SerialUSB.print(numeric_limits::max(), base); - SerialUSB.print(", unsigned int: "); - SerialUSB.println(numeric_limits::max(), base); - SerialUSB.print("\tlong: "); - SerialUSB.print(numeric_limits::max(), base); - SerialUSB.print(", unsigned long: "); - SerialUSB.println(numeric_limits::max(), base); - SerialUSB.print("\tlong long: "); - SerialUSB.print(numeric_limits::max(), base); - SerialUSB.print(", unsigned long long: "); - SerialUSB.println(numeric_limits::max(), base); -} - -void test_base_arithmetic(void) { - SerialUSB.println("Base arithmetic:"); - - SerialUSB.println("Binary:"); - base_test(BIN); - - SerialUSB.println("Octal:"); - base_test(OCT); - - SerialUSB.println("Decimal:"); - base_test(DEC); - - SerialUSB.println("Hexadecimal:"); - base_test(HEX); -} - -void test_floating_point(void) { - double dmax = numeric_limits::max(); - - SerialUSB.println("Floating point:"); - - SerialUSB.print("println(-5.67): "); - SerialUSB.print(-5.67); - SerialUSB.print(". println(5.67, 5): "); - SerialUSB.println(5.67, 5); - SerialUSB.print("println((double)(LLONG_MAX - 10)): "); - SerialUSB.print((double)(numeric_limits::max() - 10)); - SerialUSB.print("; from snprintf(): "); - snprintf(buf, BUF_SIZE, "%.2f", - (double)(numeric_limits::max() - 10)); - SerialUSB.println(buf); - SerialUSB.print("println((double)LLONG_MAX / 2): "); - SerialUSB.print((double)(numeric_limits::max()) / 2); - SerialUSB.print("; from snprintf(): "); - snprintf(buf, BUF_SIZE, "%.2f", - (double)(numeric_limits::max()) / 2); - SerialUSB.println(buf); - SerialUSB.print("DBL_MAX: "); - SerialUSB.print(dmax); - SerialUSB.print("; from snprintf(): "); - snprintf(buf, BUF_SIZE, "%g", dmax); - SerialUSB.println(buf); - SerialUSB.print("-DBL_MAX / 2: "); - SerialUSB.print(-dmax / 2.0); - SerialUSB.print("; from snprintf(): "); - snprintf(buf, BUF_SIZE, "%g", -dmax / 2.0); - SerialUSB.println(buf); - SerialUSB.print("Double epsilon, round error: "); - SerialUSB.print(numeric_limits::epsilon()); - SerialUSB.print(", "); - SerialUSB.println(numeric_limits::round_error()); - - SerialUSB.println(); - - float fmax = numeric_limits::max(); - - SerialUSB.print("println(-5.67f): "); - SerialUSB.println(-5.67f); - SerialUSB.print("Float max: "); - SerialUSB.println(fmax); -} - -void print_separator(void) { - SerialUSB.println(); - SerialUSB.println(" ** "); - SerialUSB.println(); -} - -// 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 (1) { - loop(); - } - return 0; -} diff --git a/examples/test-ring-buffer-insertion.cpp b/examples/test-ring-buffer-insertion.cpp deleted file mode 100644 index 2188b03..0000000 --- a/examples/test-ring-buffer-insertion.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Simple ring_buffer test. - * - * Does a basic test of functionality on rb_full_count(), rb_reset(), - * rb_push_insert(), and rb_safe_insert(). - * - * To test: - * - * - Connect a serial monitor to SerialUSB - * - Press any key - * - * This file is released into the public domain. - */ - -#include - -#include - -#define BUF_SIZE 64 -ring_buffer ring_buf; -ring_buffer *rb; -uint8 rb_buffer[BUF_SIZE]; - -void test_rb_push_insert(int num_bytes_to_insert); -void test_rb_safe_insert(int num_bytes_to_insert); -void test_rb_insertion_function(int num_bytes_to_insert, - int (*insertion_fn)(ring_buffer*, uint8), - const char insertion_fn_name[]); -void print_rb_contents(void); - -void setup() { - rb = &ring_buf; - rb_init(rb, BUF_SIZE, rb_buffer); - - while (!SerialUSB.available()) - ; - - SerialUSB.println("Beginning test."); - SerialUSB.println(); -} - -void loop() { - test_rb_push_insert(63); - SerialUSB.println("------------------------------"); - test_rb_push_insert(64); - SerialUSB.println("------------------------------"); - test_rb_safe_insert(63); - SerialUSB.println("------------------------------"); - test_rb_safe_insert(64); - SerialUSB.println("------------------------------"); - - SerialUSB.println(); - SerialUSB.println("Test finished."); - while (true) - ; -} - -void test_rb_push_insert(int num_bytes_to_insert) { - test_rb_insertion_function(num_bytes_to_insert, - rb_push_insert, - "rb_push_insert()"); -} - -void test_rb_safe_insert(int num_bytes_to_insert) { - test_rb_insertion_function(num_bytes_to_insert, - rb_safe_insert, - "rb_safe_insert()"); -} - -void test_rb_insertion_function(int num_bytes_to_insert, - int (*insertion_fn)(ring_buffer *, uint8), - const char insertion_fn_name[]) { - SerialUSB.println("resetting ring buffer."); - rb_reset(rb); - print_rb_contents(); - - SerialUSB.print(insertion_fn_name); - SerialUSB.print("-ing "); - SerialUSB.print(num_bytes_to_insert); - SerialUSB.println(" bytes."); - for (uint8 i = 1; i <= num_bytes_to_insert; i++) - insertion_fn(rb, i); - - uint16 count = rb_full_count(rb); - SerialUSB.print("rb_full_count(rb) = "); - SerialUSB.println(count); - - print_rb_contents(); -} - -void print_rb_contents() { - uint16 count = rb_full_count(rb); - SerialUSB.print("ring buffer contents: "); - for (uint16 i = 0; i < count; i++) { - SerialUSB.print((int)rb_remove(rb)); - if (i < count - 1) SerialUSB.print(", "); - } - SerialUSB.println(); -} - -// 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; -} diff --git a/examples/test-serial-flush.cpp b/examples/test-serial-flush.cpp deleted file mode 100644 index 409d1f9..0000000 --- a/examples/test-serial-flush.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Tests the "flush" Serial function. - */ - -#include - -void setup() { - Serial1.begin(9600); - Serial1.println("Hello world!"); -} - -void loop() { - Serial1.println("Waiting for multiple input..."); - while (Serial1.available() < 5) - ; - Serial1.println(Serial1.read()); - Serial1.println(Serial1.read()); - Serial1.flush(); - - if (Serial1.available()) { - Serial1.println("FAIL! Still had junk in the buffer..."); - } -} - -// 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; -} diff --git a/examples/test-serialusb.cpp b/examples/test-serialusb.cpp deleted file mode 100644 index 098e445..0000000 --- a/examples/test-serialusb.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// Tests SerialUSB functionality. - -#include -#include "usb_cdcacm.h" - -#define QUICKPRINT 0 -#define BIGSTUFF 1 -#define NUMBERS 2 -#define SIMPLE 3 -#define ONOFF 4 - -uint32 state = 0; - -void setup() { - /* Set up the LED to blink */ - pinMode(BOARD_LED_PIN, OUTPUT); - - /* Set up Serial2 for use as a debug channel */ - Serial2.begin(9600); - Serial2.println("This is the debug channel. Press any key."); - while (!Serial2.available()) - ; - Serial2.read(); -} - -uint8 c1 = '-'; - -void loop() { - toggleLED(); - delay(1000); - - if (Serial2.available()) { - Serial2.read(); - state++; - } - - switch (state) { - case QUICKPRINT: - for (int i = 0; i < 30; i++) { - usb_cdcacm_putc((char)c1, 1); - SerialUSB.print('.'); - SerialUSB.print('|'); - } - Serial2.println(SerialUSB.pending(), DEC); - SerialUSB.println(); - break; - case BIGSTUFF: - SerialUSB.println("0123456789012345678901234567890123456789" - "0123456789012345678901234567890123456789" - "012345678901234567890"); - SerialUSB.println((int64)123456789, DEC); - SerialUSB.println(3.1415926535); - Serial2.println(SerialUSB.pending(), DEC); - break; - case NUMBERS: - SerialUSB.println("Numbers! -----------------------------"); - Serial2.println("Numbers! -----------------------------"); - SerialUSB.println('1'); - Serial2.println('1'); - SerialUSB.println(1, DEC); - Serial2.println(1, DEC); - SerialUSB.println(-1, DEC); - Serial2.println(-1, DEC); - SerialUSB.println(3.14159265); - Serial2.println(3.14159265); - SerialUSB.println(123456789, DEC); - Serial2.println(123456789, DEC); - SerialUSB.println(-123456789, DEC); - Serial2.println(-123456789, DEC); - SerialUSB.println(65535, HEX); - Serial2.println(65535, HEX); - break; - case SIMPLE: - Serial2.println("Trying write('a')"); - SerialUSB.write('a'); - Serial2.println("Trying write(\"b\")"); - SerialUSB.write("b"); - Serial2.println("Trying print('c')"); - SerialUSB.print('c'); - Serial2.println("Trying print(\"d\")"); - SerialUSB.print("d"); - Serial2.println("Trying print(\"efg\")"); - SerialUSB.print("efg"); - Serial2.println("Trying println(\"hij\\n\\r\")"); - SerialUSB.print("hij\n\r"); - SerialUSB.write(' '); - SerialUSB.println(); - Serial2.println("Trying println(123456789, DEC)"); - SerialUSB.println(123456789, DEC); - Serial2.println("Trying println(3.141592)"); - SerialUSB.println(3.141592); - Serial2.println("Trying println(\"DONE\")"); - SerialUSB.println("DONE"); - break; - case ONOFF: - Serial2.println("Shutting down..."); - SerialUSB.println("Shutting down..."); - SerialUSB.end(); - Serial2.println("Waiting 4 seconds..."); - delay(4000); - Serial2.println("Starting up..."); - SerialUSB.begin(); - SerialUSB.println("Hello World!"); - Serial2.println("Waiting 4 seconds..."); - delay(4000); - state++; - break; - default: - state = 0; - } -} - -// 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; -} diff --git a/examples/test-servo.cpp b/examples/test-servo.cpp deleted file mode 100644 index 6f6e3ba..0000000 --- a/examples/test-servo.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Basic Servo library test program. - * - * Setup: - * - * - Connect a potentiometer to POT_PIN (default pin 15) - * - Connect an oscilloscope to SERVO_PIN1 (default pin 5) and - * SERVO_PIN2 (default pin 6). - * - Connect a serial monitor to SerialUSB - * - * The potentiometer controls the target angle for each of two Servo - * objects, one with angles in [-90, 90], and another in [0, 180]. - * Servo pulse width range is [1000, 2000]. - * - * Serial2 will tell you what inputs it's giving to each servo object, - * and some information it gets back. Pressing the button - * detaches/reattaches the Servo objects. - * - * Tests you should perform: - * - * - Check calculated pulse widths for each servo's target angle - * - Check that calculated pulse widths match actual pulse widths - * - Check that the period of the pulse train is roughly 20 ms - * - Check that the pulses stop when detached, and resume when reattached - * - Check that Servo::write() and Servo::read() round-trip properly - * - * This file is released into the public domain. - */ - -#include - -#include - -#include "libraries/Servo/Servo.h" - -#define POT_PIN 15 - -#define MIN_PW 1000 -#define MAX_PW 2000 - -#define SERVO_PIN1 5 -#define MIN_ANGLE1 0 -#define MAX_ANGLE1 180 - -#define SERVO_PIN2 6 -#define MIN_ANGLE2 (-90) -#define MAX_ANGLE2 90 - -Servo servo1; -Servo servo2; - -#define BUF_SIZE 100 -char buf[BUF_SIZE]; - -#define print_buf(fmt, ...) do { \ - snprintf(buf, BUF_SIZE, fmt, __VA_ARGS__); \ - Serial2.println(buf); } while (0) - -int averageAnalogReads(int); -void attach(); -void detach(); - -void setup() { - pinMode(POT_PIN, INPUT_ANALOG); - pinMode(BOARD_BUTTON_PIN, INPUT); - pinMode(BOARD_LED_PIN, OUTPUT); - - Serial2.begin(9600); - - servo1.attach(SERVO_PIN1, MIN_PW, MAX_PW, MIN_ANGLE1, MAX_ANGLE1); - servo2.attach(SERVO_PIN2, MIN_PW, MAX_PW, MIN_ANGLE2, MAX_ANGLE2); - - ASSERT(servo1.attachedPin() == SERVO_PIN1); - ASSERT(servo2.attachedPin() == SERVO_PIN2); -} - -void loop() { - delay(250); - toggleLED(); - - if (isButtonPressed()) { - if (servo1.attached()) detach(); - else attach(); - } - - if (!servo1.attached()) return; - - int32 average = averageAnalogReads(250); - int16 angle1 = (int16)map(average, 0, 4095, MIN_ANGLE1, MAX_ANGLE1); - int16 angle2 = (int16)map(average, 0, 4095, MIN_ANGLE2, MAX_ANGLE2); - - print_buf("pot reading = %d, angle 1 = %d, angle 2 = %d.", - average, angle1, angle2); - - servo1.write(angle1); - servo2.write(angle2); - - int16 read1 = servo1.read(); - int16 read2 = servo2.read(); - - print_buf("write/read angle 1: %d/%d, angle 2: %d/%d", - angle1, read1, angle2, read2); - - ASSERT(abs(angle1 - read1) <= 1); - ASSERT(abs(angle2 - read2) <= 1); - - print_buf("pulse width 1: %d, pulse width 2: %d", - servo1.readMicroseconds(), servo2.readMicroseconds()); - - Serial2.println("\n--------------------------\n"); -} - -int32 averageAnalogReads(int n) { - uint64 total = 0; - - for (int i = 0; i < n; i++) { - total += analogRead(POT_PIN); - } - - return (int32)(total / n); -} - -void attach() { - Serial2.println("attaching"); - servo1.attach(SERVO_PIN1); - servo2.attach(SERVO_PIN2); - ASSERT(servo1.attachedPin() == SERVO_PIN1); - ASSERT(servo2.attachedPin() == SERVO_PIN2); -} - -void detach() { - Serial2.println("detaching"); - servo1.detach(); - servo2.detach(); - ASSERT(!servo1.attached()); - ASSERT(!servo2.attached()); -} - -// 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; -} diff --git a/examples/test-session.cpp b/examples/test-session.cpp deleted file mode 100644 index 284b4b0..0000000 --- a/examples/test-session.cpp +++ /dev/null @@ -1,938 +0,0 @@ -// Interactive Test Session for LeafLabs Maple -// Copyright (c) 2010 LeafLabs LLC. -// -// Useful for testing Maple features and troubleshooting. -// Communicates over SerialUSB. - -#include - -#include - -// ASCII escape character -#define ESC ((uint8)27) - -// Default USART baud rate -#define BAUD 9600 - -// Number of times to sample a pin per ADC noise measurement -#define N_ADC_NOISE_MEASUREMENTS 40 - -uint8 gpio_state[BOARD_NR_GPIO_PINS]; - -const char* dummy_data = ("123456789012345678901234567890\r\n" - "123456789012345678901234567890\r\n"); - -// Commands -void cmd_print_help(void); -void cmd_adc_stats(void); -void cmd_stressful_adc_stats(void); -void cmd_everything(void); -void cmd_serial1_serial3(void); -void cmd_serial1_echo(void); -void cmd_gpio_monitoring(void); -void cmd_sequential_adc_reads(void); -void cmd_gpio_qa(void); -void cmd_sequential_gpio_toggling(void); -void cmd_gpio_toggling(void); -void cmd_sequential_debug_gpio_toggling(void); -void cmd_debug_gpio_toggling(void); -void cmd_but_test(void); -void cmd_sequential_pwm_test(void); -void cmd_servo_sweep(void); -void cmd_board_info(void); - -// Helper functions -void measure_adc_noise(uint8 pin); -void fast_gpio(int pin); -void serial_baud_test(HardwareSerial **serials, int n, unsigned baud); -void serial_echo_test(HardwareSerial *serial, unsigned baud); -void init_all_timers(uint16 prescale); -void enable_usarts(void); -void disable_usarts(void); -void print_board_array(const char* msg, const uint8 arr[], int len); - -// -- setup() and loop() ------------------------------------------------------ - -void setup() { - // Set up the LED to blink - pinMode(BOARD_LED_PIN, OUTPUT); - - // Start up the serial ports - Serial1.begin(BAUD); - Serial2.begin(BAUD); - Serial3.begin(BAUD); - - // Send a message out over SerialUSB interface - SerialUSB.println(" "); - SerialUSB.println(" __ __ _ _"); - SerialUSB.println(" | \\/ | __ _ _ __ | | ___| |"); - SerialUSB.println(" | |\\/| |/ _` | '_ \\| |/ _ \\ |"); - SerialUSB.println(" | | | | (_| | |_) | | __/_|"); - SerialUSB.println(" |_| |_|\\__,_| .__/|_|\\___(_)"); - SerialUSB.println(" |_|"); - SerialUSB.println(" by leaflabs"); - SerialUSB.println(""); - SerialUSB.println(""); - SerialUSB.println("Maple interactive test program (type '?' for help)"); - SerialUSB.println("-------------------------------------------------------" - "---"); - SerialUSB.print("> "); - -} - -void loop () { - toggleLED(); - delay(250); - - while (SerialUSB.available()) { - uint8 input = SerialUSB.read(); - SerialUSB.println((char)input); - - switch(input) { - case '\r': - break; - - case ' ': - SerialUSB.println("spacebar, nice!"); - break; - - case '?': - case 'h': - cmd_print_help(); - break; - - case 'u': - SerialUSB.println("Hello World!"); - break; - - case 'w': - Serial1.println("Hello World!"); - Serial2.println("Hello World!"); - Serial3.println("Hello World!"); - break; - - case 'm': - cmd_serial1_serial3(); - break; - - case 'E': - cmd_serial1_echo(); - break; - - case '.': - while (!SerialUSB.available()) { - Serial1.print("."); - Serial2.print("."); - Serial3.print("."); - SerialUSB.print("."); - } - break; - - case 'd': - SerialUSB.println("Disabling USB. Press BUT to re-enable."); - SerialUSB.end(); - pinMode(BOARD_BUTTON_PIN, INPUT); - while (!isButtonPressed()) - ; - SerialUSB.begin(); - break; - - case 'n': - cmd_adc_stats(); - break; - - case 'N': - cmd_stressful_adc_stats(); - break; - - case 'e': - cmd_everything(); - break; - - case 'W': - while (!SerialUSB.available()) { - Serial1.print(dummy_data); - Serial2.print(dummy_data); - Serial3.print(dummy_data); - } - break; - - case 'U': { - SerialUSB.println("Dumping data to USB. Press any key."); - int nprints = 0; - int start = millis(); - while (!SerialUSB.available()) { - SerialUSB.print(dummy_data); - nprints++; - } - int elapsed = millis() - start; - SerialUSB.read(); // consume available character - size_t nbytes = nprints * strlen(dummy_data); - SerialUSB.println(); - SerialUSB.print("Sent "); - SerialUSB.print(nbytes); - SerialUSB.print(" bytes ("); - SerialUSB.print((nbytes / (double)elapsed) * (1000.0 / 1024.0)); - SerialUSB.println(" kB/sec)"); - } - break; - - case 'g': - cmd_sequential_gpio_toggling(); - break; - - case 'G': - cmd_gpio_toggling(); - break; - - case 'j': - cmd_sequential_debug_gpio_toggling(); - break; - - case 'J': - cmd_debug_gpio_toggling(); - break; - - case 'B': - cmd_but_test(); - break; - - case 'f': - SerialUSB.println("Wiggling D4 as fast as possible in bursts. " - "Press any key."); - pinMode(4, OUTPUT); - while (!SerialUSB.available()) { - fast_gpio(4); - delay(1); - } - break; - - case 'p': - cmd_sequential_pwm_test(); - break; - - case '_': - SerialUSB.println("Delaying for 5 seconds..."); - delay(5000); - break; - - // Be sure to update cmd_print_help() if you implement these: - - case 't': // TODO - SerialUSB.println("Unimplemented."); - break; - - case 'T': // TODO - SerialUSB.println("Unimplemented."); - break; - - case 's': - cmd_servo_sweep(); - break; - - // Be sure to update cmd_print_help() if you implement these: - - case 'i': // TODO - SerialUSB.println("Unimplemented."); - break; - - case 'I': // TODO - SerialUSB.println("Unimplemented."); - break; - - case 'r': - cmd_gpio_monitoring(); - break; - - case 'a': - cmd_sequential_adc_reads(); - break; - - case 'b': - cmd_board_info(); - break; - - case '+': - cmd_gpio_qa(); - break; - - default: // ------------------------------- - SerialUSB.print("Unexpected byte: 0x"); - SerialUSB.print((int)input, HEX); - SerialUSB.println(", press h for help."); - } - - SerialUSB.print("> "); - } -} - -// -- Commands ---------------------------------------------------------------- - -void cmd_print_help(void) { - SerialUSB.println(""); - SerialUSB.println("Command Listing"); - SerialUSB.println("\t?: print this menu"); - SerialUSB.println("\td: Disable SerialUSB (press button to re-enable)"); - SerialUSB.println("\th: print this menu"); - SerialUSB.println("\tw: print Hello World on all 3 USARTS"); - SerialUSB.println("\tn: measure noise and do statistics"); - SerialUSB.println("\tN: measure noise and do statistics with background " - "stuff"); - SerialUSB.println("\ta: show realtime ADC info"); - SerialUSB.println("\t.: echo '.' until new input"); - SerialUSB.println("\tu: print Hello World on USB"); - SerialUSB.println("\t_: do as little as possible for a couple seconds " - "(delay)"); - SerialUSB.println("\tp: test all PWM channels sequentially"); - SerialUSB.println("\tW: dump data as fast as possible on all 3 USARTS"); - SerialUSB.println("\tU: dump data as fast as possible over USB" - " and measure data rate"); - SerialUSB.println("\tg: toggle GPIOs sequentially"); - SerialUSB.println("\tG: toggle GPIOs at the same time"); - SerialUSB.println("\tj: toggle debug port GPIOs sequentially"); - SerialUSB.println("\tJ: toggle debug port GPIOs simultaneously"); - SerialUSB.println("\tB: test the built-in button"); - SerialUSB.println("\tf: toggle pin 4 as fast as possible in bursts"); - SerialUSB.println("\tr: monitor and print GPIO status changes"); - SerialUSB.println("\ts: output a sweeping servo PWM on all PWM channels"); - SerialUSB.println("\tm: output data on USART1 and USART3 at various " - "baud rates"); - SerialUSB.println("\tE: echo data on USART1 at various baud rates"); - SerialUSB.println("\tb: print information about the board."); - SerialUSB.println("\t+: test shield mode (for quality assurance testing)"); - - SerialUSB.println("Unimplemented:"); - SerialUSB.println("\te: do everything all at once until new input"); - SerialUSB.println("\tt: output a 1khz squarewave on all GPIOs"); - SerialUSB.println("\tT: output a 1hz squarewave on all GPIOs"); - SerialUSB.println("\ti: print out a bunch of info about system state"); - SerialUSB.println("\tI: print out status of all headers"); -} - -void cmd_adc_stats(void) { - SerialUSB.println("Taking ADC noise stats. Press ESC to stop, " - "'R' to repeat same pin, anything else for next pin."); - - uint32 i = 0; - while (i < BOARD_NR_ADC_PINS) { - measure_adc_noise(boardADCPins[i]); - - SerialUSB.println("----------"); - uint8 c = SerialUSB.read(); - if (c == ESC) { - break; - } else if (c != 'r' && c != 'R') { - i++; - } - } -} - -void cmd_stressful_adc_stats(void) { - SerialUSB.println("Taking ADC noise stats under duress. Press ESC to " - "stop, 'R' to repeat same pin, anything else for next " - "pin."); - - uint32 i = 0; - while (i < BOARD_NR_ADC_PINS) { - // use PWM to create digital noise - for (uint32 j = 0; j < BOARD_NR_PWM_PINS; j++) { - if (boardADCPins[i] != boardPWMPins[j]) { - pinMode(boardPWMPins[j], PWM); - pwmWrite(boardPWMPins[j], 1000 + i); - } - } - - measure_adc_noise(boardADCPins[i]); - - // turn off the noise - for (uint32 j = 0; j < BOARD_NR_PWM_PINS; j++) { - if (boardADCPins[i] != boardPWMPins[j]) { - pinMode(boardPWMPins[j], OUTPUT); - digitalWrite(boardPWMPins[j], LOW); - } - } - - SerialUSB.println("----------"); - uint8 c = SerialUSB.read(); - if (c == ESC) { - break; - } else if (c != 'r' && c != 'R') { - i++; - } - } -} - -void cmd_everything(void) { // TODO - // Be sure to update cmd_print_help() if you implement this. - - // print to usart - // print to usb - // toggle gpios - // enable pwm - SerialUSB.println("Unimplemented."); -} - -void cmd_serial1_serial3(void) { - HardwareSerial *serial_1_and_3[] = {&Serial1, &Serial3}; - - SerialUSB.println("Testing 57600 baud on USART1 and USART3. " - "Press any key to stop."); - serial_baud_test(serial_1_and_3, 2, 57600); - SerialUSB.read(); - - SerialUSB.println("Testing 115200 baud on USART1 and USART3. " - "Press any key to stop."); - serial_baud_test(serial_1_and_3, 2, 115200); - SerialUSB.read(); - - SerialUSB.println("Testing 9600 baud on USART1 and USART3. " - "Press any key to stop."); - serial_baud_test(serial_1_and_3, 2, 9600); - SerialUSB.read(); - - SerialUSB.println("Resetting USART1 and USART3..."); - Serial1.begin(BAUD); - Serial3.begin(BAUD); -} - -void cmd_serial1_echo(void) { - SerialUSB.println("Testing serial echo at various baud rates. " - "Press any key for next baud rate, or ESC to quit " - "early."); - while (!SerialUSB.available()) - ; - - if (SerialUSB.read() == ESC) return; - SerialUSB.println("Testing 115200 baud on USART1."); - serial_echo_test(&Serial1, 115200); - - if (SerialUSB.read() == ESC) return; - SerialUSB.println("Testing 57600 baud on USART1."); - serial_echo_test(&Serial1, 57600); - - if (SerialUSB.read() == ESC) return; - SerialUSB.println("Testing 9600 baud on USART1."); - serial_echo_test(&Serial1, 9600); -} - -void cmd_gpio_monitoring(void) { - SerialUSB.println("Monitoring pin state changes. Press any key to stop."); - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(i, INPUT_PULLDOWN); - gpio_state[i] = (uint8)digitalRead(i); - } - - while (!SerialUSB.available()) { - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - - uint8 current_state = (uint8)digitalRead(i); - if (current_state != gpio_state[i]) { - SerialUSB.print("State change on pin "); - SerialUSB.print(i, DEC); - if (current_state) { - SerialUSB.println(":\tHIGH"); - } else { - SerialUSB.println(":\tLOW"); - } - gpio_state[i] = current_state; - } - } - } - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(i, OUTPUT); - } -} - -void cmd_sequential_adc_reads(void) { - SerialUSB.print("Sequentially reading most ADC ports."); - SerialUSB.println("Press any key for next port, or ESC to stop."); - - for (uint32 i = 0; i < BOARD_NR_ADC_PINS; i++) { - if (boardUsesPin(boardADCPins[i])) - continue; - - SerialUSB.print("Reading pin "); - SerialUSB.print(boardADCPins[i], DEC); - SerialUSB.println("..."); - pinMode(boardADCPins[i], INPUT_ANALOG); - while (!SerialUSB.available()) { - int sample = analogRead(boardADCPins[i]); - SerialUSB.print(boardADCPins[i], DEC); - SerialUSB.print("\t"); - SerialUSB.print(sample, DEC); - SerialUSB.print("\t"); - SerialUSB.print("|"); - for (int j = 0; j < 4096; j += 100) { - if (sample >= j) { - SerialUSB.print("#"); - } else { - SerialUSB.print(" "); - } - } - SerialUSB.print("| "); - for (int j = 0; j < 12; j++) { - if (sample & (1 << (11 - j))) { - SerialUSB.print("1"); - } else { - SerialUSB.print("0"); - } - } - SerialUSB.println(); - } - pinMode(boardADCPins[i], OUTPUT); - digitalWrite(boardADCPins[i], 0); - if (SerialUSB.read() == ESC) - break; - } -} - -bool test_single_pin_is_high(int high_pin, const char* err_msg) { - bool ok = true; - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) continue; - - if (digitalRead(i) == HIGH && i != high_pin) { - SerialUSB.println(); - SerialUSB.print("\t*** FAILURE! pin "); - SerialUSB.print(i, DEC); - SerialUSB.print(' '); - SerialUSB.println(err_msg); - ok = false; - } - } - return ok; -} - -bool wait_for_low_transition(uint8 pin) { - uint32 start = millis(); - while (millis() - start < 2000) { - if (digitalRead(pin) == LOW) { - return true; - } - } - return false; -} - -void cmd_gpio_qa(void) { - bool all_pins_ok = true; - const int not_a_pin = -1; - SerialUSB.println("Doing QA testing for unused GPIO pins."); - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) continue; - - pinMode(i, INPUT); - } - - SerialUSB.println("Waiting to start."); - ASSERT(!boardUsesPin(0)); - while (digitalRead(0) == LOW) continue; - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) { - SerialUSB.print("Skipping pin "); - SerialUSB.println(i, DEC); - continue; - } - bool pin_ok = true; - SerialUSB.print("Checking pin "); - SerialUSB.print(i, DEC); - while (digitalRead(i) == LOW) continue; - - pin_ok = pin_ok && test_single_pin_is_high(i, "is also HIGH"); - - if (!wait_for_low_transition(i)) { - SerialUSB.println("Transition to low timed out; something is " - "very wrong. Aborting test."); - return; - } - - pin_ok = pin_ok && test_single_pin_is_high(not_a_pin, "is still HIGH"); - - if (pin_ok) { - SerialUSB.println(": ok"); - } - - all_pins_ok = all_pins_ok && pin_ok; - } - - if (all_pins_ok) { - SerialUSB.println("Finished; test passes."); - } else { - SerialUSB.println("**** TEST FAILS *****"); - } - - for (int i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) continue; - - pinMode(i, OUTPUT); - digitalWrite(i, LOW); - gpio_state[i] = 0; - } -} - -void cmd_sequential_gpio_toggling(void) { - SerialUSB.println("Sequentially toggling all unused pins. " - "Press any key for next pin, ESC to stop."); - - for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - - SerialUSB.print("Toggling pin "); - SerialUSB.print((int)i, DEC); - SerialUSB.println("..."); - - pinMode(i, OUTPUT); - do { - togglePin(i); - } while (!SerialUSB.available()); - - digitalWrite(i, LOW); - if (SerialUSB.read() == ESC) - break; - } -} - -void cmd_gpio_toggling(void) { - SerialUSB.println("Toggling all unused pins simultaneously. " - "Press any key to stop."); - - for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(i, OUTPUT); - } - - while (!SerialUSB.available()) { - for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - togglePin(i); - } - } - - for (uint32 i = 0; i < BOARD_NR_GPIO_PINS; i++) { - if (boardUsesPin(i)) - continue; - digitalWrite(i, LOW); - } -} - -uint8 debugGPIOPins[] = {BOARD_JTMS_SWDIO_PIN, - BOARD_JTCK_SWCLK_PIN, - BOARD_JTDI_PIN, - BOARD_JTDO_PIN, - BOARD_NJTRST_PIN}; - -#define N_DEBUG_PINS 5 - -void cmd_sequential_debug_gpio_toggling(void) { - SerialUSB.println("Toggling all debug (JTAG/SWD) pins sequentially. " - "This will permanently disable debug port " - "functionality."); - disableDebugPorts(); - - for (int i = 0; i < N_DEBUG_PINS; i++) { - pinMode(debugGPIOPins[i], OUTPUT); - } - - for (int i = 0; i < N_DEBUG_PINS; i++) { - int pin = debugGPIOPins[i]; - SerialUSB.print("Toggling pin "); - SerialUSB.print(pin, DEC); - SerialUSB.println("..."); - - pinMode(pin, OUTPUT); - do { - togglePin(pin); - } while (!SerialUSB.available()); - - digitalWrite(pin, LOW); - if (SerialUSB.read() == ESC) - break; - } - - for (int i = 0; i < N_DEBUG_PINS; i++) { - digitalWrite(debugGPIOPins[i], 0); - } -} - -void cmd_debug_gpio_toggling(void) { - SerialUSB.println("Toggling debug GPIO simultaneously. " - "This will permanently disable JTAG and Serial Wire " - "debug port functionality. " - "Press any key to stop."); - disableDebugPorts(); - - for (uint32 i = 0; i < N_DEBUG_PINS; i++) { - pinMode(debugGPIOPins[i], OUTPUT); - } - - while (!SerialUSB.available()) { - for (uint32 i = 0; i < N_DEBUG_PINS; i++) { - togglePin(debugGPIOPins[i]); - } - } - - for (uint32 i = 0; i < N_DEBUG_PINS; i++) { - digitalWrite(debugGPIOPins[i], LOW); - } -} - -void cmd_but_test(void) { - SerialUSB.println("Press the button to test. Press any key to stop."); - pinMode(BOARD_BUTTON_PIN, INPUT); - - while (!SerialUSB.available()) { - if (isButtonPressed()) { - uint32 tstamp = millis(); - SerialUSB.print("Button press detected, timestamp: "); - SerialUSB.println(tstamp); - } - } - SerialUSB.read(); -} - -void cmd_sequential_pwm_test(void) { - SerialUSB.println("Sequentially testing PWM on all unused pins. " - "Press any key for next pin, ESC to stop."); - - for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { - if (boardUsesPin(i)) - continue; - - SerialUSB.print("PWM out on header D"); - SerialUSB.print(boardPWMPins[i], DEC); - SerialUSB.println("..."); - pinMode(boardPWMPins[i], PWM); - pwmWrite(boardPWMPins[i], 16000); - - while (!SerialUSB.available()) { - delay(10); - } - - pinMode(boardPWMPins[i], OUTPUT); - digitalWrite(boardPWMPins[i], 0); - if (SerialUSB.read() == ESC) - break; - } -} - -void cmd_servo_sweep(void) { - SerialUSB.println("Testing all PWM headers with a servo sweep. " - "Press any key to stop."); - SerialUSB.println(); - - disable_usarts(); - init_all_timers(21); - - for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(boardPWMPins[i], PWM); - pwmWrite(boardPWMPins[i], 4000); - } - - // 1.25ms = 4096counts = 0deg - // 1.50ms = 4915counts = 90deg - // 1.75ms = 5734counts = 180deg - int rate = 4096; - while (!SerialUSB.available()) { - rate += 20; - if (rate > 5734) - rate = 4096; - for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { - if (boardUsesPin(i)) - continue; - pwmWrite(boardPWMPins[i], rate); - } - delay(20); - } - - for (uint32 i = 0; i < BOARD_NR_PWM_PINS; i++) { - if (boardUsesPin(i)) - continue; - pinMode(boardPWMPins[i], OUTPUT); - } - init_all_timers(1); - enable_usarts(); -} - -void cmd_board_info(void) { // TODO print more information - SerialUSB.println("Board information"); - SerialUSB.println("================="); - - SerialUSB.print("* Clock speed (MHz): "); - SerialUSB.println(CYCLES_PER_MICROSECOND); - - SerialUSB.print("* BOARD_LED_PIN: "); - SerialUSB.println(BOARD_LED_PIN); - - SerialUSB.print("* BOARD_BUTTON_PIN: "); - SerialUSB.println(BOARD_BUTTON_PIN); - - SerialUSB.print("* GPIO information (BOARD_NR_GPIO_PINS = "); - SerialUSB.print(BOARD_NR_GPIO_PINS); - SerialUSB.println("):"); - print_board_array("ADC pins", boardADCPins, BOARD_NR_ADC_PINS); - print_board_array("PWM pins", boardPWMPins, BOARD_NR_PWM_PINS); - print_board_array("Used pins", boardUsedPins, BOARD_NR_USED_PINS); -} - -// -- Helper functions -------------------------------------------------------- - -void measure_adc_noise(uint8 pin) { - const int N = 1000; - uint16 x; - float mean = 0; - float delta = 0; - float M2 = 0; - pinMode(pin, INPUT_ANALOG); - - // Variance algorithm from Welford, via Knuth, by way of Wikipedia: - // http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm - for (int sample = 0; sample < N_ADC_NOISE_MEASUREMENTS; sample++) { - for (int i = 1; i <= N; i++) { - x = analogRead(pin); - delta = x - mean; - mean += delta / i; - M2 = M2 + delta * (x - mean); - } - SerialUSB.print("header: D"); - SerialUSB.print(pin, DEC); - SerialUSB.print("\tn: "); - SerialUSB.print(N, DEC); - SerialUSB.print("\tmean: "); - SerialUSB.print(mean); - SerialUSB.print("\tvariance: "); - SerialUSB.println(M2 / (float)(N-1)); - } - - pinMode(pin, OUTPUT); -} - -void fast_gpio(int maple_pin) { - gpio_dev *dev = PIN_MAP[maple_pin].gpio_device; - uint32 bit = PIN_MAP[maple_pin].gpio_bit; - - gpio_write_bit(dev, bit, 1); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); - gpio_toggle_bit(dev, bit); -} - -void serial_baud_test(HardwareSerial **serials, int n, unsigned baud) { - for (int i = 0; i < n; i++) { - serials[i]->begin(baud); - } - while (!SerialUSB.available()) { - for (int i = 0; i < n; i++) { - serials[i]->println(dummy_data); - if (serials[i]->available()) { - serials[i]->println(serials[i]->read()); - delay(1000); - } - } - } -} - -void serial_echo_test(HardwareSerial *serial, unsigned baud) { - serial->begin(baud); - while (!SerialUSB.available()) { - if (!serial->available()) - continue; - serial->print(serial->read()); - } -} - -static uint16 init_all_timers_prescale = 0; - -static void set_prescale(timer_dev *dev) { - timer_set_prescaler(dev, init_all_timers_prescale); -} - -void init_all_timers(uint16 prescale) { - init_all_timers_prescale = prescale; - timer_foreach(set_prescale); -} - -void enable_usarts(void) { - Serial1.begin(BAUD); - Serial2.begin(BAUD); - Serial3.begin(BAUD); -#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) - Serial4.begin(BAUD); - Serial5.begin(BAUD); -#endif -} - -void disable_usarts(void) { - Serial1.end(); - Serial2.end(); - Serial3.end(); -#if defined(STM32_HIGH_DENSITY) && !defined(BOARD_maple_RET6) - Serial4.end(); - Serial5.end(); -#endif -} - -void print_board_array(const char* msg, const uint8 arr[], int len) { - SerialUSB.print("\t"); - SerialUSB.print(msg); - SerialUSB.print(" ("); - SerialUSB.print(len); - SerialUSB.print("): "); - for (int i = 0; i < len; i++) { - SerialUSB.print(arr[i], DEC); - if (i < len - 1) SerialUSB.print(", "); - } - SerialUSB.println(); -} - -// -- premain() and main() ---------------------------------------------------- - -// 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 (1) { - loop(); - } - return 0; -} diff --git a/examples/test-spi-roundtrip.cpp b/examples/test-spi-roundtrip.cpp deleted file mode 100644 index ddc9875..0000000 --- a/examples/test-spi-roundtrip.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * 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 SerialUSB. 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 - */ - -#include - -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) { - SerialUSB.println(); - SerialUSB.print("ERROR: FAILED ASSERT("); - SerialUSB.print(exp); - SerialUSB.print("): "); - SerialUSB.print(file); - SerialUSB.print(": "); - SerialUSB.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); - SerialUSB.read(); -} - -void loop() { - SerialUSB.println("** Having a conversation, MSB first"); - haveConversation(MSBFIRST); - - SerialUSB.println("** Having a conversation, LSB first"); - haveConversation(LSBFIRST); - - SerialUSB.println(); - SerialUSB.println("*** All done! It looks like everything worked."); - SerialUSB.println(); - - SerialUSB.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) { - SerialUSB.print("Having a chat.\tFrequency: "); - printFrequencyString(frequency); - SerialUSB.print(",\tbitOrder: "); - SerialUSB.print(bitOrder == MSBFIRST ? "MSB" : "LSB"); - SerialUSB.print(",\tmode: "); - SerialUSB.print(mode); - SerialUSB.print("."); - - SerialUSB.print(" [1] "); - alice.begin(frequency, bitOrder, mode); - - SerialUSB.print(" [2] "); - uint32 txed = 0; - while (txed < TEST_BUF_SIZE) { - ASSERT(alice.transfer(test_buf[txed]) == test_buf[txed]); - txed++; - } - - SerialUSB.print(" [3] "); - alice.end(); - - SerialUSB.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; - SerialUSB.print("Alice is giving a soliloquy (repeating 0x"); - SerialUSB.print(repeat, HEX); - SerialUSB.print("). Frequency: "); - printFrequencyString(frequency); - SerialUSB.print(", bitOrder: "); - SerialUSB.print(bitOrder == MSBFIRST ? "big-endian" : "little-endian"); - SerialUSB.print(", SPI mode: "); - SerialUSB.println(mode); - - alice.begin(frequency, bitOrder, mode); - while (!SerialUSB.available()) { - alice.write(repeat); - delayMicroseconds(200); - } - SerialUSB.read(); -} - -void printFrequencyString(SPIFrequency frequency) { - switch (frequency) { - case SPI_18MHZ: - SerialUSB.print("18 MHz"); - break; - case SPI_9MHZ: - SerialUSB.print("9 MHz"); - break; - case SPI_4_5MHZ: - SerialUSB.print("4.5 MHz"); - break; - case SPI_2_25MHZ: - SerialUSB.print("2.25 MHZ"); - break; - case SPI_1_125MHZ: - SerialUSB.print("1.125 MHz"); - break; - case SPI_562_500KHZ: - SerialUSB.print("562.500 KHz"); - break; - case SPI_281_250KHZ: - SerialUSB.print("281.250 KHz"); - break; - case SPI_140_625KHZ: - SerialUSB.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; -} diff --git a/examples/test-systick.cpp b/examples/test-systick.cpp deleted file mode 100644 index 356f302..0000000 --- a/examples/test-systick.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Tests the SysTick enable/disable functions - -#include -#include - -void setup() { - pinMode(BOARD_LED_PIN, OUTPUT); - pinMode(BOARD_BUTTON_PIN, INPUT); -} - -bool disable = true; -long time = 0; - -void loop() { - volatile int i = 0; - toggleLED(); - - // An artificial delay - for(i = 0; i < 150000; i++) - ; - - if (isButtonPressed()) { - if (disable) { - systick_disable(); - SerialUSB.println("Disabling SysTick"); - } else { - SerialUSB.println("Re-enabling SysTick"); - systick_enable(); - } - disable = !disable; - } - - SerialUSB.println(millis()); -} - -// Force init to be called *first*, i.e. before static object allocation. -// Otherwise, statically allocated object that need libmaple may fail. -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} diff --git a/examples/test-timers.cpp b/examples/test-timers.cpp deleted file mode 100644 index e646916..0000000 --- a/examples/test-timers.cpp +++ /dev/null @@ -1,537 +0,0 @@ -// -// This is a mostly Wirish-free timer test. Wirish usage is minimized -// because this is a test of the C timer interface in -// , so it's good if it can be made to work even -// when most or all of Wirish is missing. Because of that, you may -// need to customize the following output configuration: -// -// Output is printed: -// - on COMM_USART, -// - via TX pin on port COMM_USART_PORT, bit COMM_USART_TX_BIT -// - via RX pin on port COMM_USART_PORT, bit COMM_USART_RX_BIT -// - at COMM_USART_BAUD baud. -#define COMM_USART USART6 -#define COMM_USART_BAUD 115200 -#define COMM_USART_PORT GPIOG -#define COMM_USART_TX_BIT 14 -#define COMM_USART_RX_BIT 9 -// Other optional configuration below. - -#include -#include -#include -#include -#include -#include - -// -// Configuration -// - -// More output if true -static bool verbose = true; - -// Timers to test -// FIXME use feature test macros for smaller MCUs -static timer_dev *timers[] = { - // Available on all currently supported MCUs - TIMER1, TIMER2, TIMER3, TIMER4, - // Available on F1 (HD and up), F2 - TIMER5, TIMER6, TIMER7, TIMER8, - // Available on F1 (XL), F2 - TIMER9, TIMER10, TIMER11, TIMER12, TIMER13, TIMER14, -}; - -// -// Test routines -// - -typedef void (*timer_test_t)(timer_dev *); - -static void runTest(const char description[], timer_test_t test); -static void runTests(void); - -static void testGetAndSetCount(timer_dev*); -static void testPauseAndResume(timer_dev*); -static void testTimerChannels(timer_dev*); - -// -// Helpers -// - -static void initTimer(timer_dev *dev); -static int timerNumber(timer_dev *dev); -// Hack: a systick-based delay, useful until delay_us() is fixed -static void _delay(uint32 msec); -// Wirish-less USART initialization routine -static void init_usart(usart_dev *dev, gpio_dev *gdev, uint8 tx, uint8 rx); -// Return whether or not the timer has capture/compare channel `ch'. -// TODO: does something like this belong in the standard timer library? -static bool timer_has_cc_ch(timer_dev *dev, int ch); - -// Printing routines and variants for verbose mode -static void putstr(const char str[]); -static void println(void); -static void putstrln(const char str[]); -static void putudec(uint32 val); -static void puttimn(timer_dev *dev); -static void v_putstr(const char str[]); -static void v_println(); -static void v_putstrln(const char str[]); -static void v_putudec(uint32 val); -static void v_puttimn(timer_dev *dev); -// Used to visually separate output from different tests -static void printBanner(void); - -// -// Handler state -// - -static int count1 = 0; -static int count2 = 0; -static int count3 = 0; -static int count4 = 0; -static int timer_num; // Current timer we're considering - -// -// Timer capture/compare interrupt handlers -// -// These are shared between timers. The global variable timer_num -// controls which timer they affect. -// - -static void handler1(void); -static void handler2(void); -static void handler3(void); -static void handler4(void); -static voidFuncPtr handlers[] = {handler1, handler2, handler3, handler4}; - -// -// setup() and loop() -// - -void setup() { - init_usart(COMM_USART, COMM_USART_PORT, - COMM_USART_TX_BIT, COMM_USART_RX_BIT); - _delay(5); - println(); - printBanner(); - putstr("Initializing timers...\r\n"); - timer_foreach(initTimer); - putstr("Done. Running tests.\r\n"); - runTests(); - printBanner(); - putstr("Done testing timers.\r\n"); -} - -void loop() { -} - -// -// Test routine implementations -// - -static void runTests(void) { - runTest("timer_get_count()/timer_set_count()", testGetAndSetCount); - runTest("timer_pause()/timer_resume()", testPauseAndResume); - runTest("capture/compare channels and interrupts", - testTimerChannels); -} - -static void runTest(const char description[], timer_test_t test) { - printBanner(); - putstr("Testing "); - putstr(description); - putstrln("."); - timer_foreach(test); -} - -static void testGetAndSetCount(timer_dev *dev) { - unsigned before, after; - unsigned val_to_set = 1234; - - timer_pause(dev); - before = timer_get_count(dev); - timer_set_count(dev, val_to_set); - after = timer_get_count(dev); - timer_resume(dev); - - if (after != val_to_set) { - puttimn(dev); - putstr(": "); - putstr("*** FAIL: get/set count for "); - puttimn(dev); - putstr("."); - putstr("Start count = "); - putudec(before); - putstr(". Count set to "); - putudec(val_to_set); - putstr(", and now count is = "); - putudec(after); - println(); - } else if (verbose) { - puttimn(dev); - putstr(": "); - putstrln("[ok]"); - } -} - -// This hack works on all currently supported STM32 series, but you -// may need to do something smarter in the future. The assertions -// ensure that our assumptions hold for your target. -static timer_dev *getDifferentTimerOnSameBusAs(timer_dev *dev) { - rcc_clk_domain dev_domain = rcc_dev_clk(dev->clk_id); - ASSERT(RCC_APB1 == dev_domain || RCC_APB2 == dev_domain); - ASSERT(rcc_dev_clk(TIMER1->clk_id) == RCC_APB2); - ASSERT(rcc_dev_clk(TIMER2->clk_id) == RCC_APB1); - ASSERT(rcc_dev_clk(TIMER8->clk_id) == RCC_APB2); - ASSERT(rcc_dev_clk(TIMER3->clk_id) == RCC_APB1); - - if (dev->clk_id == RCC_TIMER1) { - return TIMER8; - } - if (dev->clk_id == RCC_TIMER2) { - return TIMER3; - } - return dev_domain == RCC_APB2 ? TIMER1 : TIMER2; -} - -// Rough test of pause and resume. -// -// Approximately half the time, dev is in the "pause" state and the -// timer doesn't increment, while another timer (`base_dev') on the -// same bus continues. dev and base_dev have identical start counts -// and prescalers. -// -// Since dev and base_dev share a bus (and thus a base clock), and we -// configure them to have the same prescaler and start count, the -// ratio of their end counts should be approximately 1 : 2. We check -// to make sure this is true, up to tolerance `epsilon'. -static void testPauseAndResume(timer_dev *dev) { - timer_dev *base_dev = getDifferentTimerOnSameBusAs(dev); - unsigned start_count = 0, reload = 65535; - // This prescaler should be enough to ensure that we don't - // overflow, while still giving us a reasonably large number of - // timer ticks. - uint16 prescaler = CYCLES_PER_MICROSECOND * 50; - double epsilon = .02; - - if (rcc_dev_clk(base_dev->clk_id) != rcc_dev_clk(dev->clk_id)) { - putstrln("*** ERROR: cannot run test. Bus info is messed up."); - return; - } - - // Pause and set up timers - timer_pause(base_dev); - timer_pause(dev); - timer_set_count(base_dev, start_count); - timer_set_count(dev, start_count); - timer_set_reload(base_dev, reload); - timer_set_reload(dev, reload); - timer_set_prescaler(base_dev, prescaler); - timer_set_prescaler(dev, prescaler); - timer_generate_update(base_dev); - timer_generate_update(dev); - - // Resume the timers and run the test - ASSERT(timer_get_count(base_dev) == start_count); - ASSERT(timer_get_count(dev) == start_count); - timer_resume(base_dev); - timer_resume(dev); - _delay(1000); - timer_pause(dev); - _delay(1000); - timer_pause(base_dev); - - // Check the results - unsigned dev_count = timer_get_count(dev); - unsigned base_count = timer_get_count(base_dev); - double count_ratio = ((double)dev_count / base_count); - bool fail = false; - if (count_ratio > 0.5 + epsilon || count_ratio < 0.5 - epsilon) { - fail = true; - } - if (fail || verbose) { - puttimn(dev); - putstr(" vs. "); - puttimn(base_dev); - putstr(": "); - if (fail) putstr("*** FAIL: "); - else putstr("[ok] "); - putstr("(dev = "); - putudec(dev_count); - putstr(") / (base = "); - putudec(base_count); - putstr(") = "); - // hack hack hack - putudec((int)count_ratio); - count_ratio -= (int)count_ratio; - putstr("."); - int cr_x_100 = (int)(count_ratio * 100); - int hundredths = cr_x_100 % 10; - cr_x_100 /= 10; - int tenths = cr_x_100 % 10; - putudec(tenths); - putudec(hundredths); - println(); - } -} - -// This function touches every capture/compare channel of a given -// timer. The channel counts should be equal within a timer -// regardless of other interrupts on the system (note that this -// doesn't really test timers with only a single capture/compare -// channel; for that, you'll want to do visual inspection of timers -// that share a bus, in verbose mode). -static void testTimerChannels(timer_dev *dev) { - switch (dev->type) { - case TIMER_BASIC: - v_putstr("Skipping basic timer "); - v_puttimn(dev); - v_println(); - return; - case TIMER_ADVANCED: - case TIMER_GENERAL: - // Set up - v_puttimn(dev); - v_println(); - v_putstr("\tchannels: "); - - timer_num = timerNumber(dev); - timer_pause(dev); - count1 = 0; - count2 = 0; - count3 = 0; - count4 = 0; - timer_set_reload(dev, 0xFFFF); - timer_set_prescaler(dev, 1); - for (int c = 1; c <= 4; c++) { - if (timer_has_cc_ch(dev, c)) { - v_putudec(c); - v_putstr("\t"); - timer_set_compare(dev, c, 0xFFFF); - timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE); - timer_attach_interrupt(dev, c, handlers[c - 1]); - } - } - v_println(); - - // Run test - timer_generate_update(dev); - timer_resume(dev); - _delay(250); - timer_pause(dev); - - // Print results - v_putstr("\tcounts: "); - bool fail = false; - bool mismatched[4] = {false, false, false, false}; - int counts[4]; - counts[0] = count1; - counts[1] = count2; - counts[2] = count3; - counts[3] = count4; - bool first = true; - int first_count = -1; - for (int c = 1; c <= 4; c++) { - if (timer_has_cc_ch(dev, c)) { - if (first) { - first_count = counts[c - 1]; - first = false; - } - if (!first && (counts[c - 1] != first_count)) { - mismatched[c - 1] = true; - fail = true; - } - v_putudec(counts[c - 1]); - v_putstr("\t"); - } - } - v_println(); - if (fail) { - for (int i = 0; i < 4; i++) { - if (mismatched[i]) { - putstr("*** FAIL: mismatch on "); - puttimn(dev); - putstr(", channel "); - putudec(i + 1); - putstr(": expected "); - putudec(first_count); - putstr(", got "); - putudec(counts[i]); - println(); - } - } - } else { - puttimn(dev); - putstrln(" [ok]"); - } - v_println(); - - // Clean up - for (int c = 1; c <= 4; c++) { - if (timer_has_cc_ch(dev, c)) { - timer_set_mode(dev, c, TIMER_DISABLED); - } - } - break; - } -} - -// -// Helper implementations -// - -static void _delay(uint32 msec) { - uint32 end = systick_uptime() + msec; - while (systick_uptime() < end) - ; -} - -static void init_usart(usart_dev *dev, gpio_dev *gdev, uint8 tx, uint8 rx) { - usart_config_gpios_async(dev, gdev, rx, gdev, tx, 0); - usart_init(dev); - usart_set_baud_rate(dev, USART_USE_PCLK, COMM_USART_BAUD); - usart_enable(dev); -} - -static bool timer_has_cc_ch(timer_dev *dev, int ch) { - ASSERT(1 <= ch && ch <= 4); - if (dev->type == TIMER_BASIC) - return false; - int tn = timerNumber(dev); - return (// TIM1-5 and 8 have all four channels - (tn <= 5 || tn == 8) || - // TIM9 and 12 only have channels 1 and 2 - ((tn == 9 || tn == 12) && ch <= 2) || - // All other general purpose timers only have channel 1 - (ch == 1)); -} - -static void putstr(const char str[]) { - usart_putstr(COMM_USART, str); -} - -static void println(void) { - putstr("\r\n"); -} - -static void putstrln(const char str[]) { - putstr(str); - println(); -} - -static void putudec(uint32 val) { - usart_putudec(COMM_USART, val); -} - -static void puttimn(timer_dev *dev) { - putstr("TIM"); - putudec(timerNumber(dev)); -} - -static void v_putstr(const char str[]) { - if (verbose) putstr(str); -} - -static void v_println() { - if (verbose) println(); -} - -__attribute__((unused)) /* (shut up, gcc) */ -static void v_putstrln(const char str[]) { - if (verbose) putstrln(str); -} - -static void v_putudec(uint32 val) { - if (verbose) putudec(val); -} - -static void v_puttimn(timer_dev *dev) { - if (verbose) puttimn(dev); -} - -// Used to visually separate output from different tests -static void printBanner(void) { - putstrln("-----------------------------------------------------"); -} - -static void initTimer(timer_dev *dev) { - v_puttimn(dev); - timer_init(dev); - switch (dev->type) { - case TIMER_ADVANCED: - case TIMER_GENERAL: - v_putstr(" channels "); - for (int c = 1; c <= 4; c++) { - if (timer_has_cc_ch(dev, c)) { - v_putudec(c); - v_putstr(" "); - timer_set_mode(dev, c, TIMER_OUTPUT_COMPARE); - } - } - break; - case TIMER_BASIC: - break; - } - v_println(); -} - -static int timerNumber(timer_dev *dev) { - switch (dev->clk_id) { - case RCC_TIMER1: return 1; - case RCC_TIMER2: return 2; - case RCC_TIMER3: return 3; - case RCC_TIMER4: return 4; - case RCC_TIMER5: return 5; - case RCC_TIMER6: return 6; - case RCC_TIMER7: return 7; - case RCC_TIMER8: return 8; - case RCC_TIMER9: return 9; - case RCC_TIMER10: return 10; - case RCC_TIMER11: return 11; - case RCC_TIMER12: return 12; - case RCC_TIMER13: return 13; - case RCC_TIMER14: return 14; - default: - ASSERT(0); - return 0; - } -} - -// -// IRQ Handlers -// - -static void handler1(void) { - count1++; -} - -static void handler2(void) { - count2++; -} - -static void handler3(void) { - count3++; -} - -static void handler4(void) { - count4++; -} - -// -// init() and main() -// - -__attribute__((constructor)) void premain() { - init(); -} - -int main(void) { - setup(); - - while (true) { - loop(); - } - return 0; -} diff --git a/examples/test-usart-dma.cpp b/examples/test-usart-dma.cpp deleted file mode 100644 index d10dc68..0000000 --- a/examples/test-usart-dma.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/** - * @file examples/test-usart-dma.cpp - * @author Marti Bolivar - * - * Simple test of DMA used with a USART receiver. - * - * Configures a USART receiver for use with DMA. Received bytes are - * placed into a buffer, with an interrupt firing when the buffer is - * full. At that point, the USART transmitter will print the contents - * of the byte buffer. The buffer is continually filled and refilled - * in this manner. - * - * This example isn't very robust; don't use it in production. In - * particular, since the buffer keeps filling (DMA_CIRC_MODE is set), - * if you keep sending characters after filling the buffer, you'll - * overwrite earlier bytes; this may happen before those earlier bytes - * are done printing. (Typing quickly and seeing how it affects the - * output is a fun way to make sense of how the interrupts and the - * main thread of execution interleave.) - * - * This code is released into the public domain. - */ - -#include -#include -#include - -#include - -/* - * Configuration and state - */ - -// Serial port and DMA configuration. You can change these to suit -// your purposes. -HardwareSerial *serial = &Serial2; -#define USART_DMA_DEV DMA1 -#if STM32_MCU_SERIES == STM32_SERIES_F1 -// On STM32F1 microcontrollers (like what's on Maple and Maple Mini), -// dma tubes are channels. -#define USART_RX_DMA_TUBE DMA_CH6 -#elif (STM32_MCU_SERIES == STM32_SERIES_F2 || \ - STM32_MCU_SERIES == STM32_SERIES_F4) -// On STM32F2 and STM32F4 microcontrollers (Maple 2 will have an F4), -// dma tubes are streams. -#define USART_RX_DMA_TUBE DMA_S5 -#else -#error "unsupported stm32 series" -#endif -// The serial port will make a DMA request each time it receives data. -// This is the dma_request_src we use to tell the DMA tube to handle -// that DMA request. -#define USART_DMA_REQ_SRC DMA_REQ_SRC_USART2_RX -#define BAUD 9600 - -// This will store the DMA configuration for USART RX. -dma_tube_config tube_config; - -// This will store received USART characters. -#define BUF_SIZE 20 -char rx_buf[BUF_SIZE]; - -// The interrupt handler, rx_dma_irq(), sets this to 1. -volatile uint32 irq_fired = 0; -// Used to store DMA interrupt status register (ISR) bits inside -// rx_dma_irq(). This helps explain what's going on inside loop(); see -// comments below. -volatile uint32 isr = 0; - -/* - * Helper functions - */ - -// This is our DMA interrupt handler. -void rx_dma_irq(void) { - irq_fired = 1; - isr = dma_get_isr_bits(USART_DMA_DEV, USART_RX_DMA_TUBE); -} - -// Configure the USART receiver for use with DMA: -// 1. Turn it on. -// 2. Set the "DMA request on RX" bit in USART_CR3 (USART_CR3_DMAR). -void setup_usart(void) { - serial->begin(BAUD); - usart_dev *serial_dev = serial->c_dev(); - serial_dev->regs->CR3 = USART_CR3_DMAR; -} - -// Set up our dma_tube_config structure. (We could have done this -// above, when we declared tube_config, but having this function makes -// it easier to explain what's going on). -void setup_tube_config(void) { - // We're receiving from the USART data register. serial->c_dev() - // returns a pointer to the libmaple usart_dev for that serial - // port, so this is a pointer to its data register. - tube_config.tube_src = &serial->c_dev()->regs->DR; - // We're only interested in the bottom 8 bits of that data register. - tube_config.tube_src_size = DMA_SIZE_8BITS; - // We're storing to rx_buf. - tube_config.tube_dst = rx_buf; - // rx_buf is a char array, and a "char" takes up 8 bits on STM32. - tube_config.tube_dst_size = DMA_SIZE_8BITS; - // Only fill BUF_SIZE - 1 characters, to leave a null byte at the end. - tube_config.tube_nr_xfers = BUF_SIZE - 1; - // Flags: - // - DMA_CFG_DST_INC so we start at the beginning of rx_buf and - // fill towards the end. - // - DMA_CFG_CIRC so we go back to the beginning and start over when - // rx_buf fills up. - // - DMA_CFG_CMPLT_IE to turn on interrupts on transfer completion. - tube_config.tube_flags = DMA_CFG_DST_INC | DMA_CFG_CIRC | DMA_CFG_CMPLT_IE; - // Target data: none. It's important to set this to NULL if you - // don't have any special (microcontroller-specific) configuration - // in mind, which we don't. - tube_config.target_data = NULL; - // DMA request source. - tube_config.tube_req_src = USART_DMA_REQ_SRC; -} - -// Configure the DMA controller to serve DMA requests from the USART. -void setup_dma_xfer(void) { - // First, turn it on. - dma_init(USART_DMA_DEV); - // Next, configure it by calling dma_tube_cfg(), and check to make - // sure it succeeded. DMA tubes have many restrictions on their - // configuration, and there are configurations which work on some - // types of STM32 but not others. libmaple tries hard to make - // things just work, but checking the return status is important! - int status = dma_tube_cfg(USART_DMA_DEV, USART_RX_DMA_TUBE, &tube_config); - ASSERT(status == DMA_TUBE_CFG_SUCCESS); - // Now we'll perform any other configuration we want. For this - // example, we attach an interrupt handler. - dma_attach_interrupt(USART_DMA_DEV, USART_RX_DMA_TUBE, rx_dma_irq); - // Turn on the DMA tube. It will now begin serving requests. - dma_enable(USART_DMA_DEV, USART_RX_DMA_TUBE); -} - -/* - * setup() and loop() - */ - -void setup(void) { - pinMode(BOARD_LED_PIN, OUTPUT); - setup_tube_config(); - setup_dma_xfer(); - setup_usart(); -} - -void loop(void) { - toggleLED(); - delay(100); - - // See if the interrupt handler got called since the last time we - // checked. - if (irq_fired) { - serial->println("** IRQ **"); - // Notice how the interrupt status register (ISR) bits show - // transfer complete _and_ half-complete here, but the ISR - // bits we print next will be zero. That's because the - // variable "isr" gets set _inside_ rx_dma_irq(). After it - // exits, libmaple cleans up by clearing the tube's ISR - // bits. (If it didn't, and we forgot to, the interrupt would - // repeatedly fire forever.) - serial->print("ISR bits: 0x"); - serial->println(isr, HEX); - irq_fired = 0; - } - - // Print the ISR bits. - // - // Notice that the "transfer half-complete" ISR flag gets set when - // we reach the rx_buf half-way point. This is true even though we - // don't tell the DMA controller to interrupt us on a - // half-complete transfer. That is, the ISR bits get set at the - // right times no matter what; we just don't get interrupted - // unless we asked. (If an error or other problem occurs, the - // relevant ISR bits will get set in the same way). - serial->print("["); - serial->print(millis()); - serial->print("]\tISR bits: 0x"); - uint8 isr_bits = dma_get_isr_bits(USART_DMA_DEV, USART_RX_DMA_TUBE); - serial->print(isr_bits, HEX); - - // Print the contents of rx_buf. If you keep typing after it fills - // up, the new characters will overwrite the old ones, thanks to - // DMA_CIRC_MODE. - serial->print("\tCharacter buffer contents: '"); - serial->print(rx_buf); - serial->println("'"); - if (isr_bits == 0x7) { - serial->println("** Clearing ISR bits."); - dma_clear_isr_bits(USART_DMA_DEV, USART_RX_DMA_TUBE); - } -} - -// ------- init() and main() -------------------------------------------------- - -// 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; -} -- cgit v1.2.3