Thursday, February 28, 2013

RC5 IR Remote Control Receiver on Atmel ATtiny5

We want to share the experience of porting the RC5 IR Remote Control  Receiver found in this application note [1] onto Atmel ATtiny5 8-bit microcontroller.

RC5 PROTOCOL BASICS

An overview of the RC5 protocol (reproduced from [1]) is given below:

Figure 1: RC5 Frame Format
 The RC5 code is a 14-bit word bi-phase coded signal. The two first bits (St1 and St2) are start bits, always having the value one. The next bit (Ctrl) is a control bit or toggle bit, which is inverted every time a button is pressed on the remote control transmitter. Five system bits (S4, S3, S2, S1, S0) hold the system address so that only the right system responds to the code. Usually, TV sets have the system address 0, VCRs the address 5 and so on. The command sequence (C5, C4, C3, C2, C1, C0) is six bits long, allowing up to 64 different commands per address.
Figure 2: Bi-phase Coding


The bits are transmitted in bi-phase code (also known as Manchester code).

Figure 3: Example of RC5 transmission
The above figure shows an example where the command 0x35 is sent to system 0x5.

OVERVIEW OF RC5 DETECTION


The logic for detection of the RC5 frame is given in [1]. The time intervals that are used in the detection are given below.

S.No. Time Interval (ms) Remarks
1. 1.8  Approximate bit-length
2. 114  RC5 code repetition interval
3. 3.5  Start bit detection begins after the data line is idle high for this duration
4. 131  RC5 code detection restarted if no start bit detected during this duration
5. 1.1  RC5 code detection restarted if the low pulse is longer than this duration
6. 0.064  The clock base for the measuring time intervals.

IDE SELECTION

We used the AtmelStudio version 5.1.208.

MODIFICATION FOR ATMEL ATtiny5


The clock base is 64 us. To obtain the same clock base on ATtiny5 the following needs to be done. In our application we use the internal 8 MHz clock. To select this source the CLKMSR (Clock Main Settings Register) register has to written with value 0x00. The access to this register is protected by the CCP register. So to change the value of the register 0xD8 needs to be written to CCP register and then immediately the CLKMSR register should be updated with the desired value within 4 clock cycles.

The application note uses the AT90S1200 microcontroller which has a 8-bit timer/counter and connected to a 4 MHz external clock. So by using a OVERFLOW interrupt they are producing the base clock of 64 us. But on ATMEL ATtiny5 we have only a 16-bit Timer/Counter. Hence the plan is to use  a COMPA interrupt which is generated when the timer/counter reaches  a prescribed value.

The Clock Prescale Register (CLKPSR) can be used to scale down the system clock. By default, the division factor is 8. For our strategy we dont need clock division at this level hence we set the CLKPSR register with the value 0x00. This register is again protected by CCP register. Hence the modification to this register should be done as mentioned above.

We wanted to check whether this was indeed the case. So we used a small debug routine which toggles the output value on a pin and called this routine in the interrupt handler for the COMPA. Then we attached an oscilloscope to the output pin and measured the time duration of the on and off part of the waveform. We saw that instead of getting 64 us we were getting 65 ms. Then we realised that after the COMPA interrupt generation the timer/counter was not being reset to zero and was counting all the way up to the maximum 16-bit value and resetting to zero and the COMPA interrupt was being generation on its way up again.

A search in the datasheet again revealed the timer/counter operation mode called CTC. In this mode the timer/counter is reset to zero once it matches the compare value. This mode is set by writing TCCR0A and TCCR0B in this manner.

After these modification, the RC5 Remote Control receiver program was still not working. We saw that the something wrong while reading the input pin. For that, I had thought that the original code equivalent on ATtiny5 was PORTB. But after another search of the datasheet we saw that the correct way to represent it was PINB. Then voila, the code worked.




  1. CLOCK SETTING
  2. INPUT REGISTER

REFERENCE