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

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [sw/] [zipos/] [doorbell.c] - Diff between revs 29 and 39

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 29 Rev 39
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    doorbell.c
// Filename:    doorbell.c
//
//
// Project:     CMod S6 System on a Chip, ZipCPU demonstration project
// Project:     CMod S6 System on a Chip, ZipCPU demonstration project
//
//
// Purpose:     This is the user program, or perhaps more appropriately
// Purpose:     This is the user program, or perhaps more appropriately
//              user program(s), associated with running the ZipOS on the
//              user program(s), associated with running the ZipOS on the
//      CMod-S6.  To run within the ZipOS, a user program must implement
//      CMod-S6.  To run within the ZipOS, a user program must implement
//      two functions: kntasks() and kinit(TASKP *).  The first one is simple.
//      two functions: kntasks() and kinit(TASKP *).  The first one is simple.
//      it simply returns the number of tasks the kernel needs to allocate 
//      it simply returns the number of tasks the kernel needs to allocate 
//      space for.  The second routine needs to allocate space for each task,
//      space for.  The second routine needs to allocate space for each task,
//      set up any file descriptors associated with (each) task, and identify
//      set up any file descriptors associated with (each) task, and identify
//      the entry point of each task.  These are the only two routines
//      the entry point of each task.  These are the only two routines
//      associated with user tasks called from kernel space.  Examples of each
//      associated with user tasks called from kernel space.  Examples of each
//      are found within here.
//      are found within here.
//
//
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
// Copyright (C) 2015-2016, 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 "zipsys.h"
#include "zipsys.h"
#include "board.h"
#include "board.h"
#include "ksched.h"
#include "ksched.h"
#include "kfildes.h"
#include "kfildes.h"
#include "taskp.h"
#include "taskp.h"
#include "syspipe.h"
#include "syspipe.h"
#include "ktraps.h"
#include "ktraps.h"
#include "errno.h"
#include "errno.h"
#include "swint.h"
#include "swint.h"
 
 
#include "../dev/display.h"
#include "../dev/display.h"
#include "../dev/rtcsim.h"
#include "../dev/rtcsim.h"
#include "../dev/keypad.h"
#include "../dev/keypad.h"
 
 
/* Our system will need some pipes to handle ... life.  How about these:
/* Our system will need some pipes to handle ... life.  How about these:
 *
 *
 *      rxpipe  - read()s from this pipe read from the UART
 *      rxpipe  - read()s from this pipe read from the UART
 *                      Interrupt fed
 *                      Interrupt fed
 *      txpipe  - write()s to this pipe write to the UART
 *      txpipe  - write()s to this pipe write to the UART
 *                      Interrupt consumed
 *                      Interrupt consumed
 *      keypipe - read()s from this pipe return values read by the keypad
 *      keypipe - read()s from this pipe return values read by the keypad
 *      lcdpipe - write()s to this pipe write to the LCD display SPI port
 *      lcdpipe - write()s to this pipe write to the LCD display SPI port
 *      pwmpipe - write()s to this pipe will send values to the audio port
 *      pwmpipe - write()s to this pipe will send values to the audio port
 *                      Interrupt consumed
 *                      Interrupt consumed
 *
 *
 * These pipes are allocated within the kernel setup function, ksetup().
 * These pipes are allocated within the kernel setup function, ksetup().
 */
 */
 
 
/* We'll need some tasks as well:
/* We'll need some tasks as well:
 *      User command task
 *      User command task
 *              Handles user interaction
 *              Handles user interaction
 *                      Reads from pipe--either the keypad or the UARTRX pipe
 *                      Reads from pipe--either the keypad or the UARTRX pipe
 *                      (Might be two such tasks in the system, one for each.)
 *                      (Might be two such tasks in the system, one for each.)
 *              Sets clock upon request
 *              Sets clock upon request
 *              Reads from a pipe (rxpipe or keypipe), Writes to the txpipe pipe
 *              Reads from a pipe (rxpipe or keypipe), Writes to the txpipe pipe
 *      Doorbell task
 *      Doorbell task
 *              Maintains system time on the clock      : TIME: HH:MM:SS
 *              Maintains system time on the clock      : TIME: HH:MM:SS
 *              Maintains system status on display      : Light is (dis/en)abled
 *              Maintains system status on display      : Light is (dis/en)abled
 *              Transitions when the doorbell is rung to: (fixed time line)
 *              Transitions when the doorbell is rung to: (fixed time line)
 *                                                      : DOORBELL!!
 *                                                      : DOORBELL!!
 *              When the doorbell is clear, returns to the original task.
 *              When the doorbell is clear, returns to the original task.
 *              ---
 *              ---
 *              Waits on events, writes to the lcdpipe and pwmpipe.
 *              Waits on events, writes to the lcdpipe and pwmpipe.
 *              Reads from a command pipe, so that it can handle any user menu's
 *              Reads from a command pipe, so that it can handle any user menu's
 *                      Command pipe.  This, though, is tricky.  It requires
 *                      Command pipe.  This, though, is tricky.  It requires
 *                      a task that can be interrupted by either an event or a
 *                      a task that can be interrupted by either an event or a
 *                      pipe.  Blocking is going to be more tricky ...
 *                      pipe.  Blocking is going to be more tricky ...
 *      Keypad task
 *      Keypad task
 *              Normally, you might think this should be an interrupt task.
 *              Normally, you might think this should be an interrupt task.
 *              But, it needs state in order to have timeouts and to debounce
 *              But, it needs state in order to have timeouts and to debounce
 *              the input pin.  So ... let's leave this as a task.
 *              the input pin.  So ... let's leave this as a task.
 *              ---
 *              ---
 *              Waits on events(keypad/timer), writes to the keypipe
 *              Waits on events(keypad/timer), writes to the keypipe
 *      Display task
 *      Display task
 *              The display does *not* need to be written to at an interrupt
 *              The display does *not* need to be written to at an interrupt
 *              level.  It really needs to be written to at a task level, so
 *              level.  It really needs to be written to at a task level, so
 *              let's make a display task.
 *              let's make a display task.
 *              ---
 *              ---
 *              Reads from the lcdpipe
 *              Reads from the lcdpipe
 *      Real-time Clock Task
 *      Real-time Clock Task
 *              Gets called once per second to update the real-time clock
 *              Gets called once per second to update the real-time clock
 *              and to post those updates as an event to other tasks that might
 *              and to post those updates as an event to other tasks that might
 *              be interested in it.
 *              be interested in it.
 *              ---
 *              ---
 *              Waits on system tasks, uses two semaphores
 *              Waits on system tasks, uses two semaphores
 */
 */
 
 
 
 
/*
/*
 * Read the keypad, write the results to an output pipe
 * Read the keypad, write the results to an output pipe
 */
 */
// #define      KEYPAD_TASK     keypad_task_id
// #define      KEYPAD_TASK     keypad_task_id
/*
/*
 * Read from the keypad, and set up a series of menu screens on the Display,
 * Read from the keypad, and set up a series of menu screens on the Display,
 * so that we can:
 * so that we can:
 *
 *
 *      1. Set time
 *      1. Set time
 *      2. Set dawn
 *      2. Set dawn
 *      3. Set dusk
 *      3. Set dusk
 */
 */
#define MENU_TASK       menu_task_id
#define MENU_TASK       menu_task_id
/*
/*
 * Maintain a realtime clock
 * Maintain a realtime clock
 */
 */
#define RTCCLOCK_TASK   rtccclock_task_id
#define RTCCLOCK_TASK   rtccclock_task_id
/*
/*
 * Read from an incoming pipe, write results to the SPI port controlling the
 * Read from an incoming pipe, write results to the SPI port controlling the
 * display.
 * display.
 */
 */
#define DISPLAY_TASK    display_task_id
#define DISPLAY_TASK    display_task_id
 
 
/*
/*
 * Wait for a button press, and then based upon the clock set a light
 * Wait for a button press, and then based upon the clock set a light
 */
 */
#define DOORBELL_TASK   doorbell_task_id
#define DOORBELL_TASK   doorbell_task_id
 
 
#define LAST_TASK       last_task_id
#define LAST_TASK       last_task_id
 
 
typedef enum    {
typedef enum    {
#ifdef  RTCCLOCK_TASK
#ifdef  RTCCLOCK_TASK
        RTCCLOCK_TASK,
        RTCCLOCK_TASK,
#endif
#endif
#ifdef  DOORBELL_TASK
#ifdef  DOORBELL_TASK
#ifdef  DISPLAY_TASK
#ifdef  DISPLAY_TASK
        DOORBELL_TASK, DISPLAY_TASK,
        DOORBELL_TASK, DISPLAY_TASK,
#endif
#endif
#endif
#endif
//#ifdef        KEYPAD_TASK
//#ifdef        KEYPAD_TASK
        //KEYPAD_TASK,
        //KEYPAD_TASK,
//#endif
//#endif
#ifdef  MENU_TASK
#ifdef  MENU_TASK
        MENU_TASK,
        MENU_TASK,
#endif
#endif
#ifdef  COMMAND_TASK
#ifdef  COMMAND_TASK
        COMMAND_TASK,
        COMMAND_TASK,
#endif
#endif
        LAST_TASK
        LAST_TASK
} TASKNAME;
} TASKNAME;
 
 
 
 
void    rtctask(void),
void    rtctask(void),
        doorbell_task(void),
        doorbell_task(void),
        display_task(void),
        display_task(void),
        keypad_task(void),
        keypad_task(void),
        menu_task(void);
        menu_task(void);
        // idle_task ... is accomplished within the kernel
        // idle_task ... is accomplished within the kernel
extern  void    restore_context(int *), save_context(int *);
extern  void    restore_context(int *), save_context(int *);
extern  SYSPIPE *rxpipe, *txpipe, *pwmpipe, *lcdpipe;
extern  SYSPIPE *rxpipe, *txpipe, *pwmpipe, *lcdpipe;
SYSPIPE *midpipe;
SYSPIPE *midpipe;
extern  KDEVICE *pipedev;
extern  KDEVICE *pipedev;
 
 
int     kntasks(void) {
int     kntasks(void) {
        return LAST_TASK;
        return LAST_TASK;
} void  kinit(TASKP *tasklist) {
} void  kinit(TASKP *tasklist) {
#ifdef  RTCCLOCK_TASK
#ifdef  RTCCLOCK_TASK
        //
        //
        tasklist[RTCCLOCK_TASK]    = new_task(16, rtctask);
        tasklist[RTCCLOCK_TASK]    = new_task(16, rtctask);
#endif
#endif
 
 
#ifdef  DOORBELL_TASK
#ifdef  DOORBELL_TASK
#ifdef  DISPLAY_TASK
#ifdef  DISPLAY_TASK
        // 13 + 10 +9(uwrite)+4(uarthex)+2(uartstr)+2(uartchr)
        // 13 + 10 +9(uwrite)+4(uarthex)+2(uartstr)+2(uartchr)
        tasklist[DOORBELL_TASK]    = new_task(96, doorbell_task);
        tasklist[DOORBELL_TASK]    = new_task(96, doorbell_task);
//      tasklist[DOORBELL_TASK]->fd[FILENO_STDOUT]= kopen((int)lcdpipe,pipedev);
//      tasklist[DOORBELL_TASK]->fd[FILENO_STDOUT]= kopen((int)lcdpipe,pipedev);
        tasklist[DOORBELL_TASK]->fd[FILENO_STDERR]= kopen((int)txpipe, pipedev);
        tasklist[DOORBELL_TASK]->fd[FILENO_STDERR]= kopen((int)txpipe, pipedev);
        tasklist[DOORBELL_TASK]->fd[FILENO_AUX] = kopen((int)pwmpipe,  pipedev);
        tasklist[DOORBELL_TASK]->fd[FILENO_AUX] = kopen((int)pwmpipe,  pipedev);
 
 
        //
        //
        tasklist[DISPLAY_TASK] = new_task(32, display_task);
        tasklist[DISPLAY_TASK] = new_task(32, display_task);
        tasklist[DISPLAY_TASK]->fd[FILENO_STDIN] = kopen((int)lcdpipe,pipedev);
        tasklist[DISPLAY_TASK]->fd[FILENO_STDIN] = kopen((int)lcdpipe,pipedev);
#endif
#endif
#endif
#endif
 
 
 
 
#ifdef  KEYPAD_TASK
#ifdef  KEYPAD_TASK
        // Stack = 7 + 9(uwrite) + 2*4
        // Stack = 7 + 9(uwrite) + 2*4
        tasklist[KEYPAD_TASK] = new_task(32, keypad_task);
        tasklist[KEYPAD_TASK] = new_task(32, keypad_task);
        tasklist[KEYPAD_TASK]->fd[FILENO_STDOUT] = kopen((int)keypipe,pipedev);
        tasklist[KEYPAD_TASK]->fd[FILENO_STDOUT] = kopen((int)keypipe,pipedev);
#endif
#endif
#ifdef  MENU_TASK
#ifdef  MENU_TASK
        // Stack = 18 + 10(showbell/shownow) + 9(uwrite) + 2(menu_readkey)
        // Stack = 18 + 10(showbell/shownow) + 9(uwrite) + 2(menu_readkey)
        //              + 18 (time_menu/dawn_menu/dusk_menu)
        //              + 18 (time_menu/dawn_menu/dusk_menu)
        tasklist[MENU_TASK] = new_task(72, menu_task);
        tasklist[MENU_TASK] = new_task(72, menu_task);
        // tasklist[MENU_TASK]->fd[FILENO_STDIN] = kopen((int)keypipe,pipedev);
        // tasklist[MENU_TASK]->fd[FILENO_STDIN] = kopen((int)keypipe,pipedev);
        tasklist[MENU_TASK]->fd[FILENO_STDOUT]= kopen((int)lcdpipe,pipedev);
        tasklist[MENU_TASK]->fd[FILENO_STDOUT]= kopen((int)lcdpipe,pipedev);
        tasklist[MENU_TASK]->fd[FILENO_STDERR]= kopen((int)txpipe, pipedev);
        tasklist[MENU_TASK]->fd[FILENO_STDERR]= kopen((int)txpipe, pipedev);
#endif
#endif
}
}
 
 
// #define      HALF_HOUR_S     1800    // Seconds per half hour
// #define      HALF_HOUR_S     1800    // Seconds per half hour
// #define      HALF_HOUR_S     180     // Seconds per three minutes--for test
// #define      HALF_HOUR_S     180     // Seconds per three minutes--for test
#define HALF_HOUR_S     30      // 3 Mins is to long, here's 3 seconds
#define HALF_HOUR_S     30      // 3 Mins is to long, here's 3 seconds
 
 
#ifdef  MENU_TASK
#ifdef  MENU_TASK
unsigned        dawn = 0x060000, dusk = 0x180000;
unsigned        dawn = 0x060000, dusk = 0x180000;
#else
#else
const unsigned  dawn = 0x060000, dusk = 0x180000;
const unsigned  dawn = 0x060000, dusk = 0x180000;
#endif
#endif
 
 
void    shownow(unsigned now) { // Uses 10 stack slots + 8 for write()
void    shownow(unsigned now) { // Uses 10 stack slots + 8 for write()
        char    dmsg[9];
        char    dmsg[9];
        dmsg[0] = PACK(0x1b,'[','j','T');
        dmsg[0] = PACK(0x1b,'[','j','T');
        dmsg[1] = PACK('i','m','e',':');
        dmsg[1] = PACK('i','m','e',':');
        dmsg[2] = PACK(' ',((now>>20)&0x3)+'0',
        dmsg[2] = PACK(' ',((now>>20)&0x3)+'0',
                        ((now>>16)&0xf)+'0',':');
                        ((now>>16)&0xf)+'0',':');
        dmsg[3] = PACK( ((now>>12)&0xf)+'0',
        dmsg[3] = PACK( ((now>>12)&0xf)+'0',
                        ((now>> 8)&0xf)+'0',
                        ((now>> 8)&0xf)+'0',
                        ':',
                        ':',
                        ((now>> 4)&0xf)+'0');
                        ((now>> 4)&0xf)+'0');
        dmsg[4] = PACK( ((now    )&0xf)+'0',
        dmsg[4] = PACK( ((now    )&0xf)+'0',
                        0x1b, '[', '1');
                        0x1b, '[', '1');
        dmsg[5] = PACK(';','0','H',' ');
        dmsg[5] = PACK(';','0','H',' ');
        if ((now < dawn)||(now > dusk)) {
        if ((now < dawn)||(now > dusk)) {
                dmsg[6] = PACK('N','i','g','h');
                dmsg[6] = PACK('N','i','g','h');
                dmsg[7] = PACK('t',' ','t','i');
                dmsg[7] = PACK('t',' ','t','i');
                dmsg[8] = PACK('m','e',0,0);
                dmsg[8] = PACK('m','e',0,0);
        } else {
        } else {
                dmsg[6] = PACK('D','a','y','l');
                dmsg[6] = PACK('D','a','y','l');
                dmsg[7] = PACK('i','g','h','t');
                dmsg[7] = PACK('i','g','h','t');
                dmsg[8] = PACK('!',' ',0,0);
                dmsg[8] = PACK('!',' ',0,0);
        } write(FILENO_STDOUT, dmsg, 9);
        } write(FILENO_STDOUT, dmsg, 9);
}
}
 
 
void    showbell(unsigned now) {        // Uses 10 stack slots + 8 for write()
void    showbell(unsigned now) {        // Uses 10 stack slots + 8 for write()
        char    dmsg[9];
        char    dmsg[9];
        dmsg[0] = PACK(0x1b,'[','j','T');
        dmsg[0] = PACK(0x1b,'[','j','T');
        dmsg[1] = PACK('i','m','e',':');
        dmsg[1] = PACK('i','m','e',':');
        dmsg[2] = PACK(' ',((now>>20)&0x3)+'0',
        dmsg[2] = PACK(' ',((now>>20)&0x3)+'0',
                        ((now>>16)&0xf)+'0',':');
                        ((now>>16)&0xf)+'0',':');
        dmsg[3] = PACK( ((now>>12)&0xf)+'0',
        dmsg[3] = PACK( ((now>>12)&0xf)+'0',
                        ((now>> 8)&0xf)+'0',
                        ((now>> 8)&0xf)+'0',
                        ':',
                        ':',
                        ((now>> 4)&0xf)+'0');
                        ((now>> 4)&0xf)+'0');
        dmsg[4] = PACK( ((now    )&0xf)+'0',
        dmsg[4] = PACK( ((now    )&0xf)+'0',
                        0x1b, '[', '1');
                        0x1b, '[', '1');
        dmsg[5] = PACK(';','0','H',' ');
        dmsg[5] = PACK(';','0','H',' ');
        dmsg[6] = PACK('D','o','o','r');
        dmsg[6] = PACK('D','o','o','r');
        dmsg[7] = PACK('b','e','l','l');
        dmsg[7] = PACK('b','e','l','l');
        dmsg[8] = PACK('!',' ',0,0);
        dmsg[8] = PACK('!',' ',0,0);
        write(FILENO_STDOUT, dmsg, 9);
        write(FILENO_STDOUT, dmsg, 9);
}
}
 
 
void    uartchr(char v) {
void    uartchr(char v) {
        if (write(FILENO_STDERR, &v, 1) != 1)
        if (write(FILENO_STDERR, &v, 1) != 1)
                write(FILENO_STDERR, "APPLE-PANIC", 11);
                write(FILENO_STDERR, "APPLE-PANIC", 11);
}
}
 
 
void    uartstr(const char *str) {
void    uartstr(const char *str) {
        int     cnt=0;
        int     cnt=0;
        while(str[cnt])
        while(str[cnt])
                cnt++;
                cnt++;
        if (cnt != write(FILENO_STDERR, str, cnt))
        if (cnt != write(FILENO_STDERR, str, cnt))
                write(FILENO_STDERR, "PIPE-PANIC", 10);
                write(FILENO_STDERR, "PIPE-PANIC", 10);
}
}
 
 
void    uarthex(int num) {
void    uarthex(int num) {
        for(int ds=28; ds>=0; ds-=4) {
        for(int ds=28; ds>=0; ds-=4) {
                int ch;
                int ch;
                ch = (num>>ds)&0x0f;
                ch = (num>>ds)&0x0f;
                if (ch >= 10)
                if (ch >= 10)
                        ch = 'A'+ch-10;
                        ch = 'A'+ch-10;
                else
                else
                        ch += '0';
                        ch += '0';
                uartchr(ch);
                uartchr(ch);
        } uartstr("\r\n");
        } uartstr("\r\n");
}
}
 
 
#ifdef DOORBELL_TASK
#ifdef DOORBELL_TASK
#include "../dev/samples.c"
#include "../dev/samples.c"
 
 
void    belllight(unsigned now) {
void    belllight(unsigned now) {
        IOSPACE *sys = (IOSPACE *)IOADDR;
        IOSPACE *sys = (IOSPACE *)IOADDR;
        if ((now < dawn)||(now > dusk))
        if ((now < dawn)||(now > dusk))
                sys->io_spio = 0x088; // Turn our light on
                sys->io_spio = 0x088; // Turn our light on
        else
        else
                sys->io_spio = 0x80; // Turn light off
                sys->io_spio = 0x80; // Turn light off
}
}
 
 
void    doorbell_task(void) {
void    doorbell_task(void) {
        // Controls LED 0x08
        // Controls LED 0x08
 
 
        // Start by initializing the display to GT Gisselquist\nTechnology
        // Start by initializing the display to GT Gisselquist\nTechnology
        // write(KFD_STDOUT, disp_build_backslash,sizeof(disp_build_backslash));
        // write(KFD_STDOUT, disp_build_backslash,sizeof(disp_build_backslash));
        // write(KFD_STDOUT, disp_build_gtlogo, sizeof(disp_build_gtlogo));
        // write(KFD_STDOUT, disp_build_gtlogo, sizeof(disp_build_gtlogo));
        // write(KFD_STDOUT, disp_reset_data, sizeof(disp_reset_data));
        // write(KFD_STDOUT, disp_reset_data, sizeof(disp_reset_data));
        // write(KFD_STDOUT, disp_gtech_data, sizeof(disp_gtech_data));
        // write(KFD_STDOUT, disp_gtech_data, sizeof(disp_gtech_data));
        IOSPACE *sys = (IOSPACE *)IOADDR;
        IOSPACE *sys = (IOSPACE *)IOADDR;
 
 
        while(1) {
        while(1) {
                int     event;
                int     event;
                // Initial state: doorbell is not ringing.  In this state, we
                // Initial state: doorbell is not ringing.  In this state, we
                // can wait forever for an event
                // can wait forever for an event
                sys->io_spio = 0x080; // Turn our light off
                sys->io_spio = 0x080; // Turn our light off
                event = wait(INT_BUTTON|SWINT_PPS,-1);
                event = wait(INT_BUTTON|SWINT_PPS,-1);
 
 
#ifndef MENU_TASK
#ifndef MENU_TASK
                unsigned when = rtcclock;
                unsigned when = rtcclock;
                if (event & INT_BUTTON)
                if (event & INT_BUTTON)
                        showbell(when);
                        showbell(when);
                else if (event & SWINT_PPS)
                else if (event & SWINT_PPS)
                        shownow(when);
                        shownow(when);
#else
#else
                if (event & INT_BUTTON)
                if (event & INT_BUTTON)
                        post(SWINT_DOORBELL);
                        post(SWINT_DOORBELL);
#endif
#endif
 
 
                while(event & INT_BUTTON) {
                while(event & INT_BUTTON) {
                        // Next state, the button has been pressed, the
                        // Next state, the button has been pressed, the
                        // doorbell is ringing
                        // doorbell is ringing
 
 
                        // Seconds records the number of seconds since the
                        // Seconds records the number of seconds since the
                        // button was last pressed.
                        // button was last pressed.
                        int     seconds = 0;
                        int     seconds = 0;
 
 
                        // Check time: should we turn our light on or not?
                        // Check time: should we turn our light on or not?
                        belllight(rtcclock);
                        belllight((volatile unsigned)rtcclock);
                        const int *sptr = sound_data;
                        const int *sptr = sound_data;
                        // uartchr('N');
                        // uartchr('N');
                        while(sptr < &sound_data[NSAMPLE_WORDS]) {
                        while(sptr < &sound_data[NSAMPLE_WORDS]) {
                                int     len = &sound_data[NSAMPLE_WORDS]-sptr;
                                int     len = &sound_data[NSAMPLE_WORDS]-sptr;
                                if (len > 256)
                                if (len > 256)
                                        len = 256;
                                        len = 256;
 
 
                                // We will stall here, if the audio FIFO is full
                                // We will stall here, if the audio FIFO is full
                                write(FILENO_AUX, sptr, len);
                                write(FILENO_AUX, sptr, len);
                                sptr += len;
                                sptr += len;
 
 
                                // If the user presses the button more than
                                // If the user presses the button more than
                                // once, we start the sound over as well as
                                // once, we start the sound over as well as
                                // our light counter.
                                // our light counter.
                                event = wait(INT_BUTTON|SWINT_PPS, 0);
                                event = wait(INT_BUTTON|SWINT_PPS, 0);
                                if (event&INT_BUTTON) {
                                if (event&INT_BUTTON) {
                                        if (sptr > &sound_data[1024]) {
                                        if (sptr > &sound_data[1024]) {
                                                sptr = sound_data;
                                                sptr = sound_data;
                                                seconds = 0;
                                                seconds = 0;
#ifndef MENU_TASK
#ifndef MENU_TASK
                                                when = (volatile unsigned)rtcclock;
                                                when = (volatile unsigned)rtcclock;
                                                showbell(when);
                                                showbell(when);
#else
#else
                                                post(SWINT_DOORBELL);
                                                post(SWINT_DOORBELL);
#endif
#endif
                                        }
                                        }
                                } else if (event&SWINT_PPS) {
                                } else if (event&SWINT_PPS) {
                                        seconds++;
                                        seconds++;
                                        belllight(rtcclock);
                                        belllight((volatile unsigned)rtcclock);
#ifndef MENU_TASK
#ifndef MENU_TASK
                                        showbell(when);
                                        showbell(when);
#endif
#endif
                                }
                                }
                        }
                        }
 
 
                        // Next state: the doorbell is no longer ringing, but
                        // Next state: the doorbell is no longer ringing, but
                        // we have yet to return to normal--the light is still
                        // we have yet to return to normal--the light is still
                        // on.
                        // on.
                        while((seconds < HALF_HOUR_S)&&
                        while((seconds < HALF_HOUR_S)&&
                                (((event=wait(INT_BUTTON|SWINT_PPS,-1))&INT_BUTTON)==0)) {
                                (((event=wait(INT_BUTTON|SWINT_PPS,-1))&INT_BUTTON)==0)) {
                                seconds++;
                                seconds++;
                                belllight(rtcclock);
                                belllight((volatile unsigned)rtcclock);
#ifndef MENU_TASK
#ifndef MENU_TASK
                                showbell(when);
                                showbell(when);
#endif
#endif
                        }
                        }
                        if (event&INT_BUTTON) {
                        if (event&INT_BUTTON) {
#ifndef MENU_TASK
#ifndef MENU_TASK
                                when = (volatile unsigned)rtcclock;
                                when = (volatile unsigned)rtcclock;
                                showbell(when);
                                showbell(when);
#endif
#endif
                        }
                        }
                }
                }
        }
        }
}
}
#endif
#endif
 
 
#ifdef  MENU_TASK
#ifdef  MENU_TASK
void    entered_menu_str(char *str, unsigned now,int pos) {
void    entered_menu_str(char *str, unsigned now,int pos) {
        //
        //
        // Set current time
        // Set current time
        //   xx:xx:xx
        //   xx:xx:xx
        //
        //
        str[0] = PACK(0x1b, '[', '1',';');
        str[0] = PACK(0x1b, '[', '1',';');
        str[1] = PACK('0','H',' ',' ');
        str[1] = PACK('0','H',' ',' ');
        str[2] = PACK(' ','x','x',':');
        str[2] = PACK(' ','x','x',':');
        str[3] = PACK('x','x',' ',' ');
        str[3] = PACK('x','x',' ',' ');
        //str[3]=PACK('x','x',':','x');
        //str[3]=PACK('x','x',':','x');
        str[4] = PACK(' ','\0','\0','\0');
        str[4] = PACK(' ','\0','\0','\0');
 
 
        if (pos>0) {
        if (pos>0) {
                int ch = ((now >> 20)&0x0f)+'0';
                int ch = ((now >> 20)&0x0f)+'0';
                str[2] &= ~0x0ff0000;
                str[2] &= ~0x0ff0000;
                str[2] |= (ch<<16);
                str[2] |= (ch<<16);
 
 
                if (pos > 1) {
                if (pos > 1) {
                        int ch = ((now >> 16)&0x0f)+'0';
                        int ch = ((now >> 16)&0x0f)+'0';
                        str[2] &= ~0x0ff00;
                        str[2] &= ~0x0ff00;
                        str[2] |= (ch<<8);
                        str[2] |= (ch<<8);
 
 
                if (pos > 2) {
                if (pos > 2) {
                        int ch = ((now >> 12)&0x0f)+'0';
                        int ch = ((now >> 12)&0x0f)+'0';
                        str[3] &= ~0xff000000;
                        str[3] &= ~0xff000000;
                        str[3] |= (ch<<24);
                        str[3] |= (ch<<24);
 
 
                if (pos > 3) {
                if (pos > 3) {
                        int ch = ((now >> 8)&0x0f)+'0';
                        int ch = ((now >> 8)&0x0f)+'0';
                        str[3] &= ~0x0ff0000;
                        str[3] &= ~0x0ff0000;
                        str[3] |= (ch<<16);
                        str[3] |= (ch<<16);
 
 
                if (pos > 4) {
                if (pos > 4) {
                        int ch = ((now >> 4)&0x0f)+'0';
                        int ch = ((now >> 4)&0x0f)+'0';
                        str[3] &= ~0x0ff00;
                        str[3] &= ~0x0ff00;
                        str[3] |= ':'<<8;
                        str[3] |= ':'<<8;
                        str[3] &= ~0x0ff;
                        str[3] &= ~0x0ff;
                        str[3] |= (ch);
                        str[3] |= (ch);
 
 
                        if (pos > 5)
                        if (pos > 5)
                                ch = (now&0x0f)+'0';
                                ch = (now&0x0f)+'0';
                        else
                        else
                                ch = 'x';
                                ch = 'x';
                        str[4] &= ~0x0ff000000;
                        str[4] &= ~0x0ff000000;
                        str[4] |= (ch<<24);
                        str[4] |= (ch<<24);
        }}}}}
        }}}}}
}
}
 
 
void    show_time_menu(unsigned when, int posn) {
void    show_time_menu(unsigned when, int posn) {
        char    dmsg[10];
        char    dmsg[10];
        dmsg[0] = PACK(0x1b,'[','j','S');
        dmsg[0] = PACK(0x1b,'[','j','S');
        dmsg[1] = PACK('e','t',' ','c');
        dmsg[1] = PACK('e','t',' ','c');
        dmsg[2] = PACK('u','r','r','e');
        dmsg[2] = PACK('u','r','r','e');
        dmsg[3] = PACK('n','t',' ','t');
        dmsg[3] = PACK('n','t',' ','t');
        dmsg[4] = PACK('i','m','e',':');
        dmsg[4] = PACK('i','m','e',':');
        entered_menu_str(&dmsg[5], when, posn);
        entered_menu_str(&dmsg[5], when, posn);
        write(FILENO_STDOUT, dmsg, 9);
        write(FILENO_STDOUT, dmsg, 9);
}
}
 
 
void    show_dawn_menu(unsigned when, int posn) {
void    show_dawn_menu(unsigned when, int posn) {
        char    dmsg[10];
        char    dmsg[10];
        dmsg[0] = PACK(0x1b,'[','j','S');
        dmsg[0] = PACK(0x1b,'[','j','S');
        dmsg[1] = PACK('e','t',' ','s');
        dmsg[1] = PACK('e','t',' ','s');
        dmsg[2] = PACK('u','n','r','i');
        dmsg[2] = PACK('u','n','r','i');
        dmsg[3] = PACK('s','e',':','\0');
        dmsg[3] = PACK('s','e',':','\0');
        entered_menu_str(&dmsg[4], when, posn);
        entered_menu_str(&dmsg[4], when, posn);
        write(FILENO_STDOUT, dmsg, 8);
        write(FILENO_STDOUT, dmsg, 8);
}
}
 
 
void    show_dusk_menu(unsigned when, int posn) {
void    show_dusk_menu(unsigned when, int posn) {
        char    dmsg[10];
        char    dmsg[10];
        dmsg[0] = PACK(0x1b,'[','j','S');
        dmsg[0] = PACK(0x1b,'[','j','S');
        dmsg[1] = PACK('e','t',' ','s');
        dmsg[1] = PACK('e','t',' ','s');
        dmsg[2] = PACK('u','n','s','e');
        dmsg[2] = PACK('u','n','s','e');
        dmsg[3] = PACK('t',':','\0','\0');
        dmsg[3] = PACK('t',':','\0','\0');
        entered_menu_str(&dmsg[4], when, posn);
        entered_menu_str(&dmsg[4], when, posn);
        write(FILENO_STDOUT, dmsg, 8);
        write(FILENO_STDOUT, dmsg, 8);
}
}
 
 
int     menu_readkey(void) {
int     menu_readkey(void) {
        int     key;
        int     key;
        wait(0,3);
        wait(0,3);
        key = keypadread();
        key = keypadread();
        keypad_wait_for_release();
        keypad_wait_for_release();
        clear(INT_KEYPAD);
        clear(INT_KEYPAD);
        return key;
        return key;
}
}
 
 
void    time_menu(void) {
void    time_menu(void) {
        int     timeout = 60;
        int     timeout = 60;
        unsigned newclock = 0;
        unsigned newclock = 0;
        for(int p=0; p<6; p++) {
        for(int p=0; p<6; p++) {
                int     key, event;
                int     key, event;
                show_time_menu(newclock, p);
                show_time_menu(newclock, p);
                do {
                do {
                        event = wait(SWINT_PPS|INT_KEYPAD,-1);
                        event = wait(SWINT_PPS|INT_KEYPAD,-1);
                        if (event&SWINT_PPS) {
                        if (event&SWINT_PPS) {
                                timeout--;
                                timeout--;
                                if (timeout == 0)
                                if (timeout == 0)
                                        return;
                                        return;
                        } if (event&INT_KEYPAD) {
                        } if (event&INT_KEYPAD) {
                                timeout = 60;
                                timeout = 60;
                                key = menu_readkey();
                                key = menu_readkey();
                                if ((key >= 0)&&(key < 10)) {
                                if ((key >= 0)&&(key < 10)) {
                                        int     sh;
                                        int     sh;
                                        sh = (5-p)*4;
                                        sh = (5-p)*4;
                                        newclock &= ~(0x0f<<sh);
                                        newclock &= ~(0x0f<<sh);
                                        newclock |= (key<<sh);
                                        newclock |= (key<<sh);
                                } else if (key == 12) {
                                } else if (key == 12) {
                                        if (p>=0)
                                        if (p>=0)
                                                p--;
                                                p--;
                                } else {
                                } else {
                                        if (p > 4)
                                        if (p > 4)
                                                break;
                                                break;
                                        else
                                        else
                                                return;
                                                return;
                                }
                                }
                        }
                        }
                } while(0==(event&INT_KEYPAD));
                } while(0==(event&INT_KEYPAD));
        }
        }
 
 
 
        // Here's the trick here: without semaphores, we can't prevent a 
 
        // race condition on the clock.  It may be that the clock simulator
 
        // has read the clock value and is in the process of updating it, only
 
        // to have our task swapped in.  The risk here is that the RTC simulator
 
        // will write the updated value after we update our value here.  If it
 
        // does that, it will then set the SWINT_PPS interrupt.  So let's clear
 
        // this interrupt and then set our clock.  If the interrupt then
 
        // takes place in short order, we'll set the clock again.  That way,
 
        // if the RTC device was in the process of setting the clock, and then
 
        // sets it, we can adjust it again.
 
        //
 
        // Of course ... this won't work if it takes the clock longer than 
 
        // a millisecond to finish setting the clock ... but this is such a
 
        // rare race condition, and the consequences so minor, that this will
 
        // probably continue to work for now.
        clear(SWINT_PPS);
        clear(SWINT_PPS);
        rtcclock = newclock;
        rtcclock = newclock;
        if (wait(SWINT_PPS, 1))
        if (wait(SWINT_PPS, 1))
                rtcclock = newclock;
                rtcclock = newclock;
}
}
 
 
void    dawn_menu(void) {
void    dawn_menu(void) {
        int     timeout = 60;
        int     timeout = 60;
        unsigned newdawn = 0;
        unsigned newdawn = 0;
        for(int p=0; p<6; p++) {
        for(int p=0; p<6; p++) {
                int     key, event;
                int     key, event;
                show_dawn_menu(newdawn, p);
                show_dawn_menu(newdawn, p);
                do {
                do {
                        event = wait(SWINT_PPS|INT_KEYPAD,-1);
                        event = wait(SWINT_PPS|INT_KEYPAD,-1);
                        if (event&SWINT_PPS) {
                        if (event&SWINT_PPS) {
                                timeout--;
                                timeout--;
                                if (timeout == 0)
                                if (timeout == 0)
                                        return;
                                        return;
                        } if (event&INT_KEYPAD) {
                        } if (event&INT_KEYPAD) {
                                timeout = 60;
                                timeout = 60;
                                key = menu_readkey();
                                key = menu_readkey();
                                if ((key >= 0)&&(key < 10)) {
                                if ((key >= 0)&&(key < 10)) {
                                        int     sh = (5-p)*4;
                                        int     sh = (5-p)*4;
                                        newdawn &= ~(0x0f<<sh);
                                        newdawn &= ~(0x0f<<sh);
                                        newdawn |= key<<sh;
                                        newdawn |= key<<sh;
                                } else if (key == 12) {
                                } else if (key == 12) {
                                        if (p>=0)
                                        if (p>=0)
                                                p--;
                                                p--;
                                } else {
                                } else {
                                        if (p > 4)
                                        if (p > 4)
                                                break;
                                                break;
                                        else
                                        else
                                                return;
                                                return;
                                }
                                }
                        }
                        }
                } while(0 == (event&INT_KEYPAD));
                } while(0 == (event&INT_KEYPAD));
        } dawn = newdawn;
        } dawn = newdawn;
}
}
 
 
void    dusk_menu(void) {
void    dusk_menu(void) {
        int     timeout = 60;
        int     timeout = 60;
        unsigned newdusk = 0;
        unsigned newdusk = 0;
        for(int p=0; p<6; p++) {
        for(int p=0; p<6; p++) {
                int     key, event;
                int     key, event;
                show_dusk_menu(newdusk, p);
                show_dusk_menu(newdusk, p);
                do {
                do {
                        event = wait(SWINT_PPS|INT_KEYPAD,-1);
                        event = wait(SWINT_PPS|INT_KEYPAD,-1);
                        if (event&SWINT_PPS) {
                        if (event&SWINT_PPS) {
                                timeout--;
                                timeout--;
                                if (timeout == 0)
                                if (timeout == 0)
                                        return;
                                        return;
                        } if (event&INT_KEYPAD) {
                        } if (event&INT_KEYPAD) {
                                key = menu_readkey();
                                key = menu_readkey();
                                if ((key >= 0)&&(key < 10)) {
                                if ((key >= 0)&&(key < 10)) {
                                        int     sh = (5-p)*4;
                                        int     sh = (5-p)*4;
                                        newdusk &= ~(0x0f<<sh);
                                        newdusk &= ~(0x0f<<sh);
                                        newdusk |= key<<sh;
                                        newdusk |= key<<sh;
                                } else if (key == 12) {
                                } else if (key == 12) {
                                        if (p>=0)
                                        if (p>=0)
                                                p--;
                                                p--;
                                } else {
                                } else {
                                        if (p > 4)
                                        if (p > 4)
                                                break;
                                                break;
                                        else
                                        else
                                                return;
                                                return;
                                }
                                }
                        }
                        }
                } while(0 == (event&INT_KEYPAD));
                } while(0 == (event&INT_KEYPAD));
        } dusk = newdusk;
        } dusk = newdusk;
}
}
 
 
void    unknown_menu(void) {
void    unknown_menu(void) {
        //      0123456789ABCDEF
        //      0123456789ABCDEF
        //      Unknown Cmd Key
        //      Unknown Cmd Key
        //      A/Tm B/Dwn C/Dsk
        //      A/Tm B/Dwn C/Dsk
        char    dmsg[11];
        char    dmsg[11];
        dmsg[0] = PACK(0x1b,'[','j','U');
        dmsg[0] = PACK(0x1b,'[','j','U');
        dmsg[1] = PACK('n','k','n','o');
        dmsg[1] = PACK('n','k','n','o');
        dmsg[2] = PACK('w','n',' ','C');
        dmsg[2] = PACK('w','n',' ','C');
        dmsg[3] = PACK('m','d',' ','K');
        dmsg[3] = PACK('m','d',' ','K');
        dmsg[4] = PACK('e','y','\0','\0');
        dmsg[4] = PACK('e','y','\0','\0');
        dmsg[5] = PACK(0x1b,'[','1',';');
        dmsg[5] = PACK(0x1b,'[','1',';');
        dmsg[6] = PACK('0','H','A','/');
        dmsg[6] = PACK('0','H','A','/');
        dmsg[7] = PACK('T','m',' ','B');
        dmsg[7] = PACK('T','m',' ','B');
        dmsg[8] = PACK('/','D','w','n');
        dmsg[8] = PACK('/','D','w','n');
        dmsg[9] = PACK(' ','C','/','D');
        dmsg[9] = PACK(' ','C','/','D');
        dmsg[10] = PACK('s','k',0,0);
        dmsg[10] = PACK('s','k',0,0);
        write(FILENO_STDOUT, dmsg, 11);
        write(FILENO_STDOUT, dmsg, 11);
}
}
void    menu_task(void) {
void    menu_task(void) {
        // Controls LED 0x08
        // Controls LED 0x08
 
 
        // Start by initializing the display to GT Gisselquist\nTechnology
        // Start by initializing the display to GT Gisselquist\nTechnology
        // write(KFD_STDOUT, disp_build_backslash,sizeof(disp_build_backslash));
        // write(KFD_STDOUT, disp_build_backslash,sizeof(disp_build_backslash));
        // write(KFD_STDOUT, disp_build_gtlogo, sizeof(disp_build_gtlogo));
        // write(KFD_STDOUT, disp_build_gtlogo, sizeof(disp_build_gtlogo));
        // write(KFD_STDOUT, disp_reset_data, sizeof(disp_reset_data));
        // write(KFD_STDOUT, disp_reset_data, sizeof(disp_reset_data));
        // write(KFD_STDOUT, disp_gtech_data, sizeof(disp_gtech_data));
        // write(KFD_STDOUT, disp_gtech_data, sizeof(disp_gtech_data));
        IOSPACE *sys = (IOSPACE *)IOADDR;
        // IOSPACE      *sys = (IOSPACE *)IOADDR;
        unsigned belltime = 0, when;
        unsigned belltime = 0, when;
 
 
 
 
        when = rtcclock;
        when = (volatile unsigned)rtcclock;
        while(1) {
        while(1) {
                int     event;
                int     event;
                // Initial state: doorbell is not ringing.  In this state, we
                // Initial state: doorbell is not ringing.  In this state, we
                // can wait forever for an event
                // can wait forever for an event
                sys->io_spio = 0x080; // Turn our light off
 
                event = wait(SWINT_DOORBELL|SWINT_PPS|INT_KEYPAD,-1);
                event = wait(SWINT_DOORBELL|SWINT_PPS|INT_KEYPAD,-1);
                if (event & SWINT_DOORBELL) {
                if (event & SWINT_DOORBELL) {
                        showbell(when);
                        showbell(when);
                        belltime = time();
                        belltime = time();
                } else if (event & SWINT_PPS) {
                } else if (event & SWINT_PPS) {
                        unsigned        now = time();
                        unsigned        now = time();
                        if ((now-belltime)<HALF_HOUR_S)
                        if ((now-belltime)<HALF_HOUR_S)
                                showbell(when);
                                showbell(when);
                        else {
                        else {
                                when = rtcclock;
                                when = (volatile unsigned)rtcclock;
                                shownow(when);
                                shownow(when);
                        }
                        }
                }
                }
 
 
                if (event & INT_KEYPAD) {
                if (event & INT_KEYPAD) {
                        int     key;
                        int     key;
                        key = menu_readkey();
                        key = menu_readkey();
                        switch(key) {
                        switch(key) {
                                case 10: time_menu();
                                case 10: time_menu();
                                        when = rtcclock;
                                        when = (volatile unsigned)rtcclock;
                                        break;
                                        break;
                                case 11: dawn_menu(); break;
                                case 11: dawn_menu(); break;
                                case 12: dusk_menu(); break;
                                case 12: dusk_menu(); break;
                                default:
                                default:
                                        unknown_menu();
                                        unknown_menu();
                                        wait(0,3000);
                                        wait(0,3000);
                        } clear(INT_KEYPAD);
                        } clear(INT_KEYPAD);
                }
                }
        }
        }
}
}
#endif
#endif
 
 
 
 

powered by: WebSVN 2.1.0

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