diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-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 | ||||
-rw-r--r-- | libmaple/fsmc.c | 138 | ||||
-rw-r--r-- | libmaple/fsmc.h | 1 | ||||
-rw-r--r-- | libmaple/gpio.c | 8 | ||||
-rw-r--r-- | libmaple/libmaple.h | 94 | ||||
-rw-r--r-- | libmaple/usb/usb_callbacks.c | 18 | ||||
-rw-r--r-- | support/ld/maple_RET6/flash.ld | 211 | ||||
-rw-r--r-- | support/ld/maple_RET6/jtag.ld | 186 | ||||
-rw-r--r-- | support/ld/maple_RET6/ram.ld | 220 | ||||
-rw-r--r-- | wirish/boards.h | 104 | ||||
-rw-r--r-- | wirish/usb_serial.cpp | 6 |
26 files changed, 608 insertions, 1536 deletions
@@ -8,4 +8,3 @@ TAGS *.swp docs/doxygen/ arm -cscope* @@ -21,10 +21,6 @@ ifeq ($(BOARD), maple_mini) MCU := STM32F103CB PRODUCT_ID := 0003 endif -ifeq ($(BOARD), maple_RET6) - MCU := STM32F103RE - PRODUCT_ID := 0003 -endif # Useful paths ifeq ($(LIB_MAPLE_HOME),) 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) { diff --git a/libmaple/fsmc.c b/libmaple/fsmc.c index db77ff1..49526f4 100644 --- a/libmaple/fsmc.c +++ b/libmaple/fsmc.c @@ -31,58 +31,10 @@ #include "gpio.h" #include "fsmc.h" -void fsmc_init_gpios(void) { - /* Data lines... */ - gpio_set_mode(GPIOD_BASE, 0, MODE_AF_OUTPUT_PP); /* D2 */ - gpio_set_mode(GPIOD_BASE, 1, MODE_AF_OUTPUT_PP); /* D3 */ - gpio_set_mode(GPIOD_BASE, 8, MODE_AF_OUTPUT_PP); /* D13 */ - gpio_set_mode(GPIOD_BASE, 9, MODE_AF_OUTPUT_PP); /* D14 */ - gpio_set_mode(GPIOD_BASE, 10, MODE_AF_OUTPUT_PP); /* D15 */ - gpio_set_mode(GPIOD_BASE, 14, MODE_AF_OUTPUT_PP); /* D0 */ - gpio_set_mode(GPIOD_BASE, 15, MODE_AF_OUTPUT_PP); /* D1 */ - gpio_set_mode(GPIOE_BASE, 7, MODE_AF_OUTPUT_PP); /* D4 */ - gpio_set_mode(GPIOE_BASE, 8, MODE_AF_OUTPUT_PP); /* D5 */ - gpio_set_mode(GPIOE_BASE, 9, MODE_AF_OUTPUT_PP); /* D6 */ - gpio_set_mode(GPIOE_BASE, 10, MODE_AF_OUTPUT_PP); /* D7 */ - gpio_set_mode(GPIOE_BASE, 11, MODE_AF_OUTPUT_PP); /* D8 */ - gpio_set_mode(GPIOE_BASE, 12, MODE_AF_OUTPUT_PP); /* D9 */ - gpio_set_mode(GPIOE_BASE, 13, MODE_AF_OUTPUT_PP); /* D10 */ - gpio_set_mode(GPIOE_BASE, 14, MODE_AF_OUTPUT_PP); /* D11 */ - gpio_set_mode(GPIOE_BASE, 15, MODE_AF_OUTPUT_PP); /* D12 */ - - /* Address lines... */ - gpio_set_mode(GPIOD_BASE, 11, MODE_AF_OUTPUT_PP); /* A16 */ - gpio_set_mode(GPIOD_BASE, 12, MODE_AF_OUTPUT_PP); /* A17 */ - gpio_set_mode(GPIOD_BASE, 13, MODE_AF_OUTPUT_PP); /* A18 */ - gpio_set_mode(GPIOF_BASE, 0, MODE_AF_OUTPUT_PP); /* A0 */ - gpio_set_mode(GPIOF_BASE, 1, MODE_AF_OUTPUT_PP); /* A1 */ - gpio_set_mode(GPIOF_BASE, 2, MODE_AF_OUTPUT_PP); /* A2 */ - gpio_set_mode(GPIOF_BASE, 3, MODE_AF_OUTPUT_PP); /* A3 */ - gpio_set_mode(GPIOF_BASE, 4, MODE_AF_OUTPUT_PP); /* A4 */ - gpio_set_mode(GPIOF_BASE, 5, MODE_AF_OUTPUT_PP); /* A5 */ - gpio_set_mode(GPIOF_BASE, 12, MODE_AF_OUTPUT_PP); /* A6 */ - gpio_set_mode(GPIOF_BASE, 13, MODE_AF_OUTPUT_PP); /* A7 */ - gpio_set_mode(GPIOF_BASE, 14, MODE_AF_OUTPUT_PP); /* A8 */ - gpio_set_mode(GPIOF_BASE, 15, MODE_AF_OUTPUT_PP); /* A9 */ - gpio_set_mode(GPIOG_BASE, 0, MODE_AF_OUTPUT_PP); /* A10 */ - gpio_set_mode(GPIOG_BASE, 1, MODE_AF_OUTPUT_PP); /* A11 */ - gpio_set_mode(GPIOG_BASE, 2, MODE_AF_OUTPUT_PP); /* A12 */ - gpio_set_mode(GPIOG_BASE, 3, MODE_AF_OUTPUT_PP); /* A13 */ - gpio_set_mode(GPIOG_BASE, 4, MODE_AF_OUTPUT_PP); /* A14 */ - gpio_set_mode(GPIOG_BASE, 5, MODE_AF_OUTPUT_PP); /* A15 */ - - /* And control lines... */ - gpio_set_mode(GPIOD_BASE, 4, MODE_AF_OUTPUT_PP); /* NOE */ - gpio_set_mode(GPIOD_BASE, 5, MODE_AF_OUTPUT_PP); /* NWE */ - - gpio_set_mode(GPIOD_BASE, 7, MODE_AF_OUTPUT_PP); /* NE1 */ - gpio_set_mode(GPIOG_BASE, 9, MODE_AF_OUTPUT_PP); /* NE2 */ - gpio_set_mode(GPIOG_BASE, 10, MODE_AF_OUTPUT_PP); /* NE3 */ - gpio_set_mode(GPIOG_BASE, 12, MODE_AF_OUTPUT_PP); /* NE4 */ - - gpio_set_mode(GPIOE_BASE, 0, MODE_AF_OUTPUT_PP); /* NBL0 */ - gpio_set_mode(GPIOE_BASE, 1, MODE_AF_OUTPUT_PP); /* NBL1 */ -} +/* These values determined for a particular SRAM chip by following the + * calculations in the ST FSMC application note. */ +#define FSMC_ADDSET 0x0 +#define FSMC_DATAST 0x3 /* Sets up the FSMC peripheral to use the SRAM chip on the maple * native as an external segment of system memory space. This @@ -91,8 +43,57 @@ void fsmc_init_gpios(void) { void fsmc_native_sram_init(void) { FSMC_Bank *bank; - /* First set up the GPIO pins */ - fsmc_init_gpios(); + /* First we setup all the GPIO pins. */ + /* Data lines... */ + gpio_set_mode(GPIOD_BASE, 0, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD_BASE, 1, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD_BASE, 8, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD_BASE, 9, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD_BASE, 10, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD_BASE, 14, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD_BASE, 15, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOE_BASE, 7, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOE_BASE, 8, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOE_BASE, 9, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOE_BASE, 10, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOE_BASE, 11, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOE_BASE, 12, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOE_BASE, 13, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOE_BASE, 14, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOE_BASE, 15, MODE_AF_OUTPUT_PP); + + /* Address lines... */ + gpio_set_mode(GPIOD_BASE, 11, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD_BASE, 12, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOD_BASE, 13, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 0, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 1, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 2, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 3, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 4, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 5, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 12, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 13, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 14, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOF_BASE, 15, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOG_BASE, 0, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOG_BASE, 1, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOG_BASE, 2, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOG_BASE, 3, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOG_BASE, 4, MODE_AF_OUTPUT_PP); + gpio_set_mode(GPIOG_BASE, 5, MODE_AF_OUTPUT_PP); + + /* And control lines... */ + gpio_set_mode(GPIOD_BASE, 4, MODE_AF_OUTPUT_PP); // NOE + gpio_set_mode(GPIOD_BASE, 5, MODE_AF_OUTPUT_PP); // NWE + + gpio_set_mode(GPIOD_BASE, 7, MODE_AF_OUTPUT_PP); // NE1 + gpio_set_mode(GPIOG_BASE, 9, MODE_AF_OUTPUT_PP); // NE2 + gpio_set_mode(GPIOG_BASE, 10, MODE_AF_OUTPUT_PP); // NE3 + gpio_set_mode(GPIOG_BASE, 12, MODE_AF_OUTPUT_PP); // NE4 + + gpio_set_mode(GPIOE_BASE, 0, MODE_AF_OUTPUT_PP); // NBL0 + gpio_set_mode(GPIOE_BASE, 1, MODE_AF_OUTPUT_PP); // NBL1 /* Next enable the clock */ rcc_clk_enable(RCC_FSMC); @@ -101,9 +102,32 @@ void fsmc_native_sram_init(void) { * channels are in "Bank 1" of the FSMC) */ bank = (FSMC_Bank*)(FSMC1_BASE); - /* FIXME replace with macros from fsmc.h */ - bank->BCR = (1 << 12) | (1 << 4) | 1; - bank->BTR = (3 << 8); + /* Everything else is cleared (BCR1) */ + bank->BCR = 0x0000; + + /* Memory type is SRAM */ + bank->BCR &= ~(FSMC_BCR_MTYP); // '00' + + /* Databus width is 16bits */ + bank->BCR &= ~(FSMC_BCR_MWID); + bank->BCR |= 0x1 << 4; // '01' + + /* Memory is nonmultiplexed */ + bank->BCR &= ~(FSMC_BCR_MUXEN); // '0' + + /* Need write enable to write to the chip */ + bank->BCR |= FSMC_BCR_WREN; + + /* Set ADDSET */ + bank->BTR &= ~(FSMC_BTR_ADDSET); + bank->BTR |= (FSMC_BTR_ADDSET | FSMC_ADDSET); + + /* Set DATAST */ + bank->BTR &= ~(FSMC_BTR_DATAST); + bank->BTR |= (FSMC_BTR_DATAST | (FSMC_DATAST << 8)); + + /* Enable channel 1 */ + bank->BCR |= FSMC_BCR_MBKEN; // '1' /* (FSMC_BWTR3 not used for this simple configuration.) */ } diff --git a/libmaple/fsmc.h b/libmaple/fsmc.h index 7be1968..e83b529 100644 --- a/libmaple/fsmc.h +++ b/libmaple/fsmc.h @@ -80,7 +80,6 @@ typedef struct { #define FSMC_BWTR_DATLAT 0b00001111000000000000000000000000 #define FSMC_BWTR_ACCMOD 0b00110000000000000000000000000000 -void fsmc_init_gpios(void); void fsmc_native_sram_init(void); #ifdef __cplusplus diff --git a/libmaple/gpio.c b/libmaple/gpio.c index 0ebc130..71e5230 100644 --- a/libmaple/gpio.c +++ b/libmaple/gpio.c @@ -34,13 +34,9 @@ void gpio_init(void) { rcc_clk_enable(RCC_GPIOA); rcc_clk_enable(RCC_GPIOB); rcc_clk_enable(RCC_GPIOC); -#if NR_GPIO_PORTS >= 4 - /* Maple, but not Maple Mini (D0 and D1 are used for OSC on Mini, - and those are the only Port D pins). */ +#if NR_GPIO_PORTS >= 4 /* Maple, but not Maple Mini */ rcc_clk_enable(RCC_GPIOD); -#endif -#if NR_GPIO_PORTS >= 7 - /* Maple Native (high density only) */ +#elif NR_GPIO_PORTS >= 7 /* Maple Native (high density only) */ rcc_clk_enable(RCC_GPIOE); rcc_clk_enable(RCC_GPIOF); rcc_clk_enable(RCC_GPIOG); diff --git a/libmaple/libmaple.h b/libmaple/libmaple.h index f893cff..02e27d3 100644 --- a/libmaple/libmaple.h +++ b/libmaple/libmaple.h @@ -42,20 +42,6 @@ #define DEBUG_LEVEL DEBUG_ALL #endif -/* Bitbanded Memory sections */ -#define BITBAND_SRAM_REF 0x20000000 -#define BITBAND_SRAM_BASE 0x22000000 -#define BITBAND_PERI_REF 0x40000000 -#define BITBAND_PERI_BASE 0x42000000 - -#define USB_CONFIG_MAX_POWER (100 >> 1) -#define RESET_DELAY (100) - -#define ERROR_USART_NUM USART2 -#define ERROR_USART_BAUD 9600 -#define ERROR_TX_PORT GPIOA_BASE -#define ERROR_TX_PIN 2 - /* MCU-specific configuration */ #if defined(MCU_STM32F103RB) /* e.g., LeafLabs Maple */ @@ -88,21 +74,39 @@ #define VCOM_ID_PRODUCT 0x0004 #define USB_DISC_BANK GPIOC_BASE #define USB_DISC_PIN 12 + #define USB_CONFIG_MAX_POWER (100 >> 1) + #define RESET_DELAY (100) /* Where to put usercode (based on space reserved for bootloader) */ #define USER_ADDR_ROM 0x08005000 #define USER_ADDR_RAM 0x20000C00 - #define STACK_TOP 0x20000800 /* FIXME can this possibly be correct? */ + #define STACK_TOP 0x20000800 + /* Debug port settings (from ASSERT) */ #define ERROR_LED_PORT GPIOB_BASE #define ERROR_LED_PIN 12 + #define ERROR_USART_NUM USART2 + #define ERROR_USART_BAUD 9600 + #define ERROR_TX_PORT GPIOA_BASE + #define ERROR_TX_PIN 2 + + /* Just in case, most boards have at least some memory */ + #ifndef RAMSIZE + # define RAMSIZE (caddr_t)0x50000 + #endif + + /* Bitbanded Memory sections */ + #define BITBAND_SRAM_REF 0x20000000 + #define BITBAND_SRAM_BASE 0x22000000 + #define BITBAND_PERI_REF 0x40000000 + #define BITBAND_PERI_BASE 0x42000000 #elif defined(MCU_STM32F103ZE) /* e.g., LeafLabs Maple Native */ #define NR_GPIO_PORTS 7 #define NR_GPIO_PINS 100 - #define NR_BKP_REGS 42 + #define NR_BKP_REGS 42 /* TODO test on Native */ #define NR_TIMERS 8 #define NR_USART 5 /* NB: 4 and 5 are UART only */ #define NR_FSMC 1 @@ -112,6 +116,8 @@ #define VCOM_ID_PRODUCT 0x0004 #define USB_DISC_BANK GPIOB_BASE #define USB_DISC_PIN 8 + #define USB_CONFIG_MAX_POWER (100 >> 1) + #define RESET_DELAY (100) #define USER_ADDR_ROM 0x08005000 #define USER_ADDR_RAM 0x20000C00 @@ -119,13 +125,26 @@ #define ERROR_LED_PORT GPIOC_BASE #define ERROR_LED_PIN 15 + #define ERROR_USART_NUM USART1 + #define ERROR_USART_BAUD 9600 + #define ERROR_TX_PORT GPIOA_BASE + #define ERROR_TX_PIN 10 + + #ifndef RAMSIZE + # define RAMSIZE (caddr_t)0x50000 + #endif + + #define BITBAND_SRAM_REF 0x20000000 + #define BITBAND_SRAM_BASE 0x22000000 + #define BITBAND_PERI_REF 0x40000000 + #define BITBAND_PERI_BASE 0x42000000 #elif defined(MCU_STM32F103CB) /* e.g., LeafLabs Maple Mini */ #define NR_GPIO_PORTS 3 #define NR_GPIO_PINS 34 - #define NR_BKP_REGS 10 + #define NR_BKP_REGS 10 /* TODO test on Mini */ #define NR_TIMERS 4 #define NR_USART 3 #define NR_FSMC 0 @@ -135,36 +154,29 @@ #define VCOM_ID_PRODUCT 0x0005 #define USB_DISC_BANK GPIOB_BASE #define USB_DISC_PIN 9 + #define USB_CONFIG_MAX_POWER (100 >> 1) + #define RESET_DELAY 100 #define USER_ADDR_ROM 0x08005000 #define USER_ADDR_RAM 0x20000C00 #define STACK_TOP 0x20000800 #define ERROR_LED_PORT GPIOB_BASE - #define ERROR_LED_PIN 1 - -#elif defined(MCU_STM32F103RE) - /* e.g., LeafLabs Maple RET6 Edition */ - - #define NR_GPIO_PORTS 4 - #define NR_GPIO_PINS 39 - #define NR_BKP_REGS 42 - #define NR_TIMERS 8 - #define NR_USART 5 /* NB: 4 and 5 are UART only */ - #define NR_FSMC 0 - #define NR_DAC_PINS 0 /* HACK: LED hooked up to DAC2 */ - - #define VCOM_ID_VENDOR 0x1EAF - #define VCOM_ID_PRODUCT 0x0004 - #define USB_DISC_BANK GPIOC_BASE - #define USB_DISC_PIN 12 - - #define USER_ADDR_ROM 0x08005000 - #define USER_ADDR_RAM 0x20000C00 - #define STACK_TOP 0x20000800 - - #define ERROR_LED_PORT GPIOA_BASE - #define ERROR_LED_PIN 5 + #define ERROR_LED_PIN 12 + #define ERROR_USART_NUM USART2 + #define ERROR_USART_BAUD 9600 + #define ERROR_TX_PORT GPIOA_BASE + #define ERROR_TX_PIN 2 + + #ifndef RAMSIZE + # define RAMSIZE (caddr_t)0x50000 + #endif + + /* Bitbanded Memory sections */ + #define BITBAND_SRAM_REF 0x20000000 + #define BITBAND_SRAM_BASE 0x22000000 + #define BITBAND_PERI_REF 0x40000000 + #define BITBAND_PERI_BASE 0x42000000 #else diff --git a/libmaple/usb/usb_callbacks.c b/libmaple/usb/usb_callbacks.c index 375d204..ccb0fdd 100644 --- a/libmaple/usb/usb_callbacks.c +++ b/libmaple/usb/usb_callbacks.c @@ -88,19 +88,19 @@ void vcomDataRxCb(void) { } if (cmpMatch) { - asm volatile("mov r0, %[stack_top] \n\t" // Reset the stack + asm volatile("mov r0, %[stack_top] \n\t" // Reset the stack "mov sp, r0 \n\t" "mov r0, #1 \n\t" "mov r1, %[target_addr] \n\t" "mov r2, %[cpsr] \n\t" - "push {r2} \n\t" // Fake xPSR - "push {r1} \n\t" // Target address for PC - "push {r0} \n\t" // Fake LR - "push {r0} \n\t" // Fake R12 - "push {r0} \n\t" // Fake R3 - "push {r0} \n\t" // Fake R2 - "push {r0} \n\t" // Fake R1 - "push {r0} \n\t" // Fake R0 + "push {r2} \n\t" // Fake xPSR + "push {r1} \n\t" // Target address for PC + "push {r0} \n\t" // Fake LR + "push {r0} \n\t" // Fake R12 + "push {r0} \n\t" // Fake R3 + "push {r0} \n\t" // Fake R2 + "push {r0} \n\t" // Fake R1 + "push {r0} \n\t" // Fake R0 "mov lr, %[exc_return] \n\t" "bx lr" : diff --git a/support/ld/maple_RET6/flash.ld b/support/ld/maple_RET6/flash.ld deleted file mode 100644 index 4e820d2..0000000 --- a/support/ld/maple_RET6/flash.ld +++ /dev/null @@ -1,211 +0,0 @@ -/* Linker script for STM32 (by Lanchon with Mods by LeafLabs)
- *
- * Version:Sourcery G++ 4.2-84
- * BugURL:https://support.codesourcery.com/GNUToolchain/
- *
- * Copyright 2007 CodeSourcery.
- *
- * The authors hereby grant permission to use, copy, modify, distribute,
- * and license this software and its documentation for any purpose, provided
- * that existing copyright notices are retained in all copies and that this
- * notice is included verbatim in any distributions. No written agreement,
- * license, or royalty fee is required for any of the authorized uses.
- * Modifications to this software may be copyrighted by their authors
- * and need not follow the licensing terms described here, provided that
- * the new terms are clearly indicated on the first page of each file where
- * they apply. */
-
-/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
-
-/* Define memory spaces. */
-MEMORY
-{
- ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
- rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K
-}
-
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
- */
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
- *(.rom)
- *(.rom.b)
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.ARM.extab* .gnu.linkonce.armextab.*)
- *(.gcc_except_table)
- *(.eh_frame_hdr)
- *(.eh_frame)
-
- . = ALIGN(4);
- KEEP(*(.init))
-
- . = ALIGN(4);
- __preinit_array_start = .;
- KEEP (*(.preinit_array))
- __preinit_array_end = .;
-
- . = ALIGN(4);
- __init_array_start = .;
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- __init_array_end = .;
-
- . = ALIGN(0x4);
- KEEP (*crtbegin.o(.ctors))
- KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*crtend.o(.ctors))
-
- . = ALIGN(4);
- KEEP(*(.fini))
-
- . = ALIGN(4);
- __fini_array_start = .;
- KEEP (*(.fini_array))
- KEEP (*(SORT(.fini_array.*)))
- __fini_array_end = .;
-
- KEEP (*crtbegin.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*crtend.o(.dtors))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >rom
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >rom
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >rom
-
-/* expose a custom rom only section */
- .USER_FLASH :
- {
- *(.USER_FLASH)
- } >rom
-
-
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(rom);
- __cs3_region_size_rom = LENGTH(rom);
- __cs3_region_num = 1;
-
- .data :
- {
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram AT>rom
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram AT>rom
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.data);
- __cs3_region_init_size_ram = _edata - ADDR (.data);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .stab 0 (NOLOAD) : { *(.stab) }
- .stabstr 0 (NOLOAD) : { *(.stabstr) }
- /* DWARF debug sections.
- * Symbols in the DWARF debugging sections are relative to the beginning
- * of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-
- .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
- .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
diff --git a/support/ld/maple_RET6/jtag.ld b/support/ld/maple_RET6/jtag.ld deleted file mode 100644 index 90a0a3f..0000000 --- a/support/ld/maple_RET6/jtag.ld +++ /dev/null @@ -1,186 +0,0 @@ -/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
-
-/* Define memory spaces. */
-MEMORY
-{
- ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
- rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
-}
-
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
- */
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
- *(.rom)
- *(.rom.b)
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.ARM.extab* .gnu.linkonce.armextab.*)
- *(.gcc_except_table)
- *(.eh_frame_hdr)
- *(.eh_frame)
-
- . = ALIGN(4);
- KEEP(*(.init))
-
- . = ALIGN(4);
- __preinit_array_start = .;
- KEEP (*(.preinit_array))
- __preinit_array_end = .;
-
- . = ALIGN(4);
- __init_array_start = .;
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- __init_array_end = .;
-
- . = ALIGN(0x4);
- KEEP (*crtbegin.o(.ctors))
- KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*crtend.o(.ctors))
-
- . = ALIGN(4);
- KEEP(*(.fini))
-
- . = ALIGN(4);
- __fini_array_start = .;
- KEEP (*(.fini_array))
- KEEP (*(SORT(.fini_array.*)))
- __fini_array_end = .;
-
- KEEP (*crtbegin.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*crtend.o(.dtors))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >rom
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >rom
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >rom
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(rom);
- __cs3_region_size_rom = LENGTH(rom);
- __cs3_region_num = 1;
-
- .data :
- {
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram AT>rom
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram AT>rom
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.data);
- __cs3_region_init_size_ram = _edata - ADDR (.data);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .stab 0 (NOLOAD) : { *(.stab) }
- .stabstr 0 (NOLOAD) : { *(.stabstr) }
- /* DWARF debug sections.
- * Symbols in the DWARF debugging sections are relative to the beginning
- * of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-
- .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
- .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
diff --git a/support/ld/maple_RET6/ram.ld b/support/ld/maple_RET6/ram.ld deleted file mode 100644 index a5e1482..0000000 --- a/support/ld/maple_RET6/ram.ld +++ /dev/null @@ -1,220 +0,0 @@ -/* Linker script for STM32 (by Lanchon with Mods by LeafLabs)
- *
- * Version:Sourcery G++ 4.2-84
- * BugURL:https://support.codesourcery.com/GNUToolchain/
- *
- * Copyright 2007 CodeSourcery.
- *
- * The authors hereby grant permission to use, copy, modify, distribute,
- * and license this software and its documentation for any purpose, provided
- * that existing copyright notices are retained in all copies and that this
- * notice is included verbatim in any distributions. No written agreement,
- * license, or royalty fee is required for any of the authorized uses.
- * Modifications to this software may be copyrighted by their authors
- * and need not follow the licensing terms described here, provided that
- * the new terms are clearly indicated on the first page of each file where
- * they apply. */
-
-/* Linker script for STM32 (by Lanchon),
- * ROM and RAM relocated to their positions
- * as placed by Maple bootloader
- *
- * Configure target memory and included script
- * according to your application requirements. */
-
-/* Define memory spaces. */
-MEMORY
-{
- ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
- rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
-}
-
-
-OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
-ENTRY(_start)
-SEARCH_DIR(.)
-/* GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3-lanchon-stm32) */
-GROUP(libgcc.a libc.a libm.a libcs3-lanchon-stm32.a)
-
-/* These force the linker to search for particular symbols from
- * the start of the link process and thus ensure the user's
- * overrides are picked up
- */
-EXTERN(__cs3_reset_lanchon_stm32)
-INCLUDE names.inc
-EXTERN(__cs3_interrupt_vector_lanchon_stm32)
-EXTERN(__cs3_start_c main __cs3_stack __cs3_heap_end)
-EXTERN(_start)
-
-PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
-PROVIDE(__cs3_heap_start = _end);
-PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);
-
-SECTIONS
-{
- .text :
- {
- CREATE_OBJECT_SYMBOLS
- __cs3_region_start_ram = .;
- *(.cs3.region-head.ram)
- __cs3_interrupt_vector = __cs3_interrupt_vector_lanchon_stm32;
- *(.cs3.interrupt_vector)
- /* Make sure we pulled in an interrupt vector. */
- ASSERT (. != __cs3_interrupt_vector_lanchon_stm32, "No interrupt vector");
-
- PROVIDE(__cs3_reset_lanchon_stm32 = _start);
- __cs3_reset = __cs3_reset_lanchon_stm32;
- *(.cs3.reset)
-
- *(.text .text.* .gnu.linkonce.t.*)
- *(.plt)
- *(.gnu.warning)
- *(.glue_7t) *(.glue_7) *(.vfp11_veneer)
-
- *(.rodata .rodata.* .gnu.linkonce.r.*)
-
- *(.ARM.extab* .gnu.linkonce.armextab.*)
- *(.gcc_except_table)
- *(.eh_frame_hdr)
- *(.eh_frame)
-
- . = ALIGN(4);
- KEEP(*(.init))
-
- . = ALIGN(4);
- __preinit_array_start = .;
- KEEP (*(.preinit_array))
- __preinit_array_end = .;
-
- . = ALIGN(4);
- __init_array_start = .;
- KEEP (*(SORT(.init_array.*)))
- KEEP (*(.init_array))
- __init_array_end = .;
-
- . = ALIGN(0x4);
- KEEP (*crtbegin.o(.ctors))
- KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
- KEEP (*(SORT(.ctors.*)))
- KEEP (*crtend.o(.ctors))
-
- . = ALIGN(4);
- KEEP(*(.fini))
-
- . = ALIGN(4);
- __fini_array_start = .;
- KEEP (*(.fini_array))
- KEEP (*(SORT(.fini_array.*)))
- __fini_array_end = .;
-
- KEEP (*crtbegin.o(.dtors))
- KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
- KEEP (*(SORT(.dtors.*)))
- KEEP (*crtend.o(.dtors))
-
- . = ALIGN(4);
- __cs3_regions = .;
- LONG (0)
- LONG (__cs3_region_init_ram)
- LONG (__cs3_region_start_ram)
- LONG (__cs3_region_init_size_ram)
- LONG (__cs3_region_zero_size_ram)
- } >ram
-
- /* .ARM.exidx is sorted, so has to go in its own output section. */
- /* even cs3.rom is in ram since its running as user code under the Maple
- bootloader */
- __exidx_start = .;
- .ARM.exidx :
- {
- *(.ARM.exidx* .gnu.linkonce.armexidx.*)
- } >ram
- __exidx_end = .;
- .text.align :
- {
- . = ALIGN(8);
- _etext = .;
- } >ram
-
- .cs3.rom :
- {
- __cs3_region_start_rom = .;
- *(.cs3.region-head.rom)
- *(.rom)
- . = ALIGN (8);
- } >ram
-
- .cs3.rom.bss :
- {
- *(.rom.b)
- . = ALIGN (8);
- } >ram
- /* __cs3_region_end_rom is deprecated */
- __cs3_region_end_rom = __cs3_region_start_rom + LENGTH(ram);
- __cs3_region_size_rom = LENGTH(ram);
- __cs3_region_init_rom = LOADADDR (.cs3.rom);
- __cs3_region_init_size_rom = SIZEOF(.cs3.rom);
- __cs3_region_zero_size_rom = SIZEOF(.cs3.rom.bss);
-
- .data :
- {
-
- KEEP(*(.jcr))
- *(.got.plt) *(.got)
- *(.shdata)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.ram)
- . = ALIGN (8);
- _edata = .;
- } >ram
- .bss :
- {
- *(.shbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- *(.ram.b)
- . = ALIGN (8);
- _end = .;
- __end = .;
- } >ram
- /* __cs3_region_end_ram is deprecated */
- __cs3_region_end_ram = __cs3_region_start_ram + LENGTH(ram);
- __cs3_region_size_ram = LENGTH(ram);
- __cs3_region_init_ram = LOADADDR (.text);
- __cs3_region_init_size_ram = _edata - ADDR (.text);
- __cs3_region_zero_size_ram = _end - _edata;
- __cs3_region_num = 1;
-
- .stab 0 (NOLOAD) : { *(.stab) }
- .stabstr 0 (NOLOAD) : { *(.stabstr) }
- /* DWARF debug sections.
- * Symbols in the DWARF debugging sections are relative to the beginning
- * of the section so we begin them at 0. */
- /* DWARF 1 */
- .debug 0 : { *(.debug) }
- .line 0 : { *(.line) }
- /* GNU DWARF 1 extensions */
- .debug_srcinfo 0 : { *(.debug_srcinfo) }
- .debug_sfnames 0 : { *(.debug_sfnames) }
- /* DWARF 1.1 and DWARF 2 */
- .debug_aranges 0 : { *(.debug_aranges) }
- .debug_pubnames 0 : { *(.debug_pubnames) }
- /* DWARF 2 */
- .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
- .debug_abbrev 0 : { *(.debug_abbrev) }
- .debug_line 0 : { *(.debug_line) }
- .debug_frame 0 : { *(.debug_frame) }
- .debug_str 0 : { *(.debug_str) }
- .debug_loc 0 : { *(.debug_loc) }
- .debug_macinfo 0 : { *(.debug_macinfo) }
- /* SGI/MIPS DWARF 2 extensions */
- .debug_weaknames 0 : { *(.debug_weaknames) }
- .debug_funcnames 0 : { *(.debug_funcnames) }
- .debug_typenames 0 : { *(.debug_typenames) }
- .debug_varnames 0 : { *(.debug_varnames) }
-
- .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
- .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
- /DISCARD/ : { *(.note.GNU-stack) }
-}
-
diff --git a/wirish/boards.h b/wirish/boards.h index 98c58ef..f8505ab 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, TIMER4, 4}, + {GPIOB_BASE, 9, ADC_INVALID, TIMER4_CH4_CCR, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, /* D25/PD2 */ {GPIOD_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, /* D26/PC10 */ @@ -480,108 +480,6 @@ typedef struct PinMapping { *AFIO_MAPR = (*AFIO_MAPR | BIT(26)) & ~(BIT(25) | BIT(24)); \ } while (0) -#elif defined(BOARD_maple_RET6) - - // Just like Maple, except PC6 -- PC9 have Timer 8 capture/compare - // channels 1 -- 4 hooked up (which makes PC9 an unfortunate - // choice for the button). - - #define CYCLES_PER_MICROSECOND 72 - #define SYSTICK_RELOAD_VAL 71999 /* takes a cycle to reload */ - - #define BOARD_BUTTON_PIN 38 - #define BOARD_LED_PIN 13 - - static __attribute__ ((unused)) PinMapping PIN_MAP[NR_GPIO_PINS] = { - /* D0/PA3 */ - {GPIOA_BASE, 3, ADC3, TIMER2_CH4_CCR, EXTI_CONFIG_PORTA, TIMER2, 4}, - /* D1/PA2 */ - {GPIOA_BASE, 2, ADC2, TIMER2_CH3_CCR, EXTI_CONFIG_PORTA, TIMER2, 3}, - /* D2/PA0 */ - {GPIOA_BASE, 0, ADC0, TIMER2_CH1_CCR, EXTI_CONFIG_PORTA, TIMER2, 1}, - /* D3/PA1 */ - {GPIOA_BASE, 1, ADC1, TIMER2_CH2_CCR, EXTI_CONFIG_PORTA, TIMER2, 2}, - /* D4/PB5 */ - {GPIOB_BASE, 5, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D5/PB6 */ - {GPIOB_BASE, 6, ADC_INVALID, TIMER4_CH1_CCR, EXTI_CONFIG_PORTB, TIMER4, 1}, - /* D6/PA8 */ - {GPIOA_BASE, 8, ADC_INVALID, TIMER1_CH1_CCR, EXTI_CONFIG_PORTA, TIMER1, 1}, - /* D7/PA9 */ - {GPIOA_BASE, 9, ADC_INVALID, TIMER1_CH2_CCR, EXTI_CONFIG_PORTA, TIMER1, 2}, - /* D8/PA10 */ - {GPIOA_BASE, 10, ADC_INVALID, TIMER1_CH3_CCR, EXTI_CONFIG_PORTA, TIMER1, 3}, - /* D9/PB7 */ - {GPIOB_BASE, 7, ADC_INVALID, TIMER4_CH2_CCR, EXTI_CONFIG_PORTB, TIMER4, 2}, - /* D10/PA4 */ - {GPIOA_BASE, 4, ADC4, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D11/PA7 */ - {GPIOA_BASE, 7, ADC7, TIMER3_CH2_CCR, EXTI_CONFIG_PORTA, TIMER3, 2}, - /* D12/PA6 */ - {GPIOA_BASE, 6, ADC6, TIMER3_CH1_CCR, EXTI_CONFIG_PORTA, TIMER3, 1}, - /* D13/PA5 */ - {GPIOA_BASE, 5, ADC5, 0, EXTI_CONFIG_PORTA, TIMER_INVALID, TIMER_INVALID}, - /* D14/PB8 */ - {GPIOB_BASE, 8, ADC_INVALID, TIMER4_CH3_CCR, EXTI_CONFIG_PORTB, TIMER4, 3}, - - /* Little header */ - - /* D15/PC0 */ - {GPIOC_BASE, 0, ADC10, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D16/PC1 */ - {GPIOC_BASE, 1, ADC11, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D17/PC2 */ - {GPIOC_BASE, 2, ADC12, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D18/PC3 */ - {GPIOC_BASE, 3, ADC13, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D19/PC4 */ - {GPIOC_BASE, 4, ADC14, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D20/PC5 */ - {GPIOC_BASE, 5, ADC15, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - - /* External header */ - - /* D21/PC13 */ - {GPIOC_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D22/PC14 */ - {GPIOC_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* 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, TIMER4, 4}, - /* D25/PD2 */ - {GPIOD_BASE, 2, ADC_INVALID, 0, EXTI_CONFIG_PORTD, TIMER_INVALID, TIMER_INVALID}, - /* D26/PC10 */ - {GPIOC_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTC, TIMER_INVALID, TIMER_INVALID}, - /* D27/PB0 */ - {GPIOB_BASE, 0, ADC8, TIMER3_CH3_CCR, EXTI_CONFIG_PORTB, TIMER3, 3}, - /* D28/PB1 */ - {GPIOB_BASE, 1, ADC9, TIMER3_CH4_CCR, EXTI_CONFIG_PORTB, TIMER3, 4}, - /* D29/PB10 */ - {GPIOB_BASE, 10, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D30/PB11 */ - {GPIOB_BASE, 11, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D31/PB12 */ - {GPIOB_BASE, 12, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D32/PB13 */ - {GPIOB_BASE, 13, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D33/PB14 */ - {GPIOB_BASE, 14, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D34/PB15 */ - {GPIOB_BASE, 15, ADC_INVALID, 0, EXTI_CONFIG_PORTB, TIMER_INVALID, TIMER_INVALID}, - /* D35/PC6 */ - {GPIOC_BASE, 6, ADC_INVALID, TIMER8_CH1_CCR, EXTI_CONFIG_PORTC, TIMER8, 1}, - /* D36/PC7 */ - {GPIOC_BASE, 7, ADC_INVALID, TIMER8_CH2_CCR, EXTI_CONFIG_PORTC, TIMER8, 2}, - /* D37/PC8 */ - {GPIOC_BASE, 8, ADC_INVALID, TIMER8_CH3_CCR, EXTI_CONFIG_PORTC, TIMER8, 3}, - /* D38/PC9 (BUT) */ - {GPIOC_BASE, 9, ADC_INVALID, TIMER8_CH4_CCR, EXTI_CONFIG_PORTC, TIMER8, 4} - }; - - #define BOARD_INIT do { \ - } while(0) - #else #error "Board type has not been selected correctly." diff --git a/wirish/usb_serial.cpp b/wirish/usb_serial.cpp index e2751a2..e2cdee3 100644 --- a/wirish/usb_serial.cpp +++ b/wirish/usb_serial.cpp @@ -103,18 +103,18 @@ uint32 USBSerial::available(void) { /* blocks forever until len_bytes is received */ uint32 USBSerial::read(void *buf, uint32 len) { - if (buf == 0) { + if (!buf) { return 0; } uint32 bytes_in = 0; while (len > 0) { - uint32 new_bytes = usbReceiveBytes((uint8*)buf + bytes_in, len); + uint32 new_bytes = usbReceiveBytes((uint8*)((uint8*)buf+bytes_in), len); len -= new_bytes; bytes_in += new_bytes; } - return bytes_in; + return len; } /* blocks forever until 1 byte is received */ |