5329867276cc8b46ff0c49d01681efed9b3d1e0d
[bertos.git] / drv / ser_emul.c
1 /*!
2  * \file
3  * <!--
4  * Copyright 2004 Develer S.r.l. (http://www.develer.com/)
5  * This file is part of DevLib - See devlib/README for information.
6  * -->
7  *
8  * \brief Serial port emulator for hosted environments.
9  *
10  * \version $Id$
11  * \author Bernardo Innocenti <bernie@develer.com>
12  */
13
14 /*#*
15  *#* $Log$
16  *#* Revision 1.1  2004/12/31 17:40:00  bernie
17  *#* Add a simple serial emulation driver.
18  *#*
19  *#*/
20
21 #include "ser.h"
22 #include "ser_p.h"
23 #include "config.h"
24
25 #include <debug.h>
26 #include <mware/fifobuf.h>
27
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h> /* open() */
31 #include <unistd.h> /* read(), write() */
32
33
34 /* From the high-level serial driver */
35 extern struct Serial ser_handles[SER_CNT];
36
37 /* TX and RX buffers */
38 static unsigned char uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
39 static unsigned char uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
40 #if CONFIG_EMUL_UART1
41         static unsigned char uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
42         static unsigned char uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
43 #endif
44
45
46 /*!
47  * Internal state structure
48  */
49 struct EmulSerial
50 {
51         struct SerialHardware hw;
52         struct Serial *ser;
53         int fd;
54 };
55
56
57 /*
58  * Callbacks
59  */
60 static void uart_init(struct SerialHardware *_hw, struct Serial *ser)
61 {
62         struct EmulSerial *hw = (struct EmulSerial *)_hw;
63
64         hw->ser = ser;
65         hw->fd = open("/dev/ttyS0", O_RDWR);
66 }
67
68 static void uart_cleanup(UNUSED_ARG(struct SerialHardware *, _hw))
69 {
70         struct EmulSerial *hw = (struct EmulSerial *)_hw;
71
72         close(hw->fd);
73         hw->fd = -1;
74 }
75
76 static void uart_enabletxirq(struct SerialHardware * _hw)
77 {
78         struct EmulSerial *hw = (struct EmulSerial *)_hw;
79
80         while(!fifo_isempty(&hw->ser->txfifo))
81         {
82                 fputc(fifo_pop(&hw->ser->txfifo), hw->fd);
83         }
84 }
85
86 static void uart_setbaudrate(UNUSED_ARG(struct SerialHardware *, _hw), unsigned long rate)
87 {
88         TRACEMSG("rate=%lu", rate);
89         // TODO
90
91 }
92
93 static void uart_setparity(UNUSED_ARG(struct SerialHardware *, _hw), int parity)
94 {
95         TRACEMSG("parity=%d", parity);
96         // TODO
97 }
98
99
100 // FIXME: move into compiler.h?  Ditch?
101 #if COMPILER_C99
102         #define C99INIT(name,val) .name = val
103 #elif defined(__GNUC__)
104         #define C99INIT(name,val) name: val
105 #else
106         #warning No designated initializers, double check your code
107         #define C99INIT(name,val) (val)
108 #endif
109
110 /*
111  * High-level interface data structures
112  */
113 static const struct SerialHardwareVT UART0_VT =
114 {
115         C99INIT(init, uart_init),
116         C99INIT(cleanup, uart_cleanup),
117         C99INIT(setbaudrate, uart_setbaudrate),
118         C99INIT(setparity, uart_setparity),
119         C99INIT(enabletxirq, uart_enabletxirq),
120 };
121
122 #if CONFIG_EMUL_UART1
123 static const struct SerialHardwareVT UART1_VT =
124 {
125         C99INIT(init, uart_init),
126         C99INIT(cleanup, uart_cleanup),
127         C99INIT(setbaudrate, uart_setbaudrate),
128         C99INIT(setparity, uart_setparity),
129         C99INIT(enabletxirq, uart_enabletxirq),
130 };
131 #endif // CONFIG_EMUL_UART1
132
133 static struct EmulSerial UARTDescs[SER_CNT] =
134 {
135         {
136                 C99INIT(hw, /**/) {
137                         C99INIT(table, &UART0_VT),
138                         C99INIT(txbuffer, uart0_txbuffer),
139                         C99INIT(rxbuffer, uart0_rxbuffer),
140                         C99INIT(txbuffer_size, sizeof(uart0_txbuffer)),
141                         C99INIT(rxbuffer_size, sizeof(uart0_rxbuffer)),
142                 },
143                 C99INIT(fd, -1),
144         },
145 #if CONFIG_EMUL_UART1
146         {
147                 C99INIT(hw, /**/) {
148                         C99INIT(table, &UART1_VT),
149                         C99INIT(txbuffer, uart1_txbuffer),
150                         C99INIT(rxbuffer, uart1_rxbuffer),
151                         C99INIT(txbuffer_size, sizeof(uart1_txbuffer)),
152                         C99INIT(rxbuffer_size, sizeof(uart1_rxbuffer)),
153                 },
154                 C99INIT(fd, -1),
155         },
156 #endif
157 };
158
159 struct SerialHardware* ser_hw_getdesc(int unit)
160 {
161         ASSERT(unit < SER_CNT);
162         return &UARTDescs[unit].hw;
163 }