Boyu Fang
/
Ovation_Controller
TFT
Fork of Ovation_Controller_1 by
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; }