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