source: rtems/bsps/powerpc/qoriq/console/uart-bridge-master.c @ 762fa62

5
Last change on this file since 762fa62 was d7d66d7, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 19, 2018 at 4:28:01 AM

bsps: Move console drivers to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQUartBridge
5 *
6 * @brief UART bridge master implementation.
7 */
8
9/*
10 * Copyright (c) 2011-2015 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
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 <bspopts.h>
30#include <bsp/uart-bridge.h>
31
32#define TRANSMIT_EVENT RTEMS_EVENT_13
33
34static void serial_settings(int fd)
35{
36  struct termios term;
37  int rv = tcgetattr(fd, &term);
38  assert(rv == 0);
39
40  term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
41  term.c_oflag &= ~OPOST;
42  term.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
43  term.c_cflag &= ~(CSIZE | PARENB);
44  term.c_cflag |= CS8;
45
46  term.c_cc [VMIN] = 1;
47  term.c_cc [VTIME] = 1;
48
49  rv = tcsetattr(fd, TCSANOW, &term);
50  assert(rv == 0);
51}
52
53static void uart_bridge_master_service(intercom_packet *packet, void *arg)
54{
55  rtems_status_code sc = RTEMS_SUCCESSFUL;
56  uart_bridge_master_context *ctx = arg;
57
58  sc = rtems_chain_append_with_notification(
59    &ctx->transmit_fifo,
60    &packet->glue.node,
61    ctx->transmit_task,
62    TRANSMIT_EVENT
63  );
64  assert(sc == RTEMS_SUCCESSFUL);
65}
66
67static void receive_task(rtems_task_argument arg)
68{
69  uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg;
70  intercom_type type = ctx->type;
71
72  int fd = open(ctx->device_path, O_RDONLY);
73  assert(fd >= 0);
74
75  serial_settings(fd);
76
77  while (true) {
78    intercom_packet *packet = qoriq_intercom_allocate_packet(
79      type,
80      INTERCOM_SIZE_64
81    );
82    ssize_t in = read(fd, packet->data, packet->size - 1);
83    if (in > 0) {
84      packet->size = (size_t) in;
85      qoriq_intercom_send_packet(QORIQ_UART_BRIDGE_SLAVE_CORE, packet);
86    } else {
87      qoriq_intercom_free_packet(packet);
88    }
89  }
90}
91
92static void transmit_task(rtems_task_argument arg)
93{
94  rtems_status_code sc = RTEMS_SUCCESSFUL;
95  uart_bridge_master_context *ctx = (uart_bridge_master_context *) arg;
96  rtems_chain_control *fifo = &ctx->transmit_fifo;
97
98  int fd = open(ctx->device_path, O_WRONLY);
99  assert(fd >= 0);
100
101  serial_settings(fd);
102
103  while (true) {
104    intercom_packet *packet = NULL;
105    sc = rtems_chain_get_with_wait(
106      fifo,
107      TRANSMIT_EVENT,
108      RTEMS_NO_TIMEOUT,
109      (rtems_chain_node **) &packet
110    );
111    assert(sc == RTEMS_SUCCESSFUL);
112    write(fd, packet->data, packet->size);
113    qoriq_intercom_free_packet(packet);
114  }
115}
116
117static rtems_id create_task(
118  char name,
119  rtems_task_entry entry,
120  uart_bridge_master_context *ctx
121)
122{
123  rtems_status_code sc = RTEMS_SUCCESSFUL;
124  rtems_id task = RTEMS_ID_NONE;
125  char index = (char) ('0' + ctx->type - INTERCOM_TYPE_UART_0);
126
127  sc = rtems_task_create(
128    rtems_build_name('U', 'B', name, index),
129    QORIQ_UART_BRIDGE_TASK_PRIORITY,
130    0,
131    RTEMS_DEFAULT_MODES,
132    RTEMS_DEFAULT_ATTRIBUTES,
133    &task
134  );
135  assert(sc == RTEMS_SUCCESSFUL);
136
137  sc = rtems_task_start(
138    task,
139    entry,
140    (rtems_task_argument) ctx
141  );
142  assert(sc == RTEMS_SUCCESSFUL);
143
144  return task;
145}
146
147bool qoriq_uart_bridge_master_probe(rtems_termios_device_context *base)
148{
149  uart_bridge_master_context *ctx = (uart_bridge_master_context *) base;
150  intercom_type type = ctx->type;
151
152  qoriq_intercom_service_install(type, uart_bridge_master_service, ctx);
153  create_task('R', receive_task, ctx);
154  ctx->transmit_task = create_task('T', transmit_task, ctx);
155
156  return true;
157}
158
159static bool first_open(
160  struct rtems_termios_tty *tty,
161  rtems_termios_device_context *base,
162  struct termios *term,
163  rtems_libio_open_close_args_t *args
164)
165{
166  return false;
167}
168
169static bool set_attributes(
170  rtems_termios_device_context *base,
171  const struct termios *term
172)
173{
174  return false;
175}
176
177const rtems_termios_device_handler qoriq_uart_bridge_master = {
178  .first_open = first_open,
179  .set_attributes = set_attributes,
180  .mode = TERMIOS_POLLED
181};
Note: See TracBrowser for help on using the repository browser.