aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2010-07-19 00:24:31 -0400
committerbnewbold <bnewbold@robocracy.org>2010-07-19 00:38:36 -0400
commit52cbd2f1a1557002f46355e0095400a09c267ff9 (patch)
treeb2d8a95eb2cb2ac0c081fc0459a495baa75319c8
parent7ae1ce63259ef440bc13d7493e9dcee43df83591 (diff)
downloadlibrambutan-52cbd2f1a1557002f46355e0095400a09c267ff9.tar.gz
librambutan-52cbd2f1a1557002f46355e0095400a09c267ff9.zip
working serialUSB with timeout
as a temporary workaround for the fact that SerialUSB is often blocking, this crude implementation makes the low-level C usbSendBytes function non-blocking (with a return code of bytes sent) and implements a 2ms timeout in the wirish write() function. also adds begin(), end(), getDTR(), getRTS(), pending(). device is still initialized the old fashioned way during init() so that, eg, autoreset will work. includes a simple multi-test program.
-rw-r--r--examples/test-serialusb.cpp135
-rw-r--r--libmaple/usb/usb.c6
-rw-r--r--libmaple/usb/usb.h1
-rw-r--r--notes/usb.txt2
-rw-r--r--wirish/usb_serial.cpp43
-rw-r--r--wirish/usb_serial.h7
6 files changed, 189 insertions, 5 deletions
diff --git a/examples/test-serialusb.cpp b/examples/test-serialusb.cpp
new file mode 100644
index 0000000..9d0a862
--- /dev/null
+++ b/examples/test-serialusb.cpp
@@ -0,0 +1,135 @@
+// 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 13
+#define BUT_PIN 38
+
+uint32 state = 0;
+#define QUICKPRINT 0
+#define BIGSTUFF 1
+#define NUMBERS 2
+#define SIMPLE 3
+#define ONOFF 4
+
+
+void setup()
+{
+ /* Set up the LED to blink */
+ pinMode(LED_PIN, OUTPUT);
+
+ /* Set up the Button */
+ pinMode(BUT_PIN, INPUT_PULLUP);
+
+ Serial2.begin(9600);
+ Serial2.println("Hello world! This is the debug channel.");
+}
+
+int toggle = 0;
+
+uint8 c1 = '-';
+
+void loop() {
+ toggle ^= 1;
+ digitalWrite(LED_PIN, toggle);
+ delay(1000);
+
+ if(digitalRead(BUT_PIN)) {
+ while(digitalRead(BUT_PIN)) {};
+ state++;
+ }
+
+ switch(state) {
+ case QUICKPRINT:
+ for(int i = 0; i<30; i++) {
+ usbSendBytes(&c1,1);
+ SerialUSB.print('.');
+ SerialUSB.print('|');
+ }
+ Serial2.println(SerialUSB.pending(),DEC);
+ SerialUSB.println();
+ break;
+ case BIGSTUFF:
+ SerialUSB.println("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
+ SerialUSB.println((uint32)123456789,DEC);
+ SerialUSB.println(3.1415926535);
+ 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(3.14159265);
+ Serial2.println(3.14159265);
+ SerialUSB.println(3.14159265,9);
+ Serial2.println(3.14159265,9);
+ SerialUSB.println(123456789,DEC);
+ Serial2.println(123456789,DEC);
+ SerialUSB.println(-123456789,DEC);
+ Serial2.println(-123456789,DEC);
+ SerialUSB.println(65535,HEX);
+ Serial2.println(65535,HEX);
+ break;
+ case SIMPLE:
+ Serial2.println("Trying write('a')");
+ SerialUSB.write('a');
+ Serial2.println("Trying write(\"b\")");
+ SerialUSB.write("b");
+ Serial2.println("Trying print('c')");
+ SerialUSB.print('c');
+ Serial2.println("Trying print(\"d\")");
+ SerialUSB.print("d");
+ Serial2.println("Trying print(\"efg\")");
+ SerialUSB.print("efg");
+ Serial2.println("Trying println(\"hij\\n\\r\")");
+ SerialUSB.print("hij\n\r");
+ SerialUSB.write(' ');
+ SerialUSB.println();
+ Serial2.println("Trying println(123456789,DEC)");
+ SerialUSB.println(123456789);
+ Serial2.println("Trying println(3.141592)");
+ SerialUSB.println(3.141592);
+ Serial2.println("Trying println(\"DONE\")");
+ SerialUSB.println("DONE");
+ break;
+ case ONOFF:
+ Serial2.println("Shutting down...");
+ SerialUSB.println("Shutting down...");
+ SerialUSB.end();
+ Serial2.println("Waiting 4seconds...");
+ delay(4000);
+ Serial2.println("Starting up...");
+ SerialUSB.begin();
+ SerialUSB.println("Hello World!");
+ Serial2.println("Waiting 4seconds...");
+ delay(4000);
+ state++;
+ break;
+ default:
+ state = 0;
+ }
+}
+
+// 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() {
+ init();
+}
+
+int main(void)
+{
+ setup();
+
+ while (1) {
+ loop();
+ }
+ return 0;
+}
+
diff --git a/libmaple/usb/usb.c b/libmaple/usb/usb.c
index 6c010d9..881c7f9 100644
--- a/libmaple/usb/usb.c
+++ b/libmaple/usb/usb.c
@@ -120,7 +120,13 @@ void setupUSB (void) {
/* initialize the usb application */
gpio_write_bit(USB_DISC_BANK,USB_DISC_PIN,0); /* present ourselves to the host */
USB_Init(); /* low level init routine provided by st lib */
+}
+void disableUSB (void) {
+ // These are just guesses about how to do this
+ // TODO: real disable function
+ usbDsbISR();
+ gpio_write_bit(USB_DISC_BANK,USB_DISC_PIN,1);
}
void usbSuspend(void) {
diff --git a/libmaple/usb/usb.h b/libmaple/usb/usb.h
index 66e820c..e0d4231 100644
--- a/libmaple/usb/usb.h
+++ b/libmaple/usb/usb.h
@@ -36,6 +36,7 @@ typedef enum
extern volatile uint32 bDeviceState;
void setupUSB(void);
+ void disableUSB(void);
void usbSuspend(void);
void usbResumeInit(void);
void usbResume(RESUME_STATE);
diff --git a/notes/usb.txt b/notes/usb.txt
index ade35cf..5e00354 100644
--- a/notes/usb.txt
+++ b/notes/usb.txt
@@ -1,3 +1,5 @@
+[NOTE: this is a long term proposal. The current implementation just does a
+2ms TIMEOUT]
SerialUSB Implementation
-------------------------------------------------------------------------------
diff --git a/wirish/usb_serial.cpp b/wirish/usb_serial.cpp
index f186dea..2effa3d 100644
--- a/wirish/usb_serial.cpp
+++ b/wirish/usb_serial.cpp
@@ -32,24 +32,53 @@
#include "wirish.h"
#include "usb.h"
+#define USB_TIMEOUT 2
+
USBSerial :: USBSerial(void) {
}
+void USBSerial::begin(void) {
+ setupUSB();
+}
+
+void USBSerial::end(void) {
+ disableUSB();
+}
+
void USBSerial::write(uint8 ch) {
- usbSendBytes(&ch, 1);
+ uint16 status = 0;
+ uint32 start = millis();
+ while(status == 0 && (millis() - start <= USB_TIMEOUT)) {
+ status = usbSendBytes(&ch, 1);
+ }
}
void USBSerial::write(const char *str) {
- uint32 len = strlen(str);
-
- usbSendBytes((uint8*)str, len);
+ uint32 len = strlen(str);
+ uint16 status = 0;
+ uint16 oldstatus = 0;
+ uint32 start = millis();
+ while(status < len && (millis() - start < USB_TIMEOUT)) {
+ status += usbSendBytes((uint8*)str+status, len-status);
+ if(oldstatus != status)
+ start = millis();
+ oldstatus = status;
+ }
}
void USBSerial::write(void *buf, uint32 size) {
if (!buf) {
return;
}
- usbSendBytes((uint8*)buf, size);
+ uint16 status = 0;
+ uint16 oldstatus = 0;
+ uint32 start = millis();
+ while(status < size && (millis() - start < USB_TIMEOUT)) {
+ status += usbSendBytes((uint8*)buf+status, size-status);
+ if(oldstatus != status)
+ start = millis();
+ oldstatus = status;
+ }
}
uint32 USBSerial::available(void) {
@@ -70,5 +99,9 @@ uint8 USBSerial::read(void) {
return ch;
}
+uint8 USBSerial::pending(void) {
+ return usbGetPending();
+}
+
USBSerial SerialUSB;
diff --git a/wirish/usb_serial.h b/wirish/usb_serial.h
index e1c61ff..abb362b 100644
--- a/wirish/usb_serial.h
+++ b/wirish/usb_serial.h
@@ -36,6 +36,9 @@ class USBSerial : public Print {
public:
USBSerial(void);
+ void begin(void);
+ void end(void);
+
uint32 available(void);
uint32 read(void *buf, uint32 len);
@@ -44,6 +47,10 @@ class USBSerial : public Print {
void write(uint8);
void write(const char *str);
void write(void *, uint32);
+
+ uint8 getRTS();
+ uint8 getDTR();
+ uint8 pending();
};
extern USBSerial SerialUSB;