SX Specific IR
to RS232 routine
for Sony and the code for 4MHz in PIC compatibility mode
written with CC5XFree follows. see if u can figure it :-)
Rewritten by James Newton for the SX: UNTESTED!!!
//=============cut--here=================================
/*
* IR reception
* 05/Sep/1999 JLS & CAE
* jls at certi.ufsc.br
* cae at certi.ufsc.br
* CC5xFree v3.0E (www.bknd.com)
* james at sxlist.com
* use CC1B for SX (LST)
*/
/*
Sony Data format: 12 bits
Bit zero:
400
+--+ +...
| | |
+ +---+
800
Bit one:
400
+--+ +...
| | |
+ +------+
1400
Frame:
400 400
--+ +--+ +--+ +--+
| | | | | | |
+---2600---+ +---+ +------+ +...
800 1400
Decoding algorithm:
- Detect 2600us pulse,
- measure next high pulse as P1 (400us)
- measure next low pulse as P2 (800/1400us)
- store min(P1)
- store max(P2)
After all measurements:
- calculate mean = (max-min)/2 + min
- For all (P1,P2) measured:
. Add P1+P2=P3
. If P3< mean => bit is zero
. If P3>=mean => bit is one
Measures with Timer0 & Prescaler:16
2600us = 162
1400us = 87
800us = 50
400us = 25
400+800 = 25+50 = 75
400+1400 = 25+87 = 112
mean ~= (112-75)/2+75 = 18+75 = 93
*/
#define _sx28_
#include <sx28.h>
#ifdef _12C508_
bit _TxOUT @ GP0;
bit RxD_pin @ GP1;
bit IR_input @ GP2;
#else
#define RP0 STATUS.5
#pragma update_RP 0 /* OFF */
#define DEF_TRISA 0
#define DEF_TRISB 6
bit Rele @ PORTA.1;
bit IR_input @ PORTB.1;
bit RxD_pin @ PORTB.2;
bit _TxOUT @ PORTB.3;
bit LED @ PORTB.4;
#endif
#ifdef _sx28_
unsigned char x,y;
bank0 unsigned char r[4];
bank0 unsigned char med,min,max,rxBuf;
bank1 unsigned char buff[16];
bank2 unsigned char buff2[16];
#else
unsigned char x,y,med,min,max,rxBuf;
unsigned char r[4];
unsigned char buff[16];
unsigned char buff2[16];
#endif
void TxSerial (unsigned char txBuf);
/*--------------------------------------------------------------------------*/
void TxEnter (void) {
/*--------------------------------------------------------------------------*/
TxSerial(0xD);
TxSerial(0xA);
}
/*--------------------------------------------------------------------------*/
void TxHexAscii (unsigned char in) {
/*--------------------------------------------------------------------------*/
unsigned char Hex;
Hex = swap(in); // upper nibble
Hex &= 0x0F;
if (Hex<10) Hex += 0x30;
else Hex += 0x37;
TxSerial(Hex);
Hex = in & 0x0F;
if (Hex<0x0A) Hex += 0x30;
else Hex += 0x37;
TxSerial(Hex);
}
/*--------------------------------------------------------------------------*/
void Delay_uSeg (unsigned char timeout) {
/*--------------------------------------------------------------------------*/
// delay = 3*timeout + 7uS (including call and return)
while (1) {
timeout--;
if (timeout==0) {
nop();
nop();
return;
}
}
}
/*--------------------------------------------------------------------------*/
void TxSerial (unsigned char txBuf) {
/*--------------------------------------------------------------------------*/
/*
;---------------------------------------------------------------------------*
; Transmit 1 start bit Lo, 8 data bits and 1 stop bit Hi at 9600 bps
; No Parity
; Byte time = 1.040 mS
; Bit time = 104 uS (0.16% erro w/4.00 Mhz Internal RC)
; Input : W = byte to be transmitted
; Output: byte transmitted by serial pin
;---------------------------------------------------------------------------*
*/
char idx;
while (1)
{
Carry = 0; // start bit
for (idx=10; idx; idx--) // 3us
{
_TxOUT = Carry; // 4us
Delay_uSeg(28); // 91us (28*3+7)
Carry = 1; // 1us
txBuf = rr(txBuf); // 1us
nop(); // 1us
} // 3us
return;
}
}
/*--------------------------------------------------------------------------*/
void RxSerial (void) {
/*--------------------------------------------------------------------------*/
/*
;---------------------------------------------------------------------------*
; Receives 1 start bit Lo, 8 data bits and 1 stop bit Hi at 9600 bps
; No Parity
; Byte time = 1.040 mS
; Bit time = 104 uS (0.16% erro w/4.00 Mhz Internal RC)
;
; False start bit check
;
; Start bit hunting timeout = 4*1.283ms
;
; Input : none
; Output : Carry = 1 => success
; rxBuf = input byte
; Carry = 0 => error (timeout or stop bit=0)
;---------------------------------------------------------------------------*
*/
char idx;
rxBuf = 4; // 5.135 ms timeout
idx = 0;
while (1)
{
while (RxD_pin) // input "high"
{
if ((-- idx)==0)
{
if ((-- rxBuf)==0)
{
Carry = 0;
return;
}
}
}
Delay_uSeg(14); // 1/2 bit delay (14*3+7)
if (RxD_pin)
continue; // false start bit detection
rxBuf = 0x80; // 8 bits counter and reception buffer
nop();
nop(); // timming adjustment
do
{
Delay_uSeg(30); // (30*3+7)us
Carry = RxD_pin; // bit read
rxBuf = rr(rxBuf); // store and count
}
while (Carry==0);
Delay_uSeg(30); // 1 bit delay
nop(); // timming adjustment
Carry = RxD_pin; // stop bit read
return; // 100 us availiable
}
}
/*--------------------------------------------------------------------------*/
void main (void) {
/*--------------------------------------------------------------------------*/
#ifdef _12C508_
// OSCCAL = W; // OscCal Value - OTP part
OSCCAL = 0xB0; // OscCal Value - Windowed part
GPIO = 0x00;
TRIS = 0x08; // GP3 input
#endif
#ifdef _sx28_
#pragma config &= 0b11010011 // reg 1 = RTCC, no int on RTCC, RTCC internal, prescale, 1:16
PORTA = 0;
PORTB = 0;
DDRA = DEF_TRISA;
DDRA = DEF_TRISB;
PA0 = 0;
PA1 = 0;
PA2 = 0;
#endif
#ifdef _16f84_
INTCON = 0; // no interrupts
PCLATH = 0; // bank 0
PORTA = 0;
PORTB = 0;
TRISA = DEF_TRISA;
TRISB = DEF_TRISB;
RP0 = 1; // RAM bank 1
RP0 = 0; // RAM bank 0
#endif
while (1)
{
/* set vars to start */
min = 255; // min period
max = 0; // max period
y = 0; // pointer to buffer
x = 12; // only 12 bits
/* start bit management */
while (IR_input==1); // wait for 0
/* 2600us start bit */
while (IR_input==0); // wait for 1
TMR0 = 0; // start counter
do
{
// buff[y] = 0;
// buff2[y] = 0;
/* measure high pulse */
while (TMR0==0); // wait TMR0 advance
while (IR_input==1) // wait for 0
{
if (TMR0==0) // timer overflow (4096us) ?
goto frame_end ; // yes, exit
}
buff[y] = TMR0; // store period
med = TMR0; // save high period
TMR0 = 0; // start counter
/* measure low pulse */
while (TMR0==0); // wait TMR0 advance
while (IR_input==0); // wait for 1
buff2[y] = TMR0; // store period
med += TMR0; // total period
TMR0 = 0; // start counter
if (med>=max) max = med; // find max
if (med<min) min = med; // find min
y++; // bump pointer
x--; // dec max bits
}
while (x);
frame_end:
LED = 1;
med = max - min;
med /= 2;
med += min;
r[0] = 0;
r[1] = 0;
r[2] = 0;
r[3] = 0;
x = y; //save the size
do
{
Carry = 0;
r[3] = rl(r[3]);
r[2] = rl(r[2]);
r[1] = rl(r[1]);
r[0] = rl(r[0]);
y--;
max = buff[y];
max += buff2[y];
if (max>=med) r[3]++;
} while (y);
/* now r[0],r[1],r[2], r[3] has the frame */
/* Tx the periods and the encoded word */
TxHexAscii(x*2); //size
TxSerial(0x20);
TxHexAscii(med);
TxEnter();
for(y=0;y<x; y++) {
TxHexAscii(buff[y]);
TxHexAscii(buff2[y]);
TxSerial(0x20);
}
TxEnter();
TxHexAscii(r[0]);
TxHexAscii(r[1]);
TxHexAscii(r[2]);
TxHexAscii(r[3]);
TxEnter();
LED = 0;
}
}