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

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [sw/] [dev/] [doorbell2.c] - Diff between revs 45 and 53

Only display areas with differences | Details | Blame | View Log

Rev 45 Rev 53
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    doorbell2.c
// Filename:    doorbell2.c
//
//
// Project:     CMod S6 System on a Chip, ZipCPU demonstration project
// Project:     CMod S6 System on a Chip, ZipCPU demonstration project
//
//
// Purpose:     A modification to the original doorbell.c program that played
// Purpose:     A modification to the original doorbell.c program that played
//              a doorbell sound every ten seconds.  Listening to that test is
//              a doorbell sound every ten seconds.  Listening to that test is
//      ... getting old.
//      ... getting old.
//
//
//      Let's let this one do the following:
//      Let's let this one do the following:
//              1. Display the time on the display (it will be impossible to
//              1. Display the time on the display (it will be impossible to
//                      change the time, sadly, but we can at least display it.)
//                      change the time, sadly, but we can at least display it.)
//              2. On button press ...
//              2. On button press ...
//                      - Play the doorbell sound
//                      - Play the doorbell sound
//                      - Display "Doorbell!\n" on the Display, clearing the
//                      - Display "Doorbell!\n" on the Display, clearing the
//                              time
//                              time
//                      - Send "Doorbell\n"  to the UART, and then keeping the
//                      - Send "Doorbell\n"  to the UART, and then keeping the
//                              UART silent for 30 seconds.
//                              UART silent for 30 seconds.
//              4. Send the time to the UART as well, but only once a minute.
//              4. Send the time to the UART as well, but only once a minute.
//                      (and that if the Doorbell hasn't been rung in the last
//                      (and that if the Doorbell hasn't been rung in the last
//                      30 seconds ...)
//                      30 seconds ...)
//
//
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
//
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// for more details.
//
//
// You should have received a copy of the GNU General Public License along
// You should have received a copy of the GNU General Public License along
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// target there if the PDF file isn't present.)  If not, see
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
// <http://www.gnu.org/licenses/> for a copy.
//
//
// License:     GPL, v3, as defined and found on www.gnu.org,
// License:     GPL, v3, as defined and found on www.gnu.org,
//              http://www.gnu.org/licenses/gpl.html
//              http://www.gnu.org/licenses/gpl.html
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
#include "asmstartup.h"
 
#include "board.h"
#include "board.h"
#include "rtcsim.h"
#include "rtcsim.h"
#include "display.h"
#include "display.h"
#include "string.h"
#include "string.h"
#include "txfns.h"
#include "txfns.h"
 
 
#include "samples.c"
#include "samples.c"
 
 
void    zip_halt(void);
 
 
 
void    build_dpymsg(char *msg, unsigned clkval);
void    build_dpymsg(char *msg, unsigned clkval);
void    build_uartmsg(char *msg, unsigned clkval);
void    build_uartmsg(char *msg, unsigned clkval);
void    showval(int val);
void    showval(int val);
 
 
#define CLEAR_WATCHDOG  _sys->io_watchdog = 0
#define CLEAR_WATCHDOG  _sys->io_watchdog = 0
#define TOUCH_WATCHDOG  _sys->io_watchdog = 500000
#define TOUCH_WATCHDOG  _sys->io_watchdog = 500000
 
 
void entry(void) {
void entry(void) {
        register volatile IOSPACE *const sys = _sys;
        register volatile IOSPACE *const sys = _sys;
        char    dpymsg[64], *dpyptr;
        char    dpymsg[64], *dpyptr;
        char    uartmsg[160], *uartptr;
        char    uartmsg[160], *uartptr;
        int     newmsgtime = 0, leastmsgtime = -1, lstmsgtime = 0;
        int     newmsgtime = 0, leastmsgtime = -1, lstmsgtime = 0;
 
 
        CLEAR_WATCHDOG;
        CLEAR_WATCHDOG;
 
 
        txstr("\r\nREBOOT!\r\n");
        txstr("\r\nREBOOT!\r\n");
        txstr("Scope Control = "); txval(_scope->s_ctrl);
        txstr("Scope Control = "); txval(_scope->s_ctrl);
        if (_scope->s_ctrl & WBSCOPE_STOPPED) {
        if (_scope->s_ctrl & WBSCOPE_STOPPED) {
                int     ln = WBSCOPE_LENGTH(_scope->s_ctrl);
                int     ln = WBSCOPE_LENGTH(_scope->s_ctrl);
                for(int i=0; i<ln; i++)
                for(int i=0; i<ln; i++)
                        txval(_scope->s_data);
                        txval(_scope->s_data);
                txval((int)_sys->io_buserr);
                txval((int)_sys->io_buserr);
                txstr("\r\n\r\nEndScope\r\n");
                txstr("\r\n\r\nEndScope\r\n");
        } else {
        } else {
                txstr("\r\n");
                txstr("\r\n");
                _scope->s_ctrl = 20;
                _scope->s_ctrl = 20;
        }
        }
 
 
        dpymsg[0] = 0;
        dpymsg[0] = 0;
        dpyptr = dpymsg;
        dpyptr = dpymsg;
 
 
        uartmsg[0] = 0;
        uartmsg[0] = 0;
        build_uartmsg(uartmsg, 0);
        build_uartmsg(uartmsg, 0);
        uartptr = uartmsg;
        uartptr = uartmsg;
 
 
        sys->io_watchdog = 0;
        sys->io_watchdog = 0;
        sys->io_pic = INT_CLEARPIC; // Acknowledge and turn off all interrupts
        sys->io_pic = INT_CLEARPIC; // Acknowledge and turn off all interrupts
 
 
        sys->io_spio = 0x0f4;
        sys->io_spio = 0x0f4;
        newmsgtime = sys->io_timer;
        newmsgtime = sys->io_timer;
        leastmsgtime = -1;
        leastmsgtime = -1;
        lstmsgtime = newmsgtime;
        lstmsgtime = newmsgtime;
        while(1) {
        while(1) {
                int     seconds, pic;
                int     seconds, pic;
                const short     *sptr;
                const short     *sptr;
 
 
                // LED's off ... nothing to report
                // LED's off ... nothing to report
                sys->io_spio = 0x0f0;
                sys->io_spio = 0x0f0;
 
 
                // Turn the audio off (initially)
                // Turn the audio off (initially)
                sys->io_pwm_audio = 0x0018000;
                sys->io_pwm_audio = 0x0018000;
 
 
                // Set for one ticks per second, 80M clocks per tick
                // Set for one ticks per second, 80M clocks per tick
                sys->io_timer = TM_ONE_SECOND | TM_REPEAT;
                sys->io_timer = TM_ONE_SECOND | TM_REPEAT;
 
 
                // We start by waiting for a doorbell
                // We start by waiting for a doorbell
                while(((pic=sys->io_pic) & INT_BUTTON)==0) {
                while(((pic=sys->io_pic) & INT_BUTTON)==0) {
                        TOUCH_WATCHDOG;
                        TOUCH_WATCHDOG;
 
 
                        if (pic & INT_TIMER) {// top of second
                        if (pic & INT_TIMER) {// top of second
                                sys->io_pic = INT_TIMER;
                                sys->io_pic = INT_TIMER;
                                rtcclock = rtcnext(rtcclock);
                                rtcclock = rtcnext(rtcclock);
 
 
                                // Turn all LED off (again)
                                // Turn all LED off (again)
                                sys->io_spio = 0x0f0;
                                sys->io_spio = 0x0f0;
                                if (*dpyptr == '\0') {
                                if (*dpyptr == '\0') {
                                        // Build a message for the display
                                        // Build a message for the display
                                        build_dpymsg(dpymsg, rtcclock);
                                        build_dpymsg(dpymsg, rtcclock);
                                        dpyptr = dpymsg;
                                        dpyptr = dpymsg;
                                }if(((rtcclock & 0x0ff)==0)&&(*uartptr=='\0')){
                                }if(((rtcclock & 0x0ff)==0)&&(*uartptr=='\0')){
                                        build_uartmsg(uartmsg, rtcclock);
                                        build_uartmsg(uartmsg, rtcclock);
                                        uartptr = uartmsg;
                                        uartptr = uartmsg;
 
 
                                        // Turn one LED on--top of minute
                                        // Turn one LED on--top of minute
                                        sys->io_spio = 0x0f1;
                                        sys->io_spio = 0x0f1;
                                        newmsgtime = sys->io_timer;
                                        newmsgtime = sys->io_timer;
                                        lstmsgtime = -1;
                                        lstmsgtime = -1;
                                        leastmsgtime = -1;
                                        leastmsgtime = -1;
                                }
                                }
                        }
                        }
 
 
                        if (*uartptr) {
                        if (*uartptr) {
                                if (pic & INT_UARTTX) {
                                if (pic & INT_UARTTX) {
                                        sys->io_uart = *uartptr++;
                                        sys->io_uart = *uartptr++;
                                        sys->io_spio = 0x22;
                                        sys->io_spio = 0x22;
                                        sys->io_pic = INT_UARTTX;
                                        sys->io_pic = INT_UARTTX;
 
 
                                        if (lstmsgtime != -1) {
                                        if (lstmsgtime != -1) {
                                                int tmp;
                                                int tmp;
                                                tmp = (lstmsgtime-sys->io_timer);
                                                tmp = (lstmsgtime-sys->io_timer);
                                                if ((leastmsgtime<0)||(tmp<leastmsgtime))
                                                if ((leastmsgtime<0)||(tmp<leastmsgtime))
                                                        leastmsgtime = tmp;
                                                        leastmsgtime = tmp;
                                        } lstmsgtime = sys->io_timer;
                                        } lstmsgtime = sys->io_timer;
                                }
                                }
                        } else {
                        } else {
                                sys->io_spio = 0x20;
                                sys->io_spio = 0x20;
                        }
                        }
                        if (*dpyptr) {
                        if (*dpyptr) {
                                // This will take a long time.  It should be an
                                // This will take a long time.  It should be an
                                // interruptable task ... but, sigh, we're not
                                // interruptable task ... but, sigh, we're not
                                // there yet.
                                // there yet.
                                dispchar(*dpyptr++);
                                dispchar(*dpyptr++);
                                sys->io_spio = 0x44;
                                sys->io_spio = 0x44;
                        } else {
                        } else {
                                sys->io_spio = 0x40;
                                sys->io_spio = 0x40;
                        } // sys->io_pic = (pic & (INT_TIMER|INT_UARTTX));
                        } // sys->io_pic = (pic & (INT_TIMER|INT_UARTTX));
                }
                }
 
 
                TOUCH_WATCHDOG;
                TOUCH_WATCHDOG;
                // DOORBELL!!!!!!
                // DOORBELL!!!!!!
                // Set the Display message
                // Set the Display message
                strcpy(dpymsg, "a[jDoorbell!");
                strcpy(dpymsg, "a[jDoorbell!");
                dpymsg[0] = 0x1b;
                dpymsg[0] = 0x1b;
                dpyptr = dpymsg;
                dpyptr = dpymsg;
                // And the UART message / 18 characters
                // And the UART message / 18 characters
                uartptr = uartmsg;
                uartptr = uartmsg;
                strcat(uartptr, "\r\nDoorbell!\r\n\r\n");
                strcat(uartptr, "\r\nDoorbell!\r\n\r\n");
                uartptr = uartmsg;
                uartptr = uartmsg;
 
 
 
 
                seconds = 0;
                seconds = 0;
                sys->io_spio = 0x0ff; // All LED's on: we got one!
                sys->io_spio = 0x0ff; // All LED's on: we got one!
                sptr = sound_data;
                sptr = sound_data;
                sys->io_pwm_audio = 0x0310000; // Turn on the audio
                sys->io_pwm_audio = 0x0310000; // Turn on the audio
                while(sptr < &sound_data[NSAMPLE_WORDS]) {
                while(sptr < &sound_data[NSAMPLE_WORDS]) {
                        do {
                        do {
                                TOUCH_WATCHDOG;
                                TOUCH_WATCHDOG;
                                pic = sys->io_pic;
                                pic = sys->io_pic;
                                if (pic & INT_TIMER) {
                                if (pic & INT_TIMER) {
                                        sys->io_pic = INT_TIMER;
                                        sys->io_pic = INT_TIMER;
                                        seconds++;
                                        seconds++;
                                        rtcclock = rtcnext(rtcclock);
                                        rtcclock = rtcnext(rtcclock);
                                } if ((pic & INT_UARTTX)&&(*uartptr)) {
                                } if ((pic & INT_UARTTX)&&(*uartptr)) {
                                        sys->io_uart = *uartptr++;
                                        sys->io_uart = *uartptr++;
                                        sys->io_pic = INT_UARTTX;
                                        sys->io_pic = INT_UARTTX;
                                        sys->io_spio = 0x22;
                                        sys->io_spio = 0x22;
                                } else if (!*uartptr)
                                } else if (!*uartptr)
                                        sys->io_spio = 0x20;
                                        sys->io_spio = 0x20;
                                if (*dpyptr) {
                                if (*dpyptr) {
                                // This will take a long time.  It should be an
                                // This will take a long time.  It should be an
                                // interruptable task ... but, sigh, we're not
                                // interruptable task ... but, sigh, we're not
                                // there yet.
                                // there yet.
                                        dispchar(*dpyptr++);
                                        dispchar(*dpyptr++);
                                        sys->io_spio = 0x45;
                                        sys->io_spio = 0x45;
                                } else
                                } else
                                        sys->io_spio = 0x40;
                                        sys->io_spio = 0x40;
                        } while((pic & INT_AUDIO)==0);
                        } while((pic & INT_AUDIO)==0);
                        sys->io_pwm_audio = (*sptr++) & 0x0ffff;
                        sys->io_pwm_audio = (*sptr++) & 0x0ffff;
                        // Now, turn off the audio interrupt since it doesn't
                        // Now, turn off the audio interrupt since it doesn't
                        // reset itself ...
                        // reset itself ...
                        sys->io_pic = INT_AUDIO;
                        sys->io_pic = INT_AUDIO;
                } sys->io_pic = INT_BUTTON;
                } sys->io_pic = INT_BUTTON;
                sys->io_spio = 0x10;
                sys->io_spio = 0x10;
 
 
                TOUCH_WATCHDOG;
                TOUCH_WATCHDOG;
                // Now we wait for the end of our 30 second window
                // Now we wait for the end of our 30 second window
                sys->io_spio = 0x0f8;
                sys->io_spio = 0x0f8;
                sys->io_pwm_audio = 0x018000; // Turn off the Audio device
                sys->io_pwm_audio = 0x018000; // Turn off the Audio device
                while(seconds < 30) {
                while(seconds < 30) {
                        TOUCH_WATCHDOG;
                        TOUCH_WATCHDOG;
                        pic = sys->io_pic;
                        pic = sys->io_pic;
                        if (pic & INT_TIMER) {
                        if (pic & INT_TIMER) {
                                sys->io_pic = INT_TIMER;
                                sys->io_pic = INT_TIMER;
                                seconds++;
                                seconds++;
                                rtcclock = rtcnext(rtcclock);
                                rtcclock = rtcnext(rtcclock);
                        } if (pic & INT_BUTTON) {
                        } if (pic & INT_BUTTON) {
                                sys->io_pic = INT_BUTTON;
                                sys->io_pic = INT_BUTTON;
                                seconds = 0;
                                seconds = 0;
                        }
                        }
                } sys->io_pic = INT_BUTTON;
                } sys->io_pic = INT_BUTTON;
                TOUCH_WATCHDOG;
                TOUCH_WATCHDOG;
        }
        }
}
}
 
 
void    build_dpymsg(char *msg, unsigned clk) {
void    build_dpymsg(char *msg, unsigned clk) {
        msg[0] = 0x1b;
        msg[0] = 0x1b;
        strcpy(++msg, "[jClock : ");
        strcpy(++msg, "[jClock : ");
        msg += strlen(msg);
        msg += strlen(msg);
 
 
        if ((clk>>20)&0x0f)
        if ((clk>>20)&0x0f)
                *msg++ |= (((clk>>20)&0x0f)+'0');
                *msg++ |= (((clk>>20)&0x0f)+'0');
        else
        else
                *msg++ |= ' ';
                *msg++ |= ' ';
        *msg++ = (((clk>>16)&0x0f)+'0');
        *msg++ = (((clk>>16)&0x0f)+'0');
        *msg++ = ':';
        *msg++ = ':';
        *msg++ = (((clk>>12)&0x0f)+'0');
        *msg++ = (((clk>>12)&0x0f)+'0');
        *msg++ = (((clk>> 8)&0x0f)+'0');
        *msg++ = (((clk>> 8)&0x0f)+'0');
        *msg++ = ':';
        *msg++ = ':';
        *msg++ = (((clk>> 4)&0x0f)+'0');
        *msg++ = (((clk>> 4)&0x0f)+'0');
        *msg++ = (((clk    )&0x0f)+'0');
        *msg++ = (((clk    )&0x0f)+'0');
        *msg++ = 0;
        *msg++ = 0;
}
}
 
 
void    build_uartmsg(char *msg, unsigned clk) {
void    build_uartmsg(char *msg, unsigned clk) {
        strcpy(msg, "Time: ");
        strcpy(msg, "Time: ");
        msg += strlen(msg);
        msg += strlen(msg);
        *msg++ = ((clk>>20)&0x03)+'0'; // Hrs
        *msg++ = ((clk>>20)&0x03)+'0'; // Hrs
        *msg++ = ((clk>>16)&0x0f)+'0';
        *msg++ = ((clk>>16)&0x0f)+'0';
        *msg++ = ':';
        *msg++ = ':';
        *msg++ = ((clk>>12)&0x0f)+'0'; // Mins
        *msg++ = ((clk>>12)&0x0f)+'0'; // Mins
        *msg++ = ((clk>> 8)&0x0f)+'0';
        *msg++ = ((clk>> 8)&0x0f)+'0';
        *msg++ = '\r';                  // 11
        *msg++ = '\r';                  // 11
        *msg++ = '\n';                  // 12
        *msg++ = '\n';                  // 12
        *msg++ = '\0';
        *msg++ = '\0';
        *msg++ = '\0';
        *msg++ = '\0';
}
}
 
 
void    showval(int val) {
void    showval(int val) {
        // Clear and home
        // Clear and home
        dispchar(0x1b);
        dispchar(0x1b);
        dispchar('[');
        dispchar('[');
        dispchar('j');
        dispchar('j');
        for(int i=28; i>=0; i-=4) {
        for(int i=28; i>=0; i-=4) {
                int ch = ((val>>i)&0x0f)+'0';
                int ch = ((val>>i)&0x0f)+'0';
                if (ch > '9')
                if (ch > '9')
                        ch = ch - '0'+'A'-10;
                        ch = ch - '0'+'A'-10;
                dispchar(ch);
                dispchar(ch);
        }
        }
}
}
 
 

powered by: WebSVN 2.1.0

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