diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/blinky.cpp | 6 | ||||
-rw-r--r-- | examples/debug-dtrrts.cpp | 23 | ||||
-rw-r--r-- | examples/qa-slave-shield.cpp | 64 | ||||
-rw-r--r-- | examples/spi_master.cpp | 7 | ||||
-rw-r--r-- | examples/test-dac.cpp | 4 | ||||
-rw-r--r-- | examples/test-fsmc.cpp | 202 | ||||
-rw-r--r-- | examples/test-ring-buffer-insertion.cpp | 114 | ||||
-rw-r--r-- | examples/test-serial-flush.cpp | 18 | ||||
-rw-r--r-- | examples/test-serialusb.cpp | 74 | ||||
-rw-r--r-- | examples/test-session.cpp | 149 | ||||
-rw-r--r-- | examples/test-systick.cpp | 50 | ||||
-rw-r--r-- | examples/test-timers.cpp | 68 | ||||
-rw-r--r-- | examples/vga-leaf.cpp | 162 | ||||
-rw-r--r-- | examples/vga-scope.cpp | 212 |
14 files changed, 459 insertions, 694 deletions
diff --git a/examples/blinky.cpp b/examples/blinky.cpp index 209a6e6..5611987 100644 --- a/examples/blinky.cpp +++ b/examples/blinky.cpp @@ -1,4 +1,4 @@ -// Blinks the built-in LED
+// Blinks the LED, pin 13
#include "wirish.h"
@@ -20,8 +20,8 @@ void loop() { }
// 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() {
+// Otherwise, statically allocated object that need libmaple may fail.
+ __attribute__(( constructor )) void premain() {
init();
}
diff --git a/examples/debug-dtrrts.cpp b/examples/debug-dtrrts.cpp index 61c061a..f9f8b96 100644 --- a/examples/debug-dtrrts.cpp +++ b/examples/debug-dtrrts.cpp @@ -1,12 +1,14 @@ -// Test sketch for figuring out DTR/RTS behavior on different platforms. +// Sample main.cpp file. Blinks an LED, sends a message out USART2 +// and turns on PWM on pin 2 #include "wirish.h" #include "usb.h" -#define LED_PIN BOARD_LED_PIN -#define PWM_PIN 2 +#define LED_PIN 13 +#define PWM_PIN 2 -void setup() { +void setup() +{ /* Set up the LED to blink */ pinMode(LED_PIN, OUTPUT); @@ -16,10 +18,12 @@ void setup() { } +int toggle = 0; + void loop() { - toggleLED(); + toggle ^= 1; + digitalWrite(LED_PIN, toggle); delay(100); - Serial2.print("DTR: "); Serial2.print(usbGetDTR(), DEC); Serial2.print("\tRTS: "); @@ -27,12 +31,13 @@ void loop() { } // 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() { +// Otherwise, statically allocated object that need libmaple may fail. + __attribute__(( constructor )) void premain() { init(); } -int main(void) { +int main(void) +{ setup(); while (1) { diff --git a/examples/qa-slave-shield.cpp b/examples/qa-slave-shield.cpp index fc33a4a..b395cca 100644 --- a/examples/qa-slave-shield.cpp +++ b/examples/qa-slave-shield.cpp @@ -1,70 +1,50 @@ -// Slave mode for QA shield +// slave mode for QA shield #include "wirish.h" -#define LED_PIN BOARD_LED_PIN +#define LED_PIN 13 +#define NUM_GPIO 38 // not the number of the max... -#if defined(BOARD_maple) || defined(BOARD_maple_RET6) -const uint8 pins_to_skip[] = {LED_PIN}; +int i; -#elif defined(BOARD_maple_mini) -#define USB_DP 23 -#define USB_DM 24 -const uint8 pins_to_skip[] = {LED_PIN, USB_DP, USB_DM}; - -#elif defined(BOARD_maple_native) -const uint8 pins_to_skip[] = {LED_PIN}; - -#else -#error "Board type has not been selected correctly." -#endif - -bool skip_pin_p(uint8 pin); - -void setup() { +void setup() +{ /* Set up the LED to blink */ pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, 1); - for(int i = 0; i < NR_GPIO_PINS; i++) { - if (skip_pin_p(i)) { - continue; - } + for(i=0; i<NUM_GPIO; i++) { + if(i==13) { continue; } pinMode(i, OUTPUT); - digitalWrite(i, LOW); + digitalWrite(i,0); } + //delay(5000); SerialUSB.println("OK, starting..."); + } void loop() { - toggleLED(); + digitalWrite(LED_PIN,1); delay(100); + digitalWrite(LED_PIN,0); - for(int i = 0; i < NR_GPIO_PINS; i++) { - if (skip_pin_p(i)) { - continue; - } - togglePin(i); + for(i=0; i<NUM_GPIO; i++) { + if(i==13) { continue; } + digitalWrite(i,1); delay(5); - togglePin(i); + digitalWrite(i,0); delay(5); } } -bool skip_pin_p(uint8 pin) { - for (uint8 i = 0; i < sizeof(pins_to_skip); i++) { - if (pin == pins_to_skip[i]) - return true; - } - return false; -} - // 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() { +// Otherwise, statically allocated object that need libmaple may fail. + __attribute__(( constructor )) void premain() { init(); } -int main(void) { +int main(void) +{ setup(); while (1) { diff --git a/examples/spi_master.cpp b/examples/spi_master.cpp index 06cad02..9f6d81b 100644 --- a/examples/spi_master.cpp +++ b/examples/spi_master.cpp @@ -60,12 +60,13 @@ void loop() { }
// 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() {
+// Otherwise, statically allocated object that need libmaple may fail.
+ __attribute__(( constructor )) void premain() {
init();
}
-int main(void) {
+int main(void)
+{
setup();
while (1) {
diff --git a/examples/test-dac.cpp b/examples/test-dac.cpp index 6f08b05..3a699e2 100644 --- a/examples/test-dac.cpp +++ b/examples/test-dac.cpp @@ -1,4 +1,8 @@ +
#include "wirish.h"
+#include "fsmc.h"
+#include "rcc.h"
+#include "gpio.h"
#include "dac.h"
uint16 count = 0;
diff --git a/examples/test-fsmc.cpp b/examples/test-fsmc.cpp index d1c8567..f4fd068 100644 --- a/examples/test-fsmc.cpp +++ b/examples/test-fsmc.cpp @@ -1,111 +1,119 @@ -#include <stdio.h>
-#include <stddef.h>
#include "wirish.h"
#include "fsmc.h"
-#define LED BOARD_LED_PIN
-
-// Start of FSMC SRAM bank 1
-static uint16 *const ptr_start = (uint16*)0x60000000;
-// End of Maple Native SRAM chip address space (512K 16-bit words)
-static uint16 *const ptr_end = (uint16*)0x60080000;
-// For snprintf
-static char buf[100];
+#define LED_PIN 23 // hack for maple native
+#define DISC_PIN 14 // hack for USB on native
+
+// System control block registers
+#define SCB_BASE (SCB_Reg*)(0xE000ED00)
+
+// This stuff should ultimately get moved to util.h or scb.h or w/e.
+// Also in interactive test program and the HardFault IRQ handler.
+typedef struct {
+ volatile uint32 CPUID;
+ volatile uint32 ICSR;
+ volatile uint32 VTOR;
+ volatile uint32 AIRCR;
+ volatile uint32 SCR;
+ volatile uint32 CCR;
+ volatile uint32 SHPR1;
+ volatile uint32 SHPR2;
+ volatile uint32 SHPR3;
+ volatile uint32 SHCRS;
+ volatile uint32 CFSR;
+ volatile uint32 HFSR;
+ uint32 pad1;
+ volatile uint32 MMAR;
+ volatile uint32 BFAR;
+} SCB_Reg;
+
+SCB_Reg *scb;
+
+uint16 *ptr;
+int toggle = 0;
+int count = 0;
void setup() {
- pinMode(LED, OUTPUT);
- digitalWrite(LED, HIGH);
-
- Serial1.begin(115200);
- Serial1.println("Hello World!");
-
- Serial1.print("Initializing RAM chip... ");
- fsmc_native_sram_init();
- Serial1.println("Done.");
+ uint32 id;
+ scb = (SCB_Reg*)SCB_BASE;
+
+ pinMode(LED_PIN, OUTPUT);
+ pinMode(DISC_PIN, OUTPUT);
+ digitalWrite(DISC_PIN,1);
+ digitalWrite(LED_PIN,1);
+
+ Serial1.begin(9600);
+ Serial1.println("Hello World!");
+
+ Serial1.print("Init... ");
+ fsmc_native_sram_init();
+ Serial1.println("Done.");
+
+ // Start of channel1 SRAM bank (through to 0x63FFFFFF, though only a chunk
+ // of this is valid)
+ ptr = (uint16*)(0x60000000);
+
+ Serial1.print("Writing... ");
+ *ptr = 0x1234;
+ Serial1.println("Done.");
+
+ Serial1.print("Reading... ");
+ id = *ptr;
+ Serial1.print("Done: "); // shouldn't be 0xFFFFFFFF
+ Serial1.println(id,BIN);
+
+ Serial1.println("Dumping System Control Block Registers");
+ Serial1.print("CPUID: ");
+ id = scb->CPUID;
+ Serial1.println(id,BIN);
+ Serial1.print("ICSR: ");
+ id = scb->ICSR;
+ Serial1.println(id,BIN);
+ Serial1.print("CFSR: ");
+ id = scb->CFSR;
+ Serial1.println(id,BIN);
+ Serial1.print("HFSR: ");
+ id = scb->HFSR;
+ Serial1.println(id,BIN);
+ Serial1.print("MMAR: ");
+ id = scb->MMAR;
+ Serial1.println(id,BIN);
+ Serial1.print("BFAR: ");
+ id = scb->BFAR;
+ Serial1.println(id,BIN);
+
+ Serial1.println("Now testing all memory addresses... (will hardfault at the end)");
+ delay(3000);
}
-void test_single_write() {
- uint16 *ptr = ptr_start;
- uint16 tmp;
-
- Serial1.print("Writing 0x1234... ");
- *ptr = 0x1234;
- Serial1.println("Done.");
-
- Serial1.print("Reading... ");
- tmp = *ptr;
- Serial1.print("Done: 0x");
- Serial1.println(tmp, HEX);
-
- if (tmp != 0x1234) {
- Serial1.println("Mismatch, abort.");
- ASSERT(0);
- }
-}
-
-void test_all_addresses() {
- uint32 start, end;
- uint16 count = 0;
- uint16 *ptr;
- Serial1.println("Now writing all memory addresses (unrolled loop)");
- SerialUSB.end();
- start = micros();
- for (ptr = ptr_start; ptr < ptr_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.begin();
- Serial1.print("Done. Elapsed time (us): ");
- Serial1.println(end - start);
-
- Serial1.println("Validating writes.");
- for (ptr = ptr_start, count = 0; ptr < ptr_end; ptr++, count++) {
- if (*ptr != count) {
- snprintf(buf, sizeof buf, "mismatch: %p = 0x%xu, should be 0x%xu.",
- ptr, *ptr, count);
- Serial1.println(buf);
- ASSERT(0);
+void loop() {
+ digitalWrite(LED_PIN, toggle);
+ toggle ^= 1;
+ delay(1);
+
+ for(int i = 0; i<100; i++) { // modify this to speed things up
+ count++;
+ ptr++;
+ //delay(10); // tweak this to test SRAM resiliance over time
+ *ptr = (0x0000FFFF & count);
+ if(*ptr != (0x0000FFFF & count)) {
+ Serial1.println("ERROR: mismatch, halting");
+ while(1) { }
}
- }
- ptrdiff_t nwrites = ptr_end - ptr_start;
- double us_per_write = double(end-start) / double(nwrites);
- Serial1.println("Done; all writes seem valid.");
- snprintf(buf, sizeof buf,
- "Number of writes = %d; avg. time per write = %g us (%g MHz)",
- nwrites, us_per_write, 1 / us_per_write);
- Serial1.println(buf);
-}
-
-__attribute__((constructor)) void premain() {
- init();
+ }
+
+ Serial1.print((uint32)(ptr),HEX);
+ Serial1.print(": ");
+ Serial1.println(*ptr,BIN);
}
int main(void) {
- setup();
-
- test_single_write();
- test_all_addresses();
-
- Serial1.println("Tests pass, finished.");
-
- while (true)
- ;
+ init();
+ setup();
- return 0;
+ 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 8372a96..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 (no external hardware required): - * - * - Connect a serial monitor to SerialUSB - * - Press any key - * - * This file is released into the public domain. - */ - -#include "wirish.h" - -#include "ring_buffer.h" - -#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 index 1cd82b6..d7fbf7a 100644 --- a/examples/test-serial-flush.cpp +++ b/examples/test-serial-flush.cpp @@ -2,13 +2,22 @@ #include "wirish.h" -void setup() { +void setup() +{ /* Send a message out USART2 */ Serial2.begin(9600); Serial2.println("Hello world!"); } +int toggle = 0; + void loop() { + + Serial2.println("This is the first line."); + Serial2.end(); + Serial2.println("This is the second line."); + + Serial2.begin(9600); Serial2.println("Waiting for multiple input..."); while(Serial2.available() < 5) { } Serial2.println(Serial2.read()); @@ -20,12 +29,13 @@ void loop() { } // 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() { +// Otherwise, statically allocated object that need libmaple may fail. + __attribute__(( constructor )) void premain() { init(); } -int main(void) { +int main(void) +{ setup(); while (1) { diff --git a/examples/test-serialusb.cpp b/examples/test-serialusb.cpp index 678c2b9..9d0a862 100644 --- a/examples/test-serialusb.cpp +++ b/examples/test-serialusb.cpp @@ -1,10 +1,11 @@ -// Tests SerialUSB functionality. +// Sample main.cpp file. Blinks an LED, sends a message out USART2 +// and turns on PWM on pin 2 #include "wirish.h" #include "usb.h" -#define LED_PIN BOARD_LED_PIN -#define BUT_PIN BOARD_BUTTON_PIN +#define LED_PIN 13 +#define BUT_PIN 38 uint32 state = 0; #define QUICKPRINT 0 @@ -13,29 +14,33 @@ uint32 state = 0; #define SIMPLE 3 #define ONOFF 4 -void setup() { + +void setup() +{ /* Set up the LED to blink */ pinMode(LED_PIN, OUTPUT); /* Set up the Button */ - pinMode(BUT_PIN, INPUT); + pinMode(BUT_PIN, INPUT_PULLUP); Serial2.begin(9600); - Serial2.println("This is the debug channel. Press BUT."); - - waitForButtonPress(0); + Serial2.println("Hello world! This is the debug channel."); } +int toggle = 0; + uint8 c1 = '-'; void loop() { - toggleLED(); + toggle ^= 1; + digitalWrite(LED_PIN, toggle); delay(1000); - if(isButtonPressed()) { + if(digitalRead(BUT_PIN)) { + while(digitalRead(BUT_PIN)) {}; state++; } - + switch(state) { case QUICKPRINT: for(int i = 0; i<30; i++) { @@ -43,34 +48,34 @@ void loop() { SerialUSB.print('.'); SerialUSB.print('|'); } - Serial2.println(SerialUSB.pending(), DEC); + Serial2.println(SerialUSB.pending(),DEC); SerialUSB.println(); break; case BIGSTUFF: - SerialUSB.println("0123456789012345678901234567890123456789" - "0123456789012345678901234567890123456789" - "012345678901234567890"); - SerialUSB.println((int64)123456789, DEC); + SerialUSB.println("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"); + SerialUSB.println((uint32)123456789,DEC); SerialUSB.println(3.1415926535); - Serial2.println(SerialUSB.pending(), DEC); + 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(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); + SerialUSB.println(3.14159265,9); + Serial2.println(3.14159265,9); + 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')"); @@ -87,8 +92,8 @@ void loop() { SerialUSB.print("hij\n\r"); SerialUSB.write(' '); SerialUSB.println(); - Serial2.println("Trying println(123456789, DEC)"); - SerialUSB.println(123456789, DEC); + Serial2.println("Trying println(123456789,DEC)"); + SerialUSB.println(123456789); Serial2.println("Trying println(3.141592)"); SerialUSB.println(3.141592); Serial2.println("Trying println(\"DONE\")"); @@ -98,12 +103,12 @@ void loop() { Serial2.println("Shutting down..."); SerialUSB.println("Shutting down..."); SerialUSB.end(); - Serial2.println("Waiting 4 seconds..."); + Serial2.println("Waiting 4seconds..."); delay(4000); Serial2.println("Starting up..."); SerialUSB.begin(); SerialUSB.println("Hello World!"); - Serial2.println("Waiting 4 seconds..."); + Serial2.println("Waiting 4seconds..."); delay(4000); state++; break; @@ -113,12 +118,13 @@ void loop() { } // 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() { +// Otherwise, statically allocated object that need libmaple may fail. + __attribute__(( constructor )) void premain() { init(); } -int main(void) { +int main(void) +{ setup(); while (1) { diff --git a/examples/test-session.cpp b/examples/test-session.cpp index c473521..845547d 100644 --- a/examples/test-session.cpp +++ b/examples/test-session.cpp @@ -20,51 +20,27 @@ int rate = 0; -#if defined(BOARD_maple) || defined(BOARD_maple_RET6) - -#elif defined(BOARD_maple_mini) - -#elif defined(BOARD_maple_native) -const uint8[] pins_to_skip = {LED_PIN}; - -#else -#error "Board not selected correctly." -#endif - #if defined(BOARD_maple) const uint8 pwm_pins[] = {0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 25, 27, 28}; const uint8 adc_pins[] = {0, 1, 2, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 27, 28}; -const uint8 pins_to_skip[] = {LED_PIN}; #elif defined(BOARD_maple_mini) -#define USB_DP 23 -#define USB_DM 24 const uint8 pwm_pins[] = {3, 4, 5, 8, 9, 10, 11, 15, 16, 25, 26, 27}; const uint8 adc_pins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 33}; // NB: 33 is LED -const uint8 pins_to_skip[] = {LED_PIN, USB_DP, USB_DM}; #elif defined(BOARD_maple_native) -const uint8 pwm_pins[] = { - 12, 13, 14, 15, 22, 23, 24, 25, 37, 38, 45, 46, 47, 48, 49, 50, 53, 54}; -const uint8 adc_pins[] = { - 6, 7, 8, 9, 10, 11, - /* FIXME These are on ADC3, which lacks support: - 39, 40, 41, 42, 43, 45, */ - 46, 47, 48, 49, 50, 51, 52, 53, 54}; -const uint8 pins_to_skip[] = {LED_PIN}; - -#elif defined(BOARD_maple_RET6) -const uint8 pwm_pins[] = - {0, 1, 2, 3, 5, 6, 7, 8, 9, 11, 12, 14, 24, 25, 27, 28, 35, 37, 37, - 38}; // NB 38 is BUT -const uint8 adc_pins[] = - {0, 1, 2, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 27, 28}; -const uint8 pins_to_skip[] = {LED_PIN}; +const uint8 pwm_pins[] = {12, 13, 14, 15, 22, 23, 24, 25, 37, 38, 45, + 46, 47, 48, 49, 50, 53, 54}; +const uint8 adc_pins[] = {6, 7, 8, 9, 10, 11, + /* the following are on ADC3, which lacks support: + 39, 40, 41, 42, 43, 45, */ + 46, 47, 48, 49, 50, 51, 52, 53, 54}; #else -#error "Board type has not been selected correctly." +#error "Board type has not been selected correctly" + #endif uint8 gpio_state[NR_GPIO_PINS]; @@ -86,7 +62,6 @@ void cmd_sequential_pwm_test(void); void cmd_pwm_sweep(void); void cmd_servo_sweep(void); -bool skip_pin_p(uint8 pin); void measure_adc_noise(uint8 pin); void fast_gpio(int pin); void do_serials(HardwareSerial **serials, int n, unsigned baud); @@ -103,12 +78,12 @@ void setup() { // Send a message out over COMM interface COMM.println(" "); - COMM.println(" __ __ _ _ "); + COMM.println(" __ __ _ _"); COMM.println(" | \\/ | __ _ _ __ | | ___| |"); COMM.println(" | |\\/| |/ _` | '_ \\| |/ _ \\ |"); COMM.println(" | | | | (_| | |_) | | __/_|"); COMM.println(" |_| |_|\\__,_| .__/|_|\\___(_)"); - COMM.println(" |_|"); + COMM.println(" |_|"); COMM.println(" by leaflabs"); COMM.println(""); COMM.println(""); @@ -299,7 +274,7 @@ void cmd_print_help(void) { COMM.println("\tr: Monitor and print GPIO status changes"); COMM.println("\ts: output a sweeping servo PWM on all PWM channels"); COMM.println("\tm: output data on USART1 and USART3 with various rates"); - COMM.println("\t+: test shield mode (for QA; will disrupt USARTS)"); + COMM.println("\t+: test shield mode (for QA, will disrupt Serial2!)"); COMM.println("Unimplemented:"); COMM.println("\te: do everything all at once until new input"); @@ -319,11 +294,11 @@ void measure_adc_noise(uint8 pin) { // TODO // variance algorithm from knuth; see wikipedia // checked against python - for(int i = 0; i < 100; i++) { + for(int i = 0; i<100; i++) { data[i] = analogRead(pin); delta = data[i] - mean; - mean = mean + delta/(i + 1); - M2 = M2 + delta * (data[i] - mean); + mean = mean + delta/(i+1); + M2 = M2 + delta*(data[i] - mean); } //sqrt is broken? @@ -338,7 +313,7 @@ void measure_adc_noise(uint8 pin) { // TODO void cmd_adc_stats(void) { COMM.println("Taking ADC noise stats..."); digitalWrite(BOARD_LED_PIN, 0); - for(uint32 i = 0; i < sizeof(adc_pins); i++) { + for(uint32 i = 0; i<sizeof(adc_pins); i++) { delay(5); measure_adc_noise(adc_pins[i]); } @@ -347,21 +322,21 @@ void cmd_adc_stats(void) { void cmd_stressful_adc_stats(void) { COMM.println("Taking ADC noise stats under duress..."); digitalWrite(BOARD_LED_PIN, 0); - for(uint32 i = 0; i < sizeof(adc_pins); i++) { + for(uint32 i = 0; i<sizeof(adc_pins); i++) { // spool up PWM - for(uint32 j = 2; j < (uint32)sizeof(pwm_pins); j++) { + for(uint32 j = 2; j<(uint32)sizeof(pwm_pins); j++) { if(adc_pins[i] != pwm_pins[j]) { - pinMode(pwm_pins[j], PWM); + pinMode(pwm_pins[j],PWM); pwmWrite(pwm_pins[j], 1000 + i); } } SerialUSB.print(dummy_dat); SerialUSB.print(dummy_dat); measure_adc_noise(adc_pins[i]); - for(uint32 j = 2; j < (uint32)sizeof(pwm_pins); j++) { + for(uint32 j = 2; j<(uint32)sizeof(pwm_pins); j++) { if(adc_pins[i] != pwm_pins[j]) { - pinMode(pwm_pins[j], OUTPUT); - digitalWrite(pwm_pins[j], 0); + pinMode(pwm_pins[j],OUTPUT); + digitalWrite(pwm_pins[j],0); } } } @@ -433,12 +408,12 @@ void cmd_gpio_monitoring(void) { COMM.println("Monitoring GPIO read state changes. Press any key."); digitalWrite(BOARD_LED_PIN, 0); // make sure to skip the TX/RX headers - for(int i = 2; i < NR_GPIO_PINS; i++) { + for(int i = 2; i<NR_GPIO_PINS; i++) { pinMode(i, INPUT_PULLDOWN); gpio_state[i] = (uint8)digitalRead(i); } while(!COMM.available()) { - for(int i = 2; i < NR_GPIO_PINS; i++) { + for(int i = 2; i<NR_GPIO_PINS; i++) { uint8 current_state = (uint8)digitalRead(i); if(current_state != gpio_state[i]) { COMM.print("State change on header D"); @@ -449,7 +424,7 @@ void cmd_gpio_monitoring(void) { } } } - for(int i = 2; i < NR_GPIO_PINS; i++) { + for(int i = 2; i<NR_GPIO_PINS; i++) { pinMode(i, OUTPUT); } } @@ -459,7 +434,7 @@ void cmd_sequential_adc_reads(void) { COMM.println("Press any key for next port, or ESC to stop."); digitalWrite(LED_PIN, 0); // make sure to skip the TX/RX headers - for(uint32 i = 2; i < sizeof(adc_pins); i++) { + for(uint32 i = 2; i<sizeof(adc_pins); i++) { COMM.print("Reading on header D"); COMM.print(adc_pins[i], DEC); COMM.println("..."); @@ -471,13 +446,13 @@ void cmd_sequential_adc_reads(void) { COMM.print(sample,DEC); COMM.print("\t"); COMM.print("|"); - for(int j = 0; j < 4096; j += 100) { + for(int j = 0; j<4096; j+= 100) { if(sample >= j) COMM.print("#"); else COMM.print(" "); } COMM.print("| "); - for(int j = 0; j < 12; j++) { - if(sample & (1 << (11 - j))) COMM.print("1"); + for(int j = 0; j<12; j++) { + if(sample & (1 << (11-j))) COMM.print("1"); else COMM.print("0"); } COMM.println(""); @@ -491,37 +466,32 @@ void cmd_sequential_adc_reads(void) { void cmd_gpio_qa(void) { COMM.println("Doing QA testing for most GPIO pins..."); digitalWrite(BOARD_LED_PIN, 0); - for(int i = 0; i < NR_GPIO_PINS; i++) { + for(int i = 0; i<NR_GPIO_PINS; i++) { pinMode(i, INPUT); gpio_state[i] = 0; } - COMM.println("Waiting to start; press a key."); + COMM.println("Waiting to start..."); while(digitalRead(0) != 1 && !COMM.available()) { continue; } - for(int i = 0; i < NR_GPIO_PINS; i++) { - if(skip_pin_p(i)) { - COMM.print("Not checking pin "); - COMM.println(i); + for(int i=0; i<38; i++) { + if(i == BOARD_LED_PIN) { + COMM.println("Not checking LED"); continue; } - COMM.print("Checking pin "); - COMM.print(i, DEC); + COMM.print("Checking D"); + COMM.print(i,DEC); while(digitalRead(i) == 0) continue; - for(int j = 0; j < NR_GPIO_PINS; j++) { - if (skip_pin_p(j)) - continue; - if(digitalRead(j) && j != i) { + for(int j=0; j<NR_GPIO_PINS; j++) { + if(digitalRead(j) && j!=i) { COMM.print(": FAIL ########################### D"); COMM.println(j, DEC); break; } } while(digitalRead(i) == 1) continue; - for(int j = 0; j < NR_GPIO_PINS; j++) { - if (skip_pin_p(j)) - continue; - if(digitalRead(j) && j != i) { + for(int j=0; j<NR_GPIO_PINS; j++) { + if(digitalRead(j) && j!=i) { COMM.print(": FAIL ########################### D"); COMM.println(j, DEC); break; @@ -529,28 +499,20 @@ void cmd_gpio_qa(void) { } COMM.println(": Ok!"); } - for(int i = 0; i < NR_GPIO_PINS; i++) { + for(int i = 0; i<NR_GPIO_PINS; i++) { pinMode(i, OUTPUT); digitalWrite(i, 0); } } -bool skip_pin_p(uint8 pin) { - for (uint8 i = 0; i < sizeof(pins_to_skip); i++) { - if (pin == pins_to_skip[i]) - return true; - } - return false; -} - void cmd_sequential_gpio_writes(void) { COMM.print("Sequentially toggling all pins except D0, D1. "); COMM.println("Anything for next, ESC to stop."); digitalWrite(BOARD_LED_PIN, 0); // make sure to skip the TX/RX headers - for(uint32 i = 2; i < NR_GPIO_PINS; i++) { + for(uint32 i = 2; i<NR_GPIO_PINS; i++) { COMM.print("GPIO write out on header D"); - COMM.print((int)i, DEC); + COMM.print(i, DEC); COMM.println("..."); pinMode(i, OUTPUT); do { @@ -565,15 +527,15 @@ void cmd_gpio_toggling(void) { COMM.println("Toggling all GPIOs simultaneously. Press any key."); digitalWrite(BOARD_LED_PIN, 0); // make sure to skip the TX/RX headers - for(uint32 i = 2; i < NR_GPIO_PINS; i++) { + for(uint32 i = 2; i<NR_GPIO_PINS; i++) { pinMode(i, OUTPUT); } while(!COMM.available()) { - for(uint32 i = 2; i < NR_GPIO_PINS; i++) { + for(uint32 i = 2; i<NR_GPIO_PINS; i++) { togglePin(i); } } - for(uint32 i = 2; i < NR_GPIO_PINS; i++) { + for(uint32 i = 2; i<NR_GPIO_PINS; i++) { digitalWrite(i, 0); } } @@ -584,7 +546,7 @@ void cmd_sequential_pwm_test(void) { COMM.println("Press any key for next, ESC to stop."); digitalWrite(BOARD_LED_PIN, 0); // make sure to skip the TX/RX headers - for(uint32 i = 2; i < sizeof(pwm_pins); i++) { + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { COMM.print("PWM out on header D"); COMM.print(pwm_pins[i], DEC); COMM.println("..."); @@ -601,19 +563,19 @@ void cmd_pwm_sweep(void) { COMM.println("Testing all PWM ports with a sweep. Press any key."); digitalWrite(BOARD_LED_PIN, 0); // make sure to skip the TX/RX pins - for(uint32 i = 2; i < sizeof(pwm_pins); i++) { + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { pinMode(pwm_pins[i], PWM); pwmWrite(pwm_pins[i], 4000); } while(!COMM.available()) { rate += 20; if(rate > 65500) rate = 0; - for(uint32 i = 2; i < sizeof(pwm_pins); i++) { + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { pwmWrite(pwm_pins[i], rate); } delay(1); } - for(uint32 i = 2; i < sizeof(pwm_pins); i++) { + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { pinMode(pwm_pins[i], OUTPUT); } } @@ -624,7 +586,7 @@ void cmd_servo_sweep(void) { digitalWrite(BOARD_LED_PIN, 0); init_all_timers(21); // make sure to skip the TX/RX headers - for(uint32 i = 2; i < sizeof(pwm_pins); i++) { + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { pinMode(pwm_pins[i], PWM); pwmWrite(pwm_pins[i], 4000); } @@ -635,12 +597,12 @@ void cmd_servo_sweep(void) { while(!COMM.available()) { rate += 20; if(rate > 5734) rate = 4096; - for(uint32 i = 2; i < sizeof(pwm_pins); i++) { + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { pwmWrite(pwm_pins[i], rate); } delay(20); } - for(uint32 i = 2; i < sizeof(pwm_pins); i++) { + for(uint32 i = 2; i<sizeof(pwm_pins); i++) { pinMode(pwm_pins[i], OUTPUT); } init_all_timers(1); @@ -664,12 +626,13 @@ void init_all_timers(uint16 prescale) { // 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() { +// Otherwise, statically allocated object that need libmaple may fail. +__attribute__(( constructor )) void premain() { init(); } -int main(void) { +int main(void) +{ setup(); while (1) { diff --git a/examples/test-systick.cpp b/examples/test-systick.cpp index c7b5529..247892d 100644 --- a/examples/test-systick.cpp +++ b/examples/test-systick.cpp @@ -3,48 +3,54 @@ #include "wirish.h" #include "systick.h" -#define LED_PIN BOARD_LED_PIN -#define PWM_PIN 2 -#define BUT BOARD_BUTTON_PIN +#define LED_PIN 13 +#define PWM_PIN 2 +#define BUT 38 -void setup() { +void setup() +{ /* Set up the LED to blink */ pinMode(LED_PIN, OUTPUT); - pinMode(BUT, INPUT); + + /* Turn on PWM on pin PWM_PIN */ + pinMode(PWM_PIN, PWM); + pwmWrite(PWM_PIN, 0x8000); + + pinMode(BUT, INPUT_PULLDOWN); } -bool disable = true; +int toggle = 0; long time = 0; void loop() { - volatile int i = 0; - toggleLED(); + toggle ^= 1; + digitalWrite(LED_PIN, toggle); // 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_resume(); - } - disable = !disable; + int16 i = 1; + float j = 1; + for(i=0; i<6553; i++) { + j = sqrt(j) + 1; + } + + if(digitalRead(BUT)) { + systick_disable(); + } else { + systick_resume(); } + //SerialUSB.println(micros()); // there is a bug with this 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() { + __attribute__(( constructor )) void premain() { init(); } -int main(void) { +int main(void) +{ setup(); while (1) { diff --git a/examples/test-timers.cpp b/examples/test-timers.cpp index f3cfdcc..ccba251 100644 --- a/examples/test-timers.cpp +++ b/examples/test-timers.cpp @@ -2,7 +2,7 @@ #include "wirish.h" -#define LED_PIN BOARD_LED_PIN +#define LED_PIN 13 void handler1(void); void handler2(void); @@ -12,6 +12,7 @@ void handler4(void); void handler3b(void); void handler4b(void); +int toggle = 0; int t; int count1 = 0; @@ -35,24 +36,25 @@ void setup() pinMode(LED_PIN, OUTPUT); // Setup the button as input - pinMode(BOARD_BUTTON_PIN, INPUT); + pinMode(38, INPUT_PULLUP); - // Wait for user to attach... - waitForButtonPress(0); - - // Send a message out SerialUSB - SerialUSB.println("Beginning timer test..."); + /* Send a message out USART2 */ + //SerialUSB.begin(9600); + SerialUSB.println("Begining timer test..."); for(int t=0; t<4; t++) { Timers[t].setChannel1Mode(TIMER_OUTPUTCOMPARE); Timers[t].setChannel2Mode(TIMER_OUTPUTCOMPARE); Timers[t].setChannel3Mode(TIMER_OUTPUTCOMPARE); Timers[t].setChannel4Mode(TIMER_OUTPUTCOMPARE); } + + // Wait for user to attach... + delay(2000); } void loop() { SerialUSB.println("-----------------------------------------------------"); - SerialUSB.println("Testing setCount/getCount"); + SerialUSB.println("Testing setCount/getCount"); SerialUSB.print("Timer1.getCount() = "); SerialUSB.println(Timer1.getCount()); SerialUSB.println("Timer1.setCount(1234)"); Timer1.setCount(1234); @@ -61,7 +63,7 @@ void loop() { // down Timer4 is in the "pause" state and the timer doesn't increment, so // the final counts should reflect the ratio of time that BUT was held down SerialUSB.println("-----------------------------------------------------"); - SerialUSB.println("Testing Pause/Resume; button roughly controls Timer4"); + SerialUSB.println("Testing Pause/Resume; button roughly controls Timer4"); count3 = 0; count4 = 0; Timer3.setChannel1Mode(TIMER_OUTPUTCOMPARE); @@ -78,9 +80,9 @@ void loop() { Timer4.attachCompare1Interrupt(handler4b); Timer3.resume(); Timer4.resume(); - SerialUSB.println("~4 seconds..."); + SerialUSB.println("~4 seconds..."); for(int i = 0; i<4000; i++) { - if(isButtonPressed()) { + if(digitalRead(38)) { Timer4.pause(); } else { Timer4.resume(); @@ -94,14 +96,14 @@ void loop() { // These test the setPeriod auto-configure functionality SerialUSB.println("-----------------------------------------------------"); - SerialUSB.println("Testing setPeriod"); + SerialUSB.println("Testing setPeriod"); Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); Timer4.setCompare1(1); - Timer4.setPeriod(10); + Timer4.setPeriod(10); Timer4.pause(); Timer4.setCount(0); Timer4.attachCompare1Interrupt(handler4b); - SerialUSB.println("Period 10ms, wait 2 seconds..."); + SerialUSB.println("Period 10ms, wait 2 seconds..."); count4 = 0; Timer4.resume(); delay(2000); @@ -112,10 +114,10 @@ void loop() { Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); Timer4.setCompare1(1); Timer4.pause(); - Timer4.setPeriod(30000); + Timer4.setPeriod(30000); Timer4.setCount(0); Timer4.attachCompare1Interrupt(handler4b); - SerialUSB.println("Period 30000ms, wait 2 seconds..."); + SerialUSB.println("Period 30000ms, wait 2 seconds..."); count4 = 0; Timer4.resume(); delay(2000); @@ -125,12 +127,12 @@ void loop() { SerialUSB.println("(should be around 2sec/30000ms ~ 67)"); Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); - Timer4.setPeriod(300000); + Timer4.setPeriod(300000); Timer4.setCompare1(1); Timer4.pause(); Timer4.setCount(0); Timer4.attachCompare1Interrupt(handler4b); - SerialUSB.println("Period 300000ms, wait 2 seconds..."); + SerialUSB.println("Period 300000ms, wait 2 seconds..."); count4 = 0; Timer4.resume(); delay(2000); @@ -144,9 +146,9 @@ void loop() { Timer4.setOverflow(65454); Timer4.pause(); Timer4.setCount(0); - Timer4.setCompare1(1); + Timer4.setCompare1(1); Timer4.attachCompare1Interrupt(handler4b); - SerialUSB.println("Period 30000ms, wait 2 seconds..."); + SerialUSB.println("Period 30000ms, wait 2 seconds..."); count4 = 0; Timer4.resume(); delay(2000); @@ -157,11 +159,11 @@ void loop() { Timer4.setChannel1Mode(TIMER_OUTPUTCOMPARE); Timer4.setCompare1(1); - Timer4.setPeriod(30000); + Timer4.setPeriod(30000); Timer4.pause(); Timer4.setCount(0); Timer4.attachCompare1Interrupt(handler4b); - SerialUSB.println("Period 30000ms, wait 2 seconds..."); + SerialUSB.println("Period 30000ms, wait 2 seconds..."); count4 = 0; Timer4.resume(); delay(2000); @@ -175,7 +177,7 @@ void loop() { // that over time the actual timing rates get blown away by other system // interrupts. for(t=0; t<4; t++) { - toggleLED(); + toggle ^= 1; digitalWrite(LED_PIN, toggle); delay(100); SerialUSB.println("-----------------------------------------------------"); SerialUSB.print("Testing Timer "); SerialUSB.println(t+1); @@ -212,39 +214,33 @@ void handler1(void) { val1 += rate1; Timers[t].setCompare1(val1); count1++; -} - +} void handler2(void) { val2 += rate2; Timers[t].setCompare2(val2); count2++; -} - +} void handler3(void) { val3 += rate3; Timers[t].setCompare3(val3); count3++; -} - +} void handler4(void) { val4 += rate4; Timers[t].setCompare4(val4); count4++; -} +} void handler3b(void) { count3++; -} - +} void handler4b(void) { count4++; -} +} -__attribute__((constructor)) void premain() { - init(); -} int main(void) { + init(); setup(); while (1) { diff --git a/examples/vga-leaf.cpp b/examples/vga-leaf.cpp index 9d9fce2..d1c6d7d 100644 --- a/examples/vga-leaf.cpp +++ b/examples/vga-leaf.cpp @@ -1,21 +1,21 @@ /* - VGA Output + Crude VGA Output - Outputs a red and white leaf to VGA. It should run most VGA monitors - at 640x480, though it does not follow the timing spec very - carefully. Real twisted or shielded wires, proper grounding, and not - doing this on a breadboard are recommended (but it seems to work ok - without). + Outputs a red and white leaf to VGA. This implementation is crude and noisy, + but a fun demo. It should run most VGA monitors at 640x480, though it does + not follow the timing spec very carefully. Real twisted or shielded wires, + proper grounding, and not doing this on a breadboard are recommended (but + it seems to work ok without). - SerialUSB and SysTick are disabled to get rid of the most frequently - occurring interrupts (which mess with timing). This means that you - have to use perpetual bootloader mode or the reset button to flash - new programs. + SerialUSB is disabled to get rid of most interrupts (which mess with timing); + the SysTick is probably the source of the remaining flickers. This means that + you have to use perpetual bootloader or the reset button to flash new + programs. How to wire this to a VGA port: - D6 via ~200ohms to VGA Red (1) - D7 via ~200ohms to VGA Green (2) - D8 via ~200ohms to VGA Blue (3) + D5 via ~200ohms to VGA Red (1) + D6 via ~200ohms to VGA Green (2) + D7 via ~200ohms to VGA Blue (3) D11 to VGA VSync (14) (swapped?) D12 to VGA HSync (13) (swapped?) GND to VGA Ground (5) @@ -24,71 +24,48 @@ See also: - http://pinouts.ru/Video/VGA15_pinout.shtml - http://www.epanorama.net/documents/pc/vga_timing.html - + Created 20 July 2010 By Bryan Newbold for LeafLabs This code is released with no strings attached. - - Modified 4 March 2011 - By Marti Bolivar - Disabled SysTick, kept up-to-date with libmaple. + */ -// FIXME: generalize for Native and Mini - #include "wirish.h" -#define LED_PIN BOARD_LED_PIN +#define LED_PIN 13 -// Pinouts -- you also must change the GPIO macros below if you change -// these -#define VGA_R 6 // STM32: A8 -#define VGA_G 7 // STM32: A9 -#define VGA_B 8 // STM32: A10 +// Pinouts +#define VGA_R 5 // STM32: B6 +#define VGA_G 6 // STM32: A8 +#define VGA_B 7 // STM32: A9 #define VGA_V 11 // STM32: A6 #define VGA_H 12 // STM32: A7 -// These low level (and STM32 specific) macros make GPIO writes much -// faster -#define ABSRR ((volatile uint32*)0x40010810) -#define ABRR ((volatile uint32*)0x40010814) - -#define RBIT 8 // (see pinouts) -#define GBIT 9 -#define BBIT 10 - -#define VGA_R_HIGH *ABSRR = BIT(RBIT) -#define VGA_R_LOW *ABRR = BIT(RBIT) -#define VGA_G_HIGH *ABSRR = BIT(GBIT) -#define VGA_G_LOW *ABRR = BIT(GBIT) -#define VGA_B_HIGH *ABSRR = BIT(BBIT) -#define VGA_B_LOW *ABRR = BIT(BBIT) - -#define ON_COLOR BIT(RBIT) -#define OFF_COLOR (BIT(RBIT) | BIT(GBIT) | BIT(BBIT)) - -// set has priority, so clear every bit and set some given bits: -#define VGA_COLOR(c) (*ABSRR = c | \ - BIT(RBIT+16) | BIT(GBIT+16) | BIT(BBIT+16)) - -#define VGA_V_HIGH *ABSRR = BIT(6) -#define VGA_V_LOW *ABRR = BIT(6) -#define VGA_H_HIGH *ABSRR = BIT(7) -#define VGA_H_LOW *ABRR = BIT(7) +// These low level macros make GPIO writes much faster +#define VGA_R_HIGH (GPIOB_BASE)->BSRR = BIT(6) +#define VGA_R_LOW (GPIOB_BASE)->BRR = BIT(6) +#define VGA_G_HIGH (GPIOA_BASE)->BSRR = BIT(8) +#define VGA_G_LOW (GPIOA_BASE)->BRR = BIT(8) +#define VGA_B_HIGH (GPIOA_BASE)->BSRR = BIT(9) +#define VGA_B_LOW (GPIOA_BASE)->BRR = BIT(9) +#define VGA_V_HIGH (GPIOA_BASE)->BSRR = BIT(6) +#define VGA_V_LOW (GPIOA_BASE)->BRR = BIT(6) +#define VGA_H_HIGH (GPIOA_BASE)->BSRR = BIT(7) +#define VGA_H_LOW (GPIOA_BASE)->BRR = BIT(7) void isr_porch(void); void isr_start(void); void isr_stop(void); void isr_update(void); +uint8 toggle; uint16 x = 0; // X coordinate uint16 y = 0; // Y coordinate -uint16 logo_y = 0; // Y coordinate, mapped into valid logo index (for speed) -bool v_active = true; // Are we in the image? +uint8 v_active = 1; // Are we in the image? -const uint8 x_max = 16; -const uint8 y_max = 18; -uint32 logo[y_max][x_max] = { +// 1-bit! +uint8 logo[18][16] = { {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, {0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,}, {0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,}, @@ -122,20 +99,9 @@ void setup() { digitalWrite(VGA_H, HIGH); digitalWrite(VGA_V, HIGH); - // Fill the logo array with color patterns corresponding to its - // truth value. Note that we could get more tricky here, since - // there are 3 bits of color. - for (int y = 0; y < y_max; y++) { - for (int x = 0; x < x_max; x++) { - logo[y][x] = logo[y][x] ? ON_COLOR : OFF_COLOR; - } - } - // This gets rid of the majority of the interrupt artifacts; - // there's still a glitch for low values of y, but let's not worry - // about that. (Probably due to the hackish way vsync is done). SerialUSB.end(); - systick_disable(); + SystemTick.end(); // Configure Timer4.pause(); // while we configure @@ -154,13 +120,14 @@ void setup() { Timer4.attachCompare3Interrupt(isr_stop); Timer4.setCompare4(1); // Could be zero I guess Timer4.attachCompare4Interrupt(isr_update); - + Timer4.setCount(0); // Ready... Timer4.resume(); // Go! } void loop() { - toggleLED(); + toggle ^= 1; + digitalWrite(LED_PIN, toggle); delay(100); // Everything happens in the interrupts! @@ -172,59 +139,51 @@ void loop() { void isr_porch(void) { VGA_H_HIGH; y++; - logo_y = map(y, 0, 478, 0, y_max); // Back to the top - if(y >= 523) { - y = 1; - logo_y = 0; - v_active = true; + if(y>=523) { + y=1; + v_active = 1; return; } // Other vsync stuff below the image - if(y >= 492) { + if(y>=492) { VGA_V_HIGH; return; } - if(y >= 490) { + if(y>=490) { VGA_V_LOW; return; } - if(y >= 479) { - v_active = false; + if(y>=479) { + v_active = 0; return; } } // This is the main horizontal sweep -void isr_start(void) { +void isr_start(void) { // Skip if we're not in the image at all - if (!v_active) { - return; - } + if(!v_active) { return; } // Start Red VGA_R_LOW; VGA_R_HIGH; - // For each "pixel", go ON_COLOR or OFF_COLOR - for(x = 0; x < 16; x++) { - // setting the color several times is just an easy way to - // delay, so the image is wider. if you only do the following - // once, you'll be able to make the logo array a lot wider: - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); - VGA_COLOR(logo[logo_y][x]); + // For each "pixel" (really 20 or so screen pixels?) go red or white + for(x=0; x<32; x++) { + if(logo[y/28][x/2]) { + VGA_G_HIGH; + VGA_B_HIGH; + } else { + VGA_G_LOW; + VGA_B_LOW; + } } } // End of the horizontal line void isr_stop(void) { - if (!v_active) { - return; - } + if(!v_active) { return; } VGA_R_LOW; VGA_G_LOW; VGA_B_LOW; @@ -235,11 +194,8 @@ void isr_update(void) { VGA_H_LOW; } -__attribute__((constructor)) void premain() { - init(); -} - int main(void) { + init(); setup(); while (1) { diff --git a/examples/vga-scope.cpp b/examples/vga-scope.cpp index 9c6dca5..0265f9c 100644 --- a/examples/vga-scope.cpp +++ b/examples/vga-scope.cpp @@ -1,90 +1,34 @@ -/* - VGA Oscilloscope demo. - - Connect a microphone or something like it to ANALOG_PIN (0V -- 3.3V - only; 0.2V -- 3.1V will probably look nicer); an attached VGA - monitor will display the signal roughly in real-time. - - The thick blue line corresponds roughly to 0V. - - This is a fairy crude hack, but it's fun to watch/toy around with. - - SerialUSB and SysTick are disabled to get rid of the most frequently - occurring interrupts (which mess with timing). This means that you - have to use perpetual bootloader mode or the reset button to flash - new programs. - - How to wire this to a VGA port: - D6 via ~200ohms to VGA Red (1) - D7 via ~200ohms to VGA Green (2) - D8 via ~200ohms to VGA Blue (3) - D11 to VGA VSync (14) (swapped?) - D12 to VGA HSync (13) (swapped?) - GND to VGA Ground (5) - GND to VGA Sync Ground (10) - - See also: - - http://pinouts.ru/Video/VGA15_pinout.shtml - - http://www.epanorama.net/documents/pc/vga_timing.html - - This code is released into the public domain. - */ +// Low-level, non-wirish demonstration of VGA +// +// Connect a microphone or something less to ANALOG_PIN #include "wirish.h" -#include "systick.h" - -// FIXME generalize for Native and Mini -#define LED_PIN BOARD_LED_PIN +#define LED_PIN 13 #define ANALOG_PIN 18 - -// Pinouts -- you also must change the GPIO macros below if you change -// these -#define VGA_R 6 // STM32: A8 -#define VGA_G 7 // STM32: A9 -#define VGA_B 8 // STM32: A10 -#define VGA_V 11 // STM32: A6 -#define VGA_H 12 // STM32: A7 - -// These low level (and STM32 specific) macros make GPIO writes much -// faster -#define ABSRR ((volatile uint32*)0x40010810) -#define ABRR ((volatile uint32*)0x40010814) - -#define RBIT 8 // (see pinouts) -#define GBIT 9 -#define BBIT 10 - -#define VGA_R_HIGH *ABSRR = BIT(RBIT) -#define VGA_R_LOW *ABRR = BIT(RBIT) -#define VGA_G_HIGH *ABSRR = BIT(GBIT) -#define VGA_G_LOW *ABRR = BIT(GBIT) -#define VGA_B_HIGH *ABSRR = BIT(BBIT) -#define VGA_B_LOW *ABRR = BIT(BBIT) - -#define COLOR_WHITE (BIT(RBIT) | BIT(GBIT) | BIT(BBIT)) -#define COLOR_BLACK 0 -#define COLOR_RED BIT(RBIT) -#define COLOR_GREEN BIT(GBIT) -#define COLOR_BLUE BIT(BBIT) - -#define BORDER_COLOR COLOR_BLUE - -// set has priority, so clear every bit and set some given bits: -#define VGA_COLOR(c) (*ABSRR = c | \ - BIT(RBIT+16) | BIT(GBIT+16) | BIT(BBIT+16)) - -#define VGA_V_HIGH *ABSRR = BIT(6) -#define VGA_V_LOW *ABRR = BIT(6) -#define VGA_H_HIGH *ABSRR = BIT(7) -#define VGA_H_LOW *ABRR = BIT(7) +#define VGA_R 5 // B6 +#define VGA_G 6 // A8 +#define VGA_B 7 // A9 +#define VGA_V 11 // A6 +#define VGA_H 12 // A7 +#define VGA_R_HIGH (GPIOB_BASE)->BSRR = BIT(6) +#define VGA_R_LOW (GPIOB_BASE)->BRR = BIT(6) +#define VGA_G_HIGH (GPIOA_BASE)->BSRR = BIT(8) +#define VGA_G_LOW (GPIOA_BASE)->BRR = BIT(8) +#define VGA_B_HIGH (GPIOA_BASE)->BSRR = BIT(9) +#define VGA_B_LOW (GPIOA_BASE)->BRR = BIT(9) +#define VGA_V_HIGH (GPIOA_BASE)->BSRR = BIT(6) +#define VGA_V_LOW (GPIOA_BASE)->BRR = BIT(6) +#define VGA_H_HIGH (GPIOA_BASE)->BSRR = BIT(7) +#define VGA_H_LOW (GPIOA_BASE)->BRR = BIT(7) void isr_porch(void); void isr_start(void); void isr_stop(void); void isr_update(void); -void setup() { +void setup() +{ pinMode(LED_PIN, OUTPUT); pinMode(ANALOG_PIN, INPUT_ANALOG); digitalWrite(LED_PIN, 1); @@ -94,104 +38,104 @@ void setup() { pinMode(VGA_V, OUTPUT); pinMode(VGA_H, OUTPUT); - // Send a message out USART2 + /* Send a message out USART2 */ Serial2.begin(9600); - Serial2.println("Time to kill the radio star..."); + Serial2.println("Video time..."); // This gets rid of the majority of the interrupt artifacts; - // there's still a glitch for low values of y, but let's not worry - // about that. (Probably due to the hackish way vsync is done). + // a SysTick.end() is required as well SerialUSB.end(); - systick_disable(); - + digitalWrite(VGA_R, 0); digitalWrite(VGA_G, 0); digitalWrite(VGA_B, 0); - digitalWrite(VGA_H, 1); - digitalWrite(VGA_V, 1); - - timer_pause(TIMER4); - timer_set_prescaler(TIMER4, 0); - timer_set_mode(TIMER4, 1, TIMER_OUTPUTCOMPARE); - timer_set_mode(TIMER4, 2, TIMER_OUTPUTCOMPARE); - timer_set_mode(TIMER4, 3, TIMER_OUTPUTCOMPARE); - timer_set_mode(TIMER4, 4, TIMER_OUTPUTCOMPARE); - timer_set_reload(TIMER4, 2287); - timer_set_compare_value(TIMER4, 1, 200); - timer_set_compare_value(TIMER4, 2, 250); - timer_set_compare_value(TIMER4, 3, 2170); // 2219 max... - timer_set_compare_value(TIMER4, 4, 1); - timer_attach_interrupt(TIMER4, 1, isr_porch); - timer_attach_interrupt(TIMER4, 2, isr_start); - timer_attach_interrupt(TIMER4, 3, isr_stop); - timer_attach_interrupt(TIMER4, 4, isr_update); - - timer_set_count(TIMER4, 0); - timer_resume(TIMER4); + digitalWrite(VGA_H,1); + digitalWrite(VGA_V,1); + + timer_set_prescaler(4,0); + timer_set_mode(4, 1, TIMER_OUTPUTCOMPARE); + timer_set_mode(4, 2, TIMER_OUTPUTCOMPARE); + timer_set_mode(4, 3, TIMER_OUTPUTCOMPARE); + timer_set_mode(4, 4, TIMER_OUTPUTCOMPARE); + timer_set_reload(4, 2287); + timer_set_compare_value(4,1,200); + timer_set_compare_value(4,2,300); + timer_set_compare_value(4,3,2170); // 2219 max... + timer_set_compare_value(4,4,1); + timer_attach_interrupt(4,1,isr_porch); + timer_attach_interrupt(4,2,isr_start); + timer_attach_interrupt(4,3,isr_stop); + timer_attach_interrupt(4,4,isr_update); + + timer_set_count(4,0); } +int toggle = 0; +uint16 x = 0; uint16 y = 0; uint16 val = 0; -bool v_active = true; -const uint16 x_max = 60; // empirically (and lazily) determined +uint8 v_active = 1; +GPIO_Port *portb = GPIOB_BASE; void isr_porch(void) { VGA_H_HIGH; y++; - val = map(analogRead(ANALOG_PIN), 0, 4095, 0, x_max); - if(y >= 523) { - y = 1; - v_active = true; + if(y>=523) { + y=1; + v_active = 1; return; } - if(y >= 492) { + if(y>=492) { VGA_V_HIGH; return; } - if(y >= 490) { + if(y>=490) { VGA_V_LOW; return; } - if(y >= 479) { - v_active = false; + if(y>=479) { // 479 + v_active = 0; return; } } void isr_start(void) { - if (!v_active) { - return; - } - VGA_COLOR(BORDER_COLOR); - for (int x = 0; x < val; x++) { - VGA_COLOR(COLOR_BLACK); - } - VGA_COLOR(COLOR_WHITE); - VGA_COLOR(COLOR_BLACK); -} + if(!v_active) { return; } + VGA_R_HIGH; + VGA_R_HIGH; + VGA_R_HIGH; + VGA_R_LOW; + //delayMicroseconds(2); + //gpio_write_bit(GPIOA_BASE, 8, 1); // VGA_G + for(x=0; x<(val>>6); x++) { + } + VGA_B_HIGH; + VGA_G_HIGH; + VGA_G_LOW; + VGA_B_LOW; + //VGA_R_HIGH; + //val = (val + analogRead(ANALOG_PIN))/2; + val = analogRead(ANALOG_PIN); +} void isr_stop(void) { - if (!v_active) { - return; - } - VGA_COLOR(COLOR_BLACK); + if(!v_active) { return; } + VGA_R_LOW; + VGA_G_LOW; + VGA_B_LOW; } - void isr_update(void) { VGA_H_LOW; } void loop() { - toggleLED(); - delay(100); + //val = analogRead(ANALOG_PIN); } -__attribute__((constructor)) void premain() { - init(); -} int main(void) { + init(); setup(); while (1) { |