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

Wednesday, July 9, 2008

A-Parently Scripture

If you run an executable on a Linux platform which requires shared libraries, you might have to add the relevant paths of shared libraries to the LD_LIBRARY_PATH environment variable. Recently, I had to work on a development board for which I had only the zImage and ramdisk.jffs2 (and not the sources). So everytime I powered-on the board and loaded the Linux operating system I had to set up the LD_LIBRARY_PATH environment variable before I could run some applications that were accessible over a NFS mount. I thought of writing a script which will effect these changes to the environment variable thus saving me the monotony of typing the paths again and again. Even though I was able to execute the script, the desired change didnt happen.

That's when I came to know how the bash shell works. When a shell script is executed from the bash shell prompt, it is spawned as a child process and whatever actions are taken in the script (like changing the environment variable) will affect only the child process's copy of the variables and not the parent process.

I found a tip to overcome this hurdle in the "Linux For You" magazine (May 2008 edition) under the "Tips & Tricks" section. If setpath.sh is the script file containing the command

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/kailashs/bin/

then for this to take effect in the parent shell use the following command

root-bash# source setpath.sh

The source command will read and execute commands from the file and return. All the commands executed now will affect the parent shell.

Friday, June 13, 2008

Hello World and the story behind

I have a better reason for the above title than the fact that this is indeed my first posting on this blog. I was trying to get my makefile(s) that were developed for Windows (nmake) to work under Linux. When I tried to link all the objects compiled using gcc (using -c option) I was faced with the following error.

ld: warning: cannot find entry symbol _start; defaulting to 0x0804844c

The first hit on Google was this very interesting teaching material by a professor in a Brazilian University that reveals the hidden behind the scenes of the Hello World saga. (http://www.lisha.ufsc.br/~guto/teaching/os/exercise/hello.html). Check it out ...