aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorMarti Bolivar <mbolivar@leaflabs.com>2011-03-04 20:25:26 -0500
committerMarti Bolivar <mbolivar@leaflabs.com>2011-03-04 23:16:32 -0500
commit02e76ec27b5737bce836a5460427b538076f01ef (patch)
tree30fb1f21caba0504ff414edc853474f0d365f790 /examples
parent7973deea3908f4f865f59c5e2df1eef6810cc70e (diff)
downloadlibrambutan-02e76ec27b5737bce836a5460427b538076f01ef.tar.gz
librambutan-02e76ec27b5737bce836a5460427b538076f01ef.zip
Brought examples/ up to date; PIN_MAP bugfix for D24.
Diffstat (limited to 'examples')
-rw-r--r--examples/blinky.cpp6
-rw-r--r--examples/debug-dtrrts.cpp23
-rw-r--r--examples/qa-slave-shield.cpp45
-rw-r--r--examples/spi_master.cpp7
-rw-r--r--examples/test-bkp.cpp2
-rw-r--r--examples/test-dac.cpp4
-rw-r--r--examples/test-fsmc.cpp22
-rw-r--r--examples/test-serial-flush.cpp18
-rw-r--r--examples/test-serialusb.cpp74
-rw-r--r--examples/test-systick.cpp50
-rw-r--r--examples/test-timers.cpp68
-rw-r--r--examples/vga-leaf.cpp162
-rw-r--r--examples/vga-scope.cpp212
13 files changed, 380 insertions, 313 deletions
diff --git a/examples/blinky.cpp b/examples/blinky.cpp
index 5611987..209a6e6 100644
--- a/examples/blinky.cpp
+++ b/examples/blinky.cpp
@@ -1,4 +1,4 @@
-// Blinks the LED, pin 13
+// Blinks the built-in LED
#include "wirish.h"
@@ -20,8 +20,8 @@ void loop() {
}
// 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() {
+// Otherwise, statically allocated objects that need libmaple may fail.
+__attribute__((constructor)) void premain() {
init();
}
diff --git a/examples/debug-dtrrts.cpp b/examples/debug-dtrrts.cpp
index f9f8b96..61c061a 100644
--- a/examples/debug-dtrrts.cpp
+++ b/examples/debug-dtrrts.cpp
@@ -1,14 +1,12 @@
-// Sample main.cpp file. Blinks an LED, sends a message out USART2
-// and turns on PWM on pin 2
+// Test sketch for figuring out DTR/RTS behavior on different platforms.
#include "wirish.h"
#include "usb.h"
-#define LED_PIN 13
-#define PWM_PIN 2
+#define LED_PIN BOARD_LED_PIN
+#define PWM_PIN 2
-void setup()
-{
+void setup() {
/* Set up the LED to blink */
pinMode(LED_PIN, OUTPUT);
@@ -18,12 +16,10 @@ void setup()
}
-int toggle = 0;
-
void loop() {
- toggle ^= 1;
- digitalWrite(LED_PIN, toggle);
+ toggleLED();
delay(100);
+
Serial2.print("DTR: ");
Serial2.print(usbGetDTR(), DEC);
Serial2.print("\tRTS: ");
@@ -31,13 +27,12 @@ void loop() {
}
// 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() {
+// Otherwise, statically allocated objects 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 b395cca..178b780 100644
--- a/examples/qa-slave-shield.cpp
+++ b/examples/qa-slave-shield.cpp
@@ -1,50 +1,51 @@
-// slave mode for QA shield
+// Slave mode for QA shield
#include "wirish.h"
-#define LED_PIN 13
-#define NUM_GPIO 38 // not the number of the max...
+// FIXME generalize for Maple Native, Maple Mini (NUM_GPIO, Mini USB
+// breakout pins, etc.)
-int i;
+#define LED_PIN BOARD_LED_PIN
+#define NUM_GPIO 38 // Ignore JTAG pins.
-void setup()
-{
+void setup() {
/* Set up the LED to blink */
pinMode(LED_PIN, OUTPUT);
- digitalWrite(LED_PIN, 1);
+ digitalWrite(LED_PIN, HIGH);
- for(i=0; i<NUM_GPIO; i++) {
- if(i==13) { continue; }
+ for(int i = 0; i < NUM_GPIO; i++) {
+ if (i == BOARD_LED_PIN) {
+ continue;
+ }
pinMode(i, OUTPUT);
- digitalWrite(i,0);
+ digitalWrite(i, LOW);
}
- //delay(5000);
SerialUSB.println("OK, starting...");
-
}
void loop() {
- digitalWrite(LED_PIN,1);
+ toggleLED();
delay(100);
- digitalWrite(LED_PIN,0);
+ toggleLED();
- for(i=0; i<NUM_GPIO; i++) {
- if(i==13) { continue; }
- digitalWrite(i,1);
+ for(int i = 0; i < NUM_GPIO; i++) {
+ if (i == BOARD_LED_PIN) {
+ continue;
+ }
+ togglePin(i);
delay(5);
- digitalWrite(i,0);
+ togglePin(i);
delay(5);
}
}
// 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() {
+// Otherwise, statically allocated objects 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 9f6d81b..06cad02 100644
--- a/examples/spi_master.cpp
+++ b/examples/spi_master.cpp
@@ -60,13 +60,12 @@ void loop() {
}
// 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() {
+// Otherwise, statically allocated objects that need libmaple may fail.
+__attribute__((constructor)) void premain() {
init();
}
-int main(void)
-{
+int main(void) {
setup();
while (1) {
diff --git a/examples/test-bkp.cpp b/examples/test-bkp.cpp
index d0aa564..f5957b7 100644
--- a/examples/test-bkp.cpp
+++ b/examples/test-bkp.cpp
@@ -1,4 +1,4 @@
-#include <stdio.h>
+#include <stdio.h> // for snprintf()
#include "wirish.h"
#include "bkp.h"
diff --git a/examples/test-dac.cpp b/examples/test-dac.cpp
index 62f40eb..af98030 100644
--- a/examples/test-dac.cpp
+++ b/examples/test-dac.cpp
@@ -1,8 +1,4 @@
-
#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 f4fd068..4211e4d 100644
--- a/examples/test-fsmc.cpp
+++ b/examples/test-fsmc.cpp
@@ -1,14 +1,12 @@
-
#include "wirish.h"
#include "fsmc.h"
-#define LED_PIN 23 // hack for maple native
-#define DISC_PIN 14 // hack for USB on native
+#define LED_PIN BOARD_LED_PIN
// 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.
+// 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;
@@ -23,15 +21,14 @@ typedef struct {
volatile uint32 SHCRS;
volatile uint32 CFSR;
volatile uint32 HFSR;
- uint32 pad1;
+ uint32 pad1;
volatile uint32 MMAR;
volatile uint32 BFAR;
} SCB_Reg;
-SCB_Reg *scb;
+SCB_Reg *scb;
uint16 *ptr;
-int toggle = 0;
int count = 0;
void setup() {
@@ -39,8 +36,6 @@ void setup() {
scb = (SCB_Reg*)SCB_BASE;
pinMode(LED_PIN, OUTPUT);
- pinMode(DISC_PIN, OUTPUT);
- digitalWrite(DISC_PIN,1);
digitalWrite(LED_PIN,1);
Serial1.begin(9600);
@@ -82,15 +77,14 @@ void setup() {
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 loop() {
- digitalWrite(LED_PIN, toggle);
- toggle ^= 1;
- delay(1);
+ toggleLED();
+ delay(1);
for(int i = 0; i<100; i++) { // modify this to speed things up
count++;
@@ -102,7 +96,7 @@ void loop() {
while(1) { }
}
}
-
+
Serial1.print((uint32)(ptr),HEX);
Serial1.print(": ");
Serial1.println(*ptr,BIN);
diff --git a/examples/test-serial-flush.cpp b/examples/test-serial-flush.cpp
index d7fbf7a..1cd82b6 100644
--- a/examples/test-serial-flush.cpp
+++ b/examples/test-serial-flush.cpp
@@ -2,22 +2,13 @@
#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());
@@ -29,13 +20,12 @@ void loop() {
}
// 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() {
+// Otherwise, statically allocated objects 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 9d0a862..678c2b9 100644
--- a/examples/test-serialusb.cpp
+++ b/examples/test-serialusb.cpp
@@ -1,11 +1,10 @@
-// Sample main.cpp file. Blinks an LED, sends a message out USART2
-// and turns on PWM on pin 2
+// Tests SerialUSB functionality.
#include "wirish.h"
#include "usb.h"
-#define LED_PIN 13
-#define BUT_PIN 38
+#define LED_PIN BOARD_LED_PIN
+#define BUT_PIN BOARD_BUTTON_PIN
uint32 state = 0;
#define QUICKPRINT 0
@@ -14,33 +13,29 @@ 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_PULLUP);
+ pinMode(BUT_PIN, INPUT);
Serial2.begin(9600);
- Serial2.println("Hello world! This is the debug channel.");
-}
+ Serial2.println("This is the debug channel. Press BUT.");
-int toggle = 0;
+ waitForButtonPress(0);
+}
uint8 c1 = '-';
void loop() {
- toggle ^= 1;
- digitalWrite(LED_PIN, toggle);
+ toggleLED();
delay(1000);
- if(digitalRead(BUT_PIN)) {
- while(digitalRead(BUT_PIN)) {};
+ if(isButtonPressed()) {
state++;
}
-
+
switch(state) {
case QUICKPRINT:
for(int i = 0; i<30; i++) {
@@ -48,34 +43,34 @@ void loop() {
SerialUSB.print('.');
SerialUSB.print('|');
}
- Serial2.println(SerialUSB.pending(),DEC);
+ Serial2.println(SerialUSB.pending(), DEC);
SerialUSB.println();
break;
case BIGSTUFF:
- SerialUSB.println("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
- SerialUSB.println((uint32)123456789,DEC);
+ SerialUSB.println("0123456789012345678901234567890123456789"
+ "0123456789012345678901234567890123456789"
+ "012345678901234567890");
+ SerialUSB.println((int64)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(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);
+ 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')");
@@ -92,8 +87,8 @@ void loop() {
SerialUSB.print("hij\n\r");
SerialUSB.write(' ');
SerialUSB.println();
- Serial2.println("Trying println(123456789,DEC)");
- SerialUSB.println(123456789);
+ 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\")");
@@ -103,12 +98,12 @@ void loop() {
Serial2.println("Shutting down...");
SerialUSB.println("Shutting down...");
SerialUSB.end();
- Serial2.println("Waiting 4seconds...");
+ Serial2.println("Waiting 4 seconds...");
delay(4000);
Serial2.println("Starting up...");
SerialUSB.begin();
SerialUSB.println("Hello World!");
- Serial2.println("Waiting 4seconds...");
+ Serial2.println("Waiting 4 seconds...");
delay(4000);
state++;
break;
@@ -118,13 +113,12 @@ void loop() {
}
// 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() {
+// Otherwise, statically allocated objects 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 247892d..c7b5529 100644
--- a/examples/test-systick.cpp
+++ b/examples/test-systick.cpp
@@ -3,54 +3,48 @@
#include "wirish.h"
#include "systick.h"
-#define LED_PIN 13
-#define PWM_PIN 2
-#define BUT 38
+#define LED_PIN BOARD_LED_PIN
+#define PWM_PIN 2
+#define BUT BOARD_BUTTON_PIN
-void setup()
-{
+void setup() {
/* Set up the LED to blink */
pinMode(LED_PIN, OUTPUT);
-
- /* Turn on PWM on pin PWM_PIN */
- pinMode(PWM_PIN, PWM);
- pwmWrite(PWM_PIN, 0x8000);
-
- pinMode(BUT, INPUT_PULLDOWN);
+ pinMode(BUT, INPUT);
}
-int toggle = 0;
+bool disable = true;
long time = 0;
void loop() {
- toggle ^= 1;
- digitalWrite(LED_PIN, toggle);
+ volatile int i = 0;
+ toggleLED();
// An artificial delay
- int16 i = 1;
- float j = 1;
- for(i=0; i<6553; i++) {
- j = sqrt(j) + 1;
- }
-
- if(digitalRead(BUT)) {
- systick_disable();
- } else {
- systick_resume();
+ 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;
}
- //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 ccba251..f3cfdcc 100644
--- a/examples/test-timers.cpp
+++ b/examples/test-timers.cpp
@@ -2,7 +2,7 @@
#include "wirish.h"
-#define LED_PIN 13
+#define LED_PIN BOARD_LED_PIN
void handler1(void);
void handler2(void);
@@ -12,7 +12,6 @@ void handler4(void);
void handler3b(void);
void handler4b(void);
-int toggle = 0;
int t;
int count1 = 0;
@@ -36,25 +35,24 @@ void setup()
pinMode(LED_PIN, OUTPUT);
// Setup the button as input
- pinMode(38, INPUT_PULLUP);
+ pinMode(BOARD_BUTTON_PIN, INPUT);
- /* Send a message out USART2 */
- //SerialUSB.begin(9600);
- SerialUSB.println("Begining timer test...");
+ // Wait for user to attach...
+ waitForButtonPress(0);
+
+ // Send a message out SerialUSB
+ SerialUSB.println("Beginning 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);
@@ -63,7 +61,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);
@@ -80,9 +78,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(digitalRead(38)) {
+ if(isButtonPressed()) {
Timer4.pause();
} else {
Timer4.resume();
@@ -96,14 +94,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);
@@ -114,10 +112,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);
@@ -127,12 +125,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);
@@ -146,9 +144,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);
@@ -159,11 +157,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);
@@ -177,7 +175,7 @@ void loop() {
// that over time the actual timing rates get blown away by other system
// interrupts.
for(t=0; t<4; t++) {
- toggle ^= 1; digitalWrite(LED_PIN, toggle);
+ toggleLED();
delay(100);
SerialUSB.println("-----------------------------------------------------");
SerialUSB.print("Testing Timer "); SerialUSB.println(t+1);
@@ -214,33 +212,39 @@ 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 d1c6d7d..9d9fce2 100644
--- a/examples/vga-leaf.cpp
+++ b/examples/vga-leaf.cpp
@@ -1,21 +1,21 @@
/*
- Crude VGA Output
+ VGA Output
- 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).
+ 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).
- 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.
+ 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:
- D5 via ~200ohms to VGA Red (1)
- D6 via ~200ohms to VGA Green (2)
- D7 via ~200ohms to VGA Blue (3)
+ 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)
@@ -24,48 +24,71 @@
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 13
+#define LED_PIN BOARD_LED_PIN
-// Pinouts
-#define VGA_R 5 // STM32: B6
-#define VGA_G 6 // STM32: A8
-#define VGA_B 7 // STM32: A9
+// 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 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)
+// 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)
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
-uint8 v_active = 1; // Are we in the image?
+uint16 logo_y = 0; // Y coordinate, mapped into valid logo index (for speed)
+bool v_active = true; // Are we in the image?
-// 1-bit!
-uint8 logo[18][16] = {
+const uint8 x_max = 16;
+const uint8 y_max = 18;
+uint32 logo[y_max][x_max] = {
{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,},
@@ -99,9 +122,20 @@ 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();
- SystemTick.end();
+ systick_disable();
// Configure
Timer4.pause(); // while we configure
@@ -120,14 +154,13 @@ 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() {
- toggle ^= 1;
- digitalWrite(LED_PIN, toggle);
+ toggleLED();
delay(100);
// Everything happens in the interrupts!
@@ -139,51 +172,59 @@ 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;
- v_active = 1;
+ if(y >= 523) {
+ y = 1;
+ logo_y = 0;
+ v_active = true;
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 = 0;
+ if(y >= 479) {
+ v_active = false;
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" (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;
- }
+ // 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]);
}
}
// 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;
@@ -194,8 +235,11 @@ void isr_update(void) {
VGA_H_LOW;
}
-int main(void) {
+__attribute__((constructor)) void premain() {
init();
+}
+
+int main(void) {
setup();
while (1) {
diff --git a/examples/vga-scope.cpp b/examples/vga-scope.cpp
index 0265f9c..9c6dca5 100644
--- a/examples/vga-scope.cpp
+++ b/examples/vga-scope.cpp
@@ -1,34 +1,90 @@
-// Low-level, non-wirish demonstration of VGA
-//
-// Connect a microphone or something less to ANALOG_PIN
+/*
+ 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.
+ */
#include "wirish.h"
+#include "systick.h"
+
+// FIXME generalize for Native and Mini
-#define LED_PIN 13
+#define LED_PIN BOARD_LED_PIN
#define ANALOG_PIN 18
-#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)
+
+// 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)
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);
@@ -38,104 +94,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("Video time...");
+ Serial2.println("Time to kill the radio star...");
// This gets rid of the majority of the interrupt artifacts;
- // a SysTick.end() is required as well
+ // 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();
+
digitalWrite(VGA_R, 0);
digitalWrite(VGA_G, 0);
digitalWrite(VGA_B, 0);
- 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);
+ 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);
}
-int toggle = 0;
-uint16 x = 0;
uint16 y = 0;
uint16 val = 0;
-uint8 v_active = 1;
-GPIO_Port *portb = GPIOB_BASE;
+bool v_active = true;
+const uint16 x_max = 60; // empirically (and lazily) determined
void isr_porch(void) {
VGA_H_HIGH;
y++;
- if(y>=523) {
- y=1;
- v_active = 1;
+ val = map(analogRead(ANALOG_PIN), 0, 4095, 0, x_max);
+ if(y >= 523) {
+ y = 1;
+ v_active = true;
return;
}
- if(y>=492) {
+ if(y >= 492) {
VGA_V_HIGH;
return;
}
- if(y>=490) {
+ if(y >= 490) {
VGA_V_LOW;
return;
}
- if(y>=479) { // 479
- v_active = 0;
+ if(y >= 479) {
+ v_active = false;
return;
}
}
void isr_start(void) {
- 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);
-
+ 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);
}
+
void isr_stop(void) {
- if(!v_active) { return; }
- VGA_R_LOW;
- VGA_G_LOW;
- VGA_B_LOW;
+ if (!v_active) {
+ return;
+ }
+ VGA_COLOR(COLOR_BLACK);
}
+
void isr_update(void) {
VGA_H_LOW;
}
void loop() {
- //val = analogRead(ANALOG_PIN);
+ toggleLED();
+ delay(100);
}
+__attribute__((constructor)) void premain() {
+ init();
+}
int main(void) {
- init();
setup();
while (1) {