TFT

Dependencies:   mbed

Fork of Ovation_Controller_1 by Andrew R

main.cpp

Committer:
bf1891
Date:
2014-08-28
Revision:
3:92845c139aca
Parent:
2:67e16df2c89a

File content as of revision 3:92845c139aca:

/*******************************************************************/
/*************            Dec 22 2010       ************************/
/*************               V.1a           ************************/
/************* Balanced Stereo Pre-amplifer Control Program ********/
#include "mbed.h"
#include "system_defines.h"
#include "stdlib.h"
#include "font_1.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
/* global defines */
int volume;
int balance_left =0;
int balance_right=0;
int bright=8;           /* this is the backlight brightness */
int relay=0;            /* this is  just a counter */
unsigned int control = 0; /*  for the control outputs on the CPU board. This is the intial setting */
unsigned int controls = 0; /* this is temporary storage value for control above  used in power up and power  down */
int unsigned inputrelay=1;     /* inputrelay holds the bit position of the selected relay */
int pwrupvol=1;
int power=0;            /* set to 64 to turn it ON */
int loopgain=0;         /*set to 32 to turn it ON */
int trigger=0;          /* set to 16 to turn it ON */
int mutebit=0;          /* set to 1 to turn it ON */
int hpmutebit=0;        /* set to 127 to turn it ON */
int recloop1bit=0;      /*set to 2 to turn it ON */
char remcon[6], ch[6];//were 10
int remcontoken;
int remaction;
int rctimeoutflag;
int r=0, k=0;           /* these are counters used in the remote  control routine */
int flag=0;             /* this fetches the command control code  - remote or via f/panel PB's */
float lightlevel;
/********************** system constants ********************/
// baclight bit position defines
#define stripbacklight ~61440
#define HIGH 1;
#define LOW 0;
//#define TRUE 1;
#define FALSE 0;
#define incdec 1;
#define VOLA(p21);
#define VOLB(p22);
#define VOLPB(p23);
#define IPSELA(p24);
#define IPSELB(p25);
#define IPSELPB(p26);
#define SERIN(p27);
#define   STR_LENGTH 7
#define   STR_LENGTH_1 5
char   temp_string[STR_LENGTH_1 ];
/*********** these are the input select relay  bit position assignments **********/
#define Aux2    4
#define Aux1    8
#define Recorder   16
#define CD    32
#define Phono   64
/********************** declare all Graphic.h here AFTER the global defines**********************/
#include "Graphic.h"

/********************** declare all interrupt input pins  here**********************/
InterruptIn volumein(p21);          /* interuppt from the volume control encoder */
InterruptIn inputsel(p24);          /* for the input select encoder */
InterruptIn mutesw(p26);            /* this mutes the output - pb att to the sel encoder */
InterruptIn powersw(p23);           /* this turns the main power on-off.  Att. to the vol control encoder */
Timeout timeout;                    /* remote control timeout */

/********************** mbed HALT mode (from Igor Skochinsky) ****************************/
/* note:  this will not work if the usb is connected, if local files, */
/* or printf statements are used.  Disconnect  USB to  get  this to work */
void halt() {
#if defined(TARGET_LPC1768)
    __wfi(); // (enter sleep mode and) wait for interrupt
#else
    LPC_SC->PCON |= 1; // set PM0 = 1: enter idle mode (assuming PM1 and PM2 are 0)
#endif
}
/********************** how to disable interrupts ****************************/
//__disable_irq();    // Disable Interrupts
//__enable_irq();     // Enable Interrupts
/************************* read the light sensor *****************************/
void lightsensor() {
    AnalogIn light(p20); /* fetch the light intensity */
    lightlevel=light.read(); /* fetch the light intensity */
    //printf("\n\rlight level= (%f)",light.read());
}

/**************************** remote control IRQ ****************************/
void remotecontrol(void) {
    int q=0;
    int z=0;
myled=!myled;      /* just to let us know we are looping through here */
    
    do {
        remcon[z]=getc(remote);
        //printf("%c\n\r",remcon[z]);
        z++;
    } while (z<6);
    flag=atoi(remcon);           
    //flag=remaction;      //flag is either a valid command,  or its a zero which means no valid command
    //printf("%d\n\r", flag);
    //printf("%d\n\r", remaction);
    /* here we flush  everything to make sure that any garbage entries do not remain */
    /* because what we got in from the serial link was not a valid string */
    for (q=0;q<6;q++) {  //flush the uart buffer which is 16 bytes deep (was originally set to 8)
        remcon[q]=(' ');  //* clean it up for the next cycle */
           }
    remcontoken=1;
    myled=!myled;
    
   }
/*********** Power ON/OFF IRQ **********/
void power1() {
    wait_ms(10);   //was 10ms
    flag=9261;
    remcontoken=0;
}
/*************** Mute IRQ **************/
void mute1() {
    wait_ms(10); //was 10ms
    flag=9241;
    remcontoken=0;
}
/************ Input Select IRQ ********/
void inputsel1() {
    wait_ms(10);
    flag=9231;
    remcontoken=0;
}
/*************** Volume IRQ ***********/
void volume1() {
    
    wait_ms(5);        /* wait for contact bounce to subside */
    PortIn  encoder(Port2, 48); /* extract data on mbed pins 21 and 22 - bit positions 8 and 16 on p2 */
    switch (encoder) {
        case 32:
            break;
        case 48:
            break;

        case 0:  {
            volume--;
            flag=9211;
        }
        break;           /* rotary encoder was turned clockwise */
        case 16: {
            volume++;
            flag=9221;
        }
        break;
    }
    remcontoken=0;
}
/******************* volume control write routine **********************/
/* this  routine writes  the volume control data out to the PGA2320    */
void volumecontrol(void) {
    int lrvol =0;       /* lrvol (i.e. left and right volume) is the concatenated left & right volume setting */
    int gain;
    int vol_shift_bit=0;
    int volshift=0;
    int voltemp=0;
    int SCOUNT=1;
    int k = 32768;       /* k is now located at bit position 15 */
    //if the volume up/down comes in through the remote control,  it comes directly here from the R/C
    //IRQ handler.  If  it comes in via the rotarty encoder,  it skips this part
    if (remcontoken==1) {  /* command came in through the IRC */
        if (flag==9221) {
            volume=volume+4;    /* volume up and down  is a bit quicker via the IRC */
        }
        if (flag==9211) {
            volume=volume-4;
        }
    }
  /******* check here that it is within range 0 to +255  ********/
// entry point is HERE  if coming in via rotary encoder
    if (volume>=222)
        volume=222;
    if (volume <=1)     // check this - can it not be 0?
        volume=0;
    volume_slider(volume);
    gain= 31.5-(0.5*(255-volume));
    if (((gain >-10)&&(gain<10))==TRUE) {
        LCDSetRect(265,379,460,475,1,BLACK);   //clear the volume area
        snprintf( temp_string, STR_LENGTH_1, " ");  //flush the print area
        snprintf( temp_string, STR_LENGTH_1, "%+ddB",gain);
    }
    char   temp_string[ STR_LENGTH ];
    snprintf( temp_string, STR_LENGTH, " ");  //flush the print area
    snprintf( temp_string, STR_LENGTH, "%+ddB",gain);
    FontDrawString( temp_string, 185, 380, WHITE, BLACK, &Calibri72 );

    /************************ Write the data  out to the PGA2320 ************************/
    /* for the PGA2320,  data  is  clocked out MSB first, starting with the Right channel */
    
    volshift=volume;
    voltemp=volume;             /* save volume and leave it untouched */
    lrvol = (voltemp<<8);        /* volume value now occupies bits 8-16 with bits 0-7 filled with 0's */
    lrvol = (lrvol|volshift);   /* now have a copy of volume in botton 8 LSB's  - so 16 bits of data in total*/
    pga2320=LOW;            /* make sure the PGA2320 is de-selected */
    RD=LOW;                 /* ASTROBE -  we do NOT  use STROBE when writing the volume to the PGA2320 */
    WR=LOW;                 /* MDATA  in low state*/
    RS=HIGH;                /* ACLK  - it is now LOW on the isolated side*/
    SBUSON=HIGH;            /* turn the SBUS on */
    wait_us(50); //was 50
    pga2320=HIGH;           /* chip select the  PGA2320-so it goes LOW on the analog board */
    do {
        vol_shift_bit = (lrvol&k);       /* ADATA = the MSB (k=1)  */
        WR=!vol_shift_bit;  /* put the 1st bit to be written on the WR pin AFTER INVERTING IT */
        wait_us(10);
        RS=LOW;              /* clock it out */
        wait_us(10);
        RS=HIGH;
        SCOUNT=SCOUNT+1;     /* increment the bit counter */
        k=(k>>1);            /* shift bit mask up one position towards the LSB */
    } while (SCOUNT<16);     /* send all 16 bits  for L & R channel */
    /* note that it is 15 bit positions and NOT 16! */
    wait_us(10);//was 10
    pga2320=LOW;           /* deselect PGA2320 */
    wait_us(10); //was 10
    SBUSON=LOW;
    flag=0;                 /* clear the flag since the command is now completed */
    remcontoken=0;          /* we have executed the request, now clear the token */
    wait_us(10);  //was 20
    
    }
/*************** Serial bus routine for control relays and digital I/O ***************/
/* this routine takes the 8 bit relay data and the 8 bit  control data and joins them */
/* and writes 16 bits out on the serial bus */
/* it is called by the  relay function  or the control function */

void serialout(void) {
    unsigned int serialdata=0;/* the 16 bits of serial data to go out to the  analog board - flush  it so its clean */
    unsigned int shift_out_bit=0;
    long int stor_relay=0;
    int m=1;
    int SCOUNT=0;

    __disable_irq();     /* disable Interrupts - no interference while we send the data out */

    stor_relay=(255-inputrelay); /* get the complement */
    serialdata = (control | stor_relay);

    RD=LOW;                     /* ASTROBE - it must be LOW on the analog board intitially */
    WR=HIGH;                    /* MDATA */
    RS=HIGH;                    /* ACLK  - so the clock line on the analog board is now LOW*/
    SBUSON=HIGH;                /* turn the SBUS on */
    wait_us(100); //was 100
    do {
        shift_out_bit = (serialdata & m);       /* ADATA = the LSB (k=1)  */
        if (shift_out_bit!=0) {                  /* if it evaluates as TRUE,  WR=HIGH */
            WR=1;
        } else {                 /* it must have evaluated as FALSE */
            WR=0;
        }
        wait_us(100); //was 100
        RS=LOW;                /* clock goes high on main board - data latches */
        wait_us(100); //was 100
        RS=HIGH;                /* clock goes low */
        SCOUNT++;               /* increment the bit counter */
        m=(m<<1);               /* shift bit mask up one position towards the MSB */
    } while (SCOUNT<16);
    wait_us(100); //was 100
    RD=HIGH;                    /* Strobe the data  into the A6821*/
    wait_us(100); //was 100
    RD=LOW;                     /* Strobe now goes LOW again  on the main board */
    wait_us(100); //was 100
    SBUSON=LOW;                 /* remember to enable the outputs after intial set-up */
    wait_us(100); //was 100
    __enable_irq();     // Enable Interrupts
}
/******************************* Play ****************************/
void play(void) {
    //myled=!myled;
    flag=0;
    remcontoken=0;
}
/******************************* Input Selector Encoder Routine ****************************/
/* this function controls  which relays are energized  on the main analog board */
/* It calls the serialout  function to send the data */

void inputselect(void) {

    int source=0;  /* temporary storage */
    wait_ms(10);                     /*wait for  contact bounce to subside */
    // __disable_irq();     // Disable Interrupts

    if (remcontoken==0) {            /* so it must have come in from the rotary encoder */
        PortIn  select(Port2, 6);       /* fetch data on mbed pins 24 and 25 - bit positions 2 and 4 on p2 */
        switch (select) {
            case 0:
                relay++;
                break;     /* rotary encoder was turned clockwise */
            case 2:
                relay--;
                break;     /* increment the selection */

            case 4: {} break;           /* fall through values - ignore */
            case 6: {} break;
        }
    } else {
        relay++;                   /* and here because it came in from the remote */
    }                               /* because it must have equaled 1  to have got here */
    /* because you can only go round select in one direction via the remote */

    if (relay>=6)                   /* here we make sure the select knob rotates from 1-6 to again */
        relay=1;
    if (relay<=0)
        relay=5;
    /* set the correct value in the serial bit position */
    clear_input_select();
    switch (relay) {
        case 1:
            source=32;//~125;//~125;//~(2&127);
            AUX2(1);
            //printf("\n\rAux2");
            break;    /* this is Aux2*/
        case 2:
            source=16;//~123;//~(4&127);
            AUX1(1);
            //printf("\n\raux1");
            break;      /*aux1 */
        case 3:
            source=8;//~127;~(8&127);
            Recorder_d(1);
            //printf("\n\recorder");

            break;     /*recorder */
        case 4:
            source=4;//~111;//~(16&127);
            //printf("\n\rCD");
            //
            CD_d(1);
            break;     /*CD*/
        case 5:
            source=2;;//~95;//~(32&127);
            //printf("\n\rphono");
            phono_d(1);
            break;      /*phono*/
    }

    inputrelay=(hpmutebit|mutebit|recloop1bit);/* save the non input select data */

    inputrelay=(inputrelay&193); /*strip out the old input select, leaving HPMUTE, recloop1bit and mutebit intact */

    inputrelay=(inputrelay|source);   /* add in the new input selection back in*/

    flag=0;
    remcontoken=0;

    serialout(); /* send it out */
   // __enable_irq();     // Enable Interrupts
}
/*****************************************record loop ***********************************************/
void recloop(void) {

    if (recloop1bit==0) {//so it must have been OFF  so we need to turn it on
        recloop1bit=64;
        record(1);
        inputrelay=(inputrelay|64);
    }
    else if (recloop1bit!=0) {      // it was ON so turn it OFF
        recloop1bit=0;
        record(0);
        inputrelay=inputrelay & (~64);
    }
    flag=0;
    //remcontoken=0;
    serialout();
}
/**************************** output mute via front panel push button********************************/
void mute_output(void) {    /* this is the interrupt handler routine  */

    unsigned int timecountrec=0;
//__disable_irq();    // Disable Interrupts
    wait_ms(10);
    do {
        timecountrec++;
        wait_us(10);
        if (timecountrec>110000)
            timecountrec=110000;    //just make sure if the buttin is depressed for too long,  it
        //record(1);                  // it does not wrap around bacj to 0 again
    } while (IPSELPB==0);
    //printf("timecountrec=%d\n\r",timecountrec);
    if (timecountrec>100000) {
        recloop();
        goto SKIP;
    }
    if (mutebit==0) {       /* it must have been  off   */
        mutebit=128;  //was 128             /* so turn it ON -  this is a FLAG */
        inputrelay=(inputrelay|128); //was 128
        mute(0);
    }
    else if (mutebit==128) {    /* it currently ON  */
        mutebit=0;              /* so turn the output OFF - this is a FLAG */
        inputrelay=(inputrelay&127);  //so bit 128 is set  to 0
        mute(1);
    }
SKIP:
    flag=0;
    remcontoken=0;
    //__enable_irq();     // Enable Interrupts
    serialout();

}
/**********************************initialize *****************************************/
/* this routine sets  up the pre-amp at initial power-up.  all relays on the main board */
/* are de-energized,  volume  is set to 0, display off,  system in standby */

void initialize(void) {

    int SCOUNT=0;
    int k=1;        /*this is the bit place holder that gets  shifted through the data to be sent */
    int flushit=0;  /* flushit explicitly declared since we may want a setting other than all OFF */
    int shift_flush =0;

    RD=LOW;                     /* ASTROBE */
    WR=LOW;                     /* MDATA */
    RS=LOW;                     /* ACLK */
    SBUSON=HIGH;                /* turn the SBUS on */
    do {
        shift_flush=(flushit&k);       /* ADATA = the LSB (k=1)  */
        WR=shift_flush;
        wait_ms(1);
        RS=HIGH;                /* clock it out */
        wait_ms(1);
        RS=LOW;
        SCOUNT=SCOUNT+1;        /* increment the bit counter */
        k=(k<<1);               /* shift bit mask up one position towards the MSB */
    } while (SCOUNT<8);         /* counting starts from 0! */
    wait_ms(1);
    RD=HIGH;                    /* Strobe the data  into the A6821*/
    wait_ms(1);
    RD=LOW;                     /* Strobe now goes HIGH again  on the main board */
    wait_ms(1);
    SBUSON=LOW;                 /* remember to enable the outputs after intial set-up */
    power=0;
    wait_ms(10); //was 100
}
/******************** ON-OFF Push button input *******************************************/
void power_on_off(void) {
    //

    //int inputstate = 0; /* where we temporarily store the input relay status */
    //int b=5;
//__disable_irq();     // Disable Interrupts
//__enable_irq();     // Enable Interrupts
    wait_ms(10);           /* debounce time NOTE IF  ITS  MUCH LONGER THAN 10mS THERE ARE RE-ENTRY PROBLEMS*/

    if (power == 0) {        /* it must have been  off so turn it ON */
        //__disable_irq();     // Disable Interrupts

        //Write_Command(DISON);
        //clear_to_color(BLACK);  //clear the screen
        /* clean everything up first */
        inputrelay = 0;    /* all input relays are DESELECTED */
        mute(1);

        volume = 0;         /*  set the volume to 0 to make sure there are no blasts from the headphone or output */
        volumecontrol();
        control = 0;
        wait_ms(100);            /* initial wait period after power on - lets relays and electronics settle */
        serialout();

        NAOE = HIGH;          /* enable outputs of A6281's */
        wait_ms(100);
        inputrelay = 4;//32;      /* select CD input always on power up */
        CD_d(1);
        control = 33280;     /* power to main board on and LCD brightness set to 50% */
        serialout();

        wait(2);
        inputrelay = 5;// 161;    /* unmute the headphone amp */
        control = 33280;     /* stays the same power to main board on and LCD brightness set to 50% */
        serialout();

        wait(2);            /* let the power amp settle */
        control=35328;      /* turn power amp on */
        pwramp(1);
        inputrelay = 133;   /* unmute the pre-amp output */
        mute(0);
        serialout();

        mutebit = 128;          /* set to 1 to turn it ON - THIS IS A FLAG!! */
        hpmutebit = 1;          /* set to 127 to turn it ON  - THIS IS THE FLAG!!*/
        //serialout();
        power = 64;         /* this is the power ON/OFF  FLAG */
        volume=95;
        volumecontrol();

        /* re-enable the mute, volumecontrol and input selection interrupts */
        wait_ms(1);

        mutesw.fall(&mute1);
        volumein.fall(&volume1);
        inputsel.fall(&inputsel1);
        // __enable_irq();     // Enable Interrupts
    }

    else if (power == 64) {                      /* it currently ON, so turn it OFF  */
        /* disable the mute, columecontrol and input selection interrupts - leave power ON/OFF enabled though */
        // __disable_irq();     // Disable Interrupts
        volume = 0;
        volumecontrol();
        mutesw.fall(NULL);
        volumein.fall(NULL);
        inputsel.fall(NULL);
        control= (control & 62332); /*turn power amp off */
        pwramp(0);
        serialout();
        wait(2);        /* wait for the power-amp to power down and spkr relay to open */
        inputrelay = (inputrelay & 126); /* mute the pre-amp output  */
        serialout();  /* note we did not change anything on the control side */
        wait(1);
        control=(control & 768); /* turn the display off and set the zero loop gain off */
        inputrelay = (inputrelay & 127); /* mute headphone output */
        serialout();
        wait(1);
        /*here we flush the A6821 registers */
        control = 0;  /* turn everthing off */
        inputrelay = 0;
        serialout();
        wait(1);
        NAOE=LOW; /* disable the A6281's */

        mutebit = 0;  /* set to 1 to turn it ON - this is a FLAG */
        hpmutebit = 128; /* set to 127 to turn it ON  - this is a FLAG */
        power = 0; /* this is the power FLAG */
        //Write_Command(DISOFF);
        //clear_to_color(BLACK);  //clear the screen

        //__enable_irq();     // Enable Interrupts again
    }
    flag = 0;
    remcontoken = 0;
}
/******************** backlight controller *****************************************/
void backlight (void) {

    float loglight;
    int lightadjust;

    lightsensor();
    //loglight    = (lightlevel * lightlevel) * 14.0 + 1.0;
    loglight    = (lightlevel * 14)+1;
    lightadjust = ((int)loglight) << 12;
    control=(control & stripbacklight)|lightadjust;
    serialout();
    //printf("%d\n\r",control);
}
/******************** Test Mode Pushbutton input *******************************************/
/* in this mode,  both volume and select pushbuttons   must be depressed for 5 seconds  */
/* the pre-amp then enters the test  mode where all the relays are cycled continuosly */
/* and the volume is ramped up and down. To exit, depress  any push button. */

/**********************************main program*****************************************/
int main () {
    pc.baud(38400);
    pc.printf("Hello World!\n\r");
    int l=0;
    //int loopcnt=0;
    __disable_irq();        // Disable Interrupts
    NAOE=LOW;               // make sure the A6821's are disabled
    Init_SSD1963();         // set up he graphics controller
    Write_Command(DISOFF);  // make sure the display is off  while we set it up
    clear_to_color(BLACK);  //clear the screen
    wait_ms(5);
    initialize();           // call the SBUS  routine to clean things  up
    powersw.fall(&power1);
    Serial remote(NC, p27);
    remote.baud(1200);
    remote.format(8, Serial::None, 1);
    remote.attach(&remotecontrol);  /* set up serial port via USB connector */
    __enable_irq();         // Enable Interrupts
    wait_us(10);

    /**************************************************************************************/
// graphics set up
    // sett up graphics to write the data
    FontDrawInit();
    FontDraw_SetInterCharSpace( 0 );
    FontDraw_SetForegroundColor(WHITE);
    FontDraw_SetBackgroundColor(BLACK);
    FontDraw_SetFont(Calibri28);
    //big_button();
    Control_buttons();
    input_buttons();
    slider_bar();
     Write_Command(DISON);
    
    /************************ this is the main operating loop  ************************/

LOOP:
    //if ((flag>=9000)&&(flag<=9999)){
    //printf("%d\n\r",flag);
    //__disable_irq();    // Disable Interrupts
    //__enable_irq();     // Enable Interrupts
    if (flag!=0) {  //so assume  it  lies between 9000 and 9999
        switch (flag) {

            case 9211:
                volumecontrol();
                break;      /* volume UP */
            case 9221:
                volumecontrol();
                break;      /* volume DOWN */
            case 9231:
                inputselect();
                break;      /* Input Select */
            case 9241:
                mute_output();
                break;      /*  Mute */
            case 9251:
                play();
                break;      /* Play */
            case 9261:
                power_on_off();
                break;      /* power ON/OFF */
                //case 9200:
                //recloop();
            }
           }
    
    myled=!myled;
    __disable_irq();    // Disable Interrupts - this forces us to wait here for 10mS
    flag=0;                 /* flush the flag since we finished the task */
    wait_ms(10);        // 
    __enable_irq();     // Enable Interrupts
    backlight();
    halt();            /* shut processor down and wait for interrupt */
    myled=!myled;
    goto LOOP;
}