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

Subversion Repositories s6soc

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

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
// Purpose:     A modification to the original doorbell.c program.
8
//              seconds.  Listening to that test is ... getting old.
9
//
10
//      Let's let this one do the following:
11
//              1. Display the time on the display (it will be impossible to
12
//                      change the time, sadly, but we can at least display it.)
13
//              2. On button press ...
14
//                      - Play the doorbell sound
15
//                      - Display "Doorbell!\n" on the Display, clearing the
16
//                              time
17
//                      - Send "Doorbell\n"  to the UART, and then keeping the
18
//                              UART silent for 30 seconds.
19
//              4. Send the time to the UART as well, but only once a minute.
20
//                      (and that if the Doorbell hasn't been rung in the last
21
//                      30 seconds ...)
22
//
23
// Creator:     Dan Gisselquist, Ph.D.
24
//              Gisselquist Technology, LLC
25
//
26
////////////////////////////////////////////////////////////////////////////////
27
//
28
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
29
//
30
// This program is free software (firmware): you can redistribute it and/or
31
// modify it under the terms of  the GNU General Public License as published
32
// by the Free Software Foundation, either version 3 of the License, or (at
33
// your option) any later version.
34
//
35
// This program is distributed in the hope that it will be useful, but WITHOUT
36
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
37
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
38
// for more details.
39
//
40
// You should have received a copy of the GNU General Public License along
41
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
42
// target there if the PDF file isn't present.)  If not, see
43
// <http://www.gnu.org/licenses/> for a copy.
44
//
45
// License:     GPL, v3, as defined and found on www.gnu.org,
46
//              http://www.gnu.org/licenses/gpl.html
47
//
48
//
49
////////////////////////////////////////////////////////////////////////////////
50
//
51
//
52
#include "asmstartup.h"
53
#include "board.h"
54
#include "rtcsim.h"
55
#include "display.h"
56
 
57
#include "samples.c"
58
 
59
void    zip_halt(void);
60
 
61
void    build_dpymsg(char *msg, unsigned clkval);
62
void    build_uartmsg(char *msg, unsigned clkval);
63
void    showval(int val);
64
void    txval(int val);
65
 
66
void entry(void) {
67
        register IOSPACE        *sys = (IOSPACE *)0x0100;
68
        char    dpymsg[16], *dpyptr;
69
        char    uartmsg[40], *uartptr;
70
        int     newmsgtime = 0, leastmsgtime = -1, lstmsgtime = 0;
71
 
72
        dpymsg[0] = 0;
73
        dpyptr = dpymsg;
74
 
75
        uartmsg[0] = 0;
76
        build_uartmsg(uartmsg, 0);
77
        uartptr = uartmsg;
78
 
79
        sys->io_timb = 0;
80
        sys->io_pic = 0x07fffffff; // Acknowledge and turn off all interrupts
81
 
82
        sys->io_spio = 0x0f4;
83
        newmsgtime = sys->io_tima;
84
        leastmsgtime = -1;
85
        lstmsgtime = newmsgtime;
86
        while(1) {
87
                int     seconds, pic;
88
                const int       *sptr;
89
 
90
                // LED's off ... nothing to report
91
                sys->io_spio = 0x0f0;
92
 
93
                // Turn the audio off (initially)
94
                sys->io_pwm_audio = 0x0018000;
95
 
96
                // Set for one ticks per second, 80M clocks per tick
97
                sys->io_tima = TM_ONE_SECOND | TM_REPEAT;
98
 
99
                // We start by waiting for a doorbell
100
                while(((pic=sys->io_pic) & INT_BUTTON)==0) {
101
                        if (uartmsg[10] == 0) {
102
                                sys->io_spio = 0x0fe;
103
                                zip_halt();
104
                        }
105
                        if (pic & INT_TIMA) {// top of second
106
                                sys->io_pic = INT_TIMA;
107
                                rtcclock = rtcnext(rtcclock);
108
 
109
                                // Turn all LED off (again)
110
                                sys->io_spio = 0x0f0;
111
                                if (*dpyptr == '\0') {
112
                                        // Build a message for the display
113
                                        build_dpymsg(dpymsg, rtcclock);
114
                                        dpyptr = dpymsg;
115
                                }if(((rtcclock & 0x0ff)==0)&&(*uartptr=='\0')){
116
                                        build_uartmsg(uartmsg, rtcclock);
117
                                        uartptr = uartmsg;
118
 
119
                                        // Turn one LED on--top of minute
120
                                        sys->io_spio = 0x0f1;
121
                                        newmsgtime = sys->io_tima;
122
                                        lstmsgtime = -1;
123
                                        leastmsgtime = -1;
124
                                }
125
                        }
126
                        /*
127
                        if (uartmsg[10] == 0) {
128
                                sys->io_spio = 0x0fc;
129
                                zip_halt();
130
                        }
131
                        */
132
                        if (*uartptr) {
133
                                if (pic & INT_UARTTX) {
134
                                        sys->io_uart = *uartptr++;
135
                                        sys->io_spio = 0x22;
136
                                        sys->io_pic = INT_UARTTX;
137
                                        if (uartptr > &uartmsg[13]) {
138
                                                sys->io_spio = 0x0fd;
139
                                                zip_halt();
140
                                        }
141
 
142
                                        if (lstmsgtime != -1) {
143
                                                int tmp;
144
                                                tmp = (lstmsgtime-sys->io_tima);
145
                                                if ((leastmsgtime<0)||(tmp<leastmsgtime))
146
                                                        leastmsgtime = tmp;
147
                                        } lstmsgtime = sys->io_tima;
148
                                }
149
                        } else {
150
                                sys->io_spio = 0x20;
151
                                /*
152
                                if (newmsgtime != 0) {
153
                                        int thistime = sys->io_tima;
154
                                        thistime = newmsgtime - thistime;
155
                                        showval(thistime);
156
                                        txval(thistime);
157
                                        txval(leastmsgtime);
158
                                        txval(lstmsgtime);
159
                                        zip_halt();
160
                                        newmsgtime = 0;
161
                                }
162
                                for(int i=0; i<12; i++)
163
                                        if (uartmsg[i] == 0) {
164
                                                sys->io_spio = i+0xf0;
165
                                                zip_halt();
166
                                        }
167
                                */
168
                        }
169
                        if (*dpyptr) {
170
                                // This will take a long time.  It should be an
171
                                // interruptable task ... but, sigh, we're not
172
                                // there yet.
173
                                dispchar(*dpyptr++);
174
                                sys->io_spio = 0x44;
175
                        } else {
176
                                sys->io_spio = 0x40;
177
                        } // sys->io_pic = (pic & (INT_TIMA|INT_UARTTX));
178
                }
179
 
180
                // DOORBELL!!!!!!
181
                // Set the Display message
182
                dpymsg[0] = (0x1b<<24)|('['<<16)|('j'<<8)|'D';
183
                dpymsg[1] = ('o'<<24)|('o'<<16)|('r'<<8)|'b';
184
                dpymsg[2] = ('e'<<24)|('l'<<16)|('l'<<8)|'!';
185
                dpymsg[3] = 0;
186
                dpyptr = dpymsg;
187
                // And the UART message / 18 characters
188
                uartptr = uartmsg;
189
                *uartptr++ = '\r'; *uartptr++ = '\n';
190
                *uartptr++ = 'D';
191
                *uartptr++ = 'o';
192
                *uartptr++ = 'o';
193
                *uartptr++ = 'r';
194
                *uartptr++ = 'b';
195
                *uartptr++ = 'e';
196
                *uartptr++ = 'l';
197
                *uartptr++ = 'l';
198
                *uartptr++ = '!';
199
                *uartptr++ = '\r'; *uartptr++ = '\n';
200
                *uartptr++ = '\r'; *uartptr++ = '\n';
201
                *uartptr++ = '\0';
202
                uartptr = uartmsg;
203
 
204
 
205
                seconds = 0;
206
                sys->io_spio = 0x0ff; // All LED's on: we got one!
207
                sptr = sound_data;
208
                sys->io_pwm_audio = 0x0310000; // Turn on the audio
209
                while(sptr < &sound_data[NSAMPLE_WORDS]) {
210
                        do {
211
                                pic = sys->io_pic;
212
                                if (pic & INT_TIMA) {
213
                                        sys->io_pic = INT_TIMA;
214
                                        seconds++;
215
                                        rtcclock = rtcnext(rtcclock);
216
                                } if ((pic & INT_UARTTX)&&(*uartptr)) {
217
                                        sys->io_uart = *uartptr++;
218
                                        sys->io_pic = INT_UARTTX;
219
                                        sys->io_spio = 0x22;
220
                                } else if (!*uartptr)
221
                                        sys->io_spio = 0x20;
222
                                if (*dpyptr) {
223
                                // This will take a long time.  It should be an
224
                                // interruptable task ... but, sigh, we're not
225
                                // there yet.
226
                                        dispchar(*dpyptr++);
227
                                        sys->io_spio = 0x44;
228
                                } else
229
                                        sys->io_spio = 0x40;
230
                        } while((pic & INT_AUDIO)==0);
231
                        sys->io_pwm_audio = (*sptr >> 16)&0x0ffff;
232
                        // Now, turn off the audio interrupt since it doesn't
233
                        // reset itself ...
234
                        sys->io_pic = INT_AUDIO;
235
 
236
                        do {
237
                                pic = sys->io_pic;
238
 
239
                                if (pic & INT_TIMA) {
240
                                        sys->io_pic = INT_TIMA;
241
                                        seconds++;
242
                                        rtcclock = rtcnext(rtcclock);
243
                                } if ((pic & INT_UARTTX)&&(*uartptr)) {
244
                                        sys->io_uart = *uartptr++;
245
                                        sys->io_pic = INT_UARTTX;
246
                                        sys->io_spio = 0x22;
247
                                } else if (!*uartptr)
248
                                        sys->io_spio = 0x20;
249
                                if (*dpyptr) {
250
                                // This will take a long time.  It should be an
251
                                // interruptable task ... but, sigh, we're not
252
                                // there yet.
253
                                        dispchar(*dpyptr++);
254
                                        sys->io_spio = 0x44;
255
                                } else
256
                                        sys->io_spio = 0x40;
257
                        } while((pic & INT_AUDIO)==0);
258
                        sys->io_pwm_audio = (*sptr++) & 0x0ffff;
259
 
260
                        // and turn off the audio interrupt again ...
261
                        sys->io_pic = INT_AUDIO;
262
                } sys->io_pic = INT_BUTTON;
263
 
264
                // Now we wait for the end of our 30 second window
265
                sys->io_spio = 0x0f8;
266
                sys->io_pwm_audio = 0x018000; // Turn off the Audio device
267
                while(seconds < 30) {
268
                        pic = sys->io_pic;
269
                        if (pic & INT_TIMA) {
270
                                sys->io_pic = INT_TIMA;
271
                                seconds++;
272
                                rtcclock = rtcnext(rtcclock);
273
                        } if (pic & INT_BUTTON) {
274
                                sys->io_pic = INT_BUTTON;
275
                                seconds = 0;
276
                        }
277
                } sys->io_pic = INT_BUTTON;
278
        }
279
}
280
 
281
void    build_dpymsg(char *msg, unsigned clk) {
282
        *msg++ = (0x1b<<24)|('['<<16)|('j'<<8)|'C'; // Clear, and start 'C'
283
        *msg++ = ('l'<<24)|('o'<<16)|('c'<<8)|'k';
284
        *msg = (' '<<24)|(':'<<16)|(' '<<8);
285
        if ((clk>>20)&0x0f)
286
                *msg++ |= (((clk>>20)&0x0f)+'0');
287
        else
288
                *msg++ |= ' ';
289
        *msg++ = ((((clk>>16)&0x0f)+'0')<<24)
290
                |(':'<<16)
291
                |((((clk>>12)&0x0f)+'0')<< 8)   // Minutes
292
                |((((clk>> 8)&0x0f)+'0')    );
293
        *msg++ = (':'<<24)
294
                |((((clk>> 4)&0x0f)+'0')<<16)   // Seconds
295
                |((((clk    )&0x0f)+'0')<< 8);
296
        *msg++ = 0;
297
        *msg++ = 0;
298
        *msg++ = 0;
299
        *msg++ = 0;
300
}
301
 
302
void    build_uartmsg(char *msg, unsigned clk) {
303
        *msg++ = 'T';                   // 0
304
        *msg++ = 'i';                   // 1
305
        *msg++ = 'm';                   // 2
306
        *msg++ = 'e';                   // 3
307
        *msg++ = ':';                   // 4
308
        *msg++ = ' ';
309
        *msg++ = ((clk>>20)&0x03)+'0'; // Hrs
310
        *msg++ = ((clk>>16)&0x0f)+'0';
311
        *msg++ = ':';
312
        *msg++ = ((clk>>12)&0x0f)+'0'; // Mins
313
        *msg++ = ((clk>> 8)&0x0f)+'0';
314
        *msg++ = '\r';                  // 11
315
        *msg++ = '\n';                  // 12
316
        *msg++ = '\0';
317
        *msg++ = '\0';
318
}
319
 
320
void    showval(int val) {
321
        // Clear and home
322
        dispchar(0x1b);
323
        dispchar('[');
324
        dispchar('j');
325
        for(int i=28; i>=0; i-=4) {
326
                int ch = ((val>>i)&0x0f)+'0';
327
                if (ch > '9')
328
                        ch = ch - '0'+'A'-10;
329
                dispchar(ch);
330
        }
331
}
332
 
333
void    txch(int val) {
334
        register IOSPACE        *sys = (IOSPACE *)0x0100;
335
 
336
        // To read whether or not the transmitter is ready, you must first
337
        // clear the interrupt bit.
338
        sys->io_pic = INT_UARTTX;
339
        for(int i=0; i<5000; i++)
340
                asm("noop");
341
        sys->io_pic = INT_UARTTX;
342
        // If the interrupt bit sets itself again immediately, the transmitter
343
        // is ready.  Otherwise, wait until the transmitter becomes ready.
344
        while((sys->io_pic&INT_UARTTX)==0)
345
                ;
346
        sys->io_uart = (val&0x0ff);
347
        // Give the transmitter a chance to finish, and then to create an
348
        // interrupt when done
349
        sys->io_pic = INT_UARTTX;
350
}
351
 
352
void    txval(int val) {
353
        txch('\r');
354
        txch('\n');
355
        txch('0');
356
        txch('x');
357
        for(int i=28; i>=0; i-=4) {
358
                int ch = ((val>>i)&0x0f)+'0';
359
                if (ch > '9')
360
                        ch = ch - '0'+'A'-10;
361
                txch(ch);
362
        }
363
}
364
 
365
// PPONP16P
366
// 00120O91
367
// 00120NM3
368
// 00120E91 = 1183377 ~= 91029 / char, at 0x208d 8333/baud, 83,330 per char

powered by: WebSVN 2.1.0

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