An RC5 decoder and preamp controller. Written on the LPC11U24, Ported to LPC1114 and now 100% stable (January 2016)
Dependents: AppleRemoteController_copy_Production_Version AppleRemoteController_Reference_Only
Revision 4:d900d90588d0, committed 2022-11-07
- Comitter:
- andrewcrussell
- Date:
- Mon Nov 07 10:42:42 2022 +0000
- Parent:
- 3:f0cd7c22ca94
- Child:
- 8:1f9fe4d67954
- Commit message:
- Original version
Changed in this revision
--- a/Pindef1114.h Tue Jul 26 16:24:40 2022 +0000 +++ b/Pindef1114.h Mon Nov 07 10:42:42 2022 +0000 @@ -5,9 +5,9 @@ // they are all OFF DigitalOut muteout(dp13); // drives the mute relay via a mosfet or transistor -DigitalOut muteind(dp18); -InterruptIn mute_int(dp11); // mute p/button interrupt -DigitalIn mute(dp11); // mute input from associated pushbutton +//DigitalOut muteLED(dp14); +//InterruptIn mute_int(dp11); // mute p/button interrupt +//DigitalIn mute(dp11); // mute input from associated pushbutton DigitalOut stby_pa(dp25); // power amplifier standby control which follows the premap // but with suitable delays @@ -40,7 +40,7 @@ // DigitalOut myled(LED1); // for test purposes only - on the mbed module - comment out when not used // DigitalOut myled2(LED2); -// DigitalOut sync(p29); //this is a sync pin that is toggled during IR read - used for debug only +//DigitalOut bitstreamsync(dp18); //this is a sync pin that is toggled during IR read - used for debug only
--- a/main.cpp Tue Jul 26 16:24:40 2022 +0000 +++ b/main.cpp Mon Nov 07 10:42:42 2022 +0000 @@ -1,17 +1,15 @@ -/****************************** RC5 Decoder and Preamp Controller V1.0 *************************/ -/* Andrew C. Russell (c) 2015 */ -/* This RC5 decoder works by reading in the RC5 stream from one of the serial port lines */ +/****************************** Apple TV Remote Decoder and Preamp Controller V1.0 *************************/ +/* Andrew C. Russell (c) 2022 */ +/* This decoder works by reading in the Apple TV Remote IR data stream from one of the serial port lines */ /* and saving the incoming stream into an array called stream, after which it is decoded and */ -/* the command executed. A Marantz RC-68PM IR R/C was used to develop this program - it */ -/* should work with any controller complying with the Philips RC5 standard. */ -/* See the rc5codes.h header for the codes used. */ +/* the command executed. . */ /* The following audio preamplifier facilities are catered for:- */ /* 1. Manual volume control adjustment via ALPS RK27 motorized potentiometer */ /* 2. Input select via rotary encoder */ -/* 3. Output mute via push button actuation */ -/* 4. Record loop via push button actuation */ -/* 5. Power ON output to drive the /standby input of a system power supply */ +/* 3. Output mute via remote controller only */ +/* 4. Power ON output to drive the /standby input of a system power supply */ +/* 5.Trigger output to power up an amplifier or other system components */ /* Facilities 1,2,3 and 5 are supported by an RC5 compliant remote control for preamplifiers */ /* The controller pin definitions are set in Pindef1114.h file. */ @@ -20,8 +18,21 @@ // for the standby output to drive a power amplifier. Pin 8 on J2 (Controller board) #include "mbed.h" -#include "rc5codes.h" // RC code definitions - in this case for Apple TV Remote -#include "Pindef1114.h" // all microcontroller I/O pin assignments defined here +//#include "rc5codes.h" // RC code definitions - in this case for Apple TV Remote +#include "Pindef1114.h" // all microcontroller I/O pin assignments defined here + +/************************************* Apple TV Remote control codes ****************************/ +#define STANDBY 378 // toggle power ON and OFF +#define MUTE 442 // toggle output signal on and off +#define VUP 464 +#define VDOWN 432 +#define SELECT_R 480 // rotates input through inputs - must depress and then release each time +#define SELECT_L 272 // rotates input through inputs - must depress and then release each time +#define PREAMP 479 // this is the system code identifying an Apple Remote + + + +/*******************************************************************************************/ #define TRUE 1 #define FALSE 0 @@ -45,8 +56,8 @@ int toggle; // this is the 3rd bit position in the input stream and checks for // subsequent button depresses from the r/control int toggle1; // temorary storage in the volume UP and volume DOWN functions -int toggle2; // temprary storage of the PB in the mute function -int toggle3; // temp storage for the r/control tone in-out function +//int toggle2; // temprary storage of the PB in the mute function +//int toggle3; // temp storage for the r/control tone in-out function int standby; int command = 0; int vendor_id = 0; @@ -58,18 +69,18 @@ int FLAG2; // this is used in the select input processing int FLAG3; // this is for the mute pushbutton int FLAG4; // this is for the standby pushbutton -int FLAG5; // this is the recloop flag +//int FLAG5; // this is the recloop flag int RCFLAG = FALSE; // used to determine if the select command came via R/C int REPEATFLAG; // repaet command flag used for volume control int FLAGVOLUP; int FLAGVOLDWN; -int FLAG7 = FALSE; // thyis flag is set to TRUE if recloop is active +//int FLAG7 = FALSE; // this flag is set to TRUE if recloop is active int standbyflag; // used to save the standby condition int RECLOOP1 = 16; // this is the bus address 1 before the Recorder -int RECLOOP2 = 32; // this is the bus address for the Recorder input +int RECLOOP2 = 32; // this is the bus address for the Recorder input - last input // and is used in the recloop service routine int muteflag = FALSE; // use to control mute and mute indicatoe independently -int recloop_status = 32; // this is the initial value. This variable is used +int recloop_status = 0; // this is the initial value. This variable is used // in the select_out routine to indicate when the // input select should wrap around dependent upon // whether the record loop has been activated. @@ -87,7 +98,7 @@ void rc5isr(void); // RC5 ISR for remote control void mute_isr(void); void mute_sel(void); //mutes select relays for a few ms during select -void recloop_isr(void); +//void recloop_isr(void); void standby_out(void); /****************************** volume increase ***********************************/ @@ -151,40 +162,40 @@ if (standbyflag == TRUE) { // was ON so now turn it OFF stby_pa = LOW; wait_ms(500); // make sure the power amp is OFF - muteind = LOW; +// muteind = LOW; wait_ms(1000); // make sure the power amp output goes OFF muteout = LOW; // now mute the preamp // turn off all interrupts except the standby and rc5int select_int.fall(NULL); - mute_int.fall(NULL); - recloop_int.fall(NULL); - recloop_out = LOW; // make sure the recloop is OFF [its active HIGH] - recloop_status = RECLOOP2; // reset the select so on subsequent power up it does +// mute_int.fall(NULL); +// recloop_int.fall(NULL); +// recloop_out = LOW; // make sure the recloop is OFF [its active HIGH] +// recloop_status = RECLOOP2; // reset the select so on subsequent power up it does //not skip recorder input select_save = select_drv; // save the status of select_drv wait(.2); select_drv = 0; // all input select relays are OFF wait(3); standbyflag = FALSE; - muteind = HIGH; +// muteind = HIGH; } else if (standbyflag == FALSE) {// was OFF so we will turn it ON - muteind = LOW; // turn the mute indicator ON + muteLED = LOW; // turn the mute indicator ON rc5int.rise(&rc5isr); // trigger int on rising edge - go service it at rc5dat select_int.fall(&select_isr); // input from rotary encoder or input select - mute_int.fall(&mute_isr); - recloop_int.fall(&recloop_isr); +// mute_int.fall(&mute_isr); +// recloop_int.fall(&recloop_isr); // tone_pb.fall(tone_isr); - recloop_out = LOW; // make sure the recloop is OFF [its active HIGH] +// recloop_out = LOW; // make sure the recloop is OFF [its active HIGH] wait_ms(100); select_drv = select_save; // recall the input select setting and write to output wait(2); // let things settle a bit muteout = HIGH; // enable output muteflag = TRUE; - muteind = HIGH; // turn the mute indicator OFF + muteLED = HIGH; // turn the mute indicator OFF standbyflag = TRUE; stby_pa = HIGH; // now power up the amplifier } @@ -196,77 +207,92 @@ /********************************** record loop isr *******************************/ -void recloop_isr(void) -{ - FLAG5 = TRUE; -} +//void recloop_isr(void) +//{ +// FLAG5 = TRUE; +//} /********************************** recloop ***********************************/ -void recloop() -{ - - if (select_drv != RECLOOP2) { // if its anything other than recloop we can activate the recloop relay - recloop_int.fall(NULL); // to prevent re-entrance when coming here from the R/C - wait_ms(DEBOUNCE); // simple debounce for when mute is via the f/p p/b switch - - do { - continue; // wait here until the button is released - } while (recloop_in != 1); - - if (recloop_rly == HIGH) { // the recloop relay was activated - recloop_rly = LOW; // so turn it off - recloop_out = LOW; - FLAG7 = 0; - } - - else if (recloop_rly == LOW) { // it was OFF so activate it - recloop_rly = HIGH; - recloop_out = HIGH; - FLAG7 = 32; - } - - wait_ms(DEBOUNCE); - - } - - recloop_int.fall(&recloop_isr); - -} +//void recloop() +//{ +// +// if (select_drv != RECLOOP2) { // if its anything other than recloop we can activate the recloop relay +// recloop_int.fall(NULL); // to prevent re-entrance when coming here from the R/C +// wait_ms(DEBOUNCE); // simple debounce for when mute is via the f/p p/b switch +// +// do { +// continue; // wait here until the button is released +// } while (recloop_in != 1); +// +// if (recloop_rly == HIGH) { // the recloop relay was activated +// recloop_rly = LOW; // so turn it off +// recloop_out = LOW; +// FLAG7 = 0; +// } +// +// else if (recloop_rly == LOW) { // it was OFF so activate it +// recloop_rly = HIGH; +// recloop_out = HIGH; +// FLAG7 = 32; +// } +// +// wait_ms(DEBOUNCE); +// +// } +// +// recloop_int.fall(&recloop_isr); +// +//} /************************************ mute_isr ************************************/ -void mute_isr(void) -{ - FLAG3 = TRUE; - toggle2 = !toggle2; // so the p/button input is recognized in mute_out() +//void mute_isr(void) +//{ +// FLAG3 = TRUE; +// toggle2 = !toggle2; // so the p/button input is recognized in mute_out() -} +//} /************************************** mute ************************************/ void mute_out() { - mute_int.fall(NULL); // to prevent re-entance when coming here from the R/C - wait_ms(DEBOUNCE); //simple debounce for when mute is via the f/p p/b switch - do { - continue; //wait here until the button is released - } while (mute != 1); + muteout = !muteout; - if (muteflag == FALSE) { // mute was inactive so it will now get activated - muteout = TRUE; - muteind = HIGH; - muteflag = TRUE; // indicate its been activated + if (muteout == HIGH) { + muteLED = LOW; + } + + else if (muteout == LOW) { + muteLED = HIGH; } - else if (muteflag == TRUE) { //it was active, so it must be deactivated here - muteout = FALSE; - muteind = LOW; - muteflag = FALSE; - } - - wait_ms(800); // make sure relay state is settled - - mute_int.fall(&mute_isr); + wait_ms(100); } + + +// mute_int.fall(NULL); // to prevent re-entance when coming here from the R/C +// wait_ms(DEBOUNCE); //simple debounce for when mute is via the f/p p/b switch +// do { +// continue; //wait here until the button is released +// } while (mute != 1); +// +// if (muteflag == FALSE) { // mute was inactive so it will now get activated +// muteout = TRUE; +// muteind = HIGH; +// muteflag = TRUE; // indicate its been activated +// } +// +// else if (muteflag == TRUE) { //it was active, so it must be deactivated here +// muteout = FALSE; +// muteind = LOW; +// muteflag = FALSE; +// } +// +// wait_ms(800); // make sure relay state is settled +// +// mute_int.fall(&mute_isr); +//} +// /************************************ rc5isr **************************************/ -/* Interrupt triggered by a rising edge on p21 which is R/C data in */ +/* Interrupt triggered by a rising edge on p18 which is R/C data in */ void rc5isr(void) { @@ -279,14 +305,14 @@ /* This function reads the input data on pin rc5dat at 1120us ('tock')intervals */ /* and saves the data into an array stream[i]. */ -void save_stream(void) -{ +void save_stream(void) { + if (RCFLAG == TRUE) { - wait_us(13500); // this is the AGC header - ignore - } + wait_us(13500); // this is the IR AGC header - wait until passed + //} - bool stream[32];// the array is initialized each time it is used and is local only - int bitloop; // number of bit positions + bool stream[63];// the array is initialized each time it is used and is local only + int bitloop = 0; // number of bit positions - local int i = 0; // counter int k = 0; // temp storage vendor_id = 0; @@ -296,20 +322,21 @@ stop_bit = 0; //must always return a 1 to be valid, so reset it wait_us(tick); // locate read point in middle of 1st half bit time of the 1st start bit - for (bitloop = 0; bitloop <32; bitloop ++) { + for (bitloop = 0; bitloop <64; bitloop ++) { stream[bitloop] = rc5dat; //read the data and save it to array position [i] - //stby_pa = !stby_pa; // for debugging - monitor stby_pa on pin 25 + // bitstreamsync = !bitstreamsync; // the recovered IR bitstream is output on p14 for debug if (rc5dat == HIGH) { - wait_us(tock); + wait_us(tock); // wait for start of next bit time } - - wait_us(tock); //wait here until ready to read the next bit in - } // now have 31 bits loaded into stream[i] + + wait_us(tock); //wait here until ready to read the next bit in + + } // now have 32 bits loaded into stream[i] /* now put data in the array into the start, toggle, address and command variables - array counts from stream[0] */ - for (i=0; i<11; i++) { // first 11 bit positions are vendor ID - always 043f for Apple; use for error checking later + for (i=0; i<11; i++) { // first 11 bit positions are vendor ID k = stream[i]; // k will hold the vendor ID vendor_id = (vendor_id << 1); @@ -334,13 +361,16 @@ k = stream[i]; command = (command << 1); command = command|k; + printf("\n here \r "); } + stop_bit = stream[31]; - printf("\n vendor_id = %d pair_command = %d address = %d command = %d stop_bit = %d \r", vendor_id, pair_command, address, command, stop_bit); } +} + /********************************* process_stream() *******************************/ /* handles commands coming in from the remote controller only */ @@ -399,11 +429,11 @@ /****************************** mute inter select*********************************/ -void mute_sel(void) -{ - select_drv = 0; - wait_ms(2); -} +//void mute_sel(void) +//{ +// select_drv = 0; +// wait_ms(2); +//} /********************************* select_process *********************************/ /* Used for selecting the input source. This function is used by the */ @@ -444,7 +474,7 @@ } } - select_rot = (select_rot | FLAG7); +// select_rot = (select_rot | FLAG7); select_drv = select_rot; // write the value out to the bus // printf("\n RCFLAG %d \r", RCFLAG); @@ -475,9 +505,11 @@ } - select_drv = (select_rot | FLAG7); //write the selection out to the bus. + select_drv = select_rot; -// printf("\n select_rot = %d select_drv = %d\r", select_rot, select_drv); +// select_drv = (select_rot | FLAG7); //write the selection out to the bus. + + printf("\n select_rot = %d \r", select_rot); } @@ -486,53 +518,51 @@ { Serial pc(USBTX, USBRX); __disable_irq(); // just to make sure we can set up correctly without problems - stby_pa = LOW; // make sure the power aamp is OFF stby_pa = LOW; // make sure the power amp is OFF via the trigger output muteout = LOW; //make sure the outputis muted from the get go - muteind = LOW; //mute LED must be ON - power up preamble - select_drv = 0; - recloop_out = LOW; // make sure the recloop LED is OFF [its active HIGH] - recloop_rly = LOW; // make sure the recloop relay is OFF +// muteind = HIGH; //mute LED must be ON - power up preamble + select_drv = 0; // no input relays must be on + // bitstreamsync = LOW; // this is the IR bitsteeam output on pin 14 for debug + // recloop_out = LOW; // make sure the recloop LED is OFF [its active HIGH] + // recloop_rly = LOW; // make sure the recloop relay is OFF - mute_int.mode(PullUp); // set up all the pin states per Pindef1114.h +// mute_int.mode(PullUp); // set up all the pin states per Pindef1114.h rc5dat.mode(PullUp); // pin 17 sela.mode(PullUp); // pin 28 selb.mode(PullUp); // pin 27 stdby.mode(PullUp); // pin 26 - recloop_in.mode(PullUp); // pin 14 + // recloop_in.mode(PullUp); // pin 14 wait(.2); FLAG1 = FALSE; FLAG2 = FALSE; - FLAG5 = FALSE; // this is the recloop flag +// FLAG5 = FALSE; // this is the recloop flag FWD1=0; //make sure the volume control motor is OFF REV1=0; // set up the ISR's that will be used - rc5int.fall(&rc5isr); // trigger int on rising edge - go service it at rc5dat + rc5int.fall(&rc5isr); // trigger int on falling edge - go service it at rc5dat select_int.fall(&select_isr); // input from rotary encoder or input select - mute_int.fall(&mute_isr); // mute push button interrupt - recloop_int.fall(&recloop_isr); // record loop push button interrupt - stdby_int.fall(&stdby_isr); // the system power/standby switch +// mute_int.fall(&mute_isr); // mute push button interrupt +// recloop_int.fall(&recloop_isr); // record loop push button interrupt + stdby_int.fall(&stdby_isr); // the system power/standby switch - on sel rotenc //now disable them, leaving only the stand by p/button and rc5int interrupts active select_int.fall(NULL); - mute_int.fall(NULL); - recloop_int.fall(NULL); +// mute_int.fall(NULL); +// recloop_int.fall(NULL); standbyflag = TRUE; // preamp will be set-up first time for OFF standby_out(); // set system up standbyflag = FALSE; - select_save = 2; + select_save = 2; // CD always slected on initital power up select_rot = select_save; // CD will be selected when power is first turned on wait(3); - muteind = HIGH; +// muteind = LOW; __enable_irq(); // all ready and in standby from this point forward -// note: if printf is used for debug, the record indicate LED will remain ON after printing -// the first message LOOP: // this is the main operating loop @@ -560,10 +590,10 @@ FLAG4 = FALSE; } - if (FLAG5 == TRUE) { - recloop(); //recloop - FLAG5 = FALSE; - } +// if (FLAG5 == TRUE) { +// recloop(); //recloop +// FLAG5 = FALSE; +// } //printf("\r Command = %d Address = %d \n",command, address);
--- a/mbed.bld Tue Jul 26 16:24:40 2022 +0000 +++ b/mbed.bld Mon Nov 07 10:42:42 2022 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/165afa46840b \ No newline at end of file +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file
--- a/rc5codes.h Tue Jul 26 16:24:40 2022 +0000 +++ b/rc5codes.h Mon Nov 07 10:42:42 2022 +0000 @@ -21,64 +21,11 @@ #define STANDBY 378 // toggle power ON and OFF #define MUTE 442 // toggle output signal on and off -// #define 14 PRESETS #define VUP 464 #define VDOWN 432 -//#define TONE 22 - -// #define 18 BRIGHTNESS + -// #define 19 BRIGHTNESS - -// #define 20 COLOR SATURATION + -// #define 21 COLOR SATURATION - -// #define BASSUP 22 -// #define BASSDOWN 23 -// #define TREBLEUP 24 -// #define TREBLEDWN 25 -// #define BALRIGHT 26 -// #define BALLEFT 27 -// #define PAUSE 48 -// #define 50 FAST REVERSE -// #define 52 FAST FORWARD- -// #define PLAY 53 -// #define STOP 54 -// #define 55 RECORD - #define SELECT_R 480 // rotates input through inputs - must depress and then release each time #define SELECT_L 272 // rotates input through inputs - must depress and then release each time - -//#define DAC_FIL 20 -//#define BLUTOOTH 18 -//#define SYSTEM 16 - -/* RC5 address */ -// #define 0 TV SET 1 -// #define 1 TV SET 2 -// #define 2 VIDEOTEXT -// #define 3 EXPANSION FOR TV 1 AND 2 -// #define 4 LASER VIDEO PLAYER -// #define 5 VIDEO RECORDER 1 (VCR 1) -// #define 6 VIDEO RECORDER 2 (VCR 2) -// #define 7 RESERVED -// #define 8 SAT 1 -// #define 9 EXPANSION FOR VCR 1 OR 2 -// #define 10 SAT 2 -// #define 11 RESERVED -// #define 12 CD VIDEO -// #define 13 RESERVED -// #define 14 CD PHOTO -// #define 23 RESERVED // this is the official RC5 designation for system code 13 #define PREAMP 479 // this is the system code identifying an Apple Remote -// #define RECEIVER 17 -// #define 18 TAPE / CASSETE RECORDER -// #define PRE2 19 -// #define CD 20 -// #define AUDIO_RACK 21 -// #define 22 AUDIO SAT RECEIVER -// #define 23 DCC RECORDER -// #define 24 RESERVED -// #define 25 RESERVED -// #define 26 WRITABLE CD -// #define 26-31 RESERVED FOR TV SET 1