Imported Upstream version 3.2.2
[debian/gnuradio] / usrp2 / firmware / apps / sd_gentest.c
1 /*
2  * Copyright 2007,2008 Free Software Foundation, Inc.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 #include "u2_init.h"
22 #include "memory_map.h"
23 #include "spi.h"
24 #include "hal_io.h"
25 #include "buffer_pool.h"
26 #include "pic.h"
27 #include "bool.h"
28 #include "nonstdio.h"
29 #include "memset_wa.h"
30 #include <stddef.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <clocks.h>
34 #include <mdelay.h>
35
36 // ----------------------------------------------------------------
37
38 int packet_number = 0;
39 volatile bool send_packet_now = 0;
40
41 #define SERDES_TX_BUF   0
42 #define SERDES_RX_BUF   1
43
44
45 #define NLINES_PER_PKT  380
46
47
48 // ----------------------------------------------------------------
49
50 //static int timer_delta = (int)(MASTER_CLK_RATE * 100e-6);
51 static int timer_delta = 1000000; // .01 second
52
53 void
54 timer_irq_handler(unsigned irq)
55 {
56   hal_set_timeout(timer_delta); // schedule next timeout
57   send_packet_now = true;
58 }
59
60
61 static void
62 init_packet(int *buf)
63 {
64   int i = 0;
65   for (i = 0; i < BP_NLINES; i++){
66     buf[i] = ((2*i + 0) << 16) | (2*i+1);
67   }
68 }
69
70 static bool
71 check_packet(int *buf, int nlines)
72 {
73   bool ok = true;
74   int i = 0;
75   for (i = 0; i < nlines; i++){
76     int expected = ((2*i + 0) << 16) | (2*i+1);
77     if (buf[i] != expected){
78       ok = false;
79       printf("buf[%d] = 0x%x  expected = 0x%x\n", i, buf[i], expected);
80     }
81   }
82   return ok;
83 }
84
85 static void
86 zero_buffer(int bufno)
87 {
88   memset_wa(buffer_ram(bufno), 0, BP_NLINES * 4);
89 }
90
91 static void
92 init_packets(void)
93 {
94   // init just the one we're using
95   init_packet(buffer_ram(SERDES_TX_BUF));
96 }
97
98 int
99 main(void)
100 {
101   u2_init();
102
103   // We're free running and provide clock to the MIMO interface
104   clocks_mimo_config(MC_WE_DONT_LOCK | MC_PROVIDE_CLK_TO_MIMO);
105
106
107   // setup tx gpio bits for GPIOM_FPGA_1 -- fpga debug output
108   // output_regs->debug_mux_ctrl = 1;
109   // hal_gpio_set_sels(GPIO_TX_BANK, "1111111111111111");
110   // hal_gpio_set_sels(GPIO_RX_BANK, "1111111111111111");
111
112   putstr("\nsd_gentest\n");
113   
114   // Set up serdes (already enabled)
115   //output_regs->serdes_ctrl = (SERDES_ENABLE | SERDES_RXEN | SERDES_LOOPEN);
116   //output_regs->serdes_ctrl = (SERDES_ENABLE | SERDES_RXEN);
117
118   init_packets();
119
120   // pic_register_handler(IRQ_TIMER, timer_irq_handler);
121
122   //if (hwconfig_simulation_p())
123   //  timer_delta = sim_timer_delta;
124
125   // start a receive from sd
126   zero_buffer(SERDES_RX_BUF);
127   bp_receive_to_buf(SERDES_RX_BUF, PORT_SERDES, 1, 0, BP_LAST_LINE);
128
129   // fire off the first packet
130   bp_send_from_buf(SERDES_TX_BUF, PORT_SERDES, 1, 0, NLINES_PER_PKT);
131   hal_set_timeout(timer_delta);
132   int ready_to_send = 0;
133
134   int counter __attribute__((unused)) = 0;
135   int sent = 1;
136   int txerr = 0;
137   int rxerr = 0;
138   int rcvd = 0;
139   int rxcrc = 0;
140   int sent_acc = 0;
141   int txerr_acc = 0;
142   int rxerr_acc = 0;
143   int rcvd_acc = 0;
144   int rxcrc_acc = 0;
145
146 #define EXPECTING_PKT() ((counter & 0x1) == 0)
147 #define SEND_PKT()      ((counter & 0x1) != 0)
148
149   bool got_packet = false;
150
151   while(1){
152     uint32_t status = buffer_pool_status->status;
153
154     if (status & (BPS_DONE(SERDES_RX_BUF))){
155       bp_clear_buf(SERDES_RX_BUF);
156       got_packet = true;
157
158       //hal_toggle_leds(0x2);
159
160       // check packet
161       int last_line = buffer_pool_status->last_line[SERDES_RX_BUF]-1;
162       bool ok = check_packet(buffer_ram(SERDES_RX_BUF), last_line);
163       
164       if (ok) {
165         rcvd++;
166         //putchar('r');
167       }
168       else {
169         rcvd++;
170         rxcrc++;
171         //putchar('P');
172       }
173       // start a receive from sd
174       zero_buffer(SERDES_RX_BUF);
175       bp_receive_to_buf(SERDES_RX_BUF, PORT_SERDES, 1, 0, BP_LAST_LINE);
176     }
177
178     if (status & (BPS_ERROR(SERDES_RX_BUF))){
179       bp_clear_buf(SERDES_RX_BUF);
180       got_packet = true;
181       rcvd++;
182       rxerr++;
183       //putchar('E');
184
185       // start a receive from sd
186       zero_buffer(SERDES_RX_BUF);
187       bp_receive_to_buf(SERDES_RX_BUF, PORT_SERDES, 1, 0, BP_LAST_LINE);
188     }
189
190     if (status & (BPS_DONE(SERDES_TX_BUF))){
191       bp_clear_buf(SERDES_TX_BUF);
192       //putchar('t');
193       bp_send_from_buf(SERDES_TX_BUF, PORT_SERDES, 1, 0, NLINES_PER_PKT);
194       //mdelay(1);
195       int       i;
196       for (i = 0; i < 50; i++){
197         asm volatile ("or  r0, r0, r0\n\
198                    or  r0, r0, r0\n    \
199                    or  r0, r0, r0\n    \
200                    or  r0, r0, r0\n    \
201                    or  r0, r0, r0\n    \
202                    or  r0, r0, r0\n    \
203                    or  r0, r0, r0\n");
204       }
205       sent ++;
206       ready_to_send = 1;
207       //hal_toggle_leds(0x1);
208     }
209
210     if (status & BPS_ERROR(SERDES_TX_BUF)){
211       bp_clear_buf(SERDES_TX_BUF);
212       sent++;
213       txerr++;
214       ready_to_send = 1;
215       //putchar('X');
216     }
217
218     if(sent >=1000) {
219       printf("Status\tSENT %d\tTXERR %d\t",sent,txerr);
220       printf("RX %d\tERR %d\tCRC %d\tMISSED %d\n",rcvd, rxerr, rxcrc, sent-rcvd);
221       sent_acc += sent; sent = 0;
222       txerr_acc += txerr; txerr = 0;
223       rcvd_acc += rcvd; rcvd = 0;
224       rxerr_acc += rxerr; rxerr = 0;
225       rxcrc_acc += rxcrc; rxcrc = 0;
226     }
227
228     if(sent_acc >=10000) {
229       printf("\nOverall\tSENT %d\tTXERR %d\t",sent_acc,txerr_acc);
230       printf("RX %d\tERR %d\tCRC %d\tMISSED %d\n\n",rcvd_acc, rxerr_acc, rxcrc_acc, sent_acc-rcvd_acc);
231       sent_acc = 0;
232       txerr_acc = 0;
233       rcvd_acc = 0;
234       rxerr_acc = 0;
235       rxcrc_acc = 0;
236     }
237 #if 0
238     int pending = pic_regs->pending;
239     if (pending & PIC_TIMER_INT){
240       hal_set_timeout(timer_delta);
241       
242       /*
243         if (EXPECTING_PKT()){
244         if (!got_packet)
245           putchar('T');
246         got_packet = false;
247       }
248
249       if (SEND_PKT()){
250         if (status & BPS_IDLE(SERDES_TX_BUF))
251           bp_send_from_buf(SERDES_TX_BUF, PORT_SERDES, 1, 0, NLINES_PER_PKT);
252       }
253       counter++;
254       */
255
256       putchar('T');
257       if(ready_to_send) {
258         bp_send_from_buf(SERDES_TX_BUF, PORT_SERDES, 1, 0, NLINES_PER_PKT);
259         counter++;
260         ready_to_send = 0;
261       }
262       
263       pic_regs->pending = PIC_TIMER_INT;        // clear pending interrupt
264     }
265 #endif
266   }
267   
268   return 0;
269 }