0% found this document useful (0 votes)
94 views

rc5 H

This document contains header information and configuration details for an RC5 decoder driver. It defines macros, constants, and functions for decoding RC5 infrared signals. The driver handles receiving RC5 codes via an interrupt service routine that decodes the signal based on bit times. It provides functions to check for a new code, read the code value, and increment a timeout counter to resynchronize decoding.

Uploaded by

Gustavo Circelli
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
94 views

rc5 H

This document contains header information and configuration details for an RC5 decoder driver. It defines macros, constants, and functions for decoding RC5 infrared signals. The driver handles receiving RC5 codes via an interrupt service routine that decodes the signal based on bit times. It provides functions to check for a new code, read the code value, and increment a timeout counter to resynchronize decoding.

Uploaded by

Gustavo Circelli
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 11

/*** FILEHEADER

****************************************************************
*
*
FILENAME:
rc5.h
*
DATE:
26.07.2011
*
AUTHOR:
Christian Stadler
*
*
DESCRIPTION: RC5 decoder driver
*
*************************************************************************
*****/
/*** HISTORY OF CHANGE
*********************************************************
*
*
$Log: /pic/_drv/rc5.h $
*
* 8
19.10.11 21:32 Stadler
* - added Microchip C18 compiler support
*
* 7
16.10.11 20:18 Stadler
* - code cleanup
*
* 6
3.08.11 17:48 Stadler
* - made min/max bit times configurable by user
*
* 5
27.07.11 17:24 Stadler
* - updated comments
*
* 4
26.07.11 23:49 Stadler
* - updated timeout handling
*
* 3
26.07.11 22:21 Stadler
* - added interfaces to get RC5 command and RC5 device address
* - made timer ticks and timer get function configurable by user
* - documented the code
*
* 2
26.07.11 20:47 Stadler
* - only report new RC5 code received if RC5 code changed with respect
to
* previous received code
*
*************************************************************************
*****/
/* unified data type definitions */
#include "types.h"
/
*************************************************************************
****/
/* DRIVER CONFIGURATION
*/

/* ====================
*/
/*
*/
/* The following defines need to be defined by the user.
*/
/*
*/
/* The following items to be configured:
*/
/* - RC5_DATA_PIN:
RC5 input pin
*/
/* - RC5_TICKS_PER_MS: RC5 timer ticks per millisecond
*/
/* - RC5_GetTimer():
Macro to get RC5 timer value
*/
/*
*/
/* The following configuration items are optional:
*/
/* - RC5_HALF_BIT_TIME_MIN:
minimum half bit time in ticks per
milliseconds */
/*
default: (((RC5_TICKS_PER_MS) * 700) / 1000)
*/
/* - RC5_HALF_BIT_TIME_MAX: maximum half bit time in ticks per
milliseconds */
/*
default: (((RC5_TICKS_PER_MS) * 1100) /
1000)
*/
/
*************************************************************************
****/

/* === C18 compiler specific


=============================================== */
/* Note: This driver was written for CCS C compiler. The following macos
*/
/*
are required to compile this driver fo CCS C compiler.
*/
#if defined(__18CXX)
/* For C18 compiler the pin configuration must be provided by a config
*/
/* header file. This header file must define the #define mentioned in the
*/
/* driver configuration information above.
*/
#include "config.h"
#ifndef FALSE
#define FALSE
#endif
#ifndef TRUE
#define TRUE
#endif

(!(FALSE))

/* bit access marcos */


#define bit_set(value, bitpos)
(bitpos)))
#define bit_clear(value, bitpos)
(bitpos))))
#define bit_test(value, bitpos)
0)

((value) |= ((uint16)1 <<


((value) &= (~((uint16)1 <<
((((value) >> (bitpos)) & 0x1) !=

/* interrupt enable/disable macros */


#define GLOBAL
0
/* dummy value which would be
defined for CCS C */
#define disable_interrupts(x)
INTCONbits.GIE = 0
#define enable_interrupts(x)
INTCONbits.GIE = 1
/* input pin macro */
#define input(pin)

(pin)

#endif /* #if defined(__18CXX) */


/* === End C18 compiler specific
=========================================== */

/* pin where RC5 signal is connected needs to be configured in


RC5_DATA_PIN */
#ifndef RC5_DATA_PIN
#error RC5_DATA_PIN not defined!
#endif
/* number of ticks per ms which are generated by the timer which is used
*/
/* for RC5 decoding, needs to be defined in RC5_TICKS_PER_MS */
#ifndef RC5_TICKS_PER_MS
#error RC5_TICKS_PER_MS not defined!
#endif
/* function to get current timer value needs to be configured in
RC5_GetTimer() */
#ifndef RC5_GetTimer()
#error RC5_GetTimer() not defined!
#endif

/
*************************************************************************
****/
/* DRIVER INTERNAL DEFINES
*/
/* =======================
*/
/*
*/
/* Do not change any of this defines.
*/

/
*************************************************************************
****/
#define RC5_GetPin()

input(RC5_DATA_PIN)

/* min/max value for a half bit time (min = 700us, max = 1100us) */
#ifndef RC5_HALF_BIT_TIME_MIN
#define RC5_HALF_BIT_TIME_MIN
(((RC5_TICKS_PER_MS) * 700U) / 1000U)
#endif
#ifndef RC5_HALF_BIT_TIME_MAX
#define RC5_HALF_BIT_TIME_MAX
(((RC5_TICKS_PER_MS) * 1100U) / 1000U)
#endif
/* timeout time after last RC5 interrupt (3ms because maximum time
between */
/* two edges in a RC5 signal is around 1.8ms */
#define RC5_TIMEOUT
((RC5_TICKS_PER_MS) * 3)
/* decoding states: */
/* RC5_BIT_STATE_HALF: decoding
/* RC5_BIT_STATE_FULL: full bit
#define RC5_BIT_STATE_HALF
#define RC5_BIT_STATE_FULL

done until half of a bit */


has been decoded */
0
1

/* RC5 bit positions */


#define RC5_TOGGLE_BIT
#define RC5_START_BIT_2
#define RC5_START_BIT_1

11
12
13

/* RC5 masks */
#define RC5_MASK_CMD
#define RC5_MASK_DEVADDR

0x003F
0x001F

/* RC5
static
static
static

decoding status variables */


uint16 rc5_code = 0;
uint8 rc5_timeout_timer = 0; /* timeout timer, unit [ms] */
bool rc5_ready = FALSE;

/
*************************************************************************
****/
/* RC5_GetToggleBit
*/
/*
*/
/* Returns the status of the toggle bit.
*/
/*
*/
/* Return: TRUE if toggle bit is set, FALSE otherwise.
*/

/
*************************************************************************
****/
#define RC5_GetToggleBit(rc5code)
bit_test(rc5code, RC5_TOGGLE_BIT)
/
*************************************************************************
****/
/* RC5_GetDeviceAddr
*/
/*
*/
/* Gets the RC5 device address from a full RC5 code.
*/
/*
*/
/* Return: RC5 device address.
*/
/
*************************************************************************
****/
#define RC5_GetDeviceAddr(rc5code)
((rc5code >> 6) &
RC5_MASK_DEVADDR)
/
*************************************************************************
****/
/* RC5_GetCmd
*/
/*
*/
/* Gets the RC5 command from a full RC5 code.
*/
/*
*/
/* Return: RC5 command.
*/
/
*************************************************************************
****/
#define RC5_GetCmd(rc5code)
(rc5code & RC5_MASK_CMD)
/
*************************************************************************
****/
/* RC5_CodeReady
*/
/*
*/
/* Returns status if a new RC5 code has been received.
*/
/*
*/

/* Return: TRUE if new RC5 code is available, FALSE otherwise.


*/
/
*************************************************************************
****/
bool RC5_CodeReady(void)
{
bool rc;
rc = rc5_ready;
rc5_ready = FALSE;
return (rc);
}
/
*************************************************************************
****/
/* RC5_GetCode
*/
/*
*/
/* Returns received RC5 code. Use RC5_CodeReady() function first to see
if
*/
/* a valid code is available.
*/
/*
*/
/* Return: rc5_code
RC5 code.
*/
/
*************************************************************************
****/
uint16 RC5_GetCode(void)
{
return (rc5_code);
}
/
*************************************************************************
****/
/* RC5_TimeoutIncrement
*/
/*
*/
/* Function increments timeout counter to detect a RC5 timeout and
*/
/* resynchronize the RC5 decoding state machine.
*/
/* Functions shall be called cyclically in main loop or in a timer
*/
/* interrupt overflow routine which is called at around every 1ms.
*/
/*
*/
/* NOTE: Decoding will also work without calling this function, but
*/

/*
it could happen that RC5 codes are sometimes not getting
recognized */
/*
because of decoding state machine stucks due to erroneous RC5
*/
/*
signal.
*/
/*
*/
/* Return: none
*/
/
*************************************************************************
****/
void RC5_TimeoutIncrement(void)
{
static uint8 old_timer;
uint8 timer;
/* get current timer value */
timer = RC5_GetTimer();
/* disable interrupts since rc5_timeout_timer is also read and
written to in ISR */
disable_interrupts(GLOBAL);
if (rc5_timeout_timer < RC5_TIMEOUT)
{
rc5_timeout_timer += (timer - old_timer);
}
/* re-enable interrupts again */
enable_interrupts(GLOBAL);
old_timer = timer;
}
/
*************************************************************************
****/
/* RC5_InterruptHandler
*/
/*
*/
/* Interrupt handler for RC5 decoding. This function must be called by an
*/
/* "Interrupt-On-Change" interrupt service routine.
*/
/*
*/
/* Return: none
*/
/
*************************************************************************
****/
void RC5_InterruptHandler(void)

{
static uint8 rc5_timer = 0;
static uint8 rc5_pos = 13;
static uint16 rc5_code_tmp = 0;
static bool rc5_wait_start = TRUE;
static bool rc5_bit_state = RC5_BIT_STATE_FULL;
static bool rc5_pin_old = TRUE;
bool rc5_rx_last = FALSE;
bool rc5_pin;
uint8 tdiff;
/* get RC5 pin status */
rc5_pin = RC5_GetPin();
/* calculate time difference to last interrupt call */
tdiff = RC5_GetTimer() - rc5_timer;
/* start the RC5 timer again */
rc5_timer = RC5_GetTimer();
/* if timeout counter has expired, i.e. no RC5 signal was received
for some */
/* time, reset the state machine */
if (rc5_timeout_timer >= RC5_TIMEOUT)
{
rc5_wait_start = TRUE;
}
/* reset the timeout counter */
rc5_timeout_timer = 0;
if (rc5_wait_start != FALSE)
{
/* 1st half of start bit received */
if ((rc5_pin_old != FALSE) && (rc5_pin == FALSE))
{
/* leave wait state */
rc5_wait_start = FALSE;
/* 1st half of bit has been received */
rc5_bit_state = RC5_BIT_STATE_HALF;
/* 1st start bit is at position 13 */
rc5_pos = 13;
/* reset RC5 code */
rc5_code_tmp = 0;
}
}
else
{
/* rising edge of RC5 signal */
if ((rc5_pin_old == FALSE) && (rc5_pin != FALSE))
{
/* one half of the bit has already been received last time
and now */
/* we got the 2nd half of the bit */
if ((rc5_bit_state == RC5_BIT_STATE_HALF) && (tdiff >=
RC5_HALF_BIT_TIME_MIN) && (tdiff <= RC5_HALF_BIT_TIME_MAX))
{

/* logical 1 has been received => add to rc5 code */


bit_set(rc5_code_tmp, rc5_pos);
/* decrement bit position */
if (rc5_pos > 0)
{
rc5_pos--;
}
else
{
rc5_rx_last = TRUE;
}
/* we are at the end of a bit */
rc5_bit_state = RC5_BIT_STATE_FULL;
}
/* one half of the bit has already been received last time
and now */

/* we got the 2nd half of the bit and also the next half of
the following bit */
else if ((rc5_bit_state == RC5_BIT_STATE_HALF) && (tdiff >=
(2*RC5_HALF_BIT_TIME_MIN)) && (tdiff <= (2*RC5_HALF_BIT_TIME_MAX)))
{
/* logical 1 has been received => add to rc5 code */
bit_set(rc5_code_tmp, rc5_pos);
/* decrement bit position */
if (rc5_pos > 0)
{
rc5_pos--;
}
/* not done in else part because there will be no
additional interrupt for the last bit in this case */
if (rc5_pos == 0)
{
rc5_rx_last = TRUE;
}
/* we are at the half of the next bit */
rc5_bit_state = RC5_BIT_STATE_HALF;

1st */
half */

}
/* previously, we have sampled a full bit, since now only the
/* half of the next bit is available now, wait until the next

else if ((rc5_bit_state == RC5_BIT_STATE_FULL) && (tdiff >=


RC5_HALF_BIT_TIME_MIN) && (tdiff <= RC5_HALF_BIT_TIME_MAX))
{
/* we are at the half of the next bit */
rc5_bit_state = RC5_BIT_STATE_HALF;
/* we will not get an interrupt for the last half bit, so
we are finished here */
if (rc5_pos == 0)
{
rc5_rx_last = TRUE;
}
}

/* something wrong with the timing, wait for another start


condition */

else
{

/* wait for start condition */


rc5_wait_start = TRUE;

}
}
/* falling edge of RC5 signal */
if ((rc5_pin_old != FALSE) && (rc5_pin == FALSE))
{
/* one half of the bit has already been received last time
and now */
/* we got the 2nd half of the bit */
if ((rc5_bit_state == RC5_BIT_STATE_HALF) && (tdiff >=
RC5_HALF_BIT_TIME_MIN) && (tdiff <= RC5_HALF_BIT_TIME_MAX))
{
/* logical 0 has been received => add to rc5 code */
bit_clear(rc5_code_tmp, rc5_pos);
/* decrement bit position */
if (rc5_pos > 0)
{
rc5_pos--;
}
else
{
rc5_rx_last = TRUE;
}
/* we are at the end of a bit */
rc5_bit_state = RC5_BIT_STATE_FULL;
}
/* one half of the bit has already been received last time
and now */
/* we got the 2nd half of the bit and also the next half of
the following bit */
else if ((rc5_bit_state == RC5_BIT_STATE_HALF) && (tdiff >=
(2*RC5_HALF_BIT_TIME_MIN)) && (tdiff <= (2*RC5_HALF_BIT_TIME_MAX)))
{
/* logical 0 has been received => add to rc5 code */
bit_clear(rc5_code_tmp, rc5_pos);
/* decrement bit position */
if (rc5_pos > 0)
{
rc5_pos--;
}
else
{
rc5_rx_last = TRUE;
}
/* we are at the half of the next bit */
rc5_bit_state = RC5_BIT_STATE_HALF;
}
/* previously, we have sampled a full bit, since now only the
1st */
/* half of the next bit is available now, wait until the next
half */

else if ((rc5_bit_state == RC5_BIT_STATE_FULL) && (tdiff >=


RC5_HALF_BIT_TIME_MIN) && (tdiff <= RC5_HALF_BIT_TIME_MAX))
{
/* we are at the half of the next bit */
rc5_bit_state = RC5_BIT_STATE_HALF;
}
/* something wrong with the timing, wait for another start
condition */
else
{
/* wait for start condition */
rc5_wait_start = TRUE;
}
}
}
/* save current pin state for edge detection */
rc5_pin_old = rc5_pin;
/* the first two bits are the start bits and habe to be 1, else
something went */
/* wrong and hence wait for another start condition */
if ( ((rc5_pos == 12) && !bit_test(rc5_code_tmp, RC5_START_BIT_1)) ||
((rc5_pos == 11) && !bit_test(rc5_code_tmp, RC5_START_BIT_2)) )
{
rc5_wait_start = TRUE;
}
/* if all RC5 bits have been received */
if ((rc5_pos == 0) && (rc5_rx_last != FALSE))
{
/* if code is different from last received code, set flag to
indicate */
/* that a new code has been received */
if (rc5_code != rc5_code_tmp)
{
rc5_code = rc5_code_tmp;
rc5_ready = TRUE;
}
rc5_wait_start = TRUE;
}
}

You might also like