OpenCores
URL https://opencores.org/ocsvn/openarty/openarty/trunk

Subversion Repositories openarty

[/] [openarty/] [trunk/] [sw/] [board/] [exmulti.c] - Blame information for rev 49

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    exmulti.c
4
//
5
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
6
//
7
// Purpose:     Very similar to exstartup.c, the purpose of this program is to
8
//              demonstrate several working peripherals.  To the exstartup
9
//      peripherals, we'll add the GPS and the GPS PPS tracking.
10
//
11
// Creator:     Dan Gisselquist, Ph.D.
12
//              Gisselquist Technology, LLC
13
//
14
////////////////////////////////////////////////////////////////////////////////
15
//
16
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
17
//
18
// This program is free software (firmware): you can redistribute it and/or
19
// modify it under the terms of  the GNU General Public License as published
20
// by the Free Software Foundation, either version 3 of the License, or (at
21
// your option) any later version.
22
//
23
// This program is distributed in the hope that it will be useful, but WITHOUT
24
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
25
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26
// for more details.
27
//
28
// You should have received a copy of the GNU General Public License along
29
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
30
// target there if the PDF file isn't present.)  If not, see
31
// <http://www.gnu.org/licenses/> for a copy.
32
//
33
// License:     GPL, v3, as defined and found on www.gnu.org,
34
//              http://www.gnu.org/licenses/gpl.html
35
//
36
//
37
////////////////////////////////////////////////////////////////////////////////
38
//
39
//
40 49 dgisselq
#include "zipcpu.h"
41
#include "zipsys.h"
42 36 dgisselq
#include "artyboard.h"
43
 
44
void    idle_task(void) {
45
        while(1)
46
                zip_idle();
47
}
48
 
49
void    wait_on_interrupt(int mask) {
50 49 dgisselq
        zip->z_pic = DALLPIC|mask;
51
        zip->z_pic = EINT(mask);
52 36 dgisselq
        zip_rtu();
53
}
54
 
55
int     user_stack[256];
56
void    user_task(void) {
57
        const unsigned white = 0x070707, black = 0;
58
        while(1) {
59
                unsigned        btn, subnow, sw;
60
 
61
                subnow = (sys->io_gps_sub >> 28)&0x0f;
62
 
63
                // If the button is pressed, toggle the LED
64
                // Otherwise, turn the LED off.
65
                //
66
 
67
                // First, get all the pressed buttons
68
                btn = (sys->io_btnsw) & 0x0f0;
69
                // Now, acknowledge the button presses that we just read
70
                sys->io_btnsw = btn;
71
                btn >>= 4;
72
 
73
                // Now, use the time as the toggle function.
74
                btn = (subnow ^ btn)&btn & 0x07;
75
 
76
                sys->io_ledctrl = btn | 0x070;
77
 
78
                sw = sys->io_btnsw & 0x0f;
79
                for(int i=0; i<4; i++)
80
                        sys->io_clrled[i] = (sw & (1<<i)) ? white : black;
81
 
82
        }
83
}
84
 
85
int     mpyuhi(int a, int b) {
86
        // err_in_ns = mpyuhi(err_in_ns, err);
87
        // __asm__("MPYUHI %1,%0" :"+r"(a):"r"(b));
88
        unsigned alo, blo, ahi, bhi, f, o, i, l, rhi;
89
 
90
        alo = (a & 0x0ffff);
91
        ahi = (a >> 16)&0x0ffff;
92
        blo = (b & 0x0ffff);
93
        bhi = (b >> 16)&0x0ffff;
94
 
95
        l = alo * blo;
96
        o = ahi * blo;
97
        i = alo * bhi;
98
        f = ahi * bhi;
99
 
100
        rhi = o + i + (l >> 16);
101
        return (rhi >> 16) + f;
102
        // return f;
103
        // return ahi;
104
}
105
 
106
int     hexdigit(int v) {
107
        if (v < 10)
108
                return v + '0';
109
        else
110
                return v + 'A' - 10;
111
}
112
 
113
int     errstring[128];
114
 
115 49 dgisselq
void    main(int argc, char **argv) {
116 36 dgisselq
        const unsigned red = 0x0ff0000, green = 0x0ff00, blue = 0x0ff,
117
                white = 0x070707, black = 0, dimgreen = 0x1f00,
118 49 dgisselq
                second = CLOCKFREQHZ;
119 36 dgisselq
        int     i, sw;
120
 
121
        // Start the GPS converging ...
122
        sys->io_gps.g_alpha = 2;
123
        sys->io_gps.g_beta  = 0x14bda12f;
124
        sys->io_gps.g_gamma = 0x1f533ae8;
125
 
126
        int     user_context[16];
127
        for(i=0; i<15; i++)
128
                user_context[i] = 0;
129
        user_context[15] = (unsigned)idle_task;
130
        zip_restore_context(user_context);
131
 
132
        for(i=0; i<4; i++)
133
                sys->io_clrled[i] = red;
134
        sys->io_ledctrl = 0x0ff;
135
 
136
        // Clear the PIC
137
        //
138
        //      Acknowledge all interrupts, turn off all interrupts
139
        //
140 49 dgisselq
        zip->z_pic = CLEARPIC;
141 36 dgisselq
        while(sys->io_pwrcount < (second >> 4))
142
                ;
143
 
144
        // Repeating timer, every 250ms
145 49 dgisselq
        zip->z_tma = TMR_INTERVAL | (second/4);
146 36 dgisselq
        wait_on_interrupt(SYSINT_TMA);
147
 
148
        sys->io_clrled[0] = green;
149
        sys->io_ledctrl = 0x010;
150
 
151
        wait_on_interrupt(SYSINT_TMA);
152
 
153
        sys->io_clrled[0] = dimgreen;
154
        sys->io_clrled[1] = green;
155 49 dgisselq
        sys->io_scope[0].s_ctrl = SCOPE_NO_RESET | 32;
156 36 dgisselq
        sys->io_ledctrl = 0x020;
157
 
158
        wait_on_interrupt(SYSINT_TMA);
159
 
160
        sys->io_clrled[1] = dimgreen;
161
        sys->io_clrled[2] = green;
162
        sys->io_ledctrl = 0x040;
163
 
164
        wait_on_interrupt(SYSINT_TMA);
165
 
166
        sys->io_clrled[2] = dimgreen;
167
        sys->io_clrled[3] = green;
168
        sys->io_ledctrl = 0x080;
169
 
170
        wait_on_interrupt(SYSINT_TMA);
171
 
172
        sys->io_clrled[3] = dimgreen;
173
 
174
        wait_on_interrupt(SYSINT_TMA);
175
 
176
        for(i=0; i<4; i++)
177
                sys->io_clrled[i] = black;
178
 
179
        // Wait one second ...
180
        for(i=0; i<4; i++)
181
                wait_on_interrupt(SYSINT_TMA);
182
 
183
        // Blink all the LEDs
184
        //      First turn them on
185
        sys->io_ledctrl = 0x0ff;
186
        // Then wait a quarter second
187
        wait_on_interrupt(SYSINT_TMA);
188
        // Then turn the back off
189
        sys->io_ledctrl = 0x0f0;
190
        // and wait another quarter second
191
        wait_on_interrupt(SYSINT_TMA);
192
 
193
        // Now, read buttons, and flash an LED on any button being held
194
        // down ... ? neat?
195
 
196
        // Now, let's synchronize ourselves to the PPS
197
        user_context[13] = (int)&user_stack[256];
198
        user_context[15] = (int)&user_task;
199
        zip_restore_context(user_context);
200
 
201
        do {
202
                wait_on_interrupt(SYSINT_PPS|SYSINT_TMA);
203 49 dgisselq
        } while((zip->z_pic & SYSINT_PPS)==0);
204 36 dgisselq
 
205
        while(1) {
206
                int     *s = errstring;
207
 
208 49 dgisselq
                zip->z_wdt = CLOCKFREQ_HZ*4;
209 36 dgisselq
                sys->io_ledctrl = 0x088;
210
 
211
                // 1. Read and report the GPS tracking err
212
 
213
                // Get the upper 32-bits of the error;
214
                int     err = *(int *)(&sys->io_gpstb.tb_err);
215
                int     err_in_ns;
216
                /*
217
                long    err_in_ns_long = err;
218
                err_in_ns_long *= 1000000000l;
219
                err_in_ns_long >>= 32;
220
                int     err_in_ns = (int)(err_in_ns_long);
221
                */
222
                int     err_sgn = (err < 0)?1:0;
223
                err_in_ns = (err<0)?-err:err;
224
                err_in_ns = mpyuhi(err_in_ns, 1000000000);
225
                int     digit;
226
 
227
 
228
                *s++ = '\r';
229
                *s++ = '\n';
230
                *s++ = 'G';
231
                *s++ = 'P';
232
                *s++ = 'S';
233
                *s++ = ' ';
234
                *s++ = 'P';
235
                *s++ = 'P';
236
                *s++ = 'S';
237
                *s++ = ' ';
238
                *s++ = 'E';
239
                *s++ = 'r';
240
                *s++ = 'r';
241
                *s++ = ':';
242
                *s++ = ' ';
243
 
244
 
245
                *s++ = '0';
246
                *s++ = 'x';
247
                *s++ = hexdigit((err>>28)&0x0f);
248
                *s++ = hexdigit((err>>24)&0x0f);
249
                *s++ = hexdigit((err>>20)&0x0f);
250
                *s++ = hexdigit((err>>16)&0x0f);
251
                *s++ = hexdigit((err>>12)&0x0f);
252
                *s++ = hexdigit((err>> 8)&0x0f);
253
                *s++ = hexdigit((err>> 4)&0x0f);
254
                *s++ = hexdigit((err    )&0x0f);
255
 
256
                *s++ = ' ';
257
                *s++ = '=';
258
                *s++ = '>';
259
                *s++ = ' ';
260
 
261
                *s++ = '0';
262
                *s++ = 'x';
263
                *s++ = hexdigit((err_in_ns>>28)&0x0f);
264
                *s++ = hexdigit((err_in_ns>>24)&0x0f);
265
                *s++ = hexdigit((err_in_ns>>20)&0x0f);
266
                *s++ = hexdigit((err_in_ns>>16)&0x0f);
267
                *s++ = hexdigit((err_in_ns>>12)&0x0f);
268
                *s++ = hexdigit((err_in_ns>> 8)&0x0f);
269
                *s++ = hexdigit((err_in_ns>> 4)&0x0f);
270
                *s++ = hexdigit((err_in_ns    )&0x0f);
271
 
272
                *s++ = ' ';
273
                *s++ = '=';
274
                *s++ = '>';
275
                *s++ = ' ';
276
 
277
                *s++ = (err_sgn)?'-':' ';
278
                // Milliseconds
279
                digit = err_in_ns / 100000000;
280
                *s++ = digit+'0';
281
                err_in_ns -= digit * 100000000;
282
                //
283
                digit = err_in_ns / 10000000;
284
                *s++ = digit+'0';
285
                err_in_ns -= digit * 10000000;
286
                //
287
                digit = err_in_ns / 1000000;
288
                *s++ = digit+'0';
289
                err_in_ns -= digit * 1000000;
290
                // Micro seconds
291
                digit = err_in_ns / 100000;
292
                *s++ = digit+'0';
293
                err_in_ns -= digit * 100000;
294
                //
295
                digit = err_in_ns / 10000;
296
                *s++ = digit+'0';
297
                err_in_ns -= digit * 10000;
298
                //
299
                digit = err_in_ns / 1000;
300
                *s++ = digit+'0';
301
                err_in_ns -= digit * 1000;
302
                // Nano seconds
303
                *s++ = '.';
304
                digit = err_in_ns / 100;
305
                *s++ = digit+'0';
306
                err_in_ns -= digit * 100;
307
                //
308
                digit = err_in_ns / 10;
309
                *s++ = digit+'0';
310
                err_in_ns -= digit * 10;
311
                //
312
                digit = err_in_ns;
313
                *s++ = digit+'0';
314
                //
315
                *s++ = ' ';
316
                *s++ = 'u';
317
                *s++ = 'S';
318
                *s++ = '\r';
319
                *s++ = '\n';
320
                *s++ = '\r';
321
                *s++ = '\n';
322
                *s++ = '\0';
323
 
324
                /*
325 49 dgisselq
                zip->z_dma.d_ctrl = DMACLEAR;
326
                zip->z_dma.d_rd = errstring;
327
                zip->z_dma.d_wr = &sys->io_uart_tx;
328
                zip->z_dma.d_len = s - errstring-1;
329
                zip->z_dma.d_ctrl = (DMAONEATATIME|DMA_CONSTDST|DMA_GPSRX);
330 36 dgisselq
                wait_on_interrupt(SYSINT_DMAC);
331
                */
332
 
333
                for(int i=0; errstring[i]; i++) {
334
                        wait_on_interrupt(SYSINT_UARTTX);
335
                        sys->io_uart_tx = errstring[i];
336 49 dgisselq
                        zip->z_pic = SYSINT_UARTTX;
337 36 dgisselq
                }
338
 
339
                sys->io_ledctrl = 0x080;
340
 
341
                /*
342 49 dgisselq
                zip->z_dma.d_rd = &sys->io_gps_rx;
343
                zip->z_dma.d_wr = &sys->io_uart_tx;
344
                zip->z_dma.d_len = 0x01000000;
345
                zip->z_dma.d_ctrl = (DMAONEATATIME|DMA_CONSTDST|DMA_CONSTSRC|DMA_ONGPSRX);
346 36 dgisselq
                wait_on_interrupt(SYSINT_PPS);
347
                */
348
 
349
                /*
350
                if (zip_ucc() & CC_FAULT) {
351
                        zip_save_context(user_context);
352
                        user_context[14] = CC_GIE;
353
                        user_context[15] = (int)&idle_task;
354
                        zip_restore_context(user_context);
355
                }
356
                */
357
 
358 49 dgisselq
                zip->z_pic = SYSINT_GPSRX | SYSINT_PPS;
359 36 dgisselq
                do {
360
                        wait_on_interrupt(SYSINT_PPS|SYSINT_GPSRX);
361 49 dgisselq
                        if (zip->z_pic & SYSINT_GPSRX) {
362 36 dgisselq
                                sys->io_uart_tx = sys->io_gps_rx;
363 49 dgisselq
                                zip->z_pic = SYSINT_GPSRX;
364 36 dgisselq
                        }
365 49 dgisselq
                } while((zip->z_pic & SYSINT_PPS)==0);
366 36 dgisselq
 
367
                // wait_on_interrupt(SYSINT_PPS);
368 49 dgisselq
                // zip->z_dma.d_ctrl= DMACLEAR;
369 36 dgisselq
        }
370
 
371
        zip_halt();
372
}
373
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.