uart.c: make use of no_bus_mux flag
[contrib/mraa.git] / src / uart / uart.c
index cc1a06d..499af93 100644 (file)
@@ -107,6 +107,21 @@ uint2speed(unsigned int speed)
     }
 }
 
+static mraa_uart_context
+mraa_uart_init_internal(mraa_adv_func_t* func_table)
+{
+    mraa_uart_context dev = (mraa_uart_context) calloc(1, sizeof(struct _uart));
+    if (dev == NULL) {
+        syslog(LOG_CRIT, "uart: Failed to allocate memory for context");
+        return NULL;
+    }
+    dev->index = -1;
+    dev->fd = -1;
+    dev->advance_func = func_table;
+
+    return dev;
+}
+
 mraa_uart_context
 mraa_uart_init(int index)
 {
@@ -115,8 +130,13 @@ mraa_uart_init(int index)
         return NULL;
     }
 
-    if (advance_func->uart_init_pre != NULL) {
-        if (advance_func->uart_init_pre(index) != MRAA_SUCCESS) {
+    if (mraa_is_sub_platform_id(index)) {
+        syslog(LOG_NOTICE, "uart: Using sub platform is not supported");
+        return NULL;
+    }
+
+    if (plat->adv_func->uart_init_pre != NULL) {
+        if (plat->adv_func->uart_init_pre(index) != MRAA_SUCCESS) {
             syslog(LOG_ERR, "uart: failure in pre-init platform hook");
             return NULL;
         }
@@ -132,30 +152,36 @@ mraa_uart_init(int index)
         return NULL;
     }
 
-    int pos = plat->uart_dev[index].rx;
-    if (pos >= 0) {
-        if (plat->pins[pos].uart.mux_total > 0) {
-            if (mraa_setup_mux_mapped(plat->pins[pos].uart) != MRAA_SUCCESS) {
-                syslog(LOG_ERR, "uart: failed to setup muxes for RX pin");
-                return NULL;
+    if (!plat->no_bus_mux) {
+        int pos = plat->uart_dev[index].rx;
+        if (pos >= 0) {
+            if (plat->pins[pos].uart.mux_total > 0) {
+                if (mraa_setup_mux_mapped(plat->pins[pos].uart) != MRAA_SUCCESS) {
+                    syslog(LOG_ERR, "uart: failed to setup muxes for RX pin");
+                    return NULL;
+                }
             }
         }
-    }
 
-    if (pos >= 0) {
         pos = plat->uart_dev[index].tx;
-        if (plat->pins[pos].uart.mux_total > 0) {
-            if (mraa_setup_mux_mapped(plat->pins[pos].uart) != MRAA_SUCCESS) {
-                syslog(LOG_ERR, "uart: failed to setup muxes for TX pin");
-                return NULL;
+        if (pos >= 0) {
+            if (plat->pins[pos].uart.mux_total > 0) {
+                if (mraa_setup_mux_mapped(plat->pins[pos].uart) != MRAA_SUCCESS) {
+                    syslog(LOG_ERR, "uart: failed to setup muxes for TX pin");
+                    return NULL;
+                }
             }
         }
     }
 
-    mraa_uart_context dev = mraa_uart_init_raw(index);
+    mraa_uart_context dev = mraa_uart_init_raw((char*)plat->uart_dev[index].device_path);
+    if (dev == NULL) {
+        return NULL;
+    }
+    dev->index = index; //Set the board Index.
 
-    if (advance_func->uart_init_post != NULL) {
-        mraa_result_t ret = advance_func->uart_init_post(dev);
+    if (IS_FUNC_DEFINED(dev, uart_init_post)) {
+        mraa_result_t ret = dev->advance_func->uart_init_post(dev);
         if (ret != MRAA_SUCCESS) {
             free(dev);
             return NULL;
@@ -166,29 +192,23 @@ mraa_uart_init(int index)
 }
 
 mraa_uart_context
-mraa_uart_init_raw(int index)
+mraa_uart_init_raw(const char* path)
 {
-    mraa_uart_context dev = (mraa_uart_context) malloc(sizeof(struct _uart));
+    mraa_uart_context dev = mraa_uart_init_internal(plat == NULL ? NULL : plat->adv_func);
     if (dev == NULL) {
-        syslog(LOG_CRIT, "uart: Failed to allocate memory for context");
+        syslog(LOG_ERR, "uart: Failed to allocate memory for context");
         return NULL;
     }
-    memset(dev, 0, sizeof(struct _uart));
-
-    dev->index = index;
-    dev->fd = -1;
-    dev->path = (char*) plat->uart_dev[index].device_path;
-
-    char* devPath = mraa_uart_get_dev_path(dev);
+    dev->path = path;
 
-    if (!devPath) {
+    if (!dev->path) {
         syslog(LOG_ERR, "uart: device path undefined, open failed");
         free(dev);
         return NULL;
     }
 
     // now open the device
-    if ((dev->fd = open(devPath, O_RDWR)) == -1) {
+    if ((dev->fd = open(dev->path, O_RDWR)) == -1) {
         syslog(LOG_ERR, "uart: open() failed");
         free(dev);
         return NULL;
@@ -198,8 +218,9 @@ mraa_uart_init_raw(int index)
     struct termios termio;
 
     // get current modes
-    if (!tcgetattr(dev->fd, &termio)) {
+    if (tcgetattr(dev->fd, &termio)) {
         syslog(LOG_ERR, "uart: tcgetattr() failed");
+        close(dev->fd);
         free(dev);
         return NULL;
     }
@@ -208,8 +229,15 @@ mraa_uart_init_raw(int index)
     // handling, such as flow control or line editing semantics.
     // cfmakeraw is not POSIX!
     cfmakeraw(&termio);
+    if (tcsetattr(dev->fd, TCSAFLUSH, &termio) < 0) {
+        syslog(LOG_ERR, "uart: tcsetattr() failed after cfmakeraw()");
+        close(dev->fd);
+        free(dev);
+        return NULL;
+    }
 
-    if (!mraa_uart_set_baudrate(dev, 9600)) {
+    if (mraa_uart_set_baudrate(dev, 9600) != MRAA_SUCCESS) {
+        close(dev->fd);
         free(dev);
         return NULL;
     }
@@ -243,7 +271,7 @@ mraa_uart_flush(mraa_uart_context dev)
         return MRAA_ERROR_INVALID_HANDLE;
     }
 
-    if (!tcdrain(dev->fd)) {
+    if (tcdrain(dev->fd) == -1) {
         return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
     }
 
@@ -259,7 +287,7 @@ mraa_uart_set_baudrate(mraa_uart_context dev, unsigned int baud)
     }
 
     struct termios termio;
-    if (!tcgetattr(dev->fd, &termio)) {
+    if (tcgetattr(dev->fd, &termio)) {
         syslog(LOG_ERR, "uart: tcgetattr() failed");
         return MRAA_ERROR_INVALID_HANDLE;
     }
@@ -286,7 +314,7 @@ mraa_uart_set_mode(mraa_uart_context dev, int bytesize, mraa_uart_parity_t parit
     }
 
     struct termios termio;
-    if (!tcgetattr(dev->fd, &termio)) {
+    if (tcgetattr(dev->fd, &termio)) {
         syslog(LOG_ERR, "uart: tcgetattr() failed");
         return MRAA_ERROR_INVALID_HANDLE;
     }
@@ -313,7 +341,7 @@ mraa_uart_set_mode(mraa_uart_context dev, int bytesize, mraa_uart_parity_t parit
     // POSIX & linux doesn't support 1.5 and I've got bigger fish to fry
     switch (stopbits) {
         case 1:
-            termio.c_cflag &= CSTOPB;
+            termio.c_cflag &= ~CSTOPB;
             break;
         case 2:
             termio.c_cflag |= CSTOPB;
@@ -326,8 +354,8 @@ mraa_uart_set_mode(mraa_uart_context dev, int bytesize, mraa_uart_parity_t parit
             termio.c_cflag &= ~(PARENB | PARODD);
             break;
         case MRAA_UART_PARITY_EVEN:
+            termio.c_cflag |= PARENB;
             termio.c_cflag &= ~PARODD;
-            termio.c_cflag |= PARODD;
             break;
         case MRAA_UART_PARITY_ODD:
             termio.c_cflag |= PARENB | PARODD;
@@ -362,7 +390,7 @@ mraa_uart_set_flowcontrol(mraa_uart_context dev, mraa_boolean_t xonxoff, mraa_bo
     if (xonxoff) {
         action = TCION;
     }
-    if (!tcflow(dev->fd, action)) {
+    if (tcflow(dev->fd, action)) {
         return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
     }
 
@@ -370,7 +398,7 @@ mraa_uart_set_flowcontrol(mraa_uart_context dev, mraa_boolean_t xonxoff, mraa_bo
     struct termios termio;
 
     // get current modes
-    if (!tcgetattr(dev->fd, &termio)) {
+    if (tcgetattr(dev->fd, &termio)) {
         syslog(LOG_ERR, "uart: tcgetattr() failed");
         return MRAA_ERROR_INVALID_HANDLE;
     }
@@ -400,7 +428,7 @@ mraa_uart_set_timeout(mraa_uart_context dev, int read, int write, int interchar)
     return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED;
 }
 
-char*
+const char*
 mraa_uart_get_dev_path(mraa_uart_context dev)
 {
     if (!dev) {
@@ -432,7 +460,7 @@ mraa_uart_read(mraa_uart_context dev, char* buf, size_t len)
 }
 
 int
-mraa_uart_write(mraa_uart_context dev, char* buf, size_t len)
+mraa_uart_write(mraa_uart_context dev, const char* buf, size_t len)
 {
     if (!dev) {
         syslog(LOG_ERR, "uart: write: context is NULL");