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

Files at this revision

API Documentation at this revision

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

Pindef1114.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
rc5codes.h Show annotated file Show diff for this revision Revisions of this file
--- 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