Mark Gottscho / UtilityLib

Fork of UtilityLib by Mark Gottscho

Revision:
1:2a3bbec22035
Parent:
0:cc61e9d1c295
Child:
2:3e09d74e5cf0
--- a/Utility.cpp	Tue Feb 18 22:19:16 2014 +0000
+++ b/Utility.cpp	Wed Feb 19 04:04:10 2014 +0000
@@ -15,7 +15,21 @@
                                             __green_led(green_led_pin),
                                             __green_led_interrupt(),
                                             __red_led(red_led_pin),
-                                            __red_led_interrupt() {
+                                            __red_led_interrupt(),
+                                            __rx_head(0),
+                                            __rx_tail(0),
+                                            __tx_head(0),
+                                            __tx_tail(0),
+                                            __have_rx_serial(false) {
+                                                
+    __red_led = 1;
+    __green_led = 1;
+    
+    console.baud(230400); //115200, 230400 confirmed to work, above this seems to fail
+    
+    //Set up serial interrupt handlers
+    console.attach(this, &Utility::__console_rx_ISR, Serial::RxIrq);
+    //console.attach(this, &Utility::__console_tx_ISR, Serial::TxIrq);
 }
                                             
 Utility::~Utility() { }
@@ -79,6 +93,95 @@
     }
 }
 
+//THIS DOES NOT WORK YET
+/*uint32_t Utility::sendLine(const char *line, const uint32_t len) {
+    int i = 0;
+    char temp_byte;
+    bool buf_empty;
+    
+    if (line == NULL) //check input
+        return 0;
+
+    G_red_led = 0;
+    
+    // Start critical section - don't interrupt while changing global buffer variables
+    __disable_irq();
+    buf_empty = (G_tx_head == G_tx_tail);
+    
+    while (i < len && line[i] != '\r') { //Loop until we have sent the maximum number of characters or we hit a carriage return
+        // Wait if tx buffer full
+        if ((G_tx_head + 1) % BUFFER_SIZE == G_tx_tail) { //If TX buffer is full, wait.
+            // End critical section - need to let interrupt routine empty buffer by sending
+            __enable_irq();
+            while ((G_tx_head + 1) % BUFFER_SIZE == G_tx_tail) { } //Spinloop until TX buffer is not full
+            // Start critical section - don't interrupt while changing global buffer variables
+            __disable_irq();
+        }
+        G_tx_head = (G_tx_head + 1) % BUFFER_SIZE;
+        G_tx_buf[G_tx_head] = line[i++];
+    }
+    
+    //Now we have buffered all characters in the line. Trigger the TX serial interrupt
+    if (G_console.writeable() && buf_empty) {
+        //Write the first byte to get it started
+        temp_byte = G_tx_buf[G_tx_tail];
+        G_tx_tail = (G_tx_tail + 1) % BUFFER_SIZE;
+        
+        // Send first character to start tx interrupts, if stopped
+        G_console.putc(temp_byte);
+    }
+    
+    // End critical section
+    __enable_irq();
+    
+    G_red_led = 1;
+    
+    return i;
+}*/
+
+
+uint32_t Utility::receiveLine(char *line, const uint32_t len) {
+    int i = 0;
+    char lastChar = '\0';
+    
+    if (line == NULL) //check input
+        return 0;
+
+    // Start critical section - don't interrupt while changing global buffer variables
+    __disable_irq();
+    
+    while (i < len && lastChar != '\r') { //Loop until maximum number of characters or a newline symbol
+        //Wait for more characters if the rx buffer is empty
+        if (__rx_tail == __rx_head) {
+            // End critical section - need to allow rx interrupt to get new characters for buffer
+            __enable_irq();
+            while (__rx_tail == __rx_head) { } //Spinloop until there are some characters
+            // Start critical section - don't interrupt while changing global buffer variables
+            __disable_irq();
+        }
+        
+        lastChar = __rx_buf[__rx_tail];
+        if (lastChar == '\r') //newline symbol
+            line[i] = '\0';
+        else
+            line[i] = lastChar;
+        i++;
+        __rx_tail = (__rx_tail + 1) % BUFFER_SIZE;
+    }
+    
+    //Clear flag
+    __have_rx_serial = false;
+    
+    // End critical section 
+    __enable_irq();
+    
+    return i;
+}
+
+bool Utility::haveRxSerialData() {
+    return __have_rx_serial;
+}
+
 void Utility::__greenLED_ISR() {
     if (__green_led == 0) //Just flip the LED status every time we are called
         __green_led = 1;
@@ -91,4 +194,26 @@
         __red_led = 1;
     else
         __red_led = 0;
-}
\ No newline at end of file
+}
+
+void Utility::__console_rx_ISR() {
+    char tmp;
+    
+    //Loop while the UART inbound FIFO is not empty and the receiving buffer is not full
+    while (console.readable() && (__rx_head != (__rx_tail - 1) % BUFFER_SIZE)) {
+        tmp = console.getc(); //read a byte into the buffer from the serial port
+        __rx_buf[__rx_head] = tmp;
+        __rx_head = (__rx_head + 1) % BUFFER_SIZE;
+        if (tmp == '\r')
+            __have_rx_serial = true;
+    }
+}
+
+//THIS DOES NOT WORK YET
+/*void Utility::__console_tx_ISR() {
+    //Loop while the UART outbound FIFO is not full and the transmitting buffer is not empty
+    while (G_console.writeable() && (G_tx_tail != G_tx_head)) {
+        G_console.putc(G_tx_buf[G_tx_tail]); //write a byte to the serial port from the buffer
+        G_tx_tail = (G_tx_tail + 1) % BUFFER_SIZE;  
+    }
+}*/
\ No newline at end of file