rc5 H
rc5 H
rc5 H
****************************************************************
*
*
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)
*/
/
*************************************************************************
****/
(!(FALSE))
(pin)
/
*************************************************************************
****/
/* 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
11
12
13
/* RC5 masks */
#define RC5_MASK_CMD
#define RC5_MASK_DEVADDR
0x003F
0x001F
/* RC5
static
static
static
/
*************************************************************************
****/
/* 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.
*/
/*
*/
/*
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))
{
/* 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
{
}
}
/* 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 */