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

Committer:
andrewcrussell
Date:
Mon Nov 16 17:11:20 2015 +0000
Revision:
1:bb881a434906
Parent:
0:83d4a20e7bc7
Child:
2:674e2dd56e7d
RC5 Infra Red  decoder/controller written for the LPC1114. Can also be used with the LPC11U24 by changing the pinout.h file.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewcrussell 1:bb881a434906 1 /****************************** RC5 Decoder and Preamp Controller V1.0 *************************/
andrewcrussell 1:bb881a434906 2 /* AndrewR written in 2015 */
andrewcrussell 0:83d4a20e7bc7 3 /* This RC5 decoder works by reading in the RC5 stream from one of the serial port lines */
andrewcrussell 0:83d4a20e7bc7 4 /* and saving the incoming stream into an array called stream, after which it is decoded and */
andrewcrussell 1:bb881a434906 5 /* the command executed. A Marantz RC-68PM IR R/C was used to develop this program - it */
andrewcrussell 0:83d4a20e7bc7 6 /* should work with any controller complying with the Philips RC5 standard. */
andrewcrussell 1:bb881a434906 7 /* See the rc5codes.h header for the codes used. */
andrewcrussell 0:83d4a20e7bc7 8
andrewcrussell 0:83d4a20e7bc7 9 /* The following audio preamplifier facilities are catered for:- */
andrewcrussell 0:83d4a20e7bc7 10 /* 1. Manual volume control adjustment via ALPS RK27 motorized potentiometer */
andrewcrussell 0:83d4a20e7bc7 11 /* 2. Input select via rotary encoder */
andrewcrussell 0:83d4a20e7bc7 12 /* 3. Output mute via push button actuation */
andrewcrussell 0:83d4a20e7bc7 13 /* 4. Record loop via push button actuation */
andrewcrussell 0:83d4a20e7bc7 14 /* 5. Power ON output to drive the /standby input of a system power supply */
andrewcrussell 0:83d4a20e7bc7 15 /* Facilities 1,2,3 and 5 are supported by an RC5 compliant remote control for preamplifiers */
andrewcrussell 1:bb881a434906 16 /* The program can be used with either the LPC11U24 or the LPC1114 - just use the appropriate */
andrewcrussell 1:bb881a434906 17 /* Pindfefxxxx.h file */
andrewcrussell 0:83d4a20e7bc7 18
andrewcrussell 0:83d4a20e7bc7 19 #include "mbed.h"
andrewcrussell 1:bb881a434906 20 #include "rc5codes.h" // Philips RC5 code definitions
andrewcrussell 0:83d4a20e7bc7 21 #include "Pindef1114.h" // all microcontroller I/O pin assignments defined here
andrewcrussell 0:83d4a20e7bc7 22
andrewcrussell 0:83d4a20e7bc7 23 #define TRUE 1
andrewcrussell 0:83d4a20e7bc7 24 #define FALSE 0
andrewcrussell 0:83d4a20e7bc7 25 #define HIGH 1
andrewcrussell 0:83d4a20e7bc7 26 #define LOW 0
andrewcrussell 0:83d4a20e7bc7 27 #define rc5_bitcount 14 // number of RC5 bits
andrewcrussell 0:83d4a20e7bc7 28 #define tick 444 // quarter bit time in us
andrewcrussell 0:83d4a20e7bc7 29 #define tock 1778 // one bit time in us
andrewcrussell 0:83d4a20e7bc7 30 #define VUP_timeout 10 // defines max number of R/C cycles before the vol ctrl mtr drive stops
andrewcrussell 0:83d4a20e7bc7 31 #define VDWN_timeout 10 // as above but for volume decrease. Needed to ensure the motor is not burnt out
andrewcrussell 0:83d4a20e7bc7 32
andrewcrussell 0:83d4a20e7bc7 33 //#define PHONO_IN 1 // these are the input assignments - not used in V1.0 of the
andrewcrussell 0:83d4a20e7bc7 34 //#define CD_IN 2 // controller since the input select is just stepped
andrewcrussell 0:83d4a20e7bc7 35 //#define TUN_IN 4 // through from PHONO_IN to REC_IN and back again
andrewcrussell 0:83d4a20e7bc7 36 //#define AUX1_IN 8
andrewcrussell 0:83d4a20e7bc7 37 //#define MSERV_IN 16
andrewcrussell 0:83d4a20e7bc7 38 //define REC_IN 32
andrewcrussell 0:83d4a20e7bc7 39
andrewcrussell 0:83d4a20e7bc7 40 int startbit;
andrewcrussell 0:83d4a20e7bc7 41 int toggle;
andrewcrussell 0:83d4a20e7bc7 42 int toggle1;
andrewcrussell 0:83d4a20e7bc7 43 int toggle2;
andrewcrussell 0:83d4a20e7bc7 44 int standby;
andrewcrussell 0:83d4a20e7bc7 45 int address;
andrewcrussell 0:83d4a20e7bc7 46 int command;
andrewcrussell 0:83d4a20e7bc7 47
andrewcrussell 0:83d4a20e7bc7 48 int FLAG1; // this is used in the remote control input processing
andrewcrussell 0:83d4a20e7bc7 49 int FLAG2; // this is used in the select input processing
andrewcrussell 0:83d4a20e7bc7 50 int FLAG3; // this is for the mute pushbutton
andrewcrussell 0:83d4a20e7bc7 51 int FLAG4; // this is for the standby pushbutton
andrewcrussell 0:83d4a20e7bc7 52 int FLAG5; // this is the recloop flag
andrewcrussell 0:83d4a20e7bc7 53 int RCFLAG = FALSE; // used to determine if the select command came via R/C
andrewcrussell 0:83d4a20e7bc7 54 int standbyflag; // used to save the standby condition
andrewcrussell 0:83d4a20e7bc7 55
andrewcrussell 0:83d4a20e7bc7 56 int relay;
andrewcrussell 0:83d4a20e7bc7 57 int key_press = 1; // keeps track of key presses
andrewcrussell 0:83d4a20e7bc7 58 int toggle_press = 1; //stores value of toggle for key_press routine
andrewcrussell 0:83d4a20e7bc7 59
andrewcrussell 0:83d4a20e7bc7 60 // delcarations below are all for the input select proceses
andrewcrussell 0:83d4a20e7bc7 61 int select = 0;
andrewcrussell 0:83d4a20e7bc7 62 int select_save = 1; // we save the status of select drive here. Initial value is 1
andrewcrussell 0:83d4a20e7bc7 63 int select_rot = 1; // rotary encoder pulse counter
andrewcrussell 0:83d4a20e7bc7 64
andrewcrussell 0:83d4a20e7bc7 65 // declare function prototypes here
andrewcrussell 0:83d4a20e7bc7 66 void select_out (void);
andrewcrussell 0:83d4a20e7bc7 67 void rc5isr(void);
andrewcrussell 0:83d4a20e7bc7 68 void mute_isr(void);
andrewcrussell 0:83d4a20e7bc7 69 void recloop_isr(void);
andrewcrussell 0:83d4a20e7bc7 70 void select_isr(void);
andrewcrussell 0:83d4a20e7bc7 71 void standby_out(void);
andrewcrussell 0:83d4a20e7bc7 72
andrewcrussell 0:83d4a20e7bc7 73 /****************************** volume increase ***********************************/
andrewcrussell 0:83d4a20e7bc7 74 void vol_up (void)
andrewcrussell 0:83d4a20e7bc7 75 {
andrewcrussell 0:83d4a20e7bc7 76 if ((standbyflag == TRUE) && (key_press < VUP_timeout)) {
andrewcrussell 0:83d4a20e7bc7 77
andrewcrussell 0:83d4a20e7bc7 78 FWD1 = HIGH;
andrewcrussell 0:83d4a20e7bc7 79 // FWD2 = HIGH;
andrewcrussell 0:83d4a20e7bc7 80 wait(.1); //drive the motors for a short while
andrewcrussell 0:83d4a20e7bc7 81 FWD1 = LOW;
andrewcrussell 0:83d4a20e7bc7 82 // FWD2 = LOW;
andrewcrussell 0:83d4a20e7bc7 83 }
andrewcrussell 0:83d4a20e7bc7 84 if (toggle1 != toggle) {
andrewcrussell 0:83d4a20e7bc7 85 key_press = 0; // user released the button, so reset counter
andrewcrussell 0:83d4a20e7bc7 86 } else if (toggle1 == toggle) {
andrewcrussell 0:83d4a20e7bc7 87 key_press++; // button remained depressed, so increment counter
andrewcrussell 0:83d4a20e7bc7 88 }
andrewcrussell 0:83d4a20e7bc7 89 toggle1 = toggle;
andrewcrussell 0:83d4a20e7bc7 90 wait_ms(1);
andrewcrussell 0:83d4a20e7bc7 91 }
andrewcrussell 0:83d4a20e7bc7 92
andrewcrussell 0:83d4a20e7bc7 93 /******************************* volume decrease **********************************/
andrewcrussell 0:83d4a20e7bc7 94 void vol_dwn (void)
andrewcrussell 0:83d4a20e7bc7 95 {
andrewcrussell 0:83d4a20e7bc7 96 if ((standbyflag == TRUE) && (key_press < VDWN_timeout)) {
andrewcrussell 0:83d4a20e7bc7 97
andrewcrussell 0:83d4a20e7bc7 98 REV1 = HIGH;
andrewcrussell 0:83d4a20e7bc7 99 // REV2 = HIGH;
andrewcrussell 0:83d4a20e7bc7 100 wait(.1); //drive the motors for a short while
andrewcrussell 0:83d4a20e7bc7 101 REV1 = LOW;
andrewcrussell 0:83d4a20e7bc7 102 // REV2 = LOW;
andrewcrussell 0:83d4a20e7bc7 103 }
andrewcrussell 0:83d4a20e7bc7 104 if (toggle1 != toggle) {
andrewcrussell 0:83d4a20e7bc7 105 key_press = 0; // user released the button, so reset counter
andrewcrussell 0:83d4a20e7bc7 106 } else if (toggle1 == toggle) {
andrewcrussell 0:83d4a20e7bc7 107 key_press++; // button remained depressed, so increment counter
andrewcrussell 0:83d4a20e7bc7 108 }
andrewcrussell 0:83d4a20e7bc7 109 toggle1 = toggle;
andrewcrussell 0:83d4a20e7bc7 110 wait_ms(1);
andrewcrussell 0:83d4a20e7bc7 111 }
andrewcrussell 0:83d4a20e7bc7 112 /********************************** stdby_isr *************************************/
andrewcrussell 0:83d4a20e7bc7 113 void stdby_isr (void)
andrewcrussell 0:83d4a20e7bc7 114 {
andrewcrussell 0:83d4a20e7bc7 115 FLAG4 = TRUE;
andrewcrussell 0:83d4a20e7bc7 116 }
andrewcrussell 0:83d4a20e7bc7 117
andrewcrussell 0:83d4a20e7bc7 118 /*********************************** standby **************************************/
andrewcrussell 0:83d4a20e7bc7 119 /* this will require supporting hardware functionality to power down the */
andrewcrussell 0:83d4a20e7bc7 120 /* analog board, LED's etc. Best option here is to use regulators with a */
andrewcrussell 1:bb881a434906 121 /* shutdown option. for now, all the LED's are just turned off. */
andrewcrussell 0:83d4a20e7bc7 122
andrewcrussell 0:83d4a20e7bc7 123 void standby_out(void) // both p/button and R/C come in here
andrewcrussell 0:83d4a20e7bc7 124 {
andrewcrussell 0:83d4a20e7bc7 125 stdby_int.fall(NULL); // on first power up cycle NO interuppts are accepted
andrewcrussell 1:bb881a434906 126 // and neither any while this function is executed in any case
andrewcrussell 0:83d4a20e7bc7 127 wait_ms(20); // a very simple debounce
andrewcrussell 0:83d4a20e7bc7 128 do { // that waits for the depressed button to be released
andrewcrussell 0:83d4a20e7bc7 129 (1);
andrewcrussell 0:83d4a20e7bc7 130 } while (stdby !=1);
andrewcrussell 0:83d4a20e7bc7 131
andrewcrussell 0:83d4a20e7bc7 132 if (standbyflag == TRUE) { // was ON so we will turn it OFF
andrewcrussell 0:83d4a20e7bc7 133 // turn off all interrupts except the standby and rc5int
andrewcrussell 0:83d4a20e7bc7 134 select_int.fall(NULL);
andrewcrussell 0:83d4a20e7bc7 135 mute_int.fall(NULL);
andrewcrussell 0:83d4a20e7bc7 136 recloop_int.fall(NULL);
andrewcrussell 1:bb881a434906 137 muteind = LOW;
andrewcrussell 0:83d4a20e7bc7 138 muteout = LOW;
andrewcrussell 0:83d4a20e7bc7 139 recloop_out = LOW;
andrewcrussell 0:83d4a20e7bc7 140 select_save = select_drv; // save the status of select_drv
andrewcrussell 0:83d4a20e7bc7 141 select_drv = 0; // turn all input select realys OFF
andrewcrussell 1:bb881a434906 142 //power_ind = LOW; // this is the regulator shutdown control. HIGH = ON
andrewcrussell 0:83d4a20e7bc7 143 wait(1);
andrewcrussell 1:bb881a434906 144 muteind = HIGH;`
andrewcrussell 0:83d4a20e7bc7 145 standbyflag = FALSE; // set it up for the next power cycle
andrewcrussell 0:83d4a20e7bc7 146
andrewcrussell 0:83d4a20e7bc7 147 } else if (standbyflag == FALSE) { // was OFF so we will turn it ON
andrewcrussell 1:bb881a434906 148 //printf("i should be here!\n");
andrewcrussell 1:bb881a434906 149 //power_ind = HIGH;
andrewcrussell 1:bb881a434906 150 muteind = LOW;
andrewcrussell 0:83d4a20e7bc7 151 rc5int.rise(&rc5isr); // trigger int on rising edge - go service it at rc5dat
andrewcrussell 0:83d4a20e7bc7 152 select_int.fall(&select_isr); // input from rotary encoder or input select
andrewcrussell 0:83d4a20e7bc7 153 mute_int.fall(&mute_isr);
andrewcrussell 0:83d4a20e7bc7 154 recloop_int.fall(&recloop_isr);
andrewcrussell 0:83d4a20e7bc7 155 wait(2);
andrewcrussell 0:83d4a20e7bc7 156 select_drv = select_save; // recall the input select setting
andrewcrussell 1:bb881a434906 157 wait(2);
andrewcrussell 1:bb881a434906 158 muteind = HIGH; // let things settle a bit
andrewcrussell 0:83d4a20e7bc7 159 muteout = HIGH;
andrewcrussell 0:83d4a20e7bc7 160 standbyflag = TRUE;
andrewcrussell 0:83d4a20e7bc7 161
andrewcrussell 0:83d4a20e7bc7 162 }
andrewcrussell 1:bb881a434906 163 //printf("STDB ISR\n");
andrewcrussell 0:83d4a20e7bc7 164 wait_ms(5);
andrewcrussell 0:83d4a20e7bc7 165 stdby_int.fall(&stdby_isr); // re-enable the standby interrupt
andrewcrussell 0:83d4a20e7bc7 166 }
andrewcrussell 0:83d4a20e7bc7 167
andrewcrussell 0:83d4a20e7bc7 168 /********************************** record loop isr *******************************/
andrewcrussell 0:83d4a20e7bc7 169
andrewcrussell 0:83d4a20e7bc7 170 void recloop_isr(void)
andrewcrussell 0:83d4a20e7bc7 171 {
andrewcrussell 0:83d4a20e7bc7 172 FLAG5 = TRUE;
andrewcrussell 0:83d4a20e7bc7 173 }
andrewcrussell 0:83d4a20e7bc7 174 /************************** recloop - just a simple toggle ************************/
andrewcrussell 0:83d4a20e7bc7 175 void recloop()
andrewcrussell 0:83d4a20e7bc7 176 {
andrewcrussell 0:83d4a20e7bc7 177 recloop_int.fall(NULL); // to prevent re-entrance when coming here from the R/C
andrewcrussell 0:83d4a20e7bc7 178 wait_ms(20); // simple debounce for when mute is via the f/p p/b switch
andrewcrussell 0:83d4a20e7bc7 179 do {
andrewcrussell 0:83d4a20e7bc7 180 (1); // wait here until the button is released
andrewcrussell 0:83d4a20e7bc7 181 } while (recloop_in!=1);
andrewcrussell 0:83d4a20e7bc7 182 recloop_out = !recloop_out;
andrewcrussell 0:83d4a20e7bc7 183 wait_ms(20);
andrewcrussell 0:83d4a20e7bc7 184 recloop_int.fall(&recloop_isr);
andrewcrussell 0:83d4a20e7bc7 185 }
andrewcrussell 0:83d4a20e7bc7 186
andrewcrussell 0:83d4a20e7bc7 187 /************************************ mute_isr ************************************/
andrewcrussell 0:83d4a20e7bc7 188
andrewcrussell 0:83d4a20e7bc7 189 void mute_isr(void)
andrewcrussell 0:83d4a20e7bc7 190 {
andrewcrussell 0:83d4a20e7bc7 191 FLAG3 = TRUE;
andrewcrussell 0:83d4a20e7bc7 192 toggle2 = !toggle2; // so the p/button input is recognized in mute_out()
andrewcrussell 1:bb881a434906 193 if(muteout = HIGH)
andrewcrussell 1:bb881a434906 194 {muteind = LOW;}
andrewcrussell 0:83d4a20e7bc7 195 }
andrewcrussell 0:83d4a20e7bc7 196 /*************************** mute - just a simple toggle **************************/
andrewcrussell 0:83d4a20e7bc7 197 void mute_out()
andrewcrussell 0:83d4a20e7bc7 198 {
andrewcrussell 0:83d4a20e7bc7 199 mute_int.fall(NULL); // to prevent re-entance when coming here from the R/C
andrewcrussell 0:83d4a20e7bc7 200 if ((standbyflag == TRUE) && (toggle != toggle2)) { // only toggle mute if the preamp is ON
andrewcrussell 0:83d4a20e7bc7 201 wait_ms(20); //simple debounce for when mute is via the f/p p/b switch
andrewcrussell 0:83d4a20e7bc7 202 do {
andrewcrussell 0:83d4a20e7bc7 203 (1); //wait here until the button is released
andrewcrussell 0:83d4a20e7bc7 204 } while (mute != 1);
andrewcrussell 0:83d4a20e7bc7 205 muteout = !muteout;
andrewcrussell 0:83d4a20e7bc7 206 wait_ms(20);
andrewcrussell 0:83d4a20e7bc7 207
andrewcrussell 0:83d4a20e7bc7 208 }
andrewcrussell 0:83d4a20e7bc7 209 toggle2 = toggle;
andrewcrussell 0:83d4a20e7bc7 210 mute_int.fall(&mute_isr);
andrewcrussell 0:83d4a20e7bc7 211 }
andrewcrussell 0:83d4a20e7bc7 212
andrewcrussell 0:83d4a20e7bc7 213 /************************************ rc5isr **************************************/
andrewcrussell 0:83d4a20e7bc7 214 /* Interrupt triggered by a rising edge on p21 of the cont which is R/C data in */
andrewcrussell 0:83d4a20e7bc7 215
andrewcrussell 0:83d4a20e7bc7 216 void rc5isr(void)
andrewcrussell 0:83d4a20e7bc7 217 {
andrewcrussell 0:83d4a20e7bc7 218 FLAG1 = TRUE;
andrewcrussell 0:83d4a20e7bc7 219 }
andrewcrussell 0:83d4a20e7bc7 220 /***************** save rc5 bit stream from remote controller *********************/
andrewcrussell 0:83d4a20e7bc7 221 /* This function reads the input data on pin rc5dat at 1778us ('tock')intervals */
andrewcrussell 0:83d4a20e7bc7 222 /* and saves the data into an array stream[i]. */
andrewcrussell 0:83d4a20e7bc7 223 /* This function only looks at the second half of the bit position, since if that */
andrewcrussell 0:83d4a20e7bc7 224 /* is a 1 then it is assumed the first half of the bit position is a zero. Note */
andrewcrussell 0:83d4a20e7bc7 225 /* that in Manchester encoding, you cannot (should not) have both the 0 half-bit */
andrewcrussell 0:83d4a20e7bc7 226 /* position and the 1 half-bit position both HIGH or LOW in the same bit time - */
andrewcrussell 0:83d4a20e7bc7 227 /* a simplification exploited in this function. */
andrewcrussell 0:83d4a20e7bc7 228
andrewcrussell 0:83d4a20e7bc7 229 void save_stream(void)
andrewcrussell 0:83d4a20e7bc7 230 {
andrewcrussell 0:83d4a20e7bc7 231 bool stream[15];// the array is initialized each time its used and is local only
andrewcrussell 0:83d4a20e7bc7 232 int bitloop; // number of bit positions
andrewcrussell 0:83d4a20e7bc7 233 int i = 0; // counter
andrewcrussell 0:83d4a20e7bc7 234 int k = 0; // temp storage
andrewcrussell 0:83d4a20e7bc7 235 startbit = 0;
andrewcrussell 0:83d4a20e7bc7 236 address = 0;
andrewcrussell 0:83d4a20e7bc7 237 command = 0;
andrewcrussell 0:83d4a20e7bc7 238 toggle = 0;
andrewcrussell 0:83d4a20e7bc7 239 wait_us(tick); // locate read point in middle of 1st half bit time of the 1st start bit
andrewcrussell 0:83d4a20e7bc7 240 for (bitloop = 0; bitloop <15; bitloop++) {
andrewcrussell 0:83d4a20e7bc7 241 stream[bitloop] = rc5dat; //read the data and save it to array position [i]
andrewcrussell 0:83d4a20e7bc7 242 wait_us(tock); //wait here until ready to read the next bit in
andrewcrussell 0:83d4a20e7bc7 243
andrewcrussell 0:83d4a20e7bc7 244 // now have 14 bits loaded into stream[i]
andrewcrussell 0:83d4a20e7bc7 245 }
andrewcrussell 0:83d4a20e7bc7 246 /* now put data in the array into the start, toggle, address and command variables - array counts from stream[0] */
andrewcrussell 0:83d4a20e7bc7 247
andrewcrussell 0:83d4a20e7bc7 248 for (i=0; i<2; i++) { // first 2 bit positions are start bits = 3; will use this later for basic error checking
andrewcrussell 0:83d4a20e7bc7 249 k = stream[i];
andrewcrussell 0:83d4a20e7bc7 250 startbit = (startbit << 1);
andrewcrussell 0:83d4a20e7bc7 251 startbit = startbit|k;
andrewcrussell 0:83d4a20e7bc7 252 }
andrewcrussell 0:83d4a20e7bc7 253
andrewcrussell 0:83d4a20e7bc7 254 toggle = stream[2]; // 3rd bit position is the toggle bit - 1 bit
andrewcrussell 0:83d4a20e7bc7 255
andrewcrussell 0:83d4a20e7bc7 256 for (i = 3; i <8; i++) { // bit positions 3 to 7 are the address (or 'system') - 5 bit positions in total
andrewcrussell 0:83d4a20e7bc7 257 k = stream[i];
andrewcrussell 0:83d4a20e7bc7 258 address = (address << 1);
andrewcrussell 0:83d4a20e7bc7 259 address = address|k;
andrewcrussell 0:83d4a20e7bc7 260 }
andrewcrussell 0:83d4a20e7bc7 261
andrewcrussell 0:83d4a20e7bc7 262 for (i = 8; i <14; i++) { // bit positions 8 to 13 are the command - 6 bit positions
andrewcrussell 0:83d4a20e7bc7 263 k = stream[i];
andrewcrussell 0:83d4a20e7bc7 264 command = (command << 1);
andrewcrussell 0:83d4a20e7bc7 265 command = command|k;
andrewcrussell 0:83d4a20e7bc7 266 }
andrewcrussell 0:83d4a20e7bc7 267
andrewcrussell 0:83d4a20e7bc7 268 }
andrewcrussell 0:83d4a20e7bc7 269 /********************************* process_stream() *******************************/
andrewcrussell 0:83d4a20e7bc7 270 /* handles commands coming in from the remote controller only */
andrewcrussell 0:83d4a20e7bc7 271
andrewcrussell 0:83d4a20e7bc7 272 void process_stream (void)
andrewcrussell 0:83d4a20e7bc7 273 {
andrewcrussell 0:83d4a20e7bc7 274 if ((address == PREAMP) && (startbit == 3)) {
andrewcrussell 0:83d4a20e7bc7 275 // basic error checking - must be preamp + startbit ok to get executed otherwise skip completly
andrewcrussell 0:83d4a20e7bc7 276 switch (command) {
andrewcrussell 0:83d4a20e7bc7 277
andrewcrussell 0:83d4a20e7bc7 278 case VUP:
andrewcrussell 0:83d4a20e7bc7 279 vol_up();
andrewcrussell 0:83d4a20e7bc7 280 break;
andrewcrussell 0:83d4a20e7bc7 281
andrewcrussell 0:83d4a20e7bc7 282 case VDOWN:
andrewcrussell 0:83d4a20e7bc7 283 vol_dwn();
andrewcrussell 0:83d4a20e7bc7 284 break;
andrewcrussell 0:83d4a20e7bc7 285
andrewcrussell 0:83d4a20e7bc7 286 case MUTE:
andrewcrussell 0:83d4a20e7bc7 287 mute_out();
andrewcrussell 0:83d4a20e7bc7 288 break;
andrewcrussell 0:83d4a20e7bc7 289
andrewcrussell 0:83d4a20e7bc7 290 case SELECT_R:
andrewcrussell 0:83d4a20e7bc7 291 select_out();
andrewcrussell 0:83d4a20e7bc7 292 break;
andrewcrussell 0:83d4a20e7bc7 293
andrewcrussell 0:83d4a20e7bc7 294 case STANDBY:
andrewcrussell 0:83d4a20e7bc7 295 standby_out();
andrewcrussell 0:83d4a20e7bc7 296 break;
andrewcrussell 0:83d4a20e7bc7 297 }
andrewcrussell 0:83d4a20e7bc7 298 }
andrewcrussell 0:83d4a20e7bc7 299 }
andrewcrussell 0:83d4a20e7bc7 300 /*********************************** select_isr ***********************************/
andrewcrussell 0:83d4a20e7bc7 301
andrewcrussell 0:83d4a20e7bc7 302 void select_isr(void)
andrewcrussell 0:83d4a20e7bc7 303 {
andrewcrussell 0:83d4a20e7bc7 304 FLAG2 = TRUE;
andrewcrussell 0:83d4a20e7bc7 305 }
andrewcrussell 0:83d4a20e7bc7 306
andrewcrussell 0:83d4a20e7bc7 307 /********************************* select_process *********************************/
andrewcrussell 0:83d4a20e7bc7 308 /* used for selecting the input source. This function is used by both the */
andrewcrussell 0:83d4a20e7bc7 309 /* rotary encoder and the remote control */
andrewcrussell 0:83d4a20e7bc7 310
andrewcrussell 0:83d4a20e7bc7 311 void select_process(void)
andrewcrussell 0:83d4a20e7bc7 312 {
andrewcrussell 0:83d4a20e7bc7 313 if (RCFLAG == FALSE) { // if used R/C skip to select below
andrewcrussell 0:83d4a20e7bc7 314 wait_ms(5); // debounce
andrewcrussell 0:83d4a20e7bc7 315 select = 0; // flush select
andrewcrussell 0:83d4a20e7bc7 316
andrewcrussell 0:83d4a20e7bc7 317 select = (select | sela) <<1; // read the two port lines associated with the select rotary encoder
andrewcrussell 0:83d4a20e7bc7 318 select = (select | selb);
andrewcrussell 0:83d4a20e7bc7 319 }
andrewcrussell 0:83d4a20e7bc7 320
andrewcrussell 0:83d4a20e7bc7 321 switch (select) {
andrewcrussell 0:83d4a20e7bc7 322 case 1: // select encoder is being rotated CW
andrewcrussell 0:83d4a20e7bc7 323 select_rot <<= 1;
andrewcrussell 0:83d4a20e7bc7 324 if (select_rot > 32) {
andrewcrussell 0:83d4a20e7bc7 325 select_rot = 1;
andrewcrussell 0:83d4a20e7bc7 326 }
andrewcrussell 0:83d4a20e7bc7 327 break;
andrewcrussell 0:83d4a20e7bc7 328
andrewcrussell 0:83d4a20e7bc7 329 case 0:
andrewcrussell 0:83d4a20e7bc7 330 select_rot >>= 1; // encoder is being rotated CCW
andrewcrussell 0:83d4a20e7bc7 331 if (select_rot < 1) {
andrewcrussell 0:83d4a20e7bc7 332 select_rot = 32;
andrewcrussell 0:83d4a20e7bc7 333 }
andrewcrussell 0:83d4a20e7bc7 334 break;
andrewcrussell 0:83d4a20e7bc7 335
andrewcrussell 0:83d4a20e7bc7 336 case 2:
andrewcrussell 0:83d4a20e7bc7 337 {} break; // indeterminate fall through values - ignore
andrewcrussell 0:83d4a20e7bc7 338 case 3:
andrewcrussell 0:83d4a20e7bc7 339 {} break;
andrewcrussell 0:83d4a20e7bc7 340 }
andrewcrussell 1:bb881a434906 341
andrewcrussell 0:83d4a20e7bc7 342 select_drv = select_rot; // write the value out to the bus
andrewcrussell 0:83d4a20e7bc7 343 }
andrewcrussell 0:83d4a20e7bc7 344
andrewcrussell 0:83d4a20e7bc7 345
andrewcrussell 0:83d4a20e7bc7 346 /********************* input select from remote controller only *******************/
andrewcrussell 0:83d4a20e7bc7 347 void select_out (void)
andrewcrussell 0:83d4a20e7bc7 348 {
andrewcrussell 0:83d4a20e7bc7 349 if (toggle != toggle1) { // if the R/C button is held down, skip the increment
andrewcrussell 0:83d4a20e7bc7 350 RCFLAG = TRUE; // this indicates command came in through the remote
andrewcrussell 0:83d4a20e7bc7 351 select = 1;
andrewcrussell 0:83d4a20e7bc7 352 select_process();
andrewcrussell 0:83d4a20e7bc7 353 RCFLAG = FALSE;
andrewcrussell 0:83d4a20e7bc7 354 }
andrewcrussell 0:83d4a20e7bc7 355 toggle1 = toggle;
andrewcrussell 0:83d4a20e7bc7 356 }
andrewcrussell 0:83d4a20e7bc7 357 /************************************ main() ***************************************/
andrewcrussell 0:83d4a20e7bc7 358 int main(void)
andrewcrussell 0:83d4a20e7bc7 359 {
andrewcrussell 1:bb881a434906 360 disable_irq(); // just to make sure we can set up correctly without problems
andrewcrussell 1:bb881a434906 361
andrewcrussell 1:bb881a434906 362 muteind = LOW;
andrewcrussell 0:83d4a20e7bc7 363 muteout = LOW; // mute the output while we go through power-up sequence
andrewcrussell 0:83d4a20e7bc7 364 recloop_out = LOW; // make sure initial recloop condition is delected
andrewcrussell 1:bb881a434906 365 //power_ind = LOW; // power control; HIGH = power up
andrewcrussell 0:83d4a20e7bc7 366 wait(.2);
andrewcrussell 1:bb881a434906 367 //Serial pc(USBTX, USBRX); // for debuging only - comment out on production
andrewcrussell 0:83d4a20e7bc7 368 FLAG1 = FALSE;
andrewcrussell 0:83d4a20e7bc7 369 FLAG2 = FALSE;
andrewcrussell 0:83d4a20e7bc7 370 FWD1=0;
andrewcrussell 0:83d4a20e7bc7 371 // FWD2=0;
andrewcrussell 0:83d4a20e7bc7 372 REV1=0;
andrewcrussell 0:83d4a20e7bc7 373 // REV2=0; //make sure the volume control motor is OFF
andrewcrussell 0:83d4a20e7bc7 374
andrewcrussell 0:83d4a20e7bc7 375 // set up the ISR's we will be using
andrewcrussell 0:83d4a20e7bc7 376 rc5int.rise(&rc5isr); // trigger int on rising edge - go service it at rc5dat
andrewcrussell 0:83d4a20e7bc7 377 select_int.fall(&select_isr); // input from rotary encoder or input select
andrewcrussell 0:83d4a20e7bc7 378 mute_int.fall(&mute_isr); // mute push button interrupt
andrewcrussell 0:83d4a20e7bc7 379 recloop_int.fall(&recloop_isr); // record loop push button interrupt
andrewcrussell 0:83d4a20e7bc7 380 stdby_int.fall(&stdby_isr); // the system power/standby switch
andrewcrussell 0:83d4a20e7bc7 381
andrewcrussell 0:83d4a20e7bc7 382 //now disable them, leaving only the stand by p/button and rc5int interrupts active
andrewcrussell 0:83d4a20e7bc7 383 select_int.fall(NULL);
andrewcrussell 0:83d4a20e7bc7 384 mute_int.fall(NULL);
andrewcrussell 0:83d4a20e7bc7 385 recloop_int.fall(NULL);
andrewcrussell 0:83d4a20e7bc7 386
andrewcrussell 1:bb881a434906 387 //printf("diable ISR\n");
andrewcrussell 1:bb881a434906 388
andrewcrussell 1:bb881a434906 389 standbyflag = TRUE; // preamp will be set-up first time for OFF
andrewcrussell 0:83d4a20e7bc7 390 standby_out(); // go through standby_out for initial set-up
andrewcrussell 1:bb881a434906 391 select_save = 2; // CD will be selected when power is first turned on
andrewcrussell 1:bb881a434906 392 muteind = HIGH;
andrewcrussell 0:83d4a20e7bc7 393 __enable_irq();
andrewcrussell 0:83d4a20e7bc7 394
andrewcrussell 1:bb881a434906 395
andrewcrussell 0:83d4a20e7bc7 396 // all ready and in standby from this point forward
andrewcrussell 0:83d4a20e7bc7 397
andrewcrussell 0:83d4a20e7bc7 398 LOOP: // this is the main operating loop
andrewcrussell 1:bb881a434906 399 //printf("WFI\n");
andrewcrussell 0:83d4a20e7bc7 400 __WFI(); // wait here until interrupt
andrewcrussell 0:83d4a20e7bc7 401
andrewcrussell 0:83d4a20e7bc7 402 if (FLAG1 == TRUE) { // FLAG1 indicates remote control was used
andrewcrussell 0:83d4a20e7bc7 403 __disable_irq();
andrewcrussell 0:83d4a20e7bc7 404 save_stream();
andrewcrussell 0:83d4a20e7bc7 405 if (startbit == 3) {
andrewcrussell 0:83d4a20e7bc7 406 process_stream();
andrewcrussell 0:83d4a20e7bc7 407 }
andrewcrussell 0:83d4a20e7bc7 408 FLAG1 = FALSE;
andrewcrussell 0:83d4a20e7bc7 409 __enable_irq();
andrewcrussell 0:83d4a20e7bc7 410 }
andrewcrussell 0:83d4a20e7bc7 411
andrewcrussell 0:83d4a20e7bc7 412 if (FLAG2 == TRUE) {
andrewcrussell 0:83d4a20e7bc7 413 __disable_irq();
andrewcrussell 0:83d4a20e7bc7 414 select_process(); //select process
andrewcrussell 0:83d4a20e7bc7 415 FLAG2 = FALSE;
andrewcrussell 0:83d4a20e7bc7 416 __enable_irq();
andrewcrussell 0:83d4a20e7bc7 417 }
andrewcrussell 0:83d4a20e7bc7 418
andrewcrussell 0:83d4a20e7bc7 419 if (FLAG3 == TRUE) {
andrewcrussell 0:83d4a20e7bc7 420 __disable_irq();
andrewcrussell 0:83d4a20e7bc7 421 mute_out(); //mute
andrewcrussell 0:83d4a20e7bc7 422 FLAG3 = FALSE;
andrewcrussell 0:83d4a20e7bc7 423 __enable_irq();
andrewcrussell 0:83d4a20e7bc7 424 }
andrewcrussell 1:bb881a434906 425 //printf("B4stdby\n");
andrewcrussell 0:83d4a20e7bc7 426 if (FLAG4 == TRUE) {
andrewcrussell 0:83d4a20e7bc7 427 __disable_irq();
andrewcrussell 1:bb881a434906 428 standby_out();
andrewcrussell 1:bb881a434906 429 // standby
andrewcrussell 0:83d4a20e7bc7 430 FLAG4 = FALSE;
andrewcrussell 1:bb881a434906 431 // printf("back from isr\n");
andrewcrussell 0:83d4a20e7bc7 432 __enable_irq();
andrewcrussell 1:bb881a434906 433 //printf("renable isr\n");
andrewcrussell 0:83d4a20e7bc7 434 }
andrewcrussell 1:bb881a434906 435 //printf("finished with STBY\n");
andrewcrussell 0:83d4a20e7bc7 436 if (FLAG5 == TRUE) {
andrewcrussell 0:83d4a20e7bc7 437 __disable_irq();
andrewcrussell 0:83d4a20e7bc7 438 recloop(); //recloop
andrewcrussell 0:83d4a20e7bc7 439 FLAG5 = FALSE;
andrewcrussell 0:83d4a20e7bc7 440 __enable_irq();
andrewcrussell 0:83d4a20e7bc7 441 }
andrewcrussell 0:83d4a20e7bc7 442
andrewcrussell 0:83d4a20e7bc7 443 wait_us(5);
andrewcrussell 1:bb881a434906 444 //printf("loop to WFI\n");
andrewcrussell 0:83d4a20e7bc7 445 goto LOOP;
andrewcrussell 0:83d4a20e7bc7 446
andrewcrussell 0:83d4a20e7bc7 447 }
andrewcrussell 0:83d4a20e7bc7 448
andrewcrussell 0:83d4a20e7bc7 449
andrewcrussell 0:83d4a20e7bc7 450