]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blobdiff - rpp/src/drv/sci.c
Change license to MIT
[pes-rpp/rpp-lib.git] / rpp / src / drv / sci.c
index 269f25a9a69b51660d0102be77e4505b073347b9..0ace02385a453a4a86e91058ec694c91a860e634 100644 (file)
@@ -1,15 +1,48 @@
+/* Copyright (C) 2012-2013 Czech Technical University in Prague
+ *
+ * Authors:
+ *     - Michal Horn <hornmich@fel.cvut.cz>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * File : sci.c
+ *
+ */
+
 #include "drv/drv.h"
 
+static boolean_t crlf_conv_enabled = TRUE;
+
 void drv_sci_init()
 {
-    // Low level init
-    sciInit();
+       // Low level init
+       sciInit();
+       sciSetBaudrate(serialLine, 115200);
 }
 
 void drv_sci_set_baudrate(uint32_t baud)
 {
-    // Set baudrate
-    sciSetBaudrate(sciREG, baud);
+       // Set baudrate
+       sciSetBaudrate(serialLine, baud);
 }
 
 /** Declared in ti_drv_sci.c */
@@ -18,163 +51,175 @@ extern tBuffer sciInBuffer;
 
 uint16_t drv_sci_available()
 {
-    return (uint16_t)uxQueueMessagesWaiting(sciInBuffer.buf);
+       return (uint16_t)uxQueueMessagesWaiting(sciInBuffer.buf);
 }
 
 
-int8_t drv_sci_receive(uint32_t amount, uint8_tbuffer, portTickType wait)
+int8_t drv_sci_receive(uint32_t amount, uint8_t *buffer, portTickType wait)
 {
-    if(sciInBuffer.buf == NULL) {
-        return FAILURE;
-    }
-
-    if(xSemaphoreTake(sciInBuffer.mutex, wait) != pdTRUE) {
-        return FAILURE;
-    }
-
-    // If non block mode, return if not enough data is available
-    if(wait == 0) {
-        if(drv_sci_available() < amount) {
-            xSemaphoreGive(sciInBuffer.mutex);
-            return FAILURE;
-        }
-    }
-
-    int i = 0;
-    unsigned portBASE_TYPE status;
-    while(i < amount) {
-        status = xQueueReceive(sciInBuffer.buf, &buffer[i], wait);
-        if(status != pdTRUE) {
-            xSemaphoreGive(sciInBuffer.mutex);
-            return FAILURE;
-        }
-        i++;
-    }
-
-    xSemaphoreGive(sciInBuffer.mutex);
-    return SUCCESS;
+       if (sciInBuffer.buf == NULL)
+               return FAILURE;
+
+       if (xSemaphoreTake(sciInBuffer.mutex, wait) != pdTRUE)
+               return FAILURE;
+
+       // If non block mode, return if not enough data is available
+       if (wait == 0)
+               if (drv_sci_available() < amount) {
+                       xSemaphoreGive(sciInBuffer.mutex);
+                       return FAILURE;
+               }
+
+       int i = 0;
+       unsigned portBASE_TYPE status;
+       while (i < amount) {
+               status = xQueueReceive(sciInBuffer.buf, &buffer[i], wait);
+               if (status != pdTRUE) {
+                       xSemaphoreGive(sciInBuffer.mutex);
+                       return FAILURE;
+               }
+               i++;
+       }
+
+       xSemaphoreGive(sciInBuffer.mutex);
+       return SUCCESS;
 }
 
 static int crlf_conv(uint8_t ch_in, uint8_t *ch_out)
 {
        static bool was_cr = false;
-       if (ch_in == '\n' && !was_cr) {
-               *ch_out = '\r';
-               was_cr = true;
-               return 0; // Retry the same char next time
-       }
+
+       if (crlf_conv_enabled)
+               if (ch_in == '\n' && !was_cr) {
+                       *ch_out = '\r';
+                       was_cr = true;
+                       return 0; // Retry the same char next time
+               }
        *ch_out = ch_in;
        was_cr = (ch_in == '\r');
        return 1; // Move to the next character
 }
 
-void drv_sci_send_imm(uint32_t length, uint8_t* data)
+/**
+ * Non-blocking send.
+ *
+ * Sends data to the serial line without blocking. If the hardware TX
+ * buffer is not free, it busy-waits.
+ *
+ * @param length
+ * @param data
+ */
+void drv_sci_send_imm(uint32_t length, uint8_t *data)
 {
        uint8_t ch;
-    while(length > 0) {
-        int ofs = crlf_conv(*data, &ch);
-        length -= ofs;
-        data += ofs;
-        while(!(sciREG->FLR & SCI_TX_INT)); /* wait till previous char was sent */
-        sciREG->TD = ch;
-    }
+
+       while (length > 0) {
+               int ofs = crlf_conv(*data, &ch);
+               length -= ofs;
+               data += ofs;
+               while (!(serialLine->FLR & SCI_TX_INT)) ;  /* wait till previous char was sent */
+               serialLine->TD = ch;
+       }
 }
 
-int8_t drv_sci_send_try_append(uint32_t length, uint8_tdata)
+int8_t drv_sci_send_try_append(uint32_t length, uint8_t *data)
 {
        uint8_t ch;
 
-    if(sciOutBuffer.buf == NULL) {
-        return FAILURE;
-    }
-
-    portBASE_TYPE ret = pdTRUE;
-    while(length > 0) {
-        int ofs = crlf_conv(*data, &ch);
-        length -= ofs;
-        data += ofs;
-
-        if(!sciOutBuffer.flags & BUF_TRANSFER_IN_PROGRESS) {
-                if (!sciOutBuffer.flags & BUF_TRANSFER_IN_PROGRESS) {
-                    sciOutBuffer.flags |= BUF_TRANSFER_IN_PROGRESS;
-                    sciREG->SETINT = SCI_TX_INT;    // Start new transfer by sending first byte
-                    sciREG->TD     = ch;
-                    continue;
-                }
-        }
-
-        ret = xQueueSendToBackFromISR(sciOutBuffer.buf, (void*)&ch, NULL);
-        if(ret != pdTRUE) {
-            break;
-        }
-        ret = length;
-    }
-    return ret;
+       if (sciOutBuffer.buf == NULL)
+               return FAILURE;
+
+       portBASE_TYPE ret = pdTRUE;
+       while (length > 0) {
+               int ofs = crlf_conv(*data, &ch);
+               length -= ofs;
+               data += ofs;
+
+               if (!sciOutBuffer.flags & BUF_TRANSFER_IN_PROGRESS)
+                       if (!sciOutBuffer.flags & BUF_TRANSFER_IN_PROGRESS) {
+                               sciOutBuffer.flags |= BUF_TRANSFER_IN_PROGRESS;
+                               serialLine->SETINT = SCI_TX_INT;        // Start new transfer by sending first byte
+                               serialLine->TD     = ch;
+                               continue;
+                       }
+
+               ret = xQueueSendToBackFromISR(sciOutBuffer.buf, (void *)&ch, NULL);
+               if (ret != pdTRUE)
+                       break;
+               ret = length;
+       }
+       return ret;
 }
 
-int8_t drv_sci_send(uint32_t length, uint8_tdata, portTickType wait)
+int8_t drv_sci_send(uint32_t length, uint8_t *data, portTickType wait)
 {
        uint8_t ch;
-    if(sciOutBuffer.buf == NULL) {
-        return FAILURE;
-    }
-
-    if(xSemaphoreTake(sciOutBuffer.mutex, wait) != pdTRUE) {
-        return FAILURE;
-    }
-
-    portBASE_TYPE ret = pdTRUE;
-    while(length > 0) {
-        int ofs = crlf_conv(*data, &ch);
-        length -= ofs;
-        data += ofs;
-
-        if(!sciOutBuffer.flags & BUF_TRANSFER_IN_PROGRESS) {
-                taskENTER_CRITICAL();
-                if (!sciOutBuffer.flags & BUF_TRANSFER_IN_PROGRESS) {
-                    sciOutBuffer.flags |= BUF_TRANSFER_IN_PROGRESS;
-                    sciREG->SETINT = SCI_TX_INT;    // Start new transfer by sending first byte
-                    sciREG->TD     = ch;
-                    taskEXIT_CRITICAL();
-                    continue;
-                }
-                taskEXIT_CRITICAL();
-        }
-
-        ret = xQueueSend(sciOutBuffer.buf, (void*)&ch, wait);
-        if(ret != pdTRUE) {
-            xSemaphoreGive(sciOutBuffer.mutex);
-            return FAILURE;
-        }
-    }
-
-    xSemaphoreGive(sciOutBuffer.mutex);
-    return SUCCESS;
+
+       if (sciOutBuffer.buf == NULL)
+               return FAILURE;
+
+       if (xSemaphoreTake(sciOutBuffer.mutex, wait) != pdTRUE)
+               return FAILURE;
+
+       portBASE_TYPE ret = pdTRUE;
+       while (length > 0) {
+               int ofs = crlf_conv(*data, &ch);
+               length -= ofs;
+               data += ofs;
+
+               if (!sciOutBuffer.flags & BUF_TRANSFER_IN_PROGRESS) {
+                       taskENTER_CRITICAL();
+                       if (!sciOutBuffer.flags & BUF_TRANSFER_IN_PROGRESS) {
+                               sciOutBuffer.flags |= BUF_TRANSFER_IN_PROGRESS;
+                               serialLine->SETINT = SCI_TX_INT;        // Start new transfer by sending first byte
+                               serialLine->TD     = ch;
+                               taskEXIT_CRITICAL();
+                               continue;
+                       }
+                       taskEXIT_CRITICAL();
+               }
+
+               ret = xQueueSend(sciOutBuffer.buf, (void *)&ch, wait);
+               if (ret != pdTRUE) {
+                       xSemaphoreGive(sciOutBuffer.mutex);
+                       return FAILURE;
+               }
+       }
+
+       xSemaphoreGive(sciOutBuffer.mutex);
+       return SUCCESS;
 }
 
 
-int8_t drv_sci_flush_buffer(tBufferbuffer)
+int8_t drv_sci_flush_buffer(tBuffer *buffer)
 {
-    if(uxQueueMessagesWaiting(buffer->buf) == 0) {
-        return FAILURE;
-    }
-    xSemaphoreTake(buffer->mutex, portMAX_DELAY);
-    // FIXME: FreeRTOS 7.0.2 doesn't have xQueueReset
-    //xQueueReset(buffer->buf);
-    // FIXME Workaround
-    uint8_t dummy = 0;
-    while(uxQueueMessagesWaiting(buffer->buf) > 0) {
-        xQueueReceive(buffer->buf, &dummy, 0);
-    }
-    ////////////////////
-    xSemaphoreGive(buffer->mutex);
-    return SUCCESS;
+       if (uxQueueMessagesWaiting(buffer->buf) == 0)
+               return FAILURE;
+       xSemaphoreTake(buffer->mutex, portMAX_DELAY);
+       // FIXME: FreeRTOS 7.0.2 doesn't have xQueueReset
+       //xQueueReset(buffer->buf);
+       // FIXME Workaround
+       uint8_t dummy = 0;
+       while (uxQueueMessagesWaiting(buffer->buf) > 0)
+               xQueueReceive(buffer->buf, &dummy, 0);
+       ////////////////////
+       xSemaphoreGive(buffer->mutex);
+       return SUCCESS;
 }
 
 int8_t drv_sci_flush(boolean_t buf)
 {
-    if(buf) {
-        return drv_sci_flush_buffer(&sciInBuffer);
-    }
-    return drv_sci_flush_buffer(&sciOutBuffer);
+       if (buf)
+               return drv_sci_flush_buffer(&sciInBuffer);
+       return drv_sci_flush_buffer(&sciOutBuffer);
+}
+
+void drv_sci_set_crlf_conv_en(boolean_t enable)
+{
+       crlf_conv_enabled = enable;
+}
+
+boolean_t drv_sci_get_crlf_conv_en()
+{
+       return crlf_conv_enabled;
 }