From 32c426bf974912766762a84d97ca9dc8ebebe07f Mon Sep 17 00:00:00 2001 From: Abhishek Malik Date: Tue, 25 Apr 2017 00:08:17 -0700 Subject: [PATCH] UART: Moving to fifo implementation and loop back example Signed-off-by: Abhishek Malik --- examples/uart/Makefile | 4 ++ examples/uart/prj.conf | 14 +++++++ examples/uart/src/Makefile | 1 + examples/uart/src/main.c | 76 +++++++++++++++++++++++++++++++++++ source/uart.c | 81 ++++++++++++++++++++++++-------------- 5 files changed, 147 insertions(+), 29 deletions(-) create mode 100644 examples/uart/Makefile create mode 100644 examples/uart/prj.conf create mode 100644 examples/uart/src/Makefile create mode 100644 examples/uart/src/main.c diff --git a/examples/uart/Makefile b/examples/uart/Makefile new file mode 100644 index 0000000..aee0c93 --- /dev/null +++ b/examples/uart/Makefile @@ -0,0 +1,4 @@ +BOARD ?= arduino_101 +CONF_FILE = prj.conf + +include ${ZEPHYR_BASE}/Makefile.inc diff --git a/examples/uart/prj.conf b/examples/uart/prj.conf new file mode 100644 index 0000000..8399a74 --- /dev/null +++ b/examples/uart/prj.conf @@ -0,0 +1,14 @@ +CONFIG_STDOUT_CONSOLE=y +CONFIG_CONSOLE_HANDLER=y +CONFIG_CONSOLE_HANDLER_SHELL=y +CONFIG_NANO_TIMERS=y +CONFIG_NANO_TIMEOUTS=y +CONFIG_SERIAL=y +CONFIG_UART_QMSI=y +CONFIG_UART_QMSI_1=y +CONFIG_MRAA=y +CONFIG_MRAA_UART=y +CONFIG_NEWLIB_LIBC=y +CONFIG_UART_LINE_CTRL=y +#CONFIG_UART_QMSI_1_BAUDRATE=9600 +CONFIG_MRAA=y diff --git a/examples/uart/src/Makefile b/examples/uart/src/Makefile new file mode 100644 index 0000000..00066e1 --- /dev/null +++ b/examples/uart/src/Makefile @@ -0,0 +1 @@ +obj-y = main.o diff --git a/examples/uart/src/main.c b/examples/uart/src/main.c new file mode 100644 index 0000000..a2f25ad --- /dev/null +++ b/examples/uart/src/main.c @@ -0,0 +1,76 @@ +/* + * Author: Abhishek Malik + * Copyright (c) 2016 Intel Corporation. + * + * 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. + */ + +#include "version.h" +#include +#include +#include +#include +#include + +#define UART_DEVICE "UART_1" +#define SLEEPTICKS SECONDS(1) + +#if defined(CONFIG_STDOUT_CONSOLE) +#include +#define PRINT printf +#else +#include +#define PRINT printk +#endif + +uint8_t buffer[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}; +uint8_t ret_buf[8] = {0}; + +void +main(void) +{ + if (mraa_init() != MRAA_SUCCESS) { + printf("Unable to init MRAA"); + } + mraa_uart_context dev = mraa_uart_init(1); + mraa_uart_set_baudrate(dev, 9600); + + if (mraa_uart_write(dev, buffer, 8) != 8) { + printf("Error occured while writing bytes to UART\n"); + } + //printf("\n"); + + mraa_boolean_t x = mraa_uart_data_available(dev, 100); + int ret_len = 0; + int i = 0; + + if(x == true) { + ret_len = mraa_uart_read(dev, ret_buf, 8); + printf("\nReturned length: %d and returned buffer: \n", ret_len); + for (i = 0; i < 8; i++) { + printf("%c", (char)ret_buf[i]); + } + printf("\n"); + } else { + printf("Unable to read anything back from the fifo\n"); + } + + mraa_uart_stop(dev); +} diff --git a/source/uart.c b/source/uart.c index bd4f54e..d68338f 100644 --- a/source/uart.c +++ b/source/uart.c @@ -51,6 +51,31 @@ #define PRINT printk #endif +static volatile bool data_transmitted; +static volatile bool data_arrived; + +static void uart_interrupt_handler(struct device *dev) { + //printf("coming into interrupt handler\n"); + uart_irq_update(dev); + + if(uart_irq_tx_ready(dev)) { + data_transmitted = true; + } + + if(uart_irq_rx_ready(dev)) { + //printf("rx is ready\n"); + data_arrived = true; + uart_irq_rx_disable(dev); + } +} + +void mraa_ms_delay(uint32_t time) { + struct k_timer timer; + k_timer_init(&timer, NULL, NULL); + k_timer_start(&timer, time, 0); + k_timer_status_sync(&timer); +} + mraa_uart_context mraa_uart_init(int uart) { @@ -81,6 +106,10 @@ mraa_uart_init(int uart) dev->zdev = device_get_binding(UART_DEVICE); dev->block = 1; +#if 1 + uart_irq_callback_set(dev->zdev, uart_interrupt_handler); +#endif + return dev; } @@ -93,22 +122,14 @@ mraa_uart_init_raw(const char* path) int mraa_uart_write(mraa_uart_context dev, const char* buf, size_t length) { - // this isn't the expected implementation, it should be length - // instead of length+1. However, the output gets completely - // screwed up with the actual length. Need to look into this - // to find RC and fix. Current implementation works though. - unsigned char ret[length + 1]; - unsigned char temp; - int i = 0; - for (i = 0; i < length + 1; i++) { - temp = buf[i]; - ret[i] = uart_poll_out(dev->zdev, temp); - if (ret[i] != temp) { - return i; - } - } + int i; + data_transmitted = false; + + uart_irq_tx_enable(dev->zdev); + i = uart_fifo_fill(dev->zdev, buf, length); + uart_irq_tx_disable(dev->zdev); - return length; + return i; } mraa_result_t @@ -145,20 +166,9 @@ mraa_uart_set_flowcontrol(mraa_uart_context dev, mraa_boolean_t xonxoff, mraa_bo int mraa_uart_read(mraa_uart_context dev, char* buf, size_t length) { - unsigned char store; - int ret, i = 0; - for (i = 0; i < length; i++) { - ret = uart_poll_in(dev->zdev, &store); - if (ret == -1) { - return i; - } else if (ret == 0) { - buf[i] = store; - } else { - return i; - } - } + data_arrived = false; - return length; + return uart_fifo_read(dev->zdev, buf, length); } // currently not implemented/ to be implemented once there is more clarity about zephyr API @@ -201,5 +211,18 @@ mraa_uart_stop(mraa_uart_context dev) mraa_boolean_t mraa_uart_data_available(mraa_uart_context dev, unsigned int millis) { - return MRAA_ERROR_FEATURE_NOT_IMPLEMENTED; + int counter = 0; + uart_irq_rx_enable(dev->zdev); + + while(data_arrived == false && counter < millis) { + counter++; + mraa_ms_delay(1); + } + + uart_irq_rx_disable(dev->zdev); + + if(data_arrived == true) + return true; + else + return false; }