source: rtems/c/src/lib/libbsp/arm/shared/arm-pl050.c @ 64f7724

4.115
Last change on this file since 64f7724 was 116ef2e9, checked in by Sebastian Huber <sebastian.huber@…>, on 10/13/14 at 13:19:12

bsps/arm: Convert PL011 and PL050 console drivers

Use Termios device API.

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/*
2 * Copyright (c) 2013-2014 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <info@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <assert.h>
16
17#include <bsp/irq.h>
18#include <bsp/arm-pl050.h>
19
20static volatile pl050 *pl050_get_regs(rtems_termios_device_context *base)
21{
22  arm_pl050_context *ctx = (arm_pl050_context *) base;
23
24  return ctx->regs;
25}
26
27static void pl050_interrupt(void *arg)
28{
29  rtems_termios_tty *tty = arg;
30  rtems_termios_device_context *base = rtems_termios_get_device_context(tty);
31  volatile pl050 *regs = pl050_get_regs(base);
32  uint32_t kmiir_rx = PL050_KMIIR_KMIRXINTR;
33  uint32_t kmiir_tx = (regs->kmicr & PL050_KMICR_KMITXINTREN) != 0 ?
34    PL050_KMIIR_KMITXINTR : 0;
35  uint32_t kmiir = regs->kmiir;
36
37  if ((kmiir & kmiir_rx) != 0) {
38    char c = (char) PL050_KMIDATA_KMIDATA_GET(regs->kmidata);
39
40    rtems_termios_enqueue_raw_characters(tty, &c, 1);
41  }
42
43  if ((kmiir & kmiir_tx) != 0) {
44    rtems_termios_dequeue_characters(tty, 1);
45  }
46}
47
48static bool pl050_first_open(
49  struct rtems_termios_tty *tty,
50  rtems_termios_device_context *base,
51  struct termios *term,
52  rtems_libio_open_close_args_t *args
53)
54{
55  arm_pl050_context *ctx = (arm_pl050_context *) base;
56  volatile pl050 *regs = pl050_get_regs(base);
57  rtems_status_code sc;
58
59  rtems_termios_set_initial_baud(tty, ctx->initial_baud);
60
61  regs->kmicr = PL050_KMICR_KMIEN | PL050_KMICR_KMIRXINTREN;
62
63  sc = rtems_interrupt_handler_install(
64    ctx->irq,
65    "PL050",
66    RTEMS_INTERRUPT_UNIQUE,
67    pl050_interrupt,
68    tty
69  );
70  assert(sc == RTEMS_SUCCESSFUL);
71
72  return true;
73}
74
75static void pl050_last_close(
76  struct rtems_termios_tty *tty,
77  rtems_termios_device_context *base,
78  rtems_libio_open_close_args_t *args
79)
80{
81  arm_pl050_context *ctx = (arm_pl050_context *) base;
82  volatile pl050 *regs = pl050_get_regs(base);
83  rtems_status_code sc;
84
85  regs->kmicr = 0;
86
87  sc = rtems_interrupt_handler_remove(
88    ctx->irq,
89    pl050_interrupt,
90    tty
91  );
92  assert(sc == RTEMS_SUCCESSFUL);
93}
94
95static void pl050_write_support(
96  rtems_termios_device_context *base,
97  const char *s,
98  size_t n
99)
100{
101  volatile pl050 *regs = pl050_get_regs(base);
102
103  if (n > 0) {
104    regs->kmidata = PL050_KMIDATA_KMIDATA(s[0]);
105    regs->kmicr |= PL050_KMICR_KMITXINTREN;
106  } else {
107    regs->kmicr &= ~PL050_KMICR_KMITXINTREN;
108  }
109}
110
111const rtems_termios_device_handler arm_pl050_fns = {
112  .first_open = pl050_first_open,
113  .last_close = pl050_last_close,
114  .write = pl050_write_support,
115  .mode = TERMIOS_IRQ_DRIVEN
116};
Note: See TracBrowser for help on using the repository browser.