diff options
-rw-r--r-- | examples/blinky.cpp | 6 | ||||
-rw-r--r-- | examples/debug-dtrrts.cpp | 23 | ||||
-rw-r--r-- | examples/qa-slave-shield.cpp | 66 | ||||
-rw-r--r-- | examples/spi_master.cpp | 7 | ||||
-rw-r--r-- | examples/test-dac.cpp | 4 | ||||
-rw-r--r-- | examples/test-serial-flush.cpp | 18 | ||||
-rw-r--r-- | examples/test-serialusb.cpp | 74 | ||||
-rw-r--r-- | examples/test-session.cpp | 137 | ||||
-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 | ||||
-rw-r--r-- | wirish/boards.h | 2 |
13 files changed, 474 insertions, 355 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..5ca451d 100644 --- a/examples/qa-slave-shield.cpp +++ b/examples/qa-slave-shield.cpp @@ -1,50 +1,72 @@ -// 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... +#define LED_PIN BOARD_LED_PIN -int i; +#if defined(BOARD_maple) || defined(BOARD_maple_RET6) +const uint8 pins_to_skip[] = {LED_PIN}; -void setup() -{ +#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() { /* 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 < NR_GPIO_PINS; i++) { + if (skip_pin_p(i)) { + 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 < NR_GPIO_PINS; i++) { + if (skip_pin_p(i)) { + continue; + } + togglePin(i); delay(5); - digitalWrite(i,0); + togglePin(i); 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 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-dac.cpp b/examples/test-dac.cpp index 3a699e2..6f08b05 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-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-session.cpp b/examples/test-session.cpp index 7601fab..cf1f4ec 100644 --- a/examples/test-session.cpp +++ b/examples/test-session.cpp @@ -20,27 +20,43 @@ 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, - /* the following are on ADC3, which lacks support: - 39, 40, 41, 42, 43, 45, */ - 46, 47, 48, 49, 50, 51, 52, 53, 54}; +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}; #else -#error "Board type has not been selected correctly" - +#error "Board type has not been selected correctly." #endif uint8 gpio_state[NR_GPIO_PINS]; @@ -62,6 +78,7 @@ 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); @@ -79,10 +96,10 @@ 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(" |_|"); COMM.println(" by leaflabs"); COMM.println(""); @@ -274,7 +291,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 Serial2!)"); + COMM.println("\t+: test shield mode (for QA; will disrupt USARTS)"); COMM.println("Unimplemented:"); COMM.println("\te: do everything all at once until new input"); @@ -294,11 +311,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? @@ -313,7 +330,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]); } @@ -322,21 +339,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); } } } @@ -408,12 +425,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"); @@ -424,7 +441,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); } } @@ -434,7 +451,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("..."); @@ -446,13 +463,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(""); @@ -466,32 +483,33 @@ 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..."); + COMM.println("Waiting to start; press a key."); while(digitalRead(0) != 1 && !COMM.available()) { continue; } - for(int i=0; i<38; i++) { - if(i == BOARD_LED_PIN) { - COMM.println("Not checking LED"); + for(int i = 0; i < NR_GPIO_PINS; i++) { + if(skip_pin_p(i)) { + COMM.print("Not checking pin "); + COMM.println(i); continue; } - COMM.print("Checking D"); - COMM.print(i,DEC); + COMM.print("Checking pin ") + COMM.print(i, DEC); while(digitalRead(i) == 0) continue; - for(int j=0; j<NR_GPIO_PINS; j++) { - 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(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; @@ -499,18 +517,26 @@ 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.println("..."); @@ -527,15 +553,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); } } @@ -546,7 +572,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("..."); @@ -563,19 +589,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); } } @@ -586,7 +612,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); } @@ -597,12 +623,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); @@ -626,13 +652,12 @@ void init_all_timers(uint16 prescale) { // 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) { diff --git a/wirish/boards.h b/wirish/boards.h index f8505ab..ecb5f69 100644 --- a/wirish/boards.h +++ b/wirish/boards.h @@ -134,7 +134,7 @@ typedef struct PinMapping { /* D23/PC15 */ {GPIOC_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, /* D24/PB9 */ - {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER4, 4}, /* D25/PD2 */ {GPIOD_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D26/PC10 */ |