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

Subversion Repositories s6soc

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

Go to most recent revision | 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 "asmstartup.h"
54
#include "board.h"
55
#include "rtcsim.h"
56
#include "display.h"
57 45 dgisselq
#include "string.h"
58
#include "txfns.h"
59 15 dgisselq
 
60
#include "samples.c"
61
 
62
void    zip_halt(void);
63
 
64
void    build_dpymsg(char *msg, unsigned clkval);
65
void    build_uartmsg(char *msg, unsigned clkval);
66
void    showval(int val);
67
 
68 45 dgisselq
#define CLEAR_WATCHDOG  _sys->io_watchdog = 0
69
#define TOUCH_WATCHDOG  _sys->io_watchdog = 500000
70
 
71 15 dgisselq
void entry(void) {
72 45 dgisselq
        register volatile IOSPACE *const sys = _sys;
73
        char    dpymsg[64], *dpyptr;
74
        char    uartmsg[160], *uartptr;
75 15 dgisselq
        int     newmsgtime = 0, leastmsgtime = -1, lstmsgtime = 0;
76
 
77 45 dgisselq
        CLEAR_WATCHDOG;
78
 
79
        txstr("\r\nREBOOT!\r\n");
80
        txstr("Scope Control = "); txval(_scope->s_ctrl);
81
        if (_scope->s_ctrl & WBSCOPE_STOPPED) {
82
                int     ln = WBSCOPE_LENGTH(_scope->s_ctrl);
83
                for(int i=0; i<ln; i++)
84
                        txval(_scope->s_data);
85
                txval((int)_sys->io_buserr);
86
                txstr("\r\n\r\nEndScope\r\n");
87
        } else {
88
                txstr("\r\n");
89
                _scope->s_ctrl = 20;
90
        }
91
 
92 15 dgisselq
        dpymsg[0] = 0;
93
        dpyptr = dpymsg;
94
 
95
        uartmsg[0] = 0;
96
        build_uartmsg(uartmsg, 0);
97
        uartptr = uartmsg;
98
 
99 45 dgisselq
        sys->io_watchdog = 0;
100
        sys->io_pic = INT_CLEARPIC; // Acknowledge and turn off all interrupts
101 15 dgisselq
 
102
        sys->io_spio = 0x0f4;
103 45 dgisselq
        newmsgtime = sys->io_timer;
104 15 dgisselq
        leastmsgtime = -1;
105
        lstmsgtime = newmsgtime;
106
        while(1) {
107
                int     seconds, pic;
108 45 dgisselq
                const short     *sptr;
109 15 dgisselq
 
110
                // LED's off ... nothing to report
111
                sys->io_spio = 0x0f0;
112
 
113
                // Turn the audio off (initially)
114
                sys->io_pwm_audio = 0x0018000;
115
 
116
                // Set for one ticks per second, 80M clocks per tick
117 45 dgisselq
                sys->io_timer = TM_ONE_SECOND | TM_REPEAT;
118 15 dgisselq
 
119
                // We start by waiting for a doorbell
120
                while(((pic=sys->io_pic) & INT_BUTTON)==0) {
121 45 dgisselq
                        TOUCH_WATCHDOG;
122
 
123
                        if (pic & INT_TIMER) {// top of second
124
                                sys->io_pic = INT_TIMER;
125 15 dgisselq
                                rtcclock = rtcnext(rtcclock);
126
 
127
                                // Turn all LED off (again)
128
                                sys->io_spio = 0x0f0;
129
                                if (*dpyptr == '\0') {
130
                                        // Build a message for the display
131
                                        build_dpymsg(dpymsg, rtcclock);
132
                                        dpyptr = dpymsg;
133
                                }if(((rtcclock & 0x0ff)==0)&&(*uartptr=='\0')){
134
                                        build_uartmsg(uartmsg, rtcclock);
135
                                        uartptr = uartmsg;
136
 
137
                                        // Turn one LED on--top of minute
138
                                        sys->io_spio = 0x0f1;
139 45 dgisselq
                                        newmsgtime = sys->io_timer;
140 15 dgisselq
                                        lstmsgtime = -1;
141
                                        leastmsgtime = -1;
142
                                }
143
                        }
144 45 dgisselq
 
145 15 dgisselq
                        if (*uartptr) {
146
                                if (pic & INT_UARTTX) {
147
                                        sys->io_uart = *uartptr++;
148
                                        sys->io_spio = 0x22;
149
                                        sys->io_pic = INT_UARTTX;
150
 
151
                                        if (lstmsgtime != -1) {
152
                                                int tmp;
153 45 dgisselq
                                                tmp = (lstmsgtime-sys->io_timer);
154 15 dgisselq
                                                if ((leastmsgtime<0)||(tmp<leastmsgtime))
155
                                                        leastmsgtime = tmp;
156 45 dgisselq
                                        } lstmsgtime = sys->io_timer;
157 15 dgisselq
                                }
158
                        } else {
159
                                sys->io_spio = 0x20;
160
                        }
161
                        if (*dpyptr) {
162
                                // This will take a long time.  It should be an
163
                                // interruptable task ... but, sigh, we're not
164
                                // there yet.
165
                                dispchar(*dpyptr++);
166
                                sys->io_spio = 0x44;
167
                        } else {
168
                                sys->io_spio = 0x40;
169 45 dgisselq
                        } // sys->io_pic = (pic & (INT_TIMER|INT_UARTTX));
170 15 dgisselq
                }
171
 
172 45 dgisselq
                TOUCH_WATCHDOG;
173 15 dgisselq
                // DOORBELL!!!!!!
174
                // Set the Display message
175 45 dgisselq
                strcpy(dpymsg, "a[jDoorbell!");
176
                dpymsg[0] = 0x1b;
177 15 dgisselq
                dpyptr = dpymsg;
178
                // And the UART message / 18 characters
179
                uartptr = uartmsg;
180 45 dgisselq
                strcat(uartptr, "\r\nDoorbell!\r\n\r\n");
181 15 dgisselq
                uartptr = uartmsg;
182
 
183
 
184
                seconds = 0;
185
                sys->io_spio = 0x0ff; // All LED's on: we got one!
186
                sptr = sound_data;
187
                sys->io_pwm_audio = 0x0310000; // Turn on the audio
188
                while(sptr < &sound_data[NSAMPLE_WORDS]) {
189
                        do {
190 45 dgisselq
                                TOUCH_WATCHDOG;
191 15 dgisselq
                                pic = sys->io_pic;
192 45 dgisselq
                                if (pic & INT_TIMER) {
193
                                        sys->io_pic = INT_TIMER;
194 15 dgisselq
                                        seconds++;
195
                                        rtcclock = rtcnext(rtcclock);
196
                                } if ((pic & INT_UARTTX)&&(*uartptr)) {
197
                                        sys->io_uart = *uartptr++;
198
                                        sys->io_pic = INT_UARTTX;
199
                                        sys->io_spio = 0x22;
200
                                } else if (!*uartptr)
201
                                        sys->io_spio = 0x20;
202
                                if (*dpyptr) {
203
                                // This will take a long time.  It should be an
204
                                // interruptable task ... but, sigh, we're not
205
                                // there yet.
206
                                        dispchar(*dpyptr++);
207 45 dgisselq
                                        sys->io_spio = 0x45;
208 15 dgisselq
                                } else
209
                                        sys->io_spio = 0x40;
210
                        } while((pic & INT_AUDIO)==0);
211 45 dgisselq
                        sys->io_pwm_audio = (*sptr++) & 0x0ffff;
212 15 dgisselq
                        // Now, turn off the audio interrupt since it doesn't
213
                        // reset itself ...
214
                        sys->io_pic = INT_AUDIO;
215
                } sys->io_pic = INT_BUTTON;
216 45 dgisselq
                sys->io_spio = 0x10;
217 15 dgisselq
 
218 45 dgisselq
                TOUCH_WATCHDOG;
219 15 dgisselq
                // Now we wait for the end of our 30 second window
220
                sys->io_spio = 0x0f8;
221
                sys->io_pwm_audio = 0x018000; // Turn off the Audio device
222
                while(seconds < 30) {
223 45 dgisselq
                        TOUCH_WATCHDOG;
224 15 dgisselq
                        pic = sys->io_pic;
225 45 dgisselq
                        if (pic & INT_TIMER) {
226
                                sys->io_pic = INT_TIMER;
227 15 dgisselq
                                seconds++;
228
                                rtcclock = rtcnext(rtcclock);
229
                        } if (pic & INT_BUTTON) {
230
                                sys->io_pic = INT_BUTTON;
231
                                seconds = 0;
232
                        }
233
                } sys->io_pic = INT_BUTTON;
234 45 dgisselq
                TOUCH_WATCHDOG;
235 15 dgisselq
        }
236
}
237
 
238
void    build_dpymsg(char *msg, unsigned clk) {
239 45 dgisselq
        msg[0] = 0x1b;
240
        strcpy(++msg, "[jClock : ");
241
        msg += strlen(msg);
242
 
243 15 dgisselq
        if ((clk>>20)&0x0f)
244
                *msg++ |= (((clk>>20)&0x0f)+'0');
245
        else
246
                *msg++ |= ' ';
247 45 dgisselq
        *msg++ = (((clk>>16)&0x0f)+'0');
248
        *msg++ = ':';
249
        *msg++ = (((clk>>12)&0x0f)+'0');
250
        *msg++ = (((clk>> 8)&0x0f)+'0');
251
        *msg++ = ':';
252
        *msg++ = (((clk>> 4)&0x0f)+'0');
253
        *msg++ = (((clk    )&0x0f)+'0');
254 15 dgisselq
        *msg++ = 0;
255
}
256
 
257
void    build_uartmsg(char *msg, unsigned clk) {
258 45 dgisselq
        strcpy(msg, "Time: ");
259
        msg += strlen(msg);
260 15 dgisselq
        *msg++ = ((clk>>20)&0x03)+'0'; // Hrs
261
        *msg++ = ((clk>>16)&0x0f)+'0';
262
        *msg++ = ':';
263
        *msg++ = ((clk>>12)&0x0f)+'0'; // Mins
264
        *msg++ = ((clk>> 8)&0x0f)+'0';
265
        *msg++ = '\r';                  // 11
266
        *msg++ = '\n';                  // 12
267
        *msg++ = '\0';
268
        *msg++ = '\0';
269
}
270
 
271
void    showval(int val) {
272
        // Clear and home
273
        dispchar(0x1b);
274
        dispchar('[');
275
        dispchar('j');
276
        for(int i=28; i>=0; i-=4) {
277
                int ch = ((val>>i)&0x0f)+'0';
278
                if (ch > '9')
279
                        ch = ch - '0'+'A'-10;
280
                dispchar(ch);
281
        }
282
}

powered by: WebSVN 2.1.0

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