TFT

Dependencies:   mbed

Fork of Ovation_Controller_1 by Andrew R

main.cpp

Committer:
andrewcrussell
Date:
2011-04-04
Revision:
1:ecf8078bf531
Parent:
0:3811b20051b1
Child:
2:67e16df2c89a

File content as of revision 1:ecf8078bf531:

/*******************************************************************/
/*************            Dec 22 2010       ************************/
/*************               V.1a           ************************/
/************* Balanced Stereo Pre-amplifer Control Program *******/
#include "mbed.h"
#include "system_defines.h"
#include "string.h"
#include "stdlib.h"
#include "Graphic.h"
#include "font_1.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
//#include "font_new.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[10], ch[10];
int remcontoken;
int remaction;
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 */

/********************** system constants ********************/
#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);
/*********** 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 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 */
    // printf("\n\rlight level= (%f)",light.read());
}
/********************* remote control IRQ *************************/
void remotecontrol(void) {

    int q=0;
    int z=0;
    //infra=1;
    myled=!myled;      /* just to let us know we are looping through here */
    //infra(0);
    do {
        remcon[z]=getc(remote);
        z++;
    } while (z<6);
    remaction=atoi(remcon);
    //printf("%d   %s",remaction,remcon);
    /* 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<8;q++) {
        remcon[q]=(' '); /* clean it up for the next cycle */
    }

    flag=remaction;
    remaction=0;
    remcontoken=1;

}
/*********** Power ON/OFF IRQ **********/
void power1() {
    wait_ms(10);
    flag=9261;
    remcontoken=0;
}
/*************** Mute IRQ **************/
void mute1() {
    wait_ms(10);
    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) {
    char setting[10];
    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 */
    /**********  ???????????????????????????????? check your remcontoken!!!  ****/
    if (remcontoken==1) {  /* command came in through the IRC */
        if (flag==9221) {
            volume=volume++;    /* volume up and down  is a bit quicker via the IRC */
        }
        if (flag==9211) {
            volume=volume--;
        }
    }
    /******* check here that it is within range 0 - +255  ********/

    if (volume>=255)
        volume=255;
    if (volume <=1)     // check this - can it not be 0?
        volume=0;

    //setting = volume;
    volume_slider(volume);
    FontDraw_SetFont(Calibri72);
    LCDSetRect(190,370, 190,479,0,BLACK);  //clear the volume area
    //FontDraw_printf(195,375,"%d dB",(127-volume));
    FontDraw_printf(195,375,"%d dB",volume);
    //FontDraw_printf( int x, int y, stting); //char *format, ... );

    /************************ 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 */
    printf("%d   %d\n\r",lrvol, volshift);
    lrvol = (lrvol|volshift);   /* now have a copy of volume in botton 8 LSB's  - so 16 bits of data in total*/
    //printf("%d   %d\n\r",lrvol, volshift);
    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);
    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(100);
        RS=LOW;              /* clock it out */
        wait_us(100);
        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! */

    wait_us(10);
    pga2320=LOW;           /* deselect PGA2320 */
    wait_us(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(20);
    gain= 31.5-(0.5*(255-volume));
    printf("%d\n\r",gain);

}
/*************** 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) {
    __disable_irq();     /* disable Interrupts - no interference while we send the data out */

    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;

    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);
    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);
        RS=LOW;                /* clock goes high on main board - data latches */
        wait_us(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);
    RD=HIGH;                    /* Strobe the data  into the A6821*/
    wait_us(100);
    RD=LOW;                     /* Strobe now goes LOW again  on the main board */
    wait_us(100);
    SBUSON=LOW;                 /* remember to enable the outputs after intial set-up */
    wait_us(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
}
/**************************** output mute via front panel push button********************************/

void mute_output(void) {    /* this is the interrupt handler routine  */

    wait_ms(50);

    /* debounce time - CRITICAL - MORE THAN 10 OR  LESS THAN 5 GIVES PROBLEMS! */
    if (mutebit==0) {       /* it must have been  off   */
        mutebit=128;              /* so turn it ON -  this is a FLAG */
        inputrelay=(inputrelay|128);
        mute(0);
    }

    else if (mutebit==128) {    /* it currently ON  */
        mutebit=0;              /* so turn the output OFF - this is a FLAG */
        inputrelay=(inputrelay&127);
        mute(1);
    }
    flag=0;
    remcontoken=0;
    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(100);
}

/******************** ON-OFF Push button input *******************************************/

void power_on_off(void) {
    int inputstate = 0; /* where we temporarily store the input relay status */
//__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);
        control = 0;
        wait(1);            /* initial wait period after power on - lets relays and electronics settle */
        serialout();

        NAOE = HIGH;          /* enable outputs of A6281's */
        wait(1);
        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 */
        inputrelay = 133;   /* unmute the pre-amp output 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 = 110;       /*  this sets tthe volume to 10/127 - so a very low level on power up */
        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
        mutesw.fall(NULL);
        volumein.fall(NULL);
        inputsel.fall(NULL);
        control= (control & 62332); /*turn power amp off */
        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;
}

/******************** 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 () {
    int l=0;

    __disable_irq();        // Disable Interrupts
    NAOE=LOW;               // make sure the A6821's are disabled
    Init_SSD1963();         // set up he graphics controller
    Write_Command(DISOFF);
    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
    //clear_to_color(BLACK);  //clear the screen
    // 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);
    //volume_slider(100); //bring the slider up,  but set it to min vol
    //FontDrawString("-95dB",195,375,WHITE,BLACK,&Calibri72);

    /************************ this is the main operating loop  ************************/

LOOP:

    if (flag!=0) {
        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 */
        }
    }
    flag=0;                 /* flush the flag since we finished the task */
    wait_ms(10);            /* we can only get an IRQ  here */

    //for (l=0;l<256;l++)
    //{volume=l;
    // volumecontrol();}

    //halt();               /* shut precessor down and wait for interrupt */
    goto LOOP;
}