Revised file for Remote Control IR decoder by Roger Thomas, EPE Sep 00 Revision originator Malcolm Wiles Jan 5 2001. (EPE has not tested this software revision. John Becker, EPE Tech Ed) Notes by Malcolm regarding file SIRCV2.ASM: Please can I first of all make it clear that I found the article most interesting. It contains much useful info on the RC5 and SIRC protocols and encoding schemes that would be very hard to reverse engineer from scratch. The pointer to the IS1U60 device is also very helpful (though I do recall a previous project using this device (IR repeater, Ingenuity Unlimited, Jul 95)). From the info in the article I've achieved a working prototype Sony decoder which I can now use to control my current PIC project. This will be a great improvement on the inelegant array of switches and buttons which I might otherwise have had to use, so overall I'm well pleased but felt I could improve the software. I've made the following main changes. There remains one problem, which is that the most significant address bit is not decoded, as there is no falling edge after it has been transmitted by which to recognise it. The only fix for this would be to switch to interrupt on rising edges at some point after the start bit is detected. This is a non-trivial change, and since it is not a stated objective of the program to decode address bits, I've left it as it is. 1. I deleted the __config, and moved the ISR, to make it Toolkit compatible. (Toolkit has now been modified to intercept config data when found in the HEX file - use version V2.4a - John Becker, Toolkit author) 2. I added comments! Assembly code needs of the order of one good comment per line if others are to stand any chance of understanding it. 3. Many of the comparison tests were clumsy, inefficient, and hard to understand. In fact they look to me as if they might have been produced by a (not very good) code generator, perhaps one of these PICBasic things that output MPASM. I've rewritten them to be certainly shorter and I hope more intuitively obvious to a human. 4. I've added exception paths - the original had none. For example, it tested that the TMR0 value (bit length) was >50 ticks, but didn't do anything about it if it was not. In most cases I count each such error, so that I can detect if they happen, and abort this decode. It was discrepancies in these counts that led to the identification of the bug (point 9). 5. The original code shared TIMERVAL between the ISR and the CONVRTCC routine. However, interrupts can occur at any time, even if they shouldn't, so that from the point of view of CONVRTCC, TIMERVAL could change unpredictably "under its feet". This could well happen while it was in the middle of a comparison sequence. Coding like this leads to programs which behave erratically and unpredictably, and are very hard to debug because the errors are not reproducible. I've added code to make a copy of TIMERVAL in a protected section with interrupts disabled, so that the ISR cannot run while the copy is made. It is probably just about OK to clear the CONV flag without disabling interrupts (I would need to check the detailed specs of the microcontroller to see how interruptible its instructions are to be sure) but for safety and good form I clear this in the protected section too. 6. I nearly deleted the ISR altogether, but for the sake of illustration of point 5 decided to leave it. Interrupts are hard to program, and shouldn't be used unless a real time response less than a millisecond or so to asynchronous events is really necessary. In this case the program design is synchronous, that it is it relies on the PIC being able to process each interrupt completely as it occurs and before the next one occurs. Thus it would be better design to poll RB0 in an idle loop. 7. However, ISRs should always be as short as possible, because they: a) disrupt the normal program flow, making timings difficult to predict b) inhibit detection of other interrupts, and repeat occurrences of this interrupt c) (most important) are impossible to debug, so they must only contain code that is transparently and obviously correct. Any ISR that needs a procedure call is almost by definition too complex. This one didn't so I deleted it and inlined the code, saving a bit of time. I also removed the unnecessary save and restore of TEMP0. 8. I rewrote ADDTOBIN to do in 7 instructions what took 24 and an unnecessary variable in the original. 9. I fixed the bug which meant that only 6 of the 7 command code bits were added to CBINARY (C6 being lost). This was basically due to the program not treating the first interrupt (BITS=1) specially as it occurs at the beginning of the start bit, and was thus always one out in its counting. It maybe didn't help that Fig 11 in the article, showing the SIRC timing sequence, is drawn upside down with respect to what actually happens on the output of the IS1U60. 10. I replaced the register equates with the Microchip 16f84 include file, so that standard names are used (eg TMR0 not RTCC), and used equates for bit positions (eg GIE, INTE) rather than literals, to help comprehension. 11. I've used equates for minimum and maximum bit times, rather than literals embedded in the code. If anybody wanted to change these thresholds, they would only have to change the equate and reassemble, rather than fork though the code to find and change all occurrences (and maybe miss one). 12. There are misc other cosmetic improvements. One thing I didn't do was change all the instruction mnemonics to be consistently upper or lower case, though it would be pretty easy to do so. By habit I use lower case, whereas the original used upper case. This probably helps to highlight what is original code from my stuff. Malc