Code Snippets

Universal InfraRed remote pass-thru

Kenny Millar March 22, 2013 Coded in C for the Microchip PIC18
#define MAX_IR_INDEX 64
#define ESCAPE_COUNT 0x2200ul /* Could be reduced?*/

#pragma udata ircounts
unsigned int lcounts[MAX_IR_INDEX];
unsigned int hcounts[MAX_IR_INDEX];

#pragma	interrupt high_isr /*=section(".tmpdata")*/

void high_isr(void) {

	unsigned int l;
	unsigned int c;
	unsigned char th, tl;

	l = 0;
	TMR1H = 0; // Always write H before L
	TMR1L = 0;

	// Check that this is the INT0 interrupt
	// IRRX is int0
	if(INTCONbits.INT0IF)
	{
		// Disable the interrupt source
		INTCONbits.INT0IE = 0;

		// the code in the while needs to be balanced so that the ==0 and ==1 bits are the size number of cycles.
		while(lindex < MAX_IR_INDEX)
		{

			while(PORTBbits.RB0 == 0)
			{
				l++;
				if(l == ESCAPE_COUNT)
				{
					lcounts[lindex] = 0xffff;
					goto done;
				}
			}

			tl = TMR1L;
			th = TMR1H; // << 8 ;// Always read L before H
			lcounts[lindex++] = th * 256 + tl;

			l = 0;
			TMR1H = 0; // Always right H before L
			TMR1L = 0;
			while(PORTBbits.RB0 == 1)
			{
				l++;
				if(l == ESCAPE_COUNT)
				{
					hcounts[hindex] = 0xffff;
					goto done;
				}
			}

			tl = TMR1L;
			th = TMR1H; //<< 8 ;// Always read L before H
			hcounts[hindex++] = th * 256 + tl;

			l = 0;
			TMR1H = 0; // Always write H before L
			TMR1L = 0;

		}
	}

done:
	codeReady = 1;

	// reset interrupt status bit
	//INTCONbits.INT0IE = 1;
	//INTCONbits.INT0IF = 0;
	return;
}

void zeroIR() {
	unsigned char c;

	// Initialize the IR Count holders
	lindex = 0;
	hindex = 0;

	for(c = 0; c < MAX_IR_INDEX; c++)
	{
		lcounts[c] = 0xdead;
	}

	codeReady = 0;

	// reset interrupt status bit
	INTCONbits.INT0IE = 1;
	INTCONbits.INT0IF = 0;

}

void transmitIR(void) {

	unsigned char c;

	// First check that the code is valid by examining the first LCOUNT
	// if it is less than our defined threshold we will not transmit it.
	// The first lcount holds the low-going preamble, it must be a minimum length or it does not
	// represent a valid IR Transmission preamble.

	if(lcounts[0] < PREAMBLE_MINIMUM)
	{
		return;
	}
	
	sprintf(serTX, (CAST) "$%c%cIC%d,", id1, id2, lindex);
	rs485_puts(serTX);

	for(c = 0; c < lindex; c++)
	{
		sprintf(serTX, (CAST) "%04x,%04x, ", lcounts[c], hcounts[c]);
		rs485_puts(serTX);
	}

	sprintf(serTX, (CAST) "\n");
	rs485_puts(serTX);

}