ff3096516c46a86b12c327f29386c7be837d7055
[barrelfish] / usr / drivers / serial / serial_lpuart.c
1 /**
2  * \file
3  * \brief Serial port driver.
4  */
5
6 /*
7  * Copyright (c) 2007, 2008, 2010, 2011, 2012, ETH Zurich.
8  * All rights reserved.
9  *
10  * This file is distributed under the terms in the attached LICENSE file.
11  * If you do not find this file, copies can be found by writing to:
12  * ETH Zurich D-INFK, CAB F.78, Universitaetstrasse 6, CH-8092 Zurich,
13  * Attn: Systems Group.
14  */
15
16 #include <barrelfish/barrelfish.h>
17 #include <int_route/int_route_client.h>
18 #include <pci/pci.h>
19 #include "serial.h"
20 #include "serial_debug.h"
21 #include "pci/pci.h"
22 #include <dev/lpuart_dev.h>
23 #include <driverkit/driverkit.h>
24 #include <barrelfish/deferred.h>
25 #include <barrelfish/systime.h>
26
27
28 //#define LPUART_DEBUG_ON
29
30 #if defined(LPUART_DEBUG_ON) || defined(GLOBAL_DEBUG)
31 #    define LPUART_DEBUG(x...) debug_printf(x)
32 #else
33 #    define LPUART_DEBUG(x...) ((void)0)
34 #endif
35
36 struct serial_lpuart {
37     struct serial_common m;
38     struct lpuart_t uart;
39 };
40
41 static void print_regvalues(struct serial_lpuart *spc)
42 {
43     char buffer[10000];
44     lpuart_pr(buffer, 10000, &spc->uart);
45     LPUART_DEBUG("printing lpuart  %s\n", buffer);
46 }
47
48 static void serial_poll(struct serial_lpuart *spc)
49 {
50     while (lpuart_stat_rdrf_rdf(&spc->uart)) {
51         LPUART_DEBUG("befohooore\n");
52         char c = lpuart_rxdata_buf_rdf((&spc->uart));
53         if (c)
54             LPUART_DEBUG("Read char=%c\n", c);
55         else
56             LPUART_DEBUG("Read NULL char\n");
57         serial_input(&spc->m, &c, 1);
58         uint8_t or = lpuart_stat_or_rdf(&spc->uart);
59         if (or == 1) {
60             LPUART_DEBUG("OR FLAG IS SET\n");
61             lpuart_stat_or_wrf(&spc->uart, 1);
62         }
63     }
64 }
65
66 static void serial_poll2(void *arg)
67 {
68     LPUART_DEBUG("my call back worked, arg=%p\n", arg);
69     serial_poll((struct serial_lpuart *)arg);
70     struct deferred_event *de = malloc(sizeof(struct deferred_event));
71     deferred_event_init(de);
72     struct event_closure ec;
73     ec.handler = serial_poll2;
74     ec.arg = arg;
75     errval_t err = deferred_event_register(de, get_default_waitset(), 1000, ec);
76     if (err_is_fail(err)) {
77         USER_PANIC_ERR(err, "deferred event register failed.");
78     }
79 }
80
81 static void install_event(delayus_t delay, struct serial_lpuart *spc)
82 {
83     struct deferred_event *de = malloc(sizeof(struct deferred_event));
84     deferred_event_init(de);
85     errval_t err = deferred_event_register(de, get_default_waitset(), delay,
86                                            MKCLOSURE(serial_poll2, spc));
87     if (err_is_fail(err)) {
88         USER_PANIC_ERR(err, "deferred event register failed.");
89     }
90 }
91
92
93 static void hw_init(struct serial_lpuart *spc)
94 {  // Disable transceiver
95     lpuart_ctrl_t ctrl = lpuart_ctrl_rawrd(&spc->uart);
96     ctrl = lpuart_ctrl_te_insert(ctrl, 0);
97     ctrl = lpuart_ctrl_re_insert(ctrl, 0);
98     lpuart_ctrl_rawwr(&spc->uart, ctrl);
99     // Set baudrate
100     // baudrate = clock rate / (over sampling rate * SBR)
101     // TODO: Currently we assume UART clock is set to 8MHz
102     lpuart_baud_t baud = lpuart_baud_default;
103     baud = lpuart_baud_osr_insert(baud, lpuart_ratio5);
104     // OSR of 5 needs bothedge set
105     baud = lpuart_baud_bothedge_insert(baud, 1);
106     baud = lpuart_baud_sbr_insert(baud, 139);
107     lpuart_baud_rawwr(&spc->uart, baud);
108     // enable FIFOs
109     lpuart_fifo_t fcr = lpuart_fifo_default;
110     ctrl = lpuart_ctrl_default;
111     ctrl = lpuart_ctrl_te_insert(ctrl, 0);
112     ctrl = lpuart_ctrl_re_insert(ctrl, 0);
113     lpuart_ctrl_wr(&spc->uart, ctrl);
114     // enable fifo
115     fcr = lpuart_fifo_rxfe_insert(fcr, 1);
116     lpuart_fifo_wr(&spc->uart, fcr);
117     fcr = lpuart_fifo_txfe_insert(fcr, 1);
118     lpuart_fifo_wr(&spc->uart, fcr);
119     lpuart_water_rxwater_wrf(&spc->uart, 0);
120     // Enable transceiver
121     ctrl = lpuart_ctrl_default;
122     ctrl = lpuart_ctrl_te_insert(ctrl, 1);
123     ctrl = lpuart_ctrl_re_insert(ctrl, 1);
124     lpuart_ctrl_wr(&spc->uart, ctrl);
125     print_regvalues(spc);
126     // ENABLE INTERRUPTS
127     /*
128     //transmit interrupt enable
129      lpuart_ctrl_tie_wrf(&spc->uart,1);
130     //Transmission Complete Interrupt Enable
131     lpuart_ctrl_tcie_wrf(&spc->uart,1);
132     //Receiver Interrupt Enable
133     lpuart_ctrl_rie_wrf(&spc->uart,1);
134     //Overrun Interrupt Enable
135      lpuart_ctrl_orie_wrf(&spc->uart,1);
136      //noise error interrupt enable
137      lpuart_ctrl_neie_wrf(&spc->uart,1);
138      //framing error interrupt enable
139      lpuart_ctrl_feie_wrf(&spc->uart,1);
140      //Parity Error Interrupt Enable
141      lpuart_ctrl_peie_wrf(&spc->uart,1);
142      */
143 }
144
145 static void serial_putc(struct serial_lpuart *spc, char c)
146 {
147     lpuart_t *u = &spc->uart;
148     assert(u->base != 0);
149
150     while (lpuart_stat_tdre_rdf(u) == 0)
151         ;
152     lpuart_txdata_wr(u, c);
153 }
154
155 static void serial_write(void *m, const char *c, size_t len)
156 {
157     struct serial_lpuart *spc = m;
158     for (int i = 0; i < len; i++) {
159         serial_putc(spc, c[i]);
160     }
161 }
162
163 static errval_t serial_lpuart_init(struct serial_lpuart *spc, struct capref irq_src)
164 {
165     debug_printf("Hello world from serial lpuart driver\n");
166
167     // errval_t err;
168
169     // if(capref_is_null(irq_src))
170     //     USER_PANIC("serial_kernel requires an irq cap");
171
172     spc->m.output = serial_write;
173     spc->m.output_arg = spc;
174
175     // Register interrupt handler
176     // err = int_route_client_route_and_connect(irq_src, 0,
177     //        get_default_waitset(), serial_interrupt, spc);
178     // if (err_is_fail(err)) {
179     //    USER_PANIC_ERR(err, "interrupt setup failed.");
180     // }
181
182     hw_init(spc);
183
184     // offer service now we're up
185     start_service(&spc->m);
186     return SYS_ERR_OK;
187 }
188
189 static errval_t init(struct bfdriver_instance *bfi, uint64_t flags, iref_t *dev)
190 {
191     errval_t err;
192     struct serial_lpuart *spc = malloc(sizeof(struct serial_lpuart));
193     init_serial_common(&spc->m);
194     // copy
195     lvaddr_t vbase;
196     struct capref devframe_cap = { .slot = DRIVERKIT_ARGCN_SLOT_BAR0,
197                                    .cnode = bfi->argcn };
198     err = map_device_cap(devframe_cap, &vbase);
199     debug_printf("vbase = %p\n", vbase);
200     lpuart_initialize(&spc->uart, (mackerel_addr_t)vbase);
201
202     /*  struct capref irq_src;
203     irq_src.cnode = bfi->argcn;
204     irq_src.slot = PCIARG_SLOT_INT; */
205     err = serial_lpuart_init(spc, NULL_CAP);
206     assert(err_is_ok(err));
207     bfi->dstate = spc;
208
209     SERIAL_DEBUG("lpuart Serial driver initialized.\n");
210     debug_printf("installing handler, spc=%p\n", spc);
211     install_event(1000, spc);
212     return SYS_ERR_OK;
213 }
214
215 static errval_t attach(struct bfdriver_instance *bfi)
216 {
217     return SYS_ERR_OK;
218 }
219
220 static errval_t detach(struct bfdriver_instance *bfi)
221 {
222     return SYS_ERR_OK;
223 }
224
225 static errval_t set_sleep_level(struct bfdriver_instance *bfi, uint32_t level)
226 {
227     return SYS_ERR_OK;
228 }
229
230 static errval_t destroy(struct bfdriver_instance *bfi)
231 {
232     struct lpuart_t *spc = bfi->dstate;
233     free(spc);
234     bfi->dstate = NULL;
235     // XXX: Tear-down the service
236     bfi->device = 0x0;
237     return SYS_ERR_OK;
238 }
239
240 static errval_t get_ep(struct bfdriver_instance *bfi, bool lmp, struct capref *ret_cap)
241 {
242     USER_PANIC("NIY \n");
243     return SYS_ERR_OK;
244 }
245
246 DEFINE_MODULE(serial_lpuart, init, attach, detach, set_sleep_level, destroy, get_ep);