Subversion Repositories shark

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*****************************************************************************
* Filename:       osc.c                                                      *
* Author:         Ghiro Andrea,Franchino Gianluca                            *
* Date:           09/2003                                                    *
* Description:    Oscilloscope and function generator for PCI6025E           *
*----------------------------------------------------------------------------*
* Notes:          Connect DAC output pin (21) to ADC input pins (3-18) and   *
*                 watch the waveforms.                                       *
*****************************************************************************/


/* This file is part of the S.Ha.R.K. Project - http://shark.sssup.it
 *
 * Copyright (C) 2003 Ghiro Andrea,Franchino Gianluca
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */



#include <drivers/glib.h>
#include <drivers/keyb.h>
#include <math.h>
#include <drivers/pci6025e/dac.h>
#include <modules/hartport.h>
#include <modules/srp.h>
#include "adc.h"

#define  MAX_VAL         500
#define  NUM_POINT        20
#define  GRAPH_PERIOD  50000
#define  GRAPH_WCET     2000
#define  WAVE_WCET       200
#define  OSC_WCET        200
#define  TASK_GROUP        1
#define  CHFREQ_PERIOD  5000
#define  CHFREQ_WCET     200

void drawInterface(void);
void endfun(KEY_EVT *);
void close_event(void *);
void createWaves(void);
void change_disp(KEY_EVT *);
void change_mode(KEY_EVT *);
void change_wave(KEY_EVT *);
void change_passo(KEY_EVT *);
void change_channel(KEY_EVT *);
void inc(KEY_EVT *);
void dec(KEY_EVT *);

TASK video_body(int);
TASK wave_body(int);
TASK osc_body(int);
TASK chfreq_body(int);

HARD_TASK_MODEL    wave0;
HARD_TASK_MODEL    chfreq;
HARD_TASK_MODEL    osc;
SRP_RES_MODEL      r;
SRP_mutexattr_t    a;

PID wave0_pid;
PID chfreq_pid;
PID osc_pid;

mutex_t m1 ;

int black = rgb16(0,0,0),
    white = rgb16(255, 255, 255);

int wave    = 3,
    varfun  = 0,
    varosc  = 0,
    flagch  = 0,
    channel = 0;

float vfun = 0,
      vosc = 2.5,
      ffun = 1,
      tbase = 75,
      yr[MAX_VAL],
      yrdac[NUM_POINT],
      ys[MAX_VAL],
      ysdac[NUM_POINT],
      yq[MAX_VAL],
      yqdac[NUM_POINT];

BYTE disp   = 0,
     modefun= 0,
     modeosc= 0,
     lib    = 0,
     sys    = 0;

short yoscold[MAX_VAL];

unsigned int period= 1e6/NUM_POINT;
unsigned int oscperiod = 1500;

int main(int argc, char **argv)
{
   KEY_EVT  k;

   HARD_TASK_MODEL    video;
   PID video_pid;

   int modenum;

   k.flag  =  CNTR_BIT;
   k.scan  =  KEY_X;
   k.ascii =  'x';
   keyb_hook(k, endfun);
   
   k.flag  =  CNTL_BIT;
   keyb_hook(k, endfun);
   
   k.flag  =  0;
   k.scan  =  KEY_A;
   k.ascii =  'a';
   keyb_hook(k, change_disp);

   k.flag  =  0;
   k.scan  =  KEY_S;
   k.ascii =  's';
   keyb_hook(k, change_mode);

   k.flag  =  0;
   k.scan  =  KEY_F;
   k.ascii =  'f';
   keyb_hook(k, change_wave);
   
   k.flag  =  0;
   k.scan  =  KEY_G;
   k.ascii =  'g';
   keyb_hook(k, change_wave);
   
   k.flag  =  0;
   k.scan  =  KEY_H;
   k.ascii =  'H';
   keyb_hook(k, change_wave);
   
   k.flag  =  0;
   k.scan  =  KEY_D;
   k.ascii =  'd';
   keyb_hook(k, change_passo);

   k.flag  =  0;
   k.scan  =  KEY_J;
   k.ascii =  'j';
   keyb_hook(k, change_channel);

   k.flag  =  0;
   k.scan  =  78;
   k.ascii =  43;
   keyb_hook(k, inc);

   k.flag  =  0;
   k.scan  =  74;
   k.ascii =  45;
   keyb_hook(k, dec);

   sys_atrunlevel(close_event, NULL, RUNLEVEL_BEFORE_EXIT);

   /*initialize the srp mutex*/
   SRP_mutexattr_default(a);
   mutex_init(&m1,&a);

   hard_task_default_model(wave0);
   hard_task_def_wcet(wave0, WAVE_WCET);
   hard_task_def_mit(wave0, period);
   hard_task_def_group(wave0, TASK_GROUP);
   if( (wave0_pid = task_create("Wave 0", wave_body, &wave0, NULL)) == NIL )
      {
      sys = 10;
      sys_end();
      }

   hard_task_default_model(video);
   hard_task_def_wcet(video, GRAPH_WCET);
   hard_task_def_mit(video, GRAPH_PERIOD);
   hard_task_def_group(video, TASK_GROUP);
   SRP_res_default_model(r,2);
   if( (video_pid = task_createn("Video task", video_body, &video, &r,
      SRP_usemutex(&m1), NULL))== NIL )
      {
      sys = 12;
      sys_end();
      }

   hard_task_default_model(osc);
   hard_task_def_wcet(osc, OSC_WCET);
   hard_task_def_mit(osc, oscperiod);
   hard_task_def_group(osc, TASK_GROUP);
   SRP_res_default_model(r,1);
   if((osc_pid = task_createn("osc task", osc_body, &osc, &r,
      SRP_usemutex(&m1), NULL))== NIL )
      {
      sys = 11;
      sys_end();
      }

   hard_task_default_model(chfreq);
   hard_task_def_wcet(chfreq, CHFREQ_WCET);
   hard_task_def_mit(chfreq, CHFREQ_PERIOD);
   hard_task_def_group(chfreq, TASK_GROUP);
   if( (chfreq_pid = task_create("chfreq", chfreq_body, &chfreq, NULL)) == NIL )
      {
      sys = 13;
      sys_end();
      }

   if(grx_init() == -1)
      {
      sys = 30;
      sys_end();
      }

   if((modenum = grx_getmode(800, 600, 16)) == -1)
      {
      sys = 31;
      sys_end();
      }

   if(pci_init() == -1)
      {
      sys = 20;
      sys_end();
      }

   if(!reMap())
      {
      sys = 21;
      sys_end();
      }

   grx_setmode(modenum);

   createWaves();
   drawInterface();

   DAC_Init();                  //Program the DAQ-STC AOTM
   Configure_Board(channel);    //Configure the board with the channel settings.
   ADC_Init();                  //Program the DAQ-STC AITM
 
   group_activate(TASK_GROUP);

   return 0;
}

void endfun(KEY_EVT *k)
{
   sys_end();
}

void close_event(void *arg)
{
   grx_close();
   switch(sys)
     {
     case 0:  cprintf("Regular End!\n"); break;
     case 10: cprintf("Cannot create <wave 0> task!\n"); break;
     case 11: cprintf("Cannot create <osc> task!\n"); break;
     case 12: cprintf("Cannot create <video> task!\n"); break;
     case 13: cprintf("Cannot create <chfreq> task!\n"); break;
     case 14: cprintf("Cannot kill <wave 0> task!\n"); break;
     case 15: cprintf("Cannot kill <osc> task\n");break;
     case 20: cprintf("No PCI bus found!\n"); break;
     case 21: cprintf("No NATIONAL PCI E-Series board found on PCI bus!\n");break;
     case 30: cprintf("Cannot start graphic envirorment!\n"); break;
     case 31: cprintf("800x600x16 video mode not supported!\n");break;
     default: cprintf("Unknown exit event!\n"); break;
     }
}

/*
* kill wave0 or osc when frequency change
*/


TASK chfreq_body(int w)
{
   PORT p;
   char msg[1];
   p = port_create("activation",1,1,STREAM,WRITE);

   while(1)
     {
     if(flagch == 1)
       {
       if(task_kill(wave0_pid)!=0)
         {
         sys=14;
         sys_end();
         }
       hard_task_def_mit(wave0, period);
       if( (wave0_pid = task_create("wave 0", wave_body, &wave0, NULL))== NIL )
         {
         sys = 10;
         sys_end();
         }
       flagch = 0;
       task_activate(wave0_pid);
       }

     if(flagch == 2)
       {
       if(task_kill(osc_pid)!=0)
         {
         sys=15;
         sys_end();
         }
       hard_task_def_mit(osc, oscperiod);
       if( (osc_pid = task_createn("osc", osc_body, &osc, &r,
          SRP_usemutex(&m1), NULL))== NIL )
         {
         sys = 11;
         sys_end();
         }
       flagch = 0;
       msg[0]=1;
       port_send(p,msg,NON_BLOCK);
       }
    task_endcycle();
    }
}

/*
* acquisition of input samples
*/


TASK osc_body(int wv)
{
   int i = 0 ;
   short y = 0;
   WORD Status = 0;

   while(1)
     {
     mutex_lock(&m1);
     if(lib)
       {
       mutex_unlock(&m1);
       AI_Start_The_Acquisition();
       do {
          Status = DAQ_STC_Windowed_Mode_Read(AI_STATUS_1);
          if (!( (Status & 0x1000) == 0x1000 ) )
          y = Immediate_Readw(ADC_DATA_READ);
          } while(((Status & 0x1000) == 0x1000));
       y = (2.5/vosc)*(y-40)/20;
       if(abs(y)<=100)
         {
         grx_plot(19+i,483-y,rgb16(255,255,0));
         }
       yoscold[i]=y;
       i=(i+1)%500;
       if(i==0)
         {
          mutex_lock(&m1);
          lib=0;
          mutex_unlock(&m1);
          task_testcancel();
         }
      }
    else  mutex_unlock(&m1);
    task_endcycle();
    }
}

/*
* Sends out waves' samples
*/


TASK wave_body(int wv)
{
   int i = 0;
   int y = 0;
   while(1)
     {
     if(wave==0)
       {
       y=vfun*(yrdac[i]*20);
       y=(y & 0x0FFF);
       }
     if(wave==1)
       {
       y=vfun*(ysdac[i]*20);
       y=(y & 0x0FFF);
       }
     if(wave==2)
       {
       y=vfun*(yqdac[i]*20);
       y=(y & 0x0FFF);
       }
     DAC_output(DAC1,y);
     i = (i + 1) % NUM_POINT;
     task_testcancel();
     task_endcycle();
     }
}

/*
* Shows setting,wave,grid and clear display
*/


TASK video_body(int dummy)
{                                
   BYTE dispold    = 1,
        modefunold = 1,  
        modeoscold = 1,      
        new        = 0;

   int  waveold    = 3,
        varfunold  = 2,
        i          = 0,
        y          = 0,
        channelold = 16,
        yold[MAX_VAL];


   float vfunold = 1,
         voscold = 1,
         ffunold = 0,
         tbaseold = 1;
     
   char st[20];

   PORT p;
   char msg[1];
   p=port_connect("activation",1,STREAM,READ);

    while(1)
      {
      mutex_lock(&m1);
      if(!lib)
        {
        mutex_unlock(&m1);
        for(i=0;i<MAX_VAL;i++)
          {
          if(abs(yoscold[i])<=100)
            {
            grx_plot(19+i,483-yoscold[i],rgb16(0,0,0));
            }
          }
        //OSCILLOSCOPE GRID
        grx_line(19, 385, 519, 385, rgb16(150,150,150));
        grx_line(19, 410, 519, 410, rgb16(150,150,150));
        grx_line(19, 435, 519, 435, rgb16(150,150,150));
        grx_line(19, 460, 519, 460, rgb16(150,150,150));
        grx_line(19, 485, 519, 485, rgb16(150,150,150));
        grx_line(19, 510, 519, 510, rgb16(150,150,150));
        grx_line(19, 535, 519, 535, rgb16(150,150,150));
        grx_line(19, 560, 519, 560, rgb16(150,150,150));
        grx_line(19, 585, 519, 585, rgb16(150,150,150));
        grx_line(19, 385, 19, 585, rgb16(150,150,150));
        grx_line(69, 385, 69, 585, rgb16(150,150,150));
        grx_line(119, 385, 119, 585, rgb16(150,150,150));
        grx_line(169, 385, 169, 585, rgb16(150,150,150));
        grx_line(219, 385, 219, 585, rgb16(150,150,150));
        grx_line(269, 385, 269, 585, rgb16(150,150,150));
        grx_line(319, 385, 319, 585, rgb16(150,150,150));
        grx_line(369, 385, 369, 585, rgb16(150,150,150));
        grx_line(419, 385, 419, 585, rgb16(150,150,150));
        grx_line(469, 385, 469, 585, rgb16(150,150,150));
        grx_line(519, 385, 519, 585, rgb16(150,150,150));
        mutex_lock(&m1);
        lib=1;
        mutex_unlock(&m1);
        port_receive(p,msg,NON_BLOCK);
        if(msg[0]==1)
          {
          task_activate(osc_pid);
          }
        }
        else mutex_unlock(&m1);
      if(disp != dispold)
        {
        dispold = disp;
        grx_disc(780,120,10,rgb16(255*(1-disp),0,0));
        grx_disc(780,390,10,rgb16(0,255*disp,0));
        }        
     
      if(modefun != modefunold)
        {
        modefunold = modefun;
        grx_disc(780,237,5,rgb16(255*(1-modefun),0,0));
        grx_disc(780,267,5,rgb16(255*(modefun),0,0));
        }        
     
      if(modeosc != modeoscold)
        {
        modeoscold = modeosc;
        grx_disc(780,502,5,rgb16(0,255*(1-modeosc),0));
        grx_disc(780,532,5,rgb16(0,255*(modeosc),0));
        }        
     
      if(wave != waveold)
        {
        waveold = wave;
        grx_disc(730,127,3,rgb16(127*(1-wave)*(2-wave),0,0));  
        grx_disc(730,142,3,rgb16(254*wave*(2-wave),0,0));  
        grx_disc(730,157,3,rgb16(254*wave*(wave-1),0,0));  
        new=1;
        }        
     
      if(varfun != varfunold)
        {
        varfunold = varfun;
        grx_disc(675,292,3,rgb16(42*(1-varfun)*(2-varfun)*(3-varfun),0,0));  
        grx_disc(775,292,3,rgb16(126*varfun*(2-varfun)*(3-varfun),0,0));  
        grx_disc(675,307,3,rgb16(252*varfun*(varfun-1)*(3-varfun),0,0));  
        grx_disc(775,307,3,rgb16(42*varfun*(varfun-1)*(varfun-2),0,0));  
        }        
     

      if(channel != channelold)
        {
        sprintf(st,"%2d",channel);
        grx_text("  ",660,470,black,white);
        grx_text(st,660,470,black,white);
        }

      if(ffun != ffunold)
        {
        ffunold = ffun;
        sprintf(st,"%10f",ffun);
        grx_text("          ",660,265,black,white);
        grx_text(st,660,265,black,white);
        }        
     
      if(tbase != tbaseold)
        {
        tbaseold = tbase;
        sprintf(st,"%10f",tbase);
        grx_text("          ",660,530,black,white);
        grx_text(st,660,530,black,white);
        }        
         
      if(vfun != vfunold)
        {
        vfunold = vfun;
        sprintf(st,"%3.1f",vfun);
        grx_text("     ",660,235,black,white);
        grx_text(st,660,235,black,white);
        new=1;
        }        
     
      if(vosc != voscold)
        {
        voscold = vosc;
        sprintf(st,"%3.1f",vosc);
        grx_text("     ",660,500,black,white);
        grx_text(st,660,500,black,white);
        }        
 
      if(new)
        {
        for(i=0; i<MAX_VAL; i++)
          {
          grx_plot(19+i, 215-yold[i],rgb16(0, 0, 0));
          }
       
      //FUNCTION GENERATOR GRID
        grx_line(22, 115, 525, 115, rgb16(150,150,150));
        grx_line(22, 165, 525, 165, rgb16(150,150,150));
        grx_line(22, 265, 525, 265, rgb16(150,150,150));
        grx_line(22, 315, 525, 315, rgb16(150,150,150));
        grx_line(19, 110, 19, 320, rgb16(150,150,150));
        grx_line(14, 215, 525, 215, rgb16(150,150,150));
       
        if(wave==0)
          {
          for(i=0;i<MAX_VAL;i++)
            {
            y=(vfun)*yr[i];
            grx_plot(19+i,215-y,rgb16(255,255,0));
            yold[i]=y;
            }
          }
         
        if(wave==1)
          {
          for(i=0;i<MAX_VAL;i++)
            {
            y=(vfun)*ys[i];
            grx_plot(19+i,215-y,rgb16(255,255,0));
            yold[i]=y;
            }
          }
       
        if(wave==2)
          {
          for(i=0;i<MAX_VAL;i++)
            {
            y=(vfun)*yq[i];
            grx_plot(19+i,215-y,rgb16(255,255,0));
            yold[i]=y;
            }
          }

          new=0;  
      }
      task_endcycle();
      }
}                          

/*
* create wave triangular,sinusoidal and square
*/


void createWaves(void)
{
   float  u=0,
          qdac= 2*PI/NUM_POINT,
          q = 2*PI/(MAX_VAL/2);

   register int i;

   BYTE direction=0;    
/*create the vectors for the video task*/
   for(i=0;i<MAX_VAL/2;i++)
      {                
      yr[i]=yr[i+MAX_VAL/2]=u/10;
      if(!direction)   u += 1.613;
      else             u -= 1.613;
      if(u >= 100)    direction = 1;
      if(u <= -101)   direction = 0;
       
      ys[i]=ys[i+MAX_VAL/2] = (sin(i*q)*10);

      if((i>=(MAX_VAL/4) && i< (MAX_VAL/2))) yq[i]=yq[i+MAX_VAL/2]=0;
      else yq[i]=yq[i+MAX_VAL/2]=10;
      }
/*create the vectors for the wave_body task*/
   direction=0;
   u = 0;
   for(i=0;i<NUM_POINT;i++)
      {
      yrdac[i]=u/10;
      if(!direction)  u += (400/NUM_POINT);
      else            u -= (400/NUM_POINT);
      if(u >= 100)    direction = 1;
      if(u <= -100)   direction = 0;
       
      ysdac[i]=(sin(i*qdac)*10);

      if((i>=(NUM_POINT/2) && i<NUM_POINT)) yqdac[i]=0;
      else yqdac[i]=10;
      }
}  

/*
* select device (0 function generator,1 oscilloscope)
*/


void change_disp(KEY_EVT *k)
{
   if(disp)  disp = 0;
   else      disp = 1;
}

/*
* select volt or frequency
*/


void change_mode(KEY_EVT *k)
{
   if(disp && modeosc)  modeosc = 0;
   else      
   if(disp && !modeosc) modeosc = 1;
   else  
   if(!disp && modefun) modefun = 0;
   else
   if(!disp && !modefun) modefun =1;
}

/*
* select wave (0 triangular,1 sinusoindal,2 square
*/


void change_wave(KEY_EVT *k)
{
  if(!disp && k->ascii =='f')
    {
    wave=0;
    }
  else
  if(!disp && k->ascii =='g')
    {
    wave=1;
    }
  else
  if(!disp && k->ascii =='h')
    {
    wave=2;
    }
}

/*
* select increase or decrease step
*/


void change_passo(KEY_EVT *k)
{
   if(!disp && modefun)
     {
     varfun=(varfun+1)%2;
     }
}

/*
* select input channel
*/


void change_channel(KEY_EVT *k)
{
   if(disp)
     {
     channel=(channel+1)%16;
     Configure_Board(channel);
     }
}

/*
* increase selected variable
*/


void inc(KEY_EVT *k)
{
   if(disp && modeosc && tbase<300)
     {
     flagch=2;
     switch(varosc)
        {
        case(0): tbase = tbase*2;
        oscperiod=(tbase/50)*1000;
        break;
        }
     }
   else
   if(disp && !modeosc && vosc<10) vosc += 0.1;
   else
   if(!disp && modefun && ffun<(1e6/(1020*NUM_POINT))-1)
     {
     flagch=1;
     switch(varfun)
        {
        case(0):  ffun += 1;
                  period = 1e6/(NUM_POINT*ffun);
                  break;
        case(1): ffun += 10;
                 period = 1e6/(NUM_POINT*ffun);
                 break;
        }
     }
   else
   if(!disp && !modefun && vfun<10) vfun += 0.1;
}

/*
* decrease selected variable
*/


void dec(KEY_EVT *k)
{
   if(disp && modeosc && tbase> 75)
     {
     flagch=2;
     switch(varosc)
        {
        case(0): tbase = tbase/2;
        oscperiod=(tbase/50)*1000;
        break;
        }
     }
   else      
   if(disp && !modeosc && vosc> 0.2) vosc -= 0.1;
   else  
   if(!disp && modefun && ffun> 0)
     {
     flagch = 1;
     switch(varfun)
        {
        case(0): ffun -= 1;
                 if(ffun == 0) period =1e6;
                 else
                 period = 1e6/(NUM_POINT*ffun);
                 break;
        case(1): ffun -= 10;
                 if(ffun == 0) period =1e6;
                 else
                 period = 1e6/(NUM_POINT*ffun);
                 break;
        }
     }
   else
   if(!disp && !modefun && vfun> -10) vfun -= 0.1;
}

/*
* draw interface
*/


void drawInterface(void)
{
   //TITLE
   grx_rect(1, 1, 799, 69, rgb16(105, 0, 105));
   grx_rect(2, 2, 798, 68, rgb16(155, 0, 155));
   grx_rect(3, 3, 797, 67, rgb16(205, 0, 205));
   grx_rect(4, 4, 796, 66, rgb16(255, 0, 255));
   grx_text("Oscilloscope and function generator for PCI6025E",7, 10, rgb16(50, 255, 50), black);
   grx_text("Pin ADC 3-18, DAC 21",7, 25, rgb16(0, 255, 255), black);
   grx_text("A for select Oscilloscope or Function generator",7, 40, rgb16(0, 255, 255), black);
   grx_text("CTRL-X for Exit", 7, 55, rgb16(200, 200, 0), black);

   //FUNCTION GENERATOR
   grx_text("FUNCTION GENERATOR", 100, 92, rgb16(200, 200, 0), black);
   grx_rect(1, 100, 549, 325, rgb16(0, 105, 0));
   grx_rect(2, 101, 548, 324, rgb16(0, 155, 0));
   grx_rect(3, 102, 547, 323, rgb16(0, 205, 0));
   grx_rect(4, 103, 546, 322, rgb16(0, 255, 0));
   grx_rect(579, 100, 799, 325, rgb16(0, 105, 0));
   grx_rect(580, 101, 798, 324, rgb16(0, 155, 0));
   grx_rect(581, 102, 797, 323, rgb16(0, 205, 0));
   grx_rect(582, 103, 796, 322, rgb16(0, 255, 0));
   grx_text("Wave selection",589,110,rgb16(0, 255, 0), black);
   grx_text("f -->triangular",589,125,rgb16(200, 200, 0), black);
   grx_text("g -->sin",589,140,rgb16(200, 200, 0), black);
   grx_text("h -->square",589,155,rgb16(200, 200, 0), black);
   grx_text("s -->select volt/freq",589,180,rgb16(200, 200, 0), black);
   grx_text("+/- -->set volt/freq",589,195,rgb16(200, 200, 0), black);
   grx_text("d -->frequency increase",589,210,rgb16(200, 200, 0),black);
   grx_text("Vpicco               V",589,235,rgb16(0, 255, 0),black);
   grx_text("Freq                 Hz",589,265,rgb16(0, 255, 0),black);
   grx_text("+/- 1   Hz",589,290,rgb16(0, 255, 0),black);
   grx_text("+/- 10  HZ",689,290,rgb16(0, 255, 0),black);
         
   //OSCILLOSCOPE
   grx_text("OSCILLOSCOPE", 100, 362, rgb16(200, 200, 0), black);
   grx_rect(1, 370, 549, 595, rgb16(105, 0, 0));
   grx_rect(2, 371, 548, 594, rgb16(155, 0, 0));
   grx_rect(3, 372, 547, 593, rgb16(205, 0, 0));
   grx_rect(4, 373, 546, 592, rgb16(255, 0, 0));
   grx_rect(579, 370, 799, 595, rgb16(105, 0, 0));
   grx_rect(580, 371, 798, 594, rgb16(155, 0, 0));
   grx_rect(581, 372, 797, 593, rgb16(205, 0, 0));
   grx_rect(582, 373, 796, 592, rgb16(255, 0, 0));
   grx_text("Scale selection",589,380,rgb16(255, 0, 0), black);
   grx_text("s -->select volt/freq",589,400,rgb16(200, 200, 0), black);
   grx_text("+/- -->set volt/freq",589,415,rgb16(200, 200, 0), black);
   grx_text("j -->change channel",589,430,rgb16(200, 200, 0),black);
   grx_text("Channel",589,470,rgb16(255, 0, 0),black);
   grx_text("Volt/div             V",589,500,rgb16(255, 0, 0),black);
   grx_text("Time/div             ms",589,530,rgb16(255, 0, 0),black);

   //LABEL
   grx_text("0 V", 555, 211, rgb16(0, 255, 0), black);
   grx_text("+10", 555, 111, rgb16(0, 255, 0), black);
   grx_text("+5", 555, 161, rgb16(0, 255, 0), black);
   grx_text("-5", 555, 261, rgb16(0, 255, 0), black);
   grx_text("-10", 555, 311, rgb16(0, 255 , 0), black);
   grx_text("0 V", 555, 481, rgb16(255, 0, 0), black);
}