aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile4
-rw-r--r--examples/blinky.cpp6
-rw-r--r--examples/debug-dtrrts.cpp23
-rw-r--r--examples/qa-slave-shield.cpp64
-rw-r--r--examples/spi_master.cpp7
-rw-r--r--examples/test-dac.cpp4
-rw-r--r--examples/test-fsmc.cpp202
-rw-r--r--examples/test-ring-buffer-insertion.cpp114
-rw-r--r--examples/test-serial-flush.cpp18
-rw-r--r--examples/test-serialusb.cpp74
-rw-r--r--examples/test-session.cpp149
-rw-r--r--examples/test-systick.cpp50
-rw-r--r--examples/test-timers.cpp68
-rw-r--r--examples/vga-leaf.cpp162
-rw-r--r--examples/vga-scope.cpp212
-rw-r--r--libmaple/fsmc.c138
-rw-r--r--libmaple/fsmc.h1
-rw-r--r--libmaple/gpio.c8
-rw-r--r--libmaple/libmaple.h94
-rw-r--r--libmaple/usb/usb_callbacks.c18
-rw-r--r--support/ld/maple_RET6/flash.ld211
-rw-r--r--support/ld/maple_RET6/jtag.ld186
-rw-r--r--support/ld/maple_RET6/ram.ld220
-rw-r--r--wirish/boards.h104
-rw-r--r--wirish/usb_serial.cpp6
26 files changed, 608 insertions, 1536 deletions
diff --git a/.gitignore b/.gitignore
index eab8f74..7e29a09 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,3 @@ TAGS
*.swp
docs/doxygen/
arm
-cscope*
diff --git a/Makefile b/Makefile
index a953088..a709696 100644
--- a/Makefile
+++ b/Makefile
@@ -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 */