Imported Upstream version 3.2.2
[debian/gnuradio] / usrp2 / firmware / lib / hal_io.c
1 /* -*- c -*- */
2 /*
3  * Copyright 2007,2008 Free Software Foundation, Inc.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 // conditionalized on HAL_IO_USES_DBOARD_PINS && HAL_IO_USES_UART
20
21 #include "hal_io.h"
22 #include "memory_map.h"
23 #include "hal_uart.h"
24 #include "bool.h"
25 #include <stdio.h>
26 #include <string.h>
27 //#include <assert.h>
28
29 /*
30  * ========================================================================
31  *                                  GPIOS
32  * ========================================================================
33  */
34 void 
35 hal_gpio_set_ddr(int bank, int value, int mask)
36 {
37   bank &= 0x1;
38
39   if (bank == GPIO_TX_BANK){    // tx in top half
40     value <<= 16;
41     mask <<= 16;
42   }
43   else {
44     value &= 0xffff;
45     mask &= 0xffff;
46   }
47
48   int ei = hal_disable_ints();
49   gpio_base->ddr = (gpio_base->ddr & ~mask) | (value & mask);
50   hal_restore_ints(ei);
51 }
52
53 static bool
54 code_to_int(char code, int *val)
55 {
56   switch(code){
57   case 's':     *val = GPIO_SEL_SW;      return true;
58   case 'a':     *val = GPIO_SEL_ATR;     return true;
59   case '0':     *val = GPIO_SEL_DEBUG_0; return true;
60   case '1':     *val = GPIO_SEL_DEBUG_1; return true;
61   case '.':     
62   default:
63     return false;
64   }
65 }
66
67 void
68 hal_gpio_set_sel(int bank, int bitno, char code)
69 {
70   bank &= 0x1;
71   int   t;
72
73   if (!code_to_int(code, &t))
74     return;
75
76   int val  =   t << (2 * bitno);
77   int mask = 0x3 << (2 * bitno);
78
79   volatile uint32_t *sel = bank == GPIO_TX_BANK ? &gpio_base->tx_sel : &gpio_base->rx_sel;
80   int ei = hal_disable_ints();
81   int v = (*sel & ~mask) | (val & mask);
82   *sel = v;
83   hal_restore_ints(ei);
84
85   if (0)
86     printf("hal_gpio_set_sel(bank=%d, bitno=%d, code=%c) *sel = 0x%x\n",
87            bank, bitno, code, v);
88 }
89
90 void
91 hal_gpio_set_sels(int bank, char *codes)
92 {
93   //assert(strlen(codes) == 16);
94
95   int val = 0;
96   int mask = 0;
97   int i;
98
99   for (i = 15; i >= 0; i--){
100     val <<= 2;
101     mask <<= 2;
102     int t;
103     if (code_to_int(codes[i], &t)){
104       val  |= t;
105       mask |= 0x3;
106     }
107   }
108
109   volatile uint32_t *sel = bank == GPIO_TX_BANK ? &gpio_base->tx_sel : &gpio_base->rx_sel;
110   int ei = hal_disable_ints();
111   *sel = (*sel & ~mask) | (val & mask);
112   hal_restore_ints(ei);
113 }
114
115
116 /*!
117  * \brief write \p value to gpio pins specified by \p mask.
118  */
119 void
120 hal_gpio_write(int bank, int value, int mask)
121 {
122   static uint32_t       _gpio_io_shadow;
123
124   bank &= 0x1;
125
126   if (bank == GPIO_TX_BANK){    // tx in top half
127     value <<= 16;
128     mask <<= 16;
129   }
130   else {
131     value &= 0xffff;
132     mask &= 0xffff;
133   }
134
135   //int ei = hal_disable_ints();
136   _gpio_io_shadow = (_gpio_io_shadow & ~mask) | (value & mask);
137   gpio_base->io = _gpio_io_shadow;
138   //hal_restore_ints(ei);
139 }
140
141
142 /*!
143  * \brief read GPIO bits
144  */
145 int
146 hal_gpio_read(int bank)
147 {
148   bank &= 0x1;
149   int r = gpio_base->io;
150   if (bank == GPIO_TX_BANK)
151     r >>= 16;
152
153   return r & 0xffff;
154 }
155
156 /*
157  * ========================================================================
158  *                              leds
159  * ========================================================================
160  */
161
162 static unsigned long leds_shadow = 0;
163 static unsigned long led_src_shadow = 0;
164
165 void 
166 hal_set_leds(int value, int mask)
167 {
168   int ei = hal_disable_ints();
169   leds_shadow = (leds_shadow & ~mask) | (value & mask);
170   output_regs->leds = leds_shadow;
171   hal_restore_ints(ei);
172 }
173
174 // Allow hardware control over leds.  1 = hardware, 0 = software
175 void 
176 hal_set_led_src(int value, int mask)
177 {
178   int ei = hal_disable_ints();
179   led_src_shadow = (led_src_shadow & ~mask) | (value & mask);
180   output_regs->led_src = led_src_shadow;
181   hal_restore_ints(ei);
182 }
183
184 void 
185 hal_toggle_leds(int mask)
186 {
187   int ei = hal_disable_ints();
188   leds_shadow ^= mask;
189   output_regs->leds = leds_shadow;
190   hal_restore_ints(ei);
191 }
192
193
194 // ================================================================
195 //                              primitives
196 // ================================================================
197
198 #if defined(HAL_IO_USES_DBOARD_PINS)
199 //
200 // Does i/o using high 9-bits of rx daughterboard pins.
201 //
202 //  1 1 1 1 1 1
203 //  5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
204 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
205 // |      char     |W|             |
206 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
207 //
208 // 
209 // Asserts W when writing char
210 //
211
212 #define W       0x0080
213
214 void
215 hal_io_init(void)
216 {
217   // make high 9 bits of tx daughterboard outputs
218   hal_gpio_set_rx_mode(15, 7, GPIOM_OUTPUT);
219
220   // and set them to zero
221   hal_gpio_set_rx(0x0000, 0xff80);
222 }
223
224 void
225 hal_finish(void)
226 {
227   volatile unsigned long *p = (unsigned long *) 0xC2F0;
228   *p = 0;
229 }
230
231 // %c
232 inline int
233 putchar(int ch)
234 {
235   hal_gpio_set_rx((s << 8) | W, 0xff80);
236   hal_gpio_set_rx(0, 0xff80);
237   return ch;
238 }
239
240 #elif defined(HAL_IO_USES_UART)
241
242 void
243 hal_io_init(void)
244 {
245   hal_uart_init();
246 }
247
248 void
249 hal_finish(void)
250 {
251 }
252
253 // %c
254 inline int
255 putchar(int ch)
256 {
257   hal_uart_putc(ch);
258   return ch;
259 }
260
261 int
262 getchar(void)
263 {
264   return hal_uart_getc();
265 }
266
267 #else   // nop all i/o
268
269 void
270 hal_io_init(void)
271 {
272 }
273
274 void
275 hal_finish(void)
276 {
277 }
278
279 // %c
280 inline int
281 putchar(int ch)
282 {
283   return ch;
284 }
285
286 int
287 getchar(void)
288 {
289   return EOF;
290 }
291
292 #endif
293
294 // ================================================================
295 //             (slightly) higher level functions
296 //
297 // These are here so we can inline the calls to putchar.
298 // The rest of the stuff was moved to nonstdio.c
299 // ================================================================
300
301 // \n
302 inline void 
303 newline(void)
304 {
305   putchar('\n');
306 }
307
308 int
309 putstr(const char *s)
310 {
311   while (*s)
312     putchar(*s++);
313
314   return 0;
315 }
316
317 int
318 puts(const char *s)
319 {
320   putstr(s);
321   putchar('\n');
322   return 0;
323 }