source: rtems/c/src/lib/libbsp/powerpc/qoriq/console/uart-bridge-master.c @ c499856

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 4.3 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQUartBridge
5 *
6 * @brief UART bridge master implementation.
7 */
8
9/*
10 * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Obere Lagerstr. 30
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <sys/stat.h>
24#include <assert.h>
25#include <fcntl.h>
26#include <unistd.h>
27#include <termios.h>
28
29#include <libchip/sersupp.h>
30
31#include <bspopts.h>
32#include <bsp/uart-bridge.h>
33
34#define TRANSMIT_EVENT RTEMS_EVENT_13
35
36static void serial_settings(int fd)
37{
38  struct termios term;
39  int rv = tcgetattr(fd, &term);
40  assert(rv == 0);
41
42  term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
43  term.c_oflag &= ~OPOST;
44  term.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
45  term.c_cflag &= ~(CSIZE | PARENB);
46  term.c_cflag |= CS8;
47
48  term.c_cc [VMIN] = 1;
49  term.c_cc [VTIME] = 1;
50
51  rv = tcsetattr(fd, TCSANOW, &term);
52  assert(rv == 0);
53}
54
55static void uart_bridge_master_service(intercom_packet *packet, void *arg)
56{
57  rtems_status_code sc = RTEMS_SUCCESSFUL;
58  uart_bridge_master_control *control = arg;
59
60  sc = rtems_chain_append_with_notification(
61    &control->transmit_fifo,
62    &packet->glue.node,
63    control->transmit_task,
64    TRANSMIT_EVENT
65  );
66  assert(sc == RTEMS_SUCCESSFUL);
67}
68
69static void receive_task(rtems_task_argument arg)
70{
71  uart_bridge_master_control *control = (uart_bridge_master_control *) arg;
72  intercom_type type = control->type;
73
74  int fd = open(control->device_path, O_RDONLY);
75  assert(fd >= 0);
76
77  serial_settings(fd);
78
79  while (true) {
80    intercom_packet *packet = qoriq_intercom_allocate_packet(
81      type,
82      INTERCOM_SIZE_64
83    );
84    ssize_t in = read(fd, packet->data, packet->size - 1);
85    if (in > 0) {
86      packet->size = (size_t) in;
87      qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_SLAVE_CORE, packet);
88    } else {
89      qoriq_intercom_free_packet(packet);
90    }
91  }
92}
93
94static void transmit_task(rtems_task_argument arg)
95{
96  rtems_status_code sc = RTEMS_SUCCESSFUL;
97  uart_bridge_master_control *control = (uart_bridge_master_control *) arg;
98  rtems_chain_control *fifo = &control->transmit_fifo;
99
100  int fd = open(control->device_path, O_WRONLY);
101  assert(fd >= 0);
102
103  serial_settings(fd);
104
105  while (true) {
106    intercom_packet *packet = NULL;
107    sc = rtems_chain_get_with_wait(
108      fifo,
109      TRANSMIT_EVENT,
110      RTEMS_NO_TIMEOUT,
111      (rtems_chain_node **) &packet
112    );
113    assert(sc == RTEMS_SUCCESSFUL);
114    write(fd, packet->data, packet->size);
115    qoriq_intercom_free_packet(packet);
116  }
117}
118
119static rtems_id create_task(
120  char name,
121  rtems_task_entry entry,
122  uart_bridge_master_control *control
123)
124{
125  rtems_status_code sc = RTEMS_SUCCESSFUL;
126  rtems_id task = RTEMS_ID_NONE;
127  char index = (char) ('0' + control->type - INTERCOM_TYPE_UART_0);
128
129  sc = rtems_task_create(
130    rtems_build_name('U', 'B', name, index),
131    QORIQ_UART_BRIDGE_TASK_PRIORITY,
132    0,
133    RTEMS_DEFAULT_MODES,
134    RTEMS_DEFAULT_ATTRIBUTES,
135    &task
136  );
137  assert(sc == RTEMS_SUCCESSFUL);
138
139  sc = rtems_task_start(
140    task,
141    entry,
142    (rtems_task_argument) control
143  );
144  assert(sc == RTEMS_SUCCESSFUL);
145
146  return task;
147}
148
149static void initialize(int minor)
150{
151  console_tbl *ct = Console_Port_Tbl [minor];
152  uart_bridge_master_control *control = ct->pDeviceParams;
153  intercom_type type = control->type;
154
155  qoriq_intercom_service_install(type, uart_bridge_master_service, control);
156  create_task('R', receive_task, control);
157  control->transmit_task = create_task('T', transmit_task, control);
158}
159
160static int first_open(int major, int minor, void *arg)
161{
162  return -1;
163}
164
165static int last_close(int major, int minor, void *arg)
166{
167  return -1;
168}
169
170static int read_polled(int minor)
171{
172  return -1;
173}
174
175static void write_polled(int minor, char c)
176{
177  /* Do nothing */
178}
179
180static int set_attributes(int minor, const struct termios *term)
181{
182  return -1;
183}
184
185const console_fns qoriq_uart_bridge_master = {
186  .deviceProbe = libchip_serial_default_probe,
187  .deviceFirstOpen = first_open,
188  .deviceLastClose = last_close,
189  .deviceRead = read_polled,
190  .deviceWrite = NULL,
191  .deviceInitialize = initialize,
192  .deviceWritePolled = write_polled,
193  .deviceSetAttributes = set_attributes,
194  .deviceOutputUsesInterrupts = false
195};
Note: See TracBrowser for help on using the repository browser.