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

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [sw/] [dev/] [doorbell2.c] - Blame information for rev 53

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    doorbell2.c
4
//
5
// Project:     CMod S6 System on a Chip, ZipCPU demonstration project
6
//
7 45 dgisselq
// Purpose:     A modification to the original doorbell.c program that played
8
//              a doorbell sound every ten seconds.  Listening to that test is
9
//      ... getting old.
10 15 dgisselq
//
11
//      Let's let this one do the following:
12
//              1. Display the time on the display (it will be impossible to
13
//                      change the time, sadly, but we can at least display it.)
14
//              2. On button press ...
15
//                      - Play the doorbell sound
16
//                      - Display "Doorbell!\n" on the Display, clearing the
17
//                              time
18
//                      - Send "Doorbell\n"  to the UART, and then keeping the
19
//                              UART silent for 30 seconds.
20
//              4. Send the time to the UART as well, but only once a minute.
21
//                      (and that if the Doorbell hasn't been rung in the last
22
//                      30 seconds ...)
23
//
24
// Creator:     Dan Gisselquist, Ph.D.
25
//              Gisselquist Technology, LLC
26
//
27
////////////////////////////////////////////////////////////////////////////////
28
//
29 45 dgisselq
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
30 15 dgisselq
//
31
// This program is free software (firmware): you can redistribute it and/or
32
// modify it under the terms of  the GNU General Public License as published
33
// by the Free Software Foundation, either version 3 of the License, or (at
34
// your option) any later version.
35
//
36
// This program is distributed in the hope that it will be useful, but WITHOUT
37
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
38
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
39
// for more details.
40
//
41
// You should have received a copy of the GNU General Public License along
42
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
43
// target there if the PDF file isn't present.)  If not, see
44
// <http://www.gnu.org/licenses/> for a copy.
45
//
46
// License:     GPL, v3, as defined and found on www.gnu.org,
47
//              http://www.gnu.org/licenses/gpl.html
48
//
49
//
50
////////////////////////////////////////////////////////////////////////////////
51
//
52
//
53
#include "board.h"
54
#include "rtcsim.h"
55
#include "display.h"
56 45 dgisselq
#include "string.h"
57
#include "txfns.h"
58 15 dgisselq
 
59
#include "samples.c"
60
 
61
void    build_dpymsg(char *msg, unsigned clkval);
62
void    build_uartmsg(char *msg, unsigned clkval);
63
void    showval(int val);
64
 
65 45 dgisselq
#define CLEAR_WATCHDOG  _sys->io_watchdog = 0
66
#define TOUCH_WATCHDOG  _sys->io_watchdog = 500000
67
 
68 15 dgisselq
void entry(void) {
69 45 dgisselq
        register volatile IOSPACE *const sys = _sys;
70
        char    dpymsg[64], *dpyptr;
71
        char    uartmsg[160], *uartptr;
72 15 dgisselq
        int     newmsgtime = 0, leastmsgtime = -1, lstmsgtime = 0;
73
 
74 45 dgisselq
        CLEAR_WATCHDOG;
75
 
76
        txstr("\r\nREBOOT!\r\n");
77
        txstr("Scope Control = "); txval(_scope->s_ctrl);
78
        if (_scope->s_ctrl & WBSCOPE_STOPPED) {
79
                int     ln = WBSCOPE_LENGTH(_scope->s_ctrl);
80
                for(int i=0; i<ln; i++)
81
                        txval(_scope->s_data);
82
                txval((int)_sys->io_buserr);
83
                txstr("\r\n\r\nEndScope\r\n");
84
        } else {
85
                txstr("\r\n");
86
                _scope->s_ctrl = 20;
87
        }
88
 
89 15 dgisselq
        dpymsg[0] = 0;
90
        dpyptr = dpymsg;
91
 
92
        uartmsg[0] = 0;
93
        build_uartmsg(uartmsg, 0);
94
        uartptr = uartmsg;
95
 
96 45 dgisselq
        sys->io_watchdog = 0;
97
        sys->io_pic = INT_CLEARPIC; // Acknowledge and turn off all interrupts
98 15 dgisselq
 
99
        sys->io_spio = 0x0f4;
100 45 dgisselq
        newmsgtime = sys->io_timer;
101 15 dgisselq
        leastmsgtime = -1;
102
        lstmsgtime = newmsgtime;
103
        while(1) {
104
                int     seconds, pic;
105 45 dgisselq
                const short     *sptr;
106 15 dgisselq
 
107
                // LED's off ... nothing to report
108
                sys->io_spio = 0x0f0;
109
 
110
                // Turn the audio off (initially)
111
                sys->io_pwm_audio = 0x0018000;
112
 
113
                // Set for one ticks per second, 80M clocks per tick
114 45 dgisselq
                sys->io_timer = TM_ONE_SECOND | TM_REPEAT;
115 15 dgisselq
 
116
                // We start by waiting for a doorbell
117
                while(((pic=sys->io_pic) & INT_BUTTON)==0) {
118 45 dgisselq
                        TOUCH_WATCHDOG;
119
 
120
                        if (pic & INT_TIMER) {// top of second
121
                                sys->io_pic = INT_TIMER;
122 15 dgisselq
                                rtcclock = rtcnext(rtcclock);
123
 
124
                                // Turn all LED off (again)
125
                                sys->io_spio = 0x0f0;
126
                                if (*dpyptr == '\0') {
127
                                        // Build a message for the display
128
                                        build_dpymsg(dpymsg, rtcclock);
129
                                        dpyptr = dpymsg;
130
                                }if(((rtcclock & 0x0ff)==0)&&(*uartptr=='\0')){
131
                                        build_uartmsg(uartmsg, rtcclock);
132
                                        uartptr = uartmsg;
133
 
134
                                        // Turn one LED on--top of minute
135
                                        sys->io_spio = 0x0f1;
136 45 dgisselq
                                        newmsgtime = sys->io_timer;
137 15 dgisselq
                                        lstmsgtime = -1;
138
                                        leastmsgtime = -1;
139
                                }
140
                        }
141 45 dgisselq
 
142 15 dgisselq
                        if (*uartptr) {
143
                                if (pic & INT_UARTTX) {
144
                                        sys->io_uart = *uartptr++;
145
                                        sys->io_spio = 0x22;
146
                                        sys->io_pic = INT_UARTTX;
147
 
148
                                        if (lstmsgtime != -1) {
149
                                                int tmp;
150 45 dgisselq
                                                tmp = (lstmsgtime-sys->io_timer);
151 15 dgisselq
                                                if ((leastmsgtime<0)||(tmp<leastmsgtime))
152
                                                        leastmsgtime = tmp;
153 45 dgisselq
                                        } lstmsgtime = sys->io_timer;
154 15 dgisselq
                                }
155
                        } else {
156
                                sys->io_spio = 0x20;
157
                        }
158
                        if (*dpyptr) {
159
                                // This will take a long time.  It should be an
160
                                // interruptable task ... but, sigh, we're not
161
                                // there yet.
162
                                dispchar(*dpyptr++);
163
                                sys->io_spio = 0x44;
164
                        } else {
165
                                sys->io_spio = 0x40;
166 45 dgisselq
                        } // sys->io_pic = (pic & (INT_TIMER|INT_UARTTX));
167 15 dgisselq
                }
168
 
169 45 dgisselq
                TOUCH_WATCHDOG;
170 15 dgisselq
                // DOORBELL!!!!!!
171
                // Set the Display message
172 45 dgisselq
                strcpy(dpymsg, "a[jDoorbell!");
173
                dpymsg[0] = 0x1b;
174 15 dgisselq
                dpyptr = dpymsg;
175
                // And the UART message / 18 characters
176
                uartptr = uartmsg;
177 45 dgisselq
                strcat(uartptr, "\r\nDoorbell!\r\n\r\n");
178 15 dgisselq
                uartptr = uartmsg;
179
 
180
 
181
                seconds = 0;
182
                sys->io_spio = 0x0ff; // All LED's on: we got one!
183
                sptr = sound_data;
184
                sys->io_pwm_audio = 0x0310000; // Turn on the audio
185
                while(sptr < &sound_data[NSAMPLE_WORDS]) {
186
                        do {
187 45 dgisselq
                                TOUCH_WATCHDOG;
188 15 dgisselq
                                pic = sys->io_pic;
189 45 dgisselq
                                if (pic & INT_TIMER) {
190
                                        sys->io_pic = INT_TIMER;
191 15 dgisselq
                                        seconds++;
192
                                        rtcclock = rtcnext(rtcclock);
193
                                } if ((pic & INT_UARTTX)&&(*uartptr)) {
194
                                        sys->io_uart = *uartptr++;
195
                                        sys->io_pic = INT_UARTTX;
196
                                        sys->io_spio = 0x22;
197
                                } else if (!*uartptr)
198
                                        sys->io_spio = 0x20;
199
                                if (*dpyptr) {
200
                                // This will take a long time.  It should be an
201
                                // interruptable task ... but, sigh, we're not
202
                                // there yet.
203
                                        dispchar(*dpyptr++);
204 45 dgisselq
                                        sys->io_spio = 0x45;
205 15 dgisselq
                                } else
206
                                        sys->io_spio = 0x40;
207
                        } while((pic & INT_AUDIO)==0);
208 45 dgisselq
                        sys->io_pwm_audio = (*sptr++) & 0x0ffff;
209 15 dgisselq
                        // Now, turn off the audio interrupt since it doesn't
210
                        // reset itself ...
211
                        sys->io_pic = INT_AUDIO;
212
                } sys->io_pic = INT_BUTTON;
213 45 dgisselq
                sys->io_spio = 0x10;
214 15 dgisselq
 
215 45 dgisselq
                TOUCH_WATCHDOG;
216 15 dgisselq
                // Now we wait for the end of our 30 second window
217
                sys->io_spio = 0x0f8;
218
                sys->io_pwm_audio = 0x018000; // Turn off the Audio device
219
                while(seconds < 30) {
220 45 dgisselq
                        TOUCH_WATCHDOG;
221 15 dgisselq
                        pic = sys->io_pic;
222 45 dgisselq
                        if (pic & INT_TIMER) {
223
                                sys->io_pic = INT_TIMER;
224 15 dgisselq
                                seconds++;
225
                                rtcclock = rtcnext(rtcclock);
226
                        } if (pic & INT_BUTTON) {
227
                                sys->io_pic = INT_BUTTON;
228
                                seconds = 0;
229
                        }
230
                } sys->io_pic = INT_BUTTON;
231 45 dgisselq
                TOUCH_WATCHDOG;
232 15 dgisselq
        }
233
}
234
 
235
void    build_dpymsg(char *msg, unsigned clk) {
236 45 dgisselq
        msg[0] = 0x1b;
237
        strcpy(++msg, "[jClock : ");
238
        msg += strlen(msg);
239
 
240 15 dgisselq
        if ((clk>>20)&0x0f)
241
                *msg++ |= (((clk>>20)&0x0f)+'0');
242
        else
243
                *msg++ |= ' ';
244 45 dgisselq
        *msg++ = (((clk>>16)&0x0f)+'0');
245
        *msg++ = ':';
246
        *msg++ = (((clk>>12)&0x0f)+'0');
247
        *msg++ = (((clk>> 8)&0x0f)+'0');
248
        *msg++ = ':';
249
        *msg++ = (((clk>> 4)&0x0f)+'0');
250
        *msg++ = (((clk    )&0x0f)+'0');
251 15 dgisselq
        *msg++ = 0;
252
}
253
 
254
void    build_uartmsg(char *msg, unsigned clk) {
255 45 dgisselq
        strcpy(msg, "Time: ");
256
        msg += strlen(msg);
257 15 dgisselq
        *msg++ = ((clk>>20)&0x03)+'0'; // Hrs
258
        *msg++ = ((clk>>16)&0x0f)+'0';
259
        *msg++ = ':';
260
        *msg++ = ((clk>>12)&0x0f)+'0'; // Mins
261
        *msg++ = ((clk>> 8)&0x0f)+'0';
262
        *msg++ = '\r';                  // 11
263
        *msg++ = '\n';                  // 12
264
        *msg++ = '\0';
265
        *msg++ = '\0';
266
}
267
 
268
void    showval(int val) {
269
        // Clear and home
270
        dispchar(0x1b);
271
        dispchar('[');
272
        dispchar('j');
273
        for(int i=28; i>=0; i-=4) {
274
                int ch = ((val>>i)&0x0f)+'0';
275
                if (ch > '9')
276
                        ch = ch - '0'+'A'-10;
277
                dispchar(ch);
278
        }
279
}

powered by: WebSVN 2.1.0

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