Skip to content
This repository has been archived by the owner on Jan 3, 2023. It is now read-only.

UART: Moving to fifo implementation and loop back example #48

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/uart/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
BOARD ?= arduino_101
CONF_FILE = prj.conf

include ${ZEPHYR_BASE}/Makefile.inc
14 changes: 14 additions & 0 deletions examples/uart/prj.conf
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions examples/uart/src/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
obj-y = main.o
76 changes: 76 additions & 0 deletions examples/uart/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Author: Abhishek Malik <[email protected]>
* 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 <device.h>
#include <mraa/uart.h>
#include <string.h>
#include <sys_clock.h>
#include <zephyr.h>

#define UART_DEVICE "UART_1"
#define SLEEPTICKS SECONDS(1)

#if defined(CONFIG_STDOUT_CONSOLE)
#include <stdio.h>
#define PRINT printf
#else
#include <misc/printk.h>
#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);
}
81 changes: 52 additions & 29 deletions source/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,31 @@
#define PRINT printk
#endif

static volatile bool data_transmitted;
static volatile bool data_arrived;

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be stored in the context so that multiple uarts on a target could be used?

static void uart_interrupt_handler(struct device *dev) {
//printf("coming into interrupt handler\n");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing this is why you made them global statics (data_transmitted/data_arrived)? There is no way to attach the context to this device struct?

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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why disable here? Usually what I would think would happen in this intr routine would be that data would be copied out of (RX) the FIFO into a local buffer (a ring buffer would work well), and if there was a TX ring buffer, then data would be sent from it to the FIFO when tx was available (data in tx RB, and uart_irq_tx_ready() == true).

Have you tried this with a device that sends a continuous stream of data like one of the many NMEA GPS devices we support?

}
}

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)
{
Expand Down Expand Up @@ -81,6 +106,10 @@ mraa_uart_init(int uart)
dev->zdev = device_get_binding(UART_DEVICE);
dev->block = 1;

#if 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is always necessary, remove the #if

uart_irq_callback_set(dev->zdev, uart_interrupt_handler);
#endif

return dev;
}

Expand All @@ -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
Expand Down Expand Up @@ -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);
Copy link
Collaborator

@jontrulson jontrulson Apr 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not familiar with this FIFO API... How much data can be returned? Does it do it's own local buffering separate from the hardware FIFO?

}

// currently not implemented/ to be implemented once there is more clarity about zephyr API
Expand Down Expand Up @@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe

return data_arrived

is simpler?

return true;
else
return false;
}