Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 837 → Rev 838

/Servo-Controlled IR-Transmitter/Software/irsndconfig.h
New file
0,0 → 1,85
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* irsndconfig.h
*
* Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de
*
* $Id: irsndconfig.h,v 1.15 2010/11/10 08:01:46 fm Exp $
*
* ATMEGA88 @ 8 MHz
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Change F_INTERRUPTS if you change the number of interrupts per second, F_INTERRUPTS should be in the range from 10000 to 15000
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#ifndef F_INTERRUPTS
#define F_INTERRUPTS 20000 // interrupts per second
#endif
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Change settings from 1 to 0 if you want to disable one or more encoders.
* This saves program space.
* 1 enable decoder
* 0 disable decoder
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
// Protocol Enable Remarks F_INTERRUPTS Program Space
#define IRSND_SUPPORT_SIRCS_PROTOCOL 1 // Sony SIRCS >= 10000 uses ~150 bytes
#define IRSND_SUPPORT_NEC_PROTOCOL 1 // NEC + APPLE >= 10000 uses ~100 bytes
#define IRSND_SUPPORT_SAMSUNG_PROTOCOL 1 // Samsung + Samsung32 >= 10000 uses ~300 bytes
#define IRSND_SUPPORT_MATSUSHITA_PROTOCOL 0 // Matsushita >= 10000 uses ~200 bytes
#define IRSND_SUPPORT_KASEIKYO_PROTOCOL 1 // Kaseikyo >= 10000 uses ~150 bytes
#define IRSND_SUPPORT_RC5_PROTOCOL 1 // RC5 >= 10000 uses ~150 bytes
#define IRSND_SUPPORT_DENON_PROTOCOL 0 // DENON >= 10000 uses ~200 bytes
#define IRSND_SUPPORT_JVC_PROTOCOL 1 // JVC >= 10000 uses ~150 bytes
#define IRSND_SUPPORT_RC6_PROTOCOL 0 // RC6 NOT SUPPORTED YET! DON'T CHANGE!
#define IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL 0 // Bang&Olufsen >= 10000 uses ~250 bytes
#define IRSND_SUPPORT_GRUNDIG_PROTOCOL 1 // Grundig >= 10000 uses ~300 bytes
#define IRSND_SUPPORT_NOKIA_PROTOCOL 1 // Nokia >= 10000 uses ~400 bytes
#define IRSND_SUPPORT_NUBERT_PROTOCOL 0 // NUBERT >= 10000 uses ~100 bytes
#define IRSND_SUPPORT_NIKON_PROTOCOL 1 // NIKON >= 10000 uses ~150 bytes
#define IRSND_SUPPORT_FDC_PROTOCOL 0 // FDC IR keyboard >= 10000 (better 15000) uses ~150 bytes
#define IRSND_SUPPORT_RCCAR_PROTOCOL 0 // RC CAR >= 10000 (better 15000) uses ~150 bytes
#define IRSND_SUPPORT_SIEMENS_PROTOCOL 0 // Siemens, Gigaset >= 15000 uses ~150 bytes
#define IRSND_SUPPORT_RECS80_PROTOCOL 1 // RECS80 >= 20000 uses ~100 bytes
#define IRSND_SUPPORT_RECS80EXT_PROTOCOL 1 // RECS80EXT >= 20000 uses ~100 bytes
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Change hardware pin here:
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega644P__)
#define IRSND_PORT PORTD // port D
#define IRSND_DDR DDRD // ddr D
#define IRSND_BIT 7 // OC2A
#else
#define IRSND_PORT PORTB // port B
#define IRSND_DDR DDRB // ddr B
#define IRSND_BIT 3 // OC2A
#endif // __AVR...
 
 
#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 && F_INTERRUPTS < 15000
#warning F_INTERRUPTS too low, SIEMENS protocol disabled (should be at least 15000)
#undef IRSND_SUPPORT_SIEMENS_PROTOCOL
#define IRSND_SUPPORT_SIEMENS_PROTOCOL 0 // DO NOT CHANGE! F_INTERRUPTS too low!
#endif
 
#if IRSND_SUPPORT_RECS80_PROTOCOL == 1 && F_INTERRUPTS < 20000
#warning F_INTERRUPTS too low, RECS80 protocol disabled (should be at least 20000)
#undef IRSND_SUPPORT_RECS80_PROTOCOL
#define IRSND_SUPPORT_RECS80_PROTOCOL 0
#endif
 
#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1 && F_INTERRUPTS < 20000
#warning F_INTERRUPTS too low, RECS80EXT protocol disabled (should be at least 20000)
#undef IRSND_SUPPORT_RECS80EXT_PROTOCOL
#define IRSND_SUPPORT_RECS80EXT_PROTOCOL 0
#endif
/Servo-Controlled IR-Transmitter/Software/irmp.h
New file
0,0 → 1,415
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* irmp.h
*
* Copyright (c) 2009-2010 Frank Meyer - frank(at)fli4l.de
*
* $Id: irmp.h,v 1.44 2010/11/09 19:18:32 fm Exp $
*
* ATMEGA88 @ 8 MHz
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
#ifndef _WC_IRMP_H_
#define _WC_IRMP_H_
 
#ifdef __cplusplus
extern "C"
{
#endif
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* timing constants:
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#define IRMP_TIMEOUT_TIME 16500.0e-6 // timeout after 16.5 ms darkness
#define IRMP_TIMEOUT_TIME_MS 16500L // timeout after 16.5 ms darkness
 
#if IRMP_SUPPORT_NIKON_PROTOCOL == 1
#define IRMP_TIMEOUT_NIKON_TIME 29500.0e-6 // 2nd timeout after 29.5 ms darkness (only for NIKON!)
#define IRMP_TIMEOUT_NIKON_TIME_MS 29500L // 2nd timeout after 29.5 ms darkness
typedef uint16_t PAUSE_LEN;
#define IRMP_TIMEOUT_NIKON_LEN (PAUSE_LEN)(F_INTERRUPTS * IRMP_TIMEOUT_NIKON_TIME + 0.5)
#else
#if (F_INTERRUPTS * IRMP_TIMEOUT_TIME_MS) / 1000000 >= 254
typedef uint16_t PAUSE_LEN;
#else
typedef uint8_t PAUSE_LEN;
#endif
#endif
 
#define IRMP_TIMEOUT_LEN (PAUSE_LEN)(F_INTERRUPTS * IRMP_TIMEOUT_TIME + 0.5)
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* IR protocols
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#define IRMP_SIRCS_PROTOCOL 1 // Sony
#define IRMP_NEC_PROTOCOL 2 // NEC, Pioneer, JVC, Toshiba, NoName etc.
#define IRMP_SAMSUNG_PROTOCOL 3 // Samsung
#define IRMP_MATSUSHITA_PROTOCOL 4 // Matsushita
#define IRMP_KASEIKYO_PROTOCOL 5 // Kaseikyo (Panasonic etc)
#define IRMP_RECS80_PROTOCOL 6 // Philips, Thomson, Nordmende, Telefunken, Saba
#define IRMP_RC5_PROTOCOL 7 // Philips etc
#define IRMP_DENON_PROTOCOL 8 // Denon
#define IRMP_RC6_PROTOCOL 9 // Philips etc
#define IRMP_SAMSUNG32_PROTOCOL 10 // Samsung32: no sync pulse at bit 16, length 32 instead of 37
#define IRMP_APPLE_PROTOCOL 11 // Apple, very similar to NEC
#define IRMP_RECS80EXT_PROTOCOL 12 // Philips, Technisat, Thomson, Nordmende, Telefunken, Saba
#define IRMP_NUBERT_PROTOCOL 13 // Nubert
#define IRMP_BANG_OLUFSEN_PROTOCOL 14 // Bang & Olufsen
#define IRMP_GRUNDIG_PROTOCOL 15 // Grundig
#define IRMP_NOKIA_PROTOCOL 16 // Nokia
#define IRMP_SIEMENS_PROTOCOL 17 // Siemens, e.g. Gigaset
#define IRMP_FDC_PROTOCOL 18 // FDC keyboard
#define IRMP_RCCAR_PROTOCOL 19 // RC Car
#define IRMP_JVC_PROTOCOL 20 // JVC
#define IRMP_RC6A_PROTOCOL 21 // RC6A, e.g. Kathrein, XBOX
#define IRMP_NIKON_PROTOCOL 22 // Nikon
 
// some flags of struct IRMP_PARAMETER:
#define IRMP_PARAM_FLAG_IS_MANCHESTER 0x01
#define IRMP_PARAM_FLAG_1ST_PULSE_IS_1 0x02
 
#define SIRCS_START_BIT_PULSE_TIME 2400.0e-6 // 2400 usec pulse
#define SIRCS_START_BIT_PAUSE_TIME 600.0e-6 // 600 usec pause
#define SIRCS_1_PULSE_TIME 1200.0e-6 // 1200 usec pulse
#define SIRCS_0_PULSE_TIME 600.0e-6 // 600 usec pulse
#define SIRCS_PAUSE_TIME 600.0e-6 // 600 usec pause
#define SIRCS_FRAMES 3 // SIRCS sends each frame 3 times
#define SIRCS_AUTO_REPETITION_PAUSE_TIME 25.0e-3 // auto repetition after 25ms
#define SIRCS_FRAME_REPEAT_PAUSE_TIME 25.0e-3 // frame repeat after 25ms
#define SIRCS_ADDRESS_OFFSET 15 // skip 15 bits
#define SIRCS_ADDRESS_LEN 5 // read up to 5 address bits
#define SIRCS_COMMAND_OFFSET 0 // skip 0 bits
#define SIRCS_COMMAND_LEN 15 // read 12-15 command bits
#define SIRCS_MINIMUM_DATA_LEN 12 // minimum data length
#define SIRCS_COMPLETE_DATA_LEN 20 // complete length - may be up to 20
#define SIRCS_STOP_BIT 0 // has no stop bit
#define SIRCS_LSB 1 // LSB...MSB
#define SIRCS_FLAGS 0 // flags
 
#define NEC_START_BIT_PULSE_TIME 9000.0e-6 // 9000 usec pulse
#define NEC_START_BIT_PAUSE_TIME 4500.0e-6 // 4500 usec pause
#define NEC_REPEAT_START_BIT_PAUSE_TIME 2250.0e-6 // 2250 usec pause
#define NEC_PULSE_TIME 560.0e-6 // 560 usec pulse
#define NEC_1_PAUSE_TIME 1690.0e-6 // 1690 usec pause
#define NEC_0_PAUSE_TIME 560.0e-6 // 560 usec pause
#define NEC_FRAME_REPEAT_PAUSE_TIME 40.0e-3 // frame repeat after 40ms
#define NEC_ADDRESS_OFFSET 0 // skip 0 bits
#define NEC_ADDRESS_LEN 16 // read 16 address bits
#define NEC_COMMAND_OFFSET 16 // skip 16 bits (8 address + 8 /address)
#define NEC_COMMAND_LEN 16 // read 16 bits (8 command + 8 /command)
#define NEC_COMPLETE_DATA_LEN 32 // complete length
#define NEC_STOP_BIT 1 // has stop bit
#define NEC_LSB 1 // LSB...MSB
#define NEC_FLAGS 0 // flags
 
#define SAMSUNG_START_BIT_PULSE_TIME 4500.0e-6 // 4500 usec pulse
#define SAMSUNG_START_BIT_PAUSE_TIME 4500.0e-6 // 4500 usec pause
#define SAMSUNG_PULSE_TIME 550.0e-6 // 550 usec pulse
#define SAMSUNG_1_PAUSE_TIME 1450.0e-6 // 1450 usec pause
#define SAMSUNG_0_PAUSE_TIME 450.0e-6 // 450 usec pause
#define SAMSUNG_FRAME_REPEAT_PAUSE_TIME 45.0e-3 // frame repeat after 45ms
#define SAMSUNG_ADDRESS_OFFSET 0 // skip 0 bits
#define SAMSUNG_ADDRESS_LEN 16 // read 16 address bits
#define SAMSUNG_ID_OFFSET 17 // skip 16 + 1 sync bit
#define SAMSUNG_ID_LEN 4 // read 4 id bits
#define SAMSUNG_COMMAND_OFFSET 21 // skip 16 + 1 sync + 4 data bits
#define SAMSUNG_COMMAND_LEN 16 // read 16 command bits
#define SAMSUNG_COMPLETE_DATA_LEN 37 // complete length
#define SAMSUNG_STOP_BIT 1 // has stop bit
#define SAMSUNG_LSB 1 // LSB...MSB?
#define SAMSUNG_FLAGS 0 // flags
 
#define SAMSUNG32_COMMAND_OFFSET 16 // skip 16 bits
#define SAMSUNG32_COMMAND_LEN 16 // read 16 command bits
#define SAMSUNG32_COMPLETE_DATA_LEN 32 // complete length
#define SAMSUNG32_FRAMES 2 // SAMSUNG32 sends each frame 2 times
#define SAMSUNG32_AUTO_REPETITION_PAUSE_TIME 47.0e-3 // repetition after 47 ms
#define SAMSUNG32_FRAME_REPEAT_PAUSE_TIME 47.0e-3 // frame repeat after 40ms
 
#define MATSUSHITA_START_BIT_PULSE_TIME 3488.0e-6 // 3488 usec pulse
#define MATSUSHITA_START_BIT_PAUSE_TIME 3488.0e-6 // 3488 usec pause
#define MATSUSHITA_PULSE_TIME 872.0e-6 // 872 usec pulse
#define MATSUSHITA_1_PAUSE_TIME 2616.0e-6 // 2616 usec pause
#define MATSUSHITA_0_PAUSE_TIME 872.0e-6 // 872 usec pause
#define MATSUSHITA_FRAME_REPEAT_PAUSE_TIME 45.0e-3 // frame repeat after 45ms
#define MATSUSHITA_ADDRESS_OFFSET 12 // skip 12 bits
#define MATSUSHITA_ADDRESS_LEN 12 // read 12 address bits
#define MATSUSHITA_COMMAND_OFFSET 0 // skip 0 bits
#define MATSUSHITA_COMMAND_LEN 12 // read 12 bits (6 custom + 6 command)
#define MATSUSHITA_COMPLETE_DATA_LEN 24 // complete length
#define MATSUSHITA_STOP_BIT 1 // has stop bit
#define MATSUSHITA_LSB 1 // LSB...MSB?
#define MATSUSHITA_FLAGS 0 // flags
 
#define KASEIKYO_START_BIT_PULSE_TIME 3380.0e-6 // 3380 usec pulse
#define KASEIKYO_START_BIT_PAUSE_TIME 1690.0e-6 // 1690 usec pause
#define KASEIKYO_PULSE_TIME 423.0e-6 // 525 usec pulse
#define KASEIKYO_1_PAUSE_TIME 1269.0e-6 // 525 usec pause
#define KASEIKYO_0_PAUSE_TIME 423.0e-6 // 1690 usec pause
#define KASEIKYO_AUTO_REPETITION_PAUSE_TIME 74.0e-3 // repetition after 74 ms
#define KASEIKYO_FRAME_REPEAT_PAUSE_TIME 74.0e-3 // frame repeat after 74 ms
#define KASEIKYO_ADDRESS_OFFSET 0 // skip 0 bits
#define KASEIKYO_ADDRESS_LEN 16 // read 16 address bits
#define KASEIKYO_COMMAND_OFFSET 28 // skip 28 bits (16 manufacturer & 4 parity & 8 genre)
#define KASEIKYO_COMMAND_LEN 12 // read 12 command bits (10 real command & 2 id)
#define KASEIKYO_COMPLETE_DATA_LEN 48 // complete length
#define KASEIKYO_STOP_BIT 1 // has stop bit
#define KASEIKYO_LSB 1 // LSB...MSB?
#define KASEIKYO_FRAMES 2 // KASEIKYO sends 1st frame 2 times
#define KASEIKYO_FLAGS 0 // flags
 
#define RECS80_START_BIT_PULSE_TIME 158.0e-6 // 158 usec pulse
#define RECS80_START_BIT_PAUSE_TIME 7432.0e-6 // 7432 usec pause
#define RECS80_PULSE_TIME 158.0e-6 // 158 usec pulse
#define RECS80_1_PAUSE_TIME 7432.0e-6 // 7432 usec pause
#define RECS80_0_PAUSE_TIME 4902.0e-6 // 4902 usec pause
#define RECS80_FRAME_REPEAT_PAUSE_TIME 45.0e-3 // frame repeat after 45ms
#define RECS80_ADDRESS_OFFSET 2 // skip 2 bits (2nd start + 1 toggle)
#define RECS80_ADDRESS_LEN 3 // read 3 address bits
#define RECS80_COMMAND_OFFSET 5 // skip 5 bits (2nd start + 1 toggle + 3 address)
#define RECS80_COMMAND_LEN 6 // read 6 command bits
#define RECS80_COMPLETE_DATA_LEN 11 // complete length
#define RECS80_STOP_BIT 1 // has stop bit
#define RECS80_LSB 0 // MSB...LSB
#define RECS80_FLAGS 0 // flags
 
#define RC5_BIT_TIME 889.0e-6 // 889 usec pulse/pause
#define RC5_FRAME_REPEAT_PAUSE_TIME 45.0e-3 // frame repeat after 45ms
#define RC5_ADDRESS_OFFSET 2 // skip 2 bits (2nd start + 1 toggle)
#define RC5_ADDRESS_LEN 5 // read 5 address bits
#define RC5_COMMAND_OFFSET 7 // skip 5 bits (2nd start + 1 toggle + 5 address)
#define RC5_COMMAND_LEN 6 // read 6 command bits
#define RC5_COMPLETE_DATA_LEN 13 // complete length
#define RC5_STOP_BIT 0 // has no stop bit
#define RC5_LSB 0 // MSB...LSB
#define RC5_FLAGS IRMP_PARAM_FLAG_IS_MANCHESTER // flags
 
#define DENON_PULSE_TIME 275.0e-6 // 275 usec pulse
#define DENON_1_PAUSE_TIME 1900.0e-6 // 1900 usec pause
#define DENON_0_PAUSE_TIME 775.0e-6 // 775 usec pause
#define DENON_FRAMES 2 // DENON sends each frame 2 times
#define DENON_AUTO_REPETITION_PAUSE_TIME 65.0e-3 // inverted repetition after 65ms
#define DENON_FRAME_REPEAT_PAUSE_TIME 65.0e-3 // frame repeat after 65ms
#define DENON_ADDRESS_OFFSET 0 // skip 0 bits
#define DENON_ADDRESS_LEN 5 // read 5 address bits
#define DENON_COMMAND_OFFSET 5 // skip 5
#define DENON_COMMAND_LEN 10 // read 10 command bits
#define DENON_COMPLETE_DATA_LEN 15 // complete length
#define DENON_STOP_BIT 1 // has stop bit
#define DENON_LSB 0 // MSB...LSB
#define DENON_FLAGS 0 // flags
 
#define RC6_START_BIT_PULSE_TIME 2666.0e-6 // 2.666 msec pulse
#define RC6_START_BIT_PAUSE_TIME 889.0e-6 // 889 usec pause
#define RC6_TOGGLE_BIT_TIME 889.0e-6 // 889 msec pulse/pause
#define RC6_BIT_TIME 444.0e-6 // 889 usec pulse/pause
#define RC6_FRAME_REPEAT_PAUSE_TIME 45.0e-3 // frame repeat after 45ms
#define RC6_ADDRESS_OFFSET 5 // skip "1" + 3 mode bits + 1 toggle bit
#define RC6_ADDRESS_LEN 8 // read 8 address bits
#define RC6_COMMAND_OFFSET 13 // skip 12 bits ("1" + 3 mode + 1 toggle + 8 address)
#define RC6_COMMAND_LEN 8 // read 8 command bits
#define RC6_COMPLETE_DATA_LEN_SHORT 21 // complete length
#define RC6_COMPLETE_DATA_LEN_LONG 36 // complete length
#define RC6_STOP_BIT 0 // has no stop bit
#define RC6_LSB 0 // MSB...LSB
#define RC6_FLAGS (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1) // flags
 
#define RECS80EXT_START_BIT_PULSE_TIME 158.0e-6 // 158 usec pulse
#define RECS80EXT_START_BIT_PAUSE_TIME 3637.0e-6 // 3637 usec pause
#define RECS80EXT_PULSE_TIME 158.0e-6 // 158 usec pulse
#define RECS80EXT_1_PAUSE_TIME 7432.0e-6 // 7432 usec pause
#define RECS80EXT_0_PAUSE_TIME 4902.0e-6 // 4902 usec pause
#define RECS80EXT_FRAME_REPEAT_PAUSE_TIME 45.0e-3 // frame repeat after 45ms
#define RECS80EXT_ADDRESS_OFFSET 2 // skip 2 bits (2nd start + 1 toggle)
#define RECS80EXT_ADDRESS_LEN 4 // read 3 address bits
#define RECS80EXT_COMMAND_OFFSET 6 // skip 6 bits (2nd start + 1 toggle + 4 address)
#define RECS80EXT_COMMAND_LEN 6 // read 6 command bits
#define RECS80EXT_COMPLETE_DATA_LEN 12 // complete length
#define RECS80EXT_STOP_BIT 1 // has stop bit
#define RECS80EXT_LSB 0 // MSB...LSB
#define RECS80EXT_FLAGS 0 // flags
 
#define NUBERT_START_BIT_PULSE_TIME 1340.0e-6 // 1340 usec pulse
#define NUBERT_START_BIT_PAUSE_TIME 340.0e-6 // 340 usec pause
#define NUBERT_1_PULSE_TIME 1340.0e-6 // 1340 usec pulse
#define NUBERT_1_PAUSE_TIME 340.0e-6 // 340 usec pause
#define NUBERT_0_PULSE_TIME 500.0e-6 // 500 usec pulse
#define NUBERT_0_PAUSE_TIME 1300.0e-6 // 1300 usec pause
#define NUBERT_FRAMES 2 // Nubert sends 2 frames
#define NUBERT_AUTO_REPETITION_PAUSE_TIME 35.0e-3 // auto repetition after 35ms
#define NUBERT_FRAME_REPEAT_PAUSE_TIME 35.0e-3 // frame repeat after 45ms
#define NUBERT_ADDRESS_OFFSET 0 // skip 0 bits
#define NUBERT_ADDRESS_LEN 0 // read 0 address bits
#define NUBERT_COMMAND_OFFSET 0 // skip 0 bits
#define NUBERT_COMMAND_LEN 10 // read 10 bits
#define NUBERT_COMPLETE_DATA_LEN 10 // complete length
#define NUBERT_STOP_BIT 1 // has stop bit
#define NUBERT_LSB 0 // MSB?
#define NUBERT_FLAGS 0 // flags
 
#define BANG_OLUFSEN_START_BIT1_PULSE_TIME 200.0e-6 // 200 usec pulse
#define BANG_OLUFSEN_START_BIT1_PAUSE_TIME 3125.0e-6 // 3125 usec pause
#define BANG_OLUFSEN_START_BIT2_PULSE_TIME 200.0e-6 // 200 usec pulse
#define BANG_OLUFSEN_START_BIT2_PAUSE_TIME 3125.0e-6 // 3125 usec pause
#define BANG_OLUFSEN_START_BIT3_PULSE_TIME 200.0e-6 // 200 usec pulse
#define BANG_OLUFSEN_START_BIT3_PAUSE_TIME 15625.0e-6 // 15625 usec pause
#define BANG_OLUFSEN_START_BIT4_PULSE_TIME 200.0e-6 // 200 usec pulse
#define BANG_OLUFSEN_START_BIT4_PAUSE_TIME 3125.0e-6 // 3125 usec pause
#define BANG_OLUFSEN_PULSE_TIME 200.0e-6 // 200 usec pulse
#define BANG_OLUFSEN_1_PAUSE_TIME 9375.0e-6 // 9375 usec pause
#define BANG_OLUFSEN_0_PAUSE_TIME 3125.0e-6 // 3125 usec pause
#define BANG_OLUFSEN_R_PAUSE_TIME 6250.0e-6 // 6250 usec pause (repeat last bit)
#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME 12500.0e-6 // 12500 usec pause (trailer bit)
#define BANG_OLUFSEN_FRAME_REPEAT_PAUSE_TIME 45.0e-3 // frame repeat after 45ms
#define BANG_OLUFSEN_ADDRESS_OFFSET 0 // no address bits
#define BANG_OLUFSEN_ADDRESS_LEN 0 // no address bits
#define BANG_OLUFSEN_COMMAND_OFFSET 3 // skip startbits 2, 3, 4
#define BANG_OLUFSEN_COMMAND_LEN 16 // read 16 command bits
#define BANG_OLUFSEN_COMPLETE_DATA_LEN 20 // complete length: startbits 2, 3, 4 + 16 data bits + trailer bit
#define BANG_OLUFSEN_STOP_BIT 1 // has stop bit
#define BANG_OLUFSEN_LSB 0 // MSB...LSB
#define BANG_OLUFSEN_FLAGS 0 // flags
 
#define GRUNDIG_OR_NOKIA_BIT_TIME 528.0e-6 // 528 usec pulse/pause
#define GRUNDIG_OR_NOKIA_PRE_PAUSE_TIME 2639.0e-6 // 2639 usec pause after pre bit
#define GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_TIME 117.76e-3 // info frame repeat after 117.76 ms
#define GRUNDIG_OR_NOKIA_STOP_BIT 0 // has no stop bit
#define GRUNDIG_OR_NOKIA_LSB 1 // MSB...LSB
#define GRUNDIG_OR_NOKIA_FLAGS (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1) // flags
 
#define GRUNDIG_FRAMES 2 // GRUNDIG sends each frame 1+1 times
#define GRUNDIG_AUTO_REPETITION_PAUSE_TIME 20.0e-3 // repetition after 20ms
#define GRUNDIG_ADDRESS_OFFSET 0 // no address
#define GRUNDIG_ADDRESS_LEN 0 // no address
#define GRUNDIG_COMMAND_OFFSET 1 // skip 1 start bit
#define GRUNDIG_COMMAND_LEN 9 // read 9 command bits
#define GRUNDIG_COMPLETE_DATA_LEN 10 // complete length: 1 start bit + 9 data bits
 
#define NOKIA_FRAMES 3 // NOKIA sends each frame 1 + 1 + 1 times
#define NOKIA_AUTO_REPETITION_PAUSE_TIME 20.0e-3 // repetition after 20ms
#define NOKIA_ADDRESS_OFFSET 9 // skip 9 bits (1 start bit + 8 data bits)
#define NOKIA_ADDRESS_LEN 8 // 7 address bits
#define NOKIA_COMMAND_OFFSET 1 // skip 1 bit (1 start bit)
#define NOKIA_COMMAND_LEN 8 // read 8 command bits
#define NOKIA_COMPLETE_DATA_LEN 17 // complete length: 1 start bit + 8 address bits + 8 command bits
 
#define SIEMENS_BIT_TIME 250.0e-6 // 250 usec pulse/pause
#define SIEMENS_FRAME_REPEAT_PAUSE_TIME 45.0e-3 // frame repeat after 45ms
#define SIEMENS_ADDRESS_OFFSET 2 // skip 2 start bits
#define SIEMENS_ADDRESS_LEN 12 // read 12 address bits
#define SIEMENS_COMMAND_OFFSET 15 // skip 15 bits (2 start bits + 12 address bits + 1 inverted bit)
#define SIEMENS_COMMAND_LEN 8 // read 7 + 1 command bits, last bit is only check bit.
#define SIEMENS_COMPLETE_DATA_LEN 23 // complete length
#define SIEMENS_STOP_BIT 0 // has no stop bit
#define SIEMENS_LSB 0 // MSB...LSB
#define SIEMENS_FLAGS (IRMP_PARAM_FLAG_IS_MANCHESTER | IRMP_PARAM_FLAG_1ST_PULSE_IS_1) // flags
 
#define FDC_START_BIT_PULSE_TIME 2085.0e-6 // 2085 usec pulse
#define FDC_START_BIT_PAUSE_TIME 966.0e-6 // 966 usec pause
#define FDC_PULSE_TIME 300.0e-6 // 300 usec pulse
#define FDC_1_PAUSE_TIME 715.0e-6 // 715 usec pause
#define FDC_0_PAUSE_TIME 220.0e-6 // 220 usec pause
#define FDC_FRAME_REPEAT_PAUSE_TIME 60.0e-3 // frame repeat after 60ms
#define FDC_ADDRESS_OFFSET 0 // skip 0 bits
#define FDC_ADDRESS_LEN 14 // read 14 address bits, but use only 6, shift 8 into command
#define FDC_COMMAND_OFFSET 20 // skip 20 bits
#define FDC_COMMAND_LEN 12 // read 12 bits
#define FDC_COMPLETE_DATA_LEN 40 // complete length
#define FDC_STOP_BIT 1 // has stop bit
#define FDC_LSB 1 // LSB...MSB
#define FDC_FLAGS 0 // flags
 
#define RCCAR_START_BIT_PULSE_TIME 2000.0e-6 // 2000 usec pulse
#define RCCAR_START_BIT_PAUSE_TIME 2000.0e-6 // 2000 usec pause
#define RCCAR_PULSE_TIME 600.0e-6 // 360 usec pulse
#define RCCAR_1_PAUSE_TIME 450.0e-6 // 650 usec pause
#define RCCAR_0_PAUSE_TIME 900.0e-6 // 180 usec pause
#define RCCAR_FRAME_REPEAT_PAUSE_TIME 40.0e-3 // frame repeat after 40ms
#define RCCAR_ADDRESS_OFFSET 0 // skip 0 bits
#define RCCAR_ADDRESS_LEN 0 // read 0 address bits
#define RCCAR_COMMAND_OFFSET 0 // skip 0 bits
#define RCCAR_COMMAND_LEN 13 // read 13 bits
#define RCCAR_COMPLETE_DATA_LEN 13 // complete length
#define RCCAR_STOP_BIT 1 // has stop bit
#define RCCAR_LSB 1 // LSB...MSB
#define RCCAR_FLAGS 0 // flags
 
#define JVC_START_BIT_PULSE_TIME 9000.0e-6 // 9000 usec pulse
#define JVC_START_BIT_PAUSE_TIME 4500.0e-6 // 4500 usec pause
#define JVC_PULSE_TIME 560.0e-6 // 560 usec pulse
#define JVC_1_PAUSE_TIME 1690.0e-6 // 1690 usec pause
#define JVC_0_PAUSE_TIME 560.0e-6 // 560 usec pause
#define JVC_FRAME_REPEAT_PAUSE_TIME 22.0e-3 // frame repeat after 22ms
#define JVC_ADDRESS_OFFSET 0 // skip 0 bits
#define JVC_ADDRESS_LEN 4 // read 4 address bits
#define JVC_COMMAND_OFFSET 4 // skip 4 bits
#define JVC_COMMAND_LEN 12 // read 12 bits
#define JVC_COMPLETE_DATA_LEN 16 // complete length
#define JVC_STOP_BIT 1 // has stop bit
#define JVC_LSB 1 // LSB...MSB
#define JVC_FLAGS 0 // flags
 
#define NIKON_START_BIT_PULSE_TIME 2200.0e-6 // 2200 usec pulse
#define NIKON_START_BIT_PAUSE_TIME 27100.0e-6 // 27100 usec pause
#define NIKON_PULSE_TIME 500.0e-6 // 520 usec pulse
#define NIKON_1_PAUSE_TIME 3500.0e-6 // 3500 usec pause
#define NIKON_0_PAUSE_TIME 1500.0e-6 // 1500 usec pause
#define NIKON_FRAME_REPEAT_PAUSE_TIME 60.0e-3 // frame repeat after 60ms
#define NIKON_ADDRESS_OFFSET 0 // skip 0 bits
#define NIKON_ADDRESS_LEN 0 // read 0 address bits
#define NIKON_COMMAND_OFFSET 0 // skip 0 bits
#define NIKON_COMMAND_LEN 2 // read 2 bits
#define NIKON_COMPLETE_DATA_LEN 2 // complete length
#define NIKON_STOP_BIT 1 // has stop bit
#define NIKON_LSB 0 // LSB...MSB
#define NIKON_FLAGS 0 // flags
 
#define AUTO_FRAME_REPETITION_TIME 80.0e-3 // SIRCS/SAMSUNG32/NUBERT: automatic repetition after 25-50ms
// KASEIKYO: automatic repetition after 75ms
 
#define TRUE 1
#define FALSE 0
 
#define IRMP_FLAG_REPETITION 0x01
 
typedef struct
{
uint8_t protocol; // protocol, i.e. NEC_PROTOCOL
uint16_t address; // address
uint16_t command; // command
uint8_t flags; // flags, e.g. repetition
} IRMP_DATA;
 
 
/**
* Initialize IRMP decoder
* @details Configures IRMP input pin
*/
extern void irmp_init (void);
 
/**
* Get IRMP data
* @details gets decoded IRMP data
* @param pointer in order to store IRMP data
* @return TRUE: successful, FALSE: failed
*/
extern uint8_t irmp_get_data (IRMP_DATA *);
 
/**
* ISR routine
* @details ISR routine, called 10000 times per second
*/
extern uint8_t irmp_ISR (void);
 
#ifdef __cplusplus
}
#endif
 
#endif /* _WC_IRMP_H_ */
/Servo-Controlled IR-Transmitter/Software/servo-IR.aws
New file
0,0 → 1,0
<AVRWorkspace><IOSettings><CurrentRegisters/></IOSettings><part name="ATMEGA88"/><Files><File00000 Name="D:\Pendsa\IR\Software\irmp.h" Position="266 94 1462 578" LineCol="0 0" State="Maximized"/><File00001 Name="D:\Pendsa\IR\Software\irsnd.c" Position="288 116 1476 570" LineCol="0 0" State="Maximized"/><File00002 Name="D:\Pendsa\IR\Software\irsnd.h" Position="310 138 1498 592" LineCol="0 0" State="Maximized"/><File00003 Name="D:\Pendsa\IR\Software\irsndconfig.h" Position="332 160 1520 614" LineCol="0 0" State="Maximized"/><File00004 Name="D:\Pendsa\IR\Software\irmpconfig.h" Position="354 182 1542 636" LineCol="0 0" State="Maximized"/><File00005 Name="c:\programme\winavr-20081205\avr\include\avr\iom88.h" Position="376 204 1564 658" LineCol="0 0" State="Maximized"/><File00006 Name="c:\programme\winavr-20081205\avr\include\avr\common.h" Position="398 226 1586 680" LineCol="0 0" State="Maximized"/><File00007 Name="D:\Pendsa\IR\Software\irmp.c" Position="420 248 1608 702" LineCol="0 0" State="Maximized"/><File00008 Name="D:\Pendsa\IR\Software\main.c" Position="262 71 1682 776" LineCol="0 0" State="Maximized"/><File00009 Name="c:\programme\winavr-20081205\avr\include\util\delay.h" Position="464 292 1652 746" LineCol="0 0" State="Maximized"/></Files></AVRWorkspace>
/Servo-Controlled IR-Transmitter/Software/irsnd.c
New file
0,0 → 1,1545
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* @file irsnd.c
*
* Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de
*
* $Id: irsnd.c,v 1.26 2010/11/09 21:14:31 fm Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
#ifdef unix // test/debug on linux/unix
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
 
#define DEBUG
#define F_CPU 8000000L
 
#else // not unix:
 
#ifdef WIN32 // test/debug on windows
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define F_CPU 8000000L
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
#define DEBUG
 
#else
 
#ifdef CODEVISION
#define COM2A0 6
#define WGM21 1
#define CS20 0
#else
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#endif // CODEVISION
 
#endif // WIN32
#endif // unix
 
#include "irmp.h"
#include "irsndconfig.h"
#include "irsnd.h"
 
#if IRSND_SUPPORT_NIKON_PROTOCOL == 1
typedef uint16_t IRSND_PAUSE_LEN;
#else
typedef uint8_t IRSND_PAUSE_LEN;
#endif
 
#define SIRCS_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME + 0.5)
#define SIRCS_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME + 0.5)
#define SIRCS_1_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME + 0.5)
#define SIRCS_0_PULSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME + 0.5)
#define SIRCS_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME + 0.5)
#define SIRCS_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SIRCS_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
#define SIRCS_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SIRCS_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define NEC_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME + 0.5)
#define NEC_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME + 0.5)
#define NEC_REPEAT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME + 0.5)
#define NEC_PULSE_LEN (uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME + 0.5)
#define NEC_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME + 0.5)
#define NEC_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME + 0.5)
#define NEC_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NEC_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define SAMSUNG_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME + 0.5)
#define SAMSUNG_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME + 0.5)
#define SAMSUNG_PULSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME + 0.5)
#define SAMSUNG_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME + 0.5)
#define SAMSUNG_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME + 0.5)
#define SAMSUNG_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SAMSUNG_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define SAMSUNG32_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SAMSUNG32_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
#define SAMSUNG32_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SAMSUNG32_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define MATSUSHITA_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME + 0.5)
#define MATSUSHITA_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME + 0.5)
#define MATSUSHITA_PULSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME + 0.5)
#define MATSUSHITA_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME + 0.5)
#define MATSUSHITA_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME + 0.5)
#define MATSUSHITA_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * MATSUSHITA_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define KASEIKYO_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME + 0.5)
#define KASEIKYO_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME + 0.5)
#define KASEIKYO_PULSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME + 0.5)
#define KASEIKYO_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME + 0.5)
#define KASEIKYO_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME + 0.5)
#define KASEIKYO_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * KASEIKYO_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
#define KASEIKYO_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * KASEIKYO_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define RECS80_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME + 0.5)
#define RECS80_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME + 0.5)
#define RECS80_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME + 0.5)
#define RECS80_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME + 0.5)
#define RECS80_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME + 0.5)
#define RECS80_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RECS80_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define RC5_START_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
#define RC5_BIT_LEN (uint8_t)(F_INTERRUPTS * RC5_BIT_TIME + 0.5)
#define RC5_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RC5_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define RC6_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME + 0.5)
#define RC6_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME + 0.5)
#define RC6_TOGGLE_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME + 0.5)
#define RC6_BIT_LEN (uint8_t)(F_INTERRUPTS * RC6_BIT_TIME + 0.5)
#define RC6_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RC6_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define DENON_PULSE_LEN (uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME + 0.5)
#define DENON_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME + 0.5)
#define DENON_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME + 0.5)
#define DENON_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * DENON_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
#define DENON_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * DENON_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define RECS80EXT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME + 0.5)
#define RECS80EXT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME + 0.5)
#define RECS80EXT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME + 0.5)
#define RECS80EXT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME + 0.5)
#define RECS80EXT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME + 0.5)
#define RECS80EXT_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RECS80EXT_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define NUBERT_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME + 0.5)
#define NUBERT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME + 0.5)
#define NUBERT_1_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME + 0.5)
#define NUBERT_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME + 0.5)
#define NUBERT_0_PULSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME + 0.5)
#define NUBERT_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME + 0.5)
#define NUBERT_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NUBERT_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
#define NUBERT_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NUBERT_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define BANG_OLUFSEN_START_BIT1_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME + 0.5)
#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME + 0.5)
#define BANG_OLUFSEN_START_BIT2_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME + 0.5)
#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME + 0.5)
#define BANG_OLUFSEN_START_BIT3_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME + 0.5)
#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME + 0.5)
#define BANG_OLUFSEN_PULSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME + 0.5)
#define BANG_OLUFSEN_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME + 0.5)
#define BANG_OLUFSEN_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME + 0.5)
#define BANG_OLUFSEN_R_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME + 0.5)
#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME + 0.5)
#define BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * BANG_OLUFSEN_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_PRE_PAUSE_TIME + 0.5)
#define GRUNDIG_OR_NOKIA_BIT_LEN (uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_BIT_TIME + 0.5)
#define GRUNDIG_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * GRUNDIG_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
#define NOKIA_AUTO_REPETITION_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NOKIA_AUTO_REPETITION_PAUSE_TIME + 0.5) // use uint16_t!
#define GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define SIEMENS_START_BIT_LEN (uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME + 0.5)
#define SIEMENS_BIT_LEN (uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME + 0.5)
#define SIEMENS_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * SIEMENS_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define IRSND_FREQ_32_KHZ (uint8_t) ((F_CPU / 32000 / 2) - 1)
#define IRSND_FREQ_36_KHZ (uint8_t) ((F_CPU / 36000 / 2) - 1)
#define IRSND_FREQ_38_KHZ (uint8_t) ((F_CPU / 38000 / 2) - 1)
#define IRSND_FREQ_40_KHZ (uint8_t) ((F_CPU / 40000 / 2) - 1)
#define IRSND_FREQ_56_KHZ (uint8_t) ((F_CPU / 56000 / 2) - 1)
#define IRSND_FREQ_455_KHZ (uint8_t) ((F_CPU / 455000 / 2) - 1)
 
#define FDC_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME + 0.5)
#define FDC_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME + 0.5)
#define FDC_PULSE_LEN (uint8_t)(F_INTERRUPTS * FDC_PULSE_TIME + 0.5)
#define FDC_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME + 0.5)
#define FDC_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME + 0.5)
#define FDC_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * FDC_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define RCCAR_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME + 0.5)
#define RCCAR_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME + 0.5)
#define RCCAR_PULSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME + 0.5)
#define RCCAR_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME + 0.5)
#define RCCAR_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME + 0.5)
#define RCCAR_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * RCCAR_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define JVC_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME + 0.5)
#define JVC_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * JVC_START_BIT_PAUSE_TIME + 0.5)
#define JVC_REPEAT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * JVC_REPEAT_START_BIT_PAUSE_TIME + 0.5)
#define JVC_PULSE_LEN (uint8_t)(F_INTERRUPTS * JVC_PULSE_TIME + 0.5)
#define JVC_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME + 0.5)
#define JVC_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME + 0.5)
#define JVC_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * JVC_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
#define NIKON_START_BIT_PULSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME + 0.5)
#define NIKON_START_BIT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME + 0.5)
#define NIKON_REPEAT_START_BIT_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME + 0.5)
#define NIKON_PULSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_PULSE_TIME + 0.5)
#define NIKON_1_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME + 0.5)
#define NIKON_0_PAUSE_LEN (uint8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME + 0.5)
#define NIKON_FRAME_REPEAT_PAUSE_LEN (uint16_t)(F_INTERRUPTS * NIKON_FRAME_REPEAT_PAUSE_TIME + 0.5) // use uint16_t!
 
static volatile uint8_t irsnd_busy;
static volatile uint8_t irsnd_protocol;
static volatile uint8_t irsnd_buffer[6];
static volatile uint8_t irsnd_repeat;
static volatile uint8_t irsnd_is_on = FALSE;
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Switch PWM on
* @details Switches PWM on with a narrow spike on all 3 channels -> leds glowing
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
static void
irsnd_on (void)
{
if (! irsnd_is_on)
{
#ifndef DEBUG
#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega8__)
TCCR2 |= (1<<COM20)|(1<<WGM21); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
#else
TCCR2A |= (1<<COM2A0)|(1<<WGM21); // = 0x42: toggle OC2A on compare match, clear Timer 2 at compare match OCR2A
#endif // __AVR...
#endif // DEBUG
irsnd_is_on = TRUE;
}
}
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Switch PWM off
* @details Switches PWM off
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
static void
irsnd_off (void)
{
if (irsnd_is_on)
{
#ifndef DEBUG
#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega8__)
TCCR2 &= ~(1<<COM20); // normal port operation, OC2A disconnected.
#else
TCCR2A &= ~(1<<COM2A0); // normal port operation, OC2A disconnected.
#endif // __AVR...
IRSND_PORT &= ~(1<<IRSND_BIT); // set IRSND_BIT to low
#endif // DEBUG
irsnd_is_on = FALSE;
}
}
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Set PWM frequency
* @details sets pwm frequency
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
static void
irsnd_set_freq (uint8_t freq)
{
#ifndef DEBUG
#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega8__)
OCR2 = freq;
#else
OCR2A = freq;
#endif // __AVR...
#endif // DEBUG
}
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Initialize the PWM
* @details Configures 0CR0A, 0CR0B and 0CR2B as PWM channels
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
void
irsnd_init (void)
{
#ifndef DEBUG
IRSND_PORT &= ~(1<<IRSND_BIT); // set IRSND_BIT to low
IRSND_DDR |= (1<<IRSND_BIT); // set IRSND_BIT to output
 
#if defined (__AVR_ATmega32__) || defined (__AVR_ATmega8__)
TCCR2 = (1<<WGM21); // CTC mode
TCCR2 |= (1<<CS20); // 0x01, start Timer 2, no prescaling
#else
TCCR2A = (1<<WGM21); // CTC mode
TCCR2B |= (1<<CS20); // 0x01, start Timer 2, no prescaling
#endif // __AVR...
 
irsnd_set_freq (IRSND_FREQ_36_KHZ); // default frequency
#endif // DEBUG
}
 
uint8_t
irsnd_is_busy (void)
{
return irsnd_busy;
}
 
static uint16_t
bitsrevervse (uint16_t x, uint8_t len)
{
uint16_t xx = 0;
 
while(len)
{
xx <<= 1;
if (x & 1)
{
xx |= 1;
}
x >>= 1;
len--;
}
return xx;
}
 
 
uint8_t
irsnd_send_data (IRMP_DATA * irmp_data_p, uint8_t do_wait)
{
#if IRSND_SUPPORT_RECS80_PROTOCOL == 1
static uint8_t toggle_bit_recs80;
#endif
#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
static uint8_t toggle_bit_recs80ext;
#endif
#if IRSND_SUPPORT_RC5_PROTOCOL == 1
static uint8_t toggle_bit_rc5;
#endif
uint16_t address;
uint16_t command;
 
if (do_wait)
{
while (irsnd_busy)
{
// do nothing;
}
}
else if (irsnd_busy)
{
return (FALSE);
}
 
irsnd_protocol = irmp_data_p->protocol;
irsnd_repeat = irmp_data_p->flags;
 
switch (irsnd_protocol)
{
#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
case IRMP_SIRCS_PROTOCOL:
{
command = bitsrevervse (irmp_data_p->command, SIRCS_MINIMUM_DATA_LEN);
 
irsnd_buffer[0] = (command & 0x0FF0) >> 4; // CCCCCCCC
irsnd_buffer[1] = (command & 0x000F) << 4; // CCCC0000
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_NEC_PROTOCOL == 1
case IRMP_APPLE_PROTOCOL:
{
command = irmp_data_p->command | (irmp_data_p->address << 8); // store address as ID in upper byte of command
address = 0x87EE; // set fixed NEC-lookalike address (customer ID of apple)
 
address = bitsrevervse (address, NEC_ADDRESS_LEN);
command = bitsrevervse (command, NEC_COMMAND_LEN);
 
irsnd_protocol = IRMP_NEC_PROTOCOL; // APPLE protocol is NEC with id instead of inverted command
 
irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC
irsnd_buffer[3] = (command & 0x00FF); // CCCCCCCC
 
irsnd_busy = TRUE;
break;
}
case IRMP_NEC_PROTOCOL:
{
address = bitsrevervse (irmp_data_p->address, NEC_ADDRESS_LEN);
command = bitsrevervse (irmp_data_p->command, NEC_COMMAND_LEN);
 
irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC
 
irsnd_protocol = IRMP_NEC_PROTOCOL; // APPLE protocol is NEC with fix bitmask instead of inverted command
irsnd_buffer[3] = 0x8B; // 10001011
{
irsnd_buffer[3] = ~((command & 0xFF00) >> 8); // cccccccc
}
 
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
case IRMP_SAMSUNG_PROTOCOL:
{
address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);
command = bitsrevervse (irmp_data_p->command, SAMSUNG_COMMAND_LEN);
 
irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
irsnd_buffer[2] = (command & 0x00F0) | ((command & 0xF000) >> 12); // IIIICCCC
irsnd_buffer[3] = ((command & 0x0F00) >> 4) | ((~(command & 0xF000) >> 12) & 0x0F); // CCCCcccc
irsnd_buffer[4] = (~(command & 0x0F00) >> 4) & 0xF0; // cccc0000
irsnd_busy = TRUE;
break;
}
case IRMP_SAMSUNG32_PROTOCOL:
{
address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN);
command = bitsrevervse (irmp_data_p->command, SAMSUNG32_COMMAND_LEN);
 
irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC
irsnd_buffer[3] = (command & 0x00FF); // CCCCCCCC
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
case IRMP_MATSUSHITA_PROTOCOL:
{
address = bitsrevervse (irmp_data_p->address, MATSUSHITA_ADDRESS_LEN);
command = bitsrevervse (irmp_data_p->command, MATSUSHITA_COMMAND_LEN);
 
irsnd_buffer[0] = (command & 0x0FF0) >> 4; // CCCCCCCC
irsnd_buffer[1] = ((command & 0x000F) << 4) | ((address & 0x0F00) >> 8); // CCCCAAAA
irsnd_buffer[2] = (address & 0x00FF); // AAAAAAAA
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1
case IRMP_KASEIKYO_PROTOCOL:
{
uint8_t xor;
 
address = bitsrevervse (irmp_data_p->address, KASEIKYO_ADDRESS_LEN);
command = bitsrevervse (irmp_data_p->command, KASEIKYO_COMMAND_LEN + 4);
 
xor = ((address & 0x000F) ^ ((address & 0x00F0) >> 4) ^ ((address & 0x0F00) >> 8) ^ ((address & 0xF000) >> 12)) & 0x0F;
 
irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA
irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA
irsnd_buffer[2] = xor << 4 | (command & 0x000F); // XXXXCCCC
irsnd_buffer[3] = 0 | (command & 0xF000) >> 12; // 0000CCCC
irsnd_buffer[4] = (command & 0x0FF0) >> 4; // CCCCCCCC
 
xor = irsnd_buffer[2] ^ irsnd_buffer[3] ^ irsnd_buffer[4];
 
irsnd_buffer[5] = xor;
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_RECS80_PROTOCOL == 1
case IRMP_RECS80_PROTOCOL:
{
toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x40;
 
irsnd_buffer[0] = 0x80 | toggle_bit_recs80 | ((irmp_data_p->address & 0x0007) << 3) |
((irmp_data_p->command & 0x0038) >> 3); // STAAACCC
irsnd_buffer[1] = (irmp_data_p->command & 0x07) << 5; // CCC00000
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
case IRMP_RECS80EXT_PROTOCOL:
{
toggle_bit_recs80ext = toggle_bit_recs80ext ? 0x00 : 0x40;
 
irsnd_buffer[0] = 0x80 | toggle_bit_recs80ext | ((irmp_data_p->address & 0x000F) << 2) |
((irmp_data_p->command & 0x0030) >> 4); // STAAAACC
irsnd_buffer[1] = (irmp_data_p->command & 0x0F) << 4; // CCCC0000
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_RC5_PROTOCOL == 1
case IRMP_RC5_PROTOCOL:
{
toggle_bit_rc5 = toggle_bit_rc5 ? 0x00 : 0x40;
 
irsnd_buffer[0] = ((irmp_data_p->command & 0x40) ? 0x00 : 0x80) | toggle_bit_rc5 |
((irmp_data_p->address & 0x001F) << 1) | ((irmp_data_p->command & 0x20) >> 5); // CTAAAAAC
irsnd_buffer[1] = (irmp_data_p->command & 0x1F) << 3; // CCCCC000
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_DENON_PROTOCOL == 1
case IRMP_DENON_PROTOCOL:
{
irsnd_buffer[0] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x0380) >> 7); // AAAAACCC (1st frame)
irsnd_buffer[1] = (irmp_data_p->command & 0x7F) << 1; // CCCCCCC
irsnd_buffer[2] = ((irmp_data_p->address & 0x1F) << 3) | (((~irmp_data_p->command) & 0x0380) >> 7); // AAAAACCC (2nd frame)
irsnd_buffer[3] = (~(irmp_data_p->command) & 0x7F) << 1; // CCCCCCC
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
case IRMP_NUBERT_PROTOCOL:
{
irsnd_buffer[0] = irmp_data_p->command >> 2; // CCCCCCCC
irsnd_buffer[1] = (irmp_data_p->command & 0x0003) << 6; // CC000000
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
case IRMP_BANG_OLUFSEN_PROTOCOL:
{
irsnd_buffer[0] = irmp_data_p->command >> 11; // SXSCCCCC
irsnd_buffer[1] = irmp_data_p->command >> 3; // CCCCCCCC
irsnd_buffer[2] = (irmp_data_p->command & 0x0007) << 5; // CCC00000
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1
case IRMP_GRUNDIG_PROTOCOL:
{
command = bitsrevervse (irmp_data_p->command, GRUNDIG_COMMAND_LEN);
 
irsnd_buffer[0] = 0xFF; // S1111111 (1st frame)
irsnd_buffer[1] = 0xC0; // 11
irsnd_buffer[2] = 0x80 | (command >> 2); // SCCCCCCC (2nd frame)
irsnd_buffer[3] = (command << 6) & 0xC0; // CC
 
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1
case IRMP_NOKIA_PROTOCOL:
{
address = bitsrevervse (irmp_data_p->address, NOKIA_ADDRESS_LEN);
command = bitsrevervse (irmp_data_p->command, NOKIA_COMMAND_LEN);
 
irsnd_buffer[0] = 0xBF; // S0111111 (1st + 3rd frame)
irsnd_buffer[1] = 0xFF; // 11111111
irsnd_buffer[2] = 0x80; // 1
irsnd_buffer[3] = 0x80 | command >> 1; // SCCCCCCC (2nd frame)
irsnd_buffer[4] = (command << 7) | (address >> 1); // CAAAAAAA
irsnd_buffer[5] = (address << 7); // A
 
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1
case IRMP_SIEMENS_PROTOCOL:
{
irsnd_buffer[0] = ((irmp_data_p->address & 0x0FFF) >> 5); // SAAAAAAA
irsnd_buffer[1] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x7F) >> 5); // AAAAA0CC
irsnd_buffer[2] = (irmp_data_p->command << 3) | ((~irmp_data_p->command & 0x01) << 2); // CCCCCc
 
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_FDC_PROTOCOL == 1
case IRMP_FDC_PROTOCOL:
{
address = bitsrevervse (irmp_data_p->address, FDC_ADDRESS_LEN);
command = bitsrevervse (irmp_data_p->command, FDC_COMMAND_LEN);
 
irsnd_buffer[0] = (address & 0xFF); // AAAAAAAA
irsnd_buffer[1] = 0; // 00000000
irsnd_buffer[2] = 0; // 0000RRRR
irsnd_buffer[3] = (command & 0xFF); // CCCCCCCC
irsnd_buffer[4] = ~(command & 0xFF); // cccccccc
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1
case IRMP_RCCAR_PROTOCOL:
{
address = bitsrevervse (irmp_data_p->address, 2); // A0 A1
command = bitsrevervse (irmp_data_p->command, RCCAR_COMMAND_LEN - 2); // D0 D1 D2 D3 D4 D5 D6 D7 C0 C1 V
 
irsnd_buffer[0] = ((command & 0x06) << 5) | ((address & 0x0003) << 4) | ((command & 0x0780) >> 7); // C0 C1 A0 A1 D0 D1 D2 D3
irsnd_buffer[1] = ((command & 0x78) << 1) | ((command & 0x0001) << 3); // D4 D5 D6 D7 V 0 0 0
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_JVC_PROTOCOL == 1
case IRMP_JVC_PROTOCOL:
{
address = bitsrevervse (irmp_data_p->address, JVC_ADDRESS_LEN);
command = bitsrevervse (irmp_data_p->command, JVC_COMMAND_LEN);
 
irsnd_buffer[0] = ((address & 0x000F) << 4) | (command & 0x0F00) >> 8; // AAAACCCC
irsnd_buffer[1] = (command & 0x00FF); // CCCCCCCC
 
irsnd_busy = TRUE;
break;
}
#endif
#if IRSND_SUPPORT_NIKON_PROTOCOL == 1
case IRMP_NIKON_PROTOCOL:
{
irsnd_buffer[0] = (irmp_data_p->command & 0x0003) << 6; // CC
irsnd_busy = TRUE;
break;
}
#endif
default:
{
break;
}
}
 
return irsnd_busy;
}
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* ISR routine
* @details ISR routine, called 10000 times per second
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
uint8_t
irsnd_ISR (void)
{
static uint8_t current_bit = 0xFF;
static uint8_t pulse_counter;
static IRSND_PAUSE_LEN pause_counter;
static uint8_t startbit_pulse_len;
static IRSND_PAUSE_LEN startbit_pause_len;
static uint8_t pulse_1_len;
static uint8_t pause_1_len;
static uint8_t pulse_0_len;
static uint8_t pause_0_len;
static uint8_t has_stop_bit;
static uint8_t new_frame = TRUE;
static uint8_t complete_data_len;
static uint8_t n_auto_repetitions; // number of auto_repetitions
static uint8_t auto_repetition_counter; // auto_repetition counter
static uint16_t auto_repetition_pause_len; // pause before auto_repetition, uint16_t!
static uint16_t auto_repetition_pause_counter; // pause before auto_repetition, uint16_t!
static uint8_t n_repeat_frames; // number of repeat frames
static uint8_t repeat_counter; // repeat counter
static uint16_t repeat_frame_pause_len; // pause before repeat, uint16_t!
static uint16_t packet_repeat_pause_counter; // pause before repeat, uint16_t!
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
static uint8_t last_bit_value;
#endif
static uint8_t pulse_len = 0xFF;
static IRSND_PAUSE_LEN pause_len = 0xFF;
 
if (irsnd_busy)
{
if (current_bit == 0xFF && new_frame) // start of transmission...
{
if (auto_repetition_counter > 0)
{
auto_repetition_pause_counter++;
 
if (auto_repetition_pause_counter >= auto_repetition_pause_len)
{
auto_repetition_pause_counter = 0;
 
if (irsnd_protocol == IRMP_DENON_PROTOCOL)
{
current_bit = 16;
complete_data_len = 2 * DENON_COMPLETE_DATA_LEN + 1;
}
else if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL) // n'th grundig info frame
{
current_bit = 15;
complete_data_len = 16 + GRUNDIG_COMPLETE_DATA_LEN;
}
else if (irsnd_protocol == IRMP_NOKIA_PROTOCOL) // n'th nokia info frame
{
if (auto_repetition_counter + 1 < n_auto_repetitions)
{
current_bit = 23;
complete_data_len = 24 + NOKIA_COMPLETE_DATA_LEN;
}
else // nokia stop frame
{
current_bit = 0xFF;
complete_data_len = NOKIA_COMPLETE_DATA_LEN;
}
}
}
else
{
#ifdef DEBUG
if (irsnd_is_on)
{
putchar ('0');
}
else
{
putchar ('1');
}
#endif
return irsnd_busy;
}
}
else if (repeat_counter > 0 && packet_repeat_pause_counter < repeat_frame_pause_len)
{
packet_repeat_pause_counter++;
 
#ifdef DEBUG
if (irsnd_is_on)
{
putchar ('0');
}
else
{
putchar ('1');
}
#endif
return irsnd_busy;
}
else
{
n_repeat_frames = irsnd_repeat;
packet_repeat_pause_counter = 0;
pulse_counter = 0;
pause_counter = 0;
 
switch (irsnd_protocol)
{
#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
case IRMP_SIRCS_PROTOCOL:
{
startbit_pulse_len = SIRCS_START_BIT_PULSE_LEN;
startbit_pause_len = SIRCS_START_BIT_PAUSE_LEN;
pulse_1_len = SIRCS_1_PULSE_LEN;
pause_1_len = SIRCS_PAUSE_LEN;
pulse_0_len = SIRCS_0_PULSE_LEN;
pause_0_len = SIRCS_PAUSE_LEN;
has_stop_bit = SIRCS_STOP_BIT;
complete_data_len = SIRCS_MINIMUM_DATA_LEN;
n_auto_repetitions = (repeat_counter == 0) ? SIRCS_FRAMES : 1; // 3 frames auto repetition if first frame
auto_repetition_pause_len = SIRCS_AUTO_REPETITION_PAUSE_LEN; // 25ms pause
repeat_frame_pause_len = SIRCS_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_40_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_NEC_PROTOCOL == 1
case IRMP_NEC_PROTOCOL:
{
startbit_pulse_len = NEC_START_BIT_PULSE_LEN;
 
if (repeat_counter > 0)
{
startbit_pause_len = NEC_REPEAT_START_BIT_PAUSE_LEN;
complete_data_len = 0;
}
else
{
startbit_pause_len = NEC_START_BIT_PAUSE_LEN;
complete_data_len = NEC_COMPLETE_DATA_LEN;
}
 
pulse_1_len = NEC_PULSE_LEN;
pause_1_len = NEC_1_PAUSE_LEN;
pulse_0_len = NEC_PULSE_LEN;
pause_0_len = NEC_0_PAUSE_LEN;
has_stop_bit = NEC_STOP_BIT;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = NEC_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
case IRMP_SAMSUNG_PROTOCOL:
{
startbit_pulse_len = SAMSUNG_START_BIT_PULSE_LEN;
startbit_pause_len = SAMSUNG_START_BIT_PAUSE_LEN;
pulse_1_len = SAMSUNG_PULSE_LEN;
pause_1_len = SAMSUNG_1_PAUSE_LEN;
pulse_0_len = SAMSUNG_PULSE_LEN;
pause_0_len = SAMSUNG_0_PAUSE_LEN;
has_stop_bit = SAMSUNG_STOP_BIT;
complete_data_len = SAMSUNG_COMPLETE_DATA_LEN;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = SAMSUNG_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
break;
}
 
case IRMP_SAMSUNG32_PROTOCOL:
{
startbit_pulse_len = SAMSUNG_START_BIT_PULSE_LEN;
startbit_pause_len = SAMSUNG_START_BIT_PAUSE_LEN;
pulse_1_len = SAMSUNG_PULSE_LEN;
pause_1_len = SAMSUNG_1_PAUSE_LEN;
pulse_0_len = SAMSUNG_PULSE_LEN;
pause_0_len = SAMSUNG_0_PAUSE_LEN;
has_stop_bit = SAMSUNG_STOP_BIT;
complete_data_len = SAMSUNG32_COMPLETE_DATA_LEN;
n_auto_repetitions = SAMSUNG32_FRAMES; // 2 frames
auto_repetition_pause_len = SAMSUNG32_AUTO_REPETITION_PAUSE_LEN; // 47 ms pause
repeat_frame_pause_len = SAMSUNG32_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
case IRMP_MATSUSHITA_PROTOCOL:
{
startbit_pulse_len = MATSUSHITA_START_BIT_PULSE_LEN;
startbit_pause_len = MATSUSHITA_START_BIT_PAUSE_LEN;
pulse_1_len = MATSUSHITA_PULSE_LEN;
pause_1_len = MATSUSHITA_1_PAUSE_LEN;
pulse_0_len = MATSUSHITA_PULSE_LEN;
pause_0_len = MATSUSHITA_0_PAUSE_LEN;
has_stop_bit = MATSUSHITA_STOP_BIT;
complete_data_len = MATSUSHITA_COMPLETE_DATA_LEN;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = MATSUSHITA_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_36_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1
case IRMP_KASEIKYO_PROTOCOL:
{
startbit_pulse_len = KASEIKYO_START_BIT_PULSE_LEN;
startbit_pause_len = KASEIKYO_START_BIT_PAUSE_LEN;
pulse_1_len = KASEIKYO_PULSE_LEN;
pause_1_len = KASEIKYO_1_PAUSE_LEN;
pulse_0_len = KASEIKYO_PULSE_LEN;
pause_0_len = KASEIKYO_0_PAUSE_LEN;
has_stop_bit = KASEIKYO_STOP_BIT;
complete_data_len = KASEIKYO_COMPLETE_DATA_LEN;
n_auto_repetitions = (repeat_counter == 0) ? KASEIKYO_FRAMES : 1; // 2 frames auto repetition if first frame
auto_repetition_pause_len = KASEIKYO_AUTO_REPETITION_PAUSE_LEN; // 75 ms pause
repeat_frame_pause_len = KASEIKYO_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_RECS80_PROTOCOL == 1
case IRMP_RECS80_PROTOCOL:
{
startbit_pulse_len = RECS80_START_BIT_PULSE_LEN;
startbit_pause_len = RECS80_START_BIT_PAUSE_LEN;
pulse_1_len = RECS80_PULSE_LEN;
pause_1_len = RECS80_1_PAUSE_LEN;
pulse_0_len = RECS80_PULSE_LEN;
pause_0_len = RECS80_0_PAUSE_LEN;
has_stop_bit = RECS80_STOP_BIT;
complete_data_len = RECS80_COMPLETE_DATA_LEN;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = RECS80_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
case IRMP_RECS80EXT_PROTOCOL:
{
startbit_pulse_len = RECS80EXT_START_BIT_PULSE_LEN;
startbit_pause_len = RECS80EXT_START_BIT_PAUSE_LEN;
pulse_1_len = RECS80EXT_PULSE_LEN;
pause_1_len = RECS80EXT_1_PAUSE_LEN;
pulse_0_len = RECS80EXT_PULSE_LEN;
pause_0_len = RECS80EXT_0_PAUSE_LEN;
has_stop_bit = RECS80EXT_STOP_BIT;
complete_data_len = RECS80EXT_COMPLETE_DATA_LEN;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = RECS80EXT_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_RC5_PROTOCOL == 1
case IRMP_RC5_PROTOCOL:
{
startbit_pulse_len = RC5_BIT_LEN;
startbit_pause_len = RC5_BIT_LEN;
pulse_len = RC5_BIT_LEN;
pause_len = RC5_BIT_LEN;
has_stop_bit = RC5_STOP_BIT;
complete_data_len = RC5_COMPLETE_DATA_LEN;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = RC5_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_36_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_DENON_PROTOCOL == 1
case IRMP_DENON_PROTOCOL:
{
startbit_pulse_len = 0x00;
startbit_pause_len = 0x00;
pulse_1_len = DENON_PULSE_LEN;
pause_1_len = DENON_1_PAUSE_LEN;
pulse_0_len = DENON_PULSE_LEN;
pause_0_len = DENON_0_PAUSE_LEN;
has_stop_bit = DENON_STOP_BIT;
complete_data_len = DENON_COMPLETE_DATA_LEN;
n_auto_repetitions = DENON_FRAMES; // 2 frames, 2nd with inverted command
auto_repetition_pause_len = DENON_AUTO_REPETITION_PAUSE_LEN; // 65 ms pause after 1st frame
repeat_frame_pause_len = DENON_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_32_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
case IRMP_NUBERT_PROTOCOL:
{
startbit_pulse_len = NUBERT_START_BIT_PULSE_LEN;
startbit_pause_len = NUBERT_START_BIT_PAUSE_LEN;
pulse_1_len = NUBERT_1_PULSE_LEN;
pause_1_len = NUBERT_1_PAUSE_LEN;
pulse_0_len = NUBERT_0_PULSE_LEN;
pause_0_len = NUBERT_0_PAUSE_LEN;
has_stop_bit = NUBERT_STOP_BIT;
complete_data_len = NUBERT_COMPLETE_DATA_LEN;
n_auto_repetitions = NUBERT_FRAMES; // 2 frames
auto_repetition_pause_len = NUBERT_AUTO_REPETITION_PAUSE_LEN; // 35 ms pause
repeat_frame_pause_len = NUBERT_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_36_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
case IRMP_BANG_OLUFSEN_PROTOCOL:
{
startbit_pulse_len = BANG_OLUFSEN_START_BIT1_PULSE_LEN;
startbit_pause_len = BANG_OLUFSEN_START_BIT1_PAUSE_LEN;
pulse_1_len = BANG_OLUFSEN_PULSE_LEN;
pause_1_len = BANG_OLUFSEN_1_PAUSE_LEN;
pulse_0_len = BANG_OLUFSEN_PULSE_LEN;
pause_0_len = BANG_OLUFSEN_0_PAUSE_LEN;
has_stop_bit = BANG_OLUFSEN_STOP_BIT;
complete_data_len = BANG_OLUFSEN_COMPLETE_DATA_LEN;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = BANG_OLUFSEN_FRAME_REPEAT_PAUSE_LEN;
last_bit_value = 0;
irsnd_set_freq (IRSND_FREQ_455_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1
case IRMP_GRUNDIG_PROTOCOL:
{
startbit_pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
startbit_pause_len = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN;
pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
pause_len = GRUNDIG_OR_NOKIA_BIT_LEN;
has_stop_bit = GRUNDIG_OR_NOKIA_STOP_BIT;
complete_data_len = GRUNDIG_COMPLETE_DATA_LEN;
n_auto_repetitions = GRUNDIG_FRAMES; // 2 frames
auto_repetition_pause_len = GRUNDIG_AUTO_REPETITION_PAUSE_LEN; // 20m sec pause
repeat_frame_pause_len = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN; // 117 msec pause
irsnd_set_freq (IRSND_FREQ_38_KHZ);
 
break;
}
#endif
#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1
case IRMP_NOKIA_PROTOCOL:
{
startbit_pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
startbit_pause_len = GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN;
pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
pause_len = GRUNDIG_OR_NOKIA_BIT_LEN;
has_stop_bit = GRUNDIG_OR_NOKIA_STOP_BIT;
complete_data_len = NOKIA_COMPLETE_DATA_LEN;
n_auto_repetitions = NOKIA_FRAMES; // 2 frames
auto_repetition_pause_len = NOKIA_AUTO_REPETITION_PAUSE_LEN; // 20 msec pause
repeat_frame_pause_len = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN; // 117 msec pause
irsnd_set_freq (IRSND_FREQ_38_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1
case IRMP_SIEMENS_PROTOCOL:
{
startbit_pulse_len = SIEMENS_BIT_LEN;
startbit_pause_len = SIEMENS_BIT_LEN;
pulse_len = SIEMENS_BIT_LEN;
pause_len = SIEMENS_BIT_LEN;
has_stop_bit = SIEMENS_STOP_BIT;
complete_data_len = SIEMENS_COMPLETE_DATA_LEN - 1;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = SIEMENS_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_36_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_FDC_PROTOCOL == 1
case IRMP_FDC_PROTOCOL:
{
startbit_pulse_len = FDC_START_BIT_PULSE_LEN;
startbit_pause_len = FDC_START_BIT_PAUSE_LEN;
complete_data_len = FDC_COMPLETE_DATA_LEN;
pulse_1_len = FDC_PULSE_LEN;
pause_1_len = FDC_1_PAUSE_LEN;
pulse_0_len = FDC_PULSE_LEN;
pause_0_len = FDC_0_PAUSE_LEN;
has_stop_bit = FDC_STOP_BIT;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = FDC_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1
case IRMP_RCCAR_PROTOCOL:
{
startbit_pulse_len = RCCAR_START_BIT_PULSE_LEN;
startbit_pause_len = RCCAR_START_BIT_PAUSE_LEN;
complete_data_len = RCCAR_COMPLETE_DATA_LEN;
pulse_1_len = RCCAR_PULSE_LEN;
pause_1_len = RCCAR_1_PAUSE_LEN;
pulse_0_len = RCCAR_PULSE_LEN;
pause_0_len = RCCAR_0_PAUSE_LEN;
has_stop_bit = RCCAR_STOP_BIT;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = RCCAR_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
break;
}
#endif
#if IRSND_SUPPORT_JVC_PROTOCOL == 1
case IRMP_JVC_PROTOCOL:
{
if (repeat_counter != 0) // skip start bit if repetition frame
{
current_bit = 0;
}
 
startbit_pulse_len = JVC_START_BIT_PULSE_LEN;
startbit_pause_len = JVC_START_BIT_PAUSE_LEN;
complete_data_len = JVC_COMPLETE_DATA_LEN;
pulse_1_len = JVC_PULSE_LEN;
pause_1_len = JVC_1_PAUSE_LEN;
pulse_0_len = JVC_PULSE_LEN;
pause_0_len = JVC_0_PAUSE_LEN;
has_stop_bit = JVC_STOP_BIT;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = JVC_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
 
break;
}
#endif
#if IRSND_SUPPORT_NIKON_PROTOCOL == 1
case IRMP_NIKON_PROTOCOL:
{
startbit_pulse_len = NIKON_START_BIT_PULSE_LEN;
startbit_pause_len = 271; // NIKON_START_BIT_PAUSE_LEN;
complete_data_len = NIKON_COMPLETE_DATA_LEN;
pulse_1_len = NIKON_PULSE_LEN;
pause_1_len = NIKON_1_PAUSE_LEN;
pulse_0_len = NIKON_PULSE_LEN;
pause_0_len = NIKON_0_PAUSE_LEN;
has_stop_bit = NIKON_STOP_BIT;
n_auto_repetitions = 1; // 1 frame
auto_repetition_pause_len = 0;
repeat_frame_pause_len = NIKON_FRAME_REPEAT_PAUSE_LEN;
irsnd_set_freq (IRSND_FREQ_38_KHZ);
 
break;
}
#endif
default:
{
irsnd_busy = FALSE;
break;
}
}
}
}
 
if (irsnd_busy)
{
new_frame = FALSE;
 
switch (irsnd_protocol)
{
#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1
case IRMP_SIRCS_PROTOCOL:
#endif
#if IRSND_SUPPORT_NEC_PROTOCOL == 1
case IRMP_NEC_PROTOCOL:
#endif
#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
case IRMP_SAMSUNG_PROTOCOL:
case IRMP_SAMSUNG32_PROTOCOL:
#endif
#if IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1
case IRMP_MATSUSHITA_PROTOCOL:
#endif
#if IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1
case IRMP_KASEIKYO_PROTOCOL:
#endif
#if IRSND_SUPPORT_RECS80_PROTOCOL == 1
case IRMP_RECS80_PROTOCOL:
#endif
#if IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1
case IRMP_RECS80EXT_PROTOCOL:
#endif
#if IRSND_SUPPORT_DENON_PROTOCOL == 1
case IRMP_DENON_PROTOCOL:
#endif
#if IRSND_SUPPORT_NUBERT_PROTOCOL == 1
case IRMP_NUBERT_PROTOCOL:
#endif
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
case IRMP_BANG_OLUFSEN_PROTOCOL:
#endif
#if IRSND_SUPPORT_FDC_PROTOCOL == 1
case IRMP_FDC_PROTOCOL:
#endif
#if IRSND_SUPPORT_RCCAR_PROTOCOL == 1
case IRMP_RCCAR_PROTOCOL:
#endif
#if IRSND_SUPPORT_JVC_PROTOCOL == 1
case IRMP_JVC_PROTOCOL:
#endif
#if IRSND_SUPPORT_NIKON_PROTOCOL == 1
case IRMP_NIKON_PROTOCOL:
#endif
 
 
#if IRSND_SUPPORT_SIRCS_PROTOCOL == 1 || IRSND_SUPPORT_NEC_PROTOCOL == 1 || IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1 || IRSND_SUPPORT_MATSUSHITA_PROTOCOL == 1 || \
IRSND_SUPPORT_KASEIKYO_PROTOCOL == 1 || IRSND_SUPPORT_RECS80_PROTOCOL == 1 || IRSND_SUPPORT_RECS80EXT_PROTOCOL == 1 || IRSND_SUPPORT_DENON_PROTOCOL == 1 || \
IRSND_SUPPORT_NUBERT_PROTOCOL == 1 || IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 || IRSND_SUPPORT_FDC_PROTOCOL == 1 || IRSND_SUPPORT_RCCAR_PROTOCOL == 1 || \
IRSND_SUPPORT_JVC_PROTOCOL == 1 || IRSND_SUPPORT_NIKON_PROTOCOL == 1
{
if (pulse_counter == 0)
{
if (current_bit == 0xFF) // send start bit
{
pulse_len = startbit_pulse_len;
pause_len = startbit_pause_len;
}
else if (current_bit < complete_data_len) // send n'th bit
{
#if IRSND_SUPPORT_SAMSUNG_PROTOCOL == 1
if (irsnd_protocol == IRMP_SAMSUNG_PROTOCOL)
{
if (current_bit < SAMSUNG_ADDRESS_LEN) // send address bits
{
pulse_len = SAMSUNG_PULSE_LEN;
pause_len = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ?
SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;
}
else if (current_bit == SAMSUNG_ADDRESS_LEN) // send SYNC bit (16th bit)
{
pulse_len = SAMSUNG_PULSE_LEN;
pause_len = SAMSUNG_START_BIT_PAUSE_LEN;
}
else if (current_bit < SAMSUNG_COMPLETE_DATA_LEN) // send n'th bit
{
uint8_t cur_bit = current_bit - 1; // sync skipped, offset = -1 !
 
pulse_len = SAMSUNG_PULSE_LEN;
pause_len = (irsnd_buffer[cur_bit / 8] & (1<<(7-(cur_bit % 8)))) ?
SAMSUNG_1_PAUSE_LEN : SAMSUNG_0_PAUSE_LEN;
}
}
else
#endif
 
#if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
if (irsnd_protocol == IRMP_BANG_OLUFSEN_PROTOCOL)
{
if (current_bit == 0) // send 2nd start bit
{
pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;
pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;
}
else if (current_bit == 1) // send 3rd start bit
{
pulse_len = BANG_OLUFSEN_START_BIT3_PULSE_LEN;
pause_len = BANG_OLUFSEN_START_BIT3_PAUSE_LEN;
}
else if (current_bit == 2) // send 4th start bit
{
pulse_len = BANG_OLUFSEN_START_BIT2_PULSE_LEN;
pause_len = BANG_OLUFSEN_START_BIT2_PAUSE_LEN;
}
else if (current_bit == 19) // send trailer bit
{
pulse_len = BANG_OLUFSEN_PULSE_LEN;
pause_len = BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN;
}
else if (current_bit < BANG_OLUFSEN_COMPLETE_DATA_LEN) // send n'th bit
{
uint8_t cur_bit_value = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? 1 : 0;
pulse_len = BANG_OLUFSEN_PULSE_LEN;
 
if (cur_bit_value == last_bit_value)
{
pause_len = BANG_OLUFSEN_R_PAUSE_LEN;
}
else
{
pause_len = cur_bit_value ? BANG_OLUFSEN_1_PAUSE_LEN : BANG_OLUFSEN_0_PAUSE_LEN;
last_bit_value = cur_bit_value;
}
}
}
else
#endif
if (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8))))
{
pulse_len = pulse_1_len;
pause_len = pause_1_len;
}
else
{
pulse_len = pulse_0_len;
pause_len = pause_0_len;
}
}
else if (has_stop_bit) // send stop bit
{
pulse_len = pulse_0_len;
 
if (auto_repetition_counter < n_auto_repetitions)
{
pause_len = pause_0_len;
}
else
{
pause_len = 255; // last frame: pause of 255
}
}
}
 
if (pulse_counter < pulse_len)
{
if (pulse_counter == 0)
{
irsnd_on ();
}
pulse_counter++;
}
else if (pause_counter < pause_len)
{
if (pause_counter == 0)
{
irsnd_off ();
}
pause_counter++;
}
else
{
current_bit++;
 
if (current_bit >= complete_data_len + has_stop_bit)
{
current_bit = 0xFF;
auto_repetition_counter++;
 
if (auto_repetition_counter == n_auto_repetitions)
{
irsnd_busy = FALSE;
auto_repetition_counter = 0;
}
new_frame = TRUE;
}
 
pulse_counter = 0;
pause_counter = 0;
}
break;
}
#endif
 
#if IRSND_SUPPORT_RC5_PROTOCOL == 1
case IRMP_RC5_PROTOCOL:
#endif
#if IRSND_SUPPORT_SIEMENS_PROTOCOL == 1
case IRMP_SIEMENS_PROTOCOL:
#endif
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1
case IRMP_GRUNDIG_PROTOCOL:
#endif
#if IRSND_SUPPORT_NOKIA_PROTOCOL == 1
case IRMP_NOKIA_PROTOCOL:
#endif
 
#if IRSND_SUPPORT_RC5_PROTOCOL == 1 || IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 || IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
{
if (pulse_counter == pulse_len && pause_counter == pause_len)
{
current_bit++;
 
if (current_bit >= complete_data_len)
{
current_bit = 0xFF;
 
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)
{
auto_repetition_counter++;
 
if (repeat_counter > 0)
{ // set 117 msec pause time
auto_repetition_pause_len = GRUNDIG_OR_NOKIA_FRAME_REPEAT_PAUSE_LEN;
}
 
if (repeat_counter < n_repeat_frames) // tricky: repeat n info frames per auto repetition before sending last stop frame
{
n_auto_repetitions++; // increment number of auto repetitions
repeat_counter++;
}
else if (auto_repetition_counter == n_auto_repetitions)
{
irsnd_busy = FALSE;
auto_repetition_counter = 0;
}
}
else
#endif
{
irsnd_busy = FALSE;
}
 
new_frame = TRUE;
irsnd_off ();
}
 
pulse_counter = 0;
pause_counter = 0;
}
 
if (! new_frame)
{
uint8_t first_pulse;
 
#if IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
if (irsnd_protocol == IRMP_GRUNDIG_PROTOCOL || irsnd_protocol == IRMP_NOKIA_PROTOCOL)
{
if (current_bit == 0xFF || // start bit of start-frame
(irsnd_protocol == IRMP_GRUNDIG_PROTOCOL && current_bit == 15) || // start bit of info-frame (Grundig)
(irsnd_protocol == IRMP_NOKIA_PROTOCOL && (current_bit == 23 || current_bit == 47))) // start bit of info- or stop-frame (Nokia)
{
pulse_len = startbit_pulse_len;
pause_len = startbit_pause_len;
first_pulse = TRUE;
}
else // send n'th bit
{
pulse_len = GRUNDIG_OR_NOKIA_BIT_LEN;
pause_len = GRUNDIG_OR_NOKIA_BIT_LEN;
first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;
}
}
else // if (irsnd_protocol == IRMP_RC5_PROTOCOL || irsnd_protocol == IRMP_SIEMENS_PROTOCOL)
#endif
{
if (current_bit == 0xFF) // 1 start bit
{
first_pulse = TRUE;
}
else // send n'th bit
{
first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? TRUE : FALSE;
}
 
if (irsnd_protocol == IRMP_RC5_PROTOCOL)
{
first_pulse = first_pulse ? FALSE : TRUE;
}
}
 
if (first_pulse)
{
if (pulse_counter < pulse_len)
{
if (pulse_counter == 0)
{
irsnd_on ();
}
pulse_counter++;
}
else // if (pause_counter < pause_len)
{
if (pause_counter == 0)
{
irsnd_off ();
}
pause_counter++;
}
}
else
{
if (pause_counter < pause_len)
{
if (pause_counter == 0)
{
irsnd_off ();
}
pause_counter++;
}
else // if (pulse_counter < pulse_len)
{
if (pulse_counter == 0)
{
irsnd_on ();
}
pulse_counter++;
}
}
}
break;
}
#endif // IRSND_SUPPORT_RC5_PROTOCOL == 1 || IRSND_SUPPORT_SIEMENS_PROTOCOL == 1 || IRSND_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRSND_SUPPORT_NOKIA_PROTOCOL == 1
 
default:
{
irsnd_busy = FALSE;
break;
}
}
}
 
if (! irsnd_busy)
{
if (repeat_counter < n_repeat_frames)
{
#if IRSND_SUPPORT_FDC_PROTOCOL == 1
if (irsnd_protocol == IRMP_FDC_PROTOCOL)
{
irsnd_buffer[2] |= 0x0F;
}
#endif
repeat_counter++;
irsnd_busy = TRUE;
}
else
{
n_repeat_frames = 0;
repeat_counter = 0;
}
}
}
 
#ifdef DEBUG
if (irsnd_is_on)
{
putchar ('0');
}
else
{
putchar ('1');
}
#endif
 
return irsnd_busy;
}
 
#ifdef DEBUG
 
// main function - for unix/linux + windows only!
// AVR: see main.c!
// Compile it under linux with:
// cc irsnd.c -o irsnd
//
// usage: ./irsnd protocol hex-address hex-command >filename
 
int
main (int argc, char ** argv)
{
int idx;
int protocol;
int address;
int command;
IRMP_DATA irmp_data;
 
if (argc != 4 && argc != 5)
{
fprintf (stderr, "usage: %s protocol hex-address hex-command [repeat] > filename\n", argv[0]);
return 1;
}
 
if (sscanf (argv[1], "%d", &protocol) == 1 &&
sscanf (argv[2], "%x", &address) == 1 &&
sscanf (argv[3], "%x", &command) == 1)
{
irmp_data.protocol = protocol;
irmp_data.address = address;
irmp_data.command = command;
 
if (argc == 5)
{
irmp_data.flags = atoi (argv[4]);
}
else
{
irmp_data.flags = 0;
}
 
irsnd_init ();
 
(void) irsnd_send_data (&irmp_data, TRUE);
 
while (irsnd_busy)
{
irsnd_ISR ();
}
for (idx = 0; idx < 20; idx++)
{
irsnd_ISR ();
}
 
putchar ('\n');
}
else
{
fprintf (stderr, "%s: wrong arguments\n", argv[0]);
return 1;
}
return 0;
}
 
#endif // DEBUG
/Servo-Controlled IR-Transmitter/Software/irmpconfig.h
New file
0,0 → 1,116
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* irmpconfig.h
*
* Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de
*
* $Id: irmpconfig.h,v 1.43 2010/11/10 08:01:46 fm Exp $
*
* ATMEGA88 @ 8 MHz
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
#ifndef _IRMPCONFIG_H_
#define _IRMPCONFIG_H_
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Change F_INTERRUPTS if you change the number of interrupts per second,
* Normally, F_INTERRUPTS should be in the range from 10000 to 15000.
* A value above 15000 costs additional program space, absolut maximum value is 20000.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#ifndef F_INTERRUPTS
#define F_INTERRUPTS 20000 // interrupts per second, min: 10000, max: 20000
#endif
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Change settings from 1 to 0 if you want to disable one or more decoders.
* This saves program space.
*
* 1 enable decoder
* 0 disable decoder
*
* The standard decoders are enabled per default.
* Some less common protocols are disabled here, you need to enable them manually.
*
* If you want to use FDC or RCCAR simultaneous with RC5 protocol, additional program space is required.
* If you don't need RC5 when using FDC/RCCAR, you should disable RC5.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
// Protocol Enable Remarks F_INTERRUPTS Program Space
#define IRMP_SUPPORT_SIRCS_PROTOCOL 1 // Sony SIRCS >= 10000 ~100 bytes
#define IRMP_SUPPORT_NEC_PROTOCOL 1 // NEC + APPLE >= 10000 ~250 bytes
#define IRMP_SUPPORT_SAMSUNG_PROTOCOL 1 // Samsung + Samsung32 >= 10000 ~250 bytes
#define IRMP_SUPPORT_MATSUSHITA_PROTOCOL 0 // Matsushita >= 10000 ~50 bytes
#define IRMP_SUPPORT_KASEIKYO_PROTOCOL 1 // Kaseikyo >= 10000 ~250 bytes
#define IRMP_SUPPORT_DENON_PROTOCOL 0 // DENON >= 10000 ~250 bytes
#define IRMP_SUPPORT_JVC_PROTOCOL 1 // JVC >= 10000 ~250 bytes
#define IRMP_SUPPORT_RC5_PROTOCOL 1 // RC5 >= 10000 ~250 bytes
#define IRMP_SUPPORT_RC6_PROTOCOL 0 // RC6 & RC6A >= 10000 ~200 bytes
#define IRMP_SUPPORT_GRUNDIG_PROTOCOL 1 // Grundig >= 10000 ~150 bytes
#define IRMP_SUPPORT_NOKIA_PROTOCOL 1 // Nokia >= 10000 ~150 bytes
#define IRMP_SUPPORT_NUBERT_PROTOCOL 0 // NUBERT >= 10000 ~50 bytes
#define IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL 0 // Bang & Olufsen >= 10000 ~200 bytes
#define IRMP_SUPPORT_NIKON_PROTOCOL 1 // NIKON >= 10000 ~250 bytes
#define IRMP_SUPPORT_FDC_PROTOCOL 0 // FDC3402 keyboard >= 10000 (better 15000) ~50 bytes (~400 in combination with RC5)
#define IRMP_SUPPORT_RCCAR_PROTOCOL 0 // RC Car >= 10000 (better 15000) ~150 bytes (~500 in combination with RC5)
#define IRMP_SUPPORT_SIEMENS_PROTOCOL 0 // Siemens Gigaset >= 15000 ~150 bytes
#define IRMP_SUPPORT_RECS80_PROTOCOL 1 // RECS80 >= 20000 ~50 bytes
#define IRMP_SUPPORT_RECS80EXT_PROTOCOL 1 // RECS80EXT >= 20000 ~50 bytes
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Change hardware pin here:
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#ifdef PIC_CCS_COMPILER // PIC CCS Compiler:
 
#define IRMP_PIN PIN_B4 // use PB4 as IR input on PIC
 
#else // AVR:
 
#define IRMP_PORT PORTD
#define IRMP_DDR DDRD
#define IRMP_PIN PIND
#define IRMP_BIT 6 // use PD6 as IR input on AVR
 
#define input(x) ((x) & (1 << IRMP_BIT))
#endif
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Set IRMP_LOGGING to 1 if want to log data to UART with 9600Bd
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#ifndef IRMP_LOGGING
#define IRMP_LOGGING 0 // 1: log IR signal (scan), 0: do not (default)
#endif
 
#if IRMP_SUPPORT_SIEMENS_PROTOCOL == 1 && F_INTERRUPTS < 15000
#warning F_INTERRUPTS too low, SIEMENS protocol disabled (should be at least 15000)
#undef IRMP_SUPPORT_SIEMENS_PROTOCOL
#define IRMP_SUPPORT_SIEMENS_PROTOCOL 0
#endif
 
#if IRMP_SUPPORT_RECS80_PROTOCOL == 1 && F_INTERRUPTS < 20000
#warning F_INTERRUPTS too low, RECS80 protocol disabled (should be at least 20000)
#undef IRMP_SUPPORT_RECS80_PROTOCOL
#define IRMP_SUPPORT_RECS80_PROTOCOL 0
#endif
 
#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1 && F_INTERRUPTS < 20000
#warning F_INTERRUPTS too low, RECS80EXT protocol disabled (should be at least 20000)
#undef IRMP_SUPPORT_RECS80EXT_PROTOCOL
#define IRMP_SUPPORT_RECS80EXT_PROTOCOL 0
#endif
 
#if IRMP_SUPPORT_JVC_PROTOCOL == 1 && IRMP_SUPPORT_NEC_PROTOCOL == 0
#warning JVC protocol needs also NEC protocol, NEC protocol enabled
#undef IRMP_SUPPORT_NEC_PROTOCOL
#define IRMP_SUPPORT_NEC_PROTOCOL 1
#endif
 
#endif /* _WC_IRMPCONFIG_H_ */
/Servo-Controlled IR-Transmitter/Software/Hex-Files/fuses.txt
New file
0,0 → 1,9
Fuse-Bits:
----------
Hi 0xD9
Low 0xAE
 
Programming Examples:
---------------------
avrdude -p m8 -P COM1 -c ponyser -U lfuse:w:0xAE:m -U hfuse:w:0xD9:m -U flash:w:servo-IR.hex
avrdude -p m8 -P COM1 -c avr910 -b 115200 -U lfuse:w:0xAE:m -U hfuse:w:0xD9:m -U flash:w:servo-IR.hex
/Servo-Controlled IR-Transmitter/Software/Hex-Files/servo-IR.hex
New file
0,0 → 1,510
:10000000A9C0C3C0C2C0C1C0C0C0BFC01BC3BDC0A7
:10001000BCC0BBC0BAC0B9C0B8C0B7C0B6C0B5C01C
:10002000B4C0B3C0B2C063C3A1C3CBC37BC534C427
:1000300083C4C2C477C576C50AC473C39EC472C5DF
:1000400071C5E0C403C56EC56DC56CC53AC56AC54A
:100050005FC5F3C51CC648C68DC77FC6A5C6DEC62C
:1000600089C788C75AC686C7B7C684C783C7F9C6B3
:1000700010C780C77FC77EC72EC77CC752C78FC730
:100080008EC78DC774C98BC78AC765C870C96FC949
:1000900086C76DC984C76BC96AC95DC85CC867C9B2
:1000A00066C965C97CC763C97AC701151B0A0E0AF0
:1000B0000E0A0E0F14000F14000100020611133077
:1000C0000611061100101020200101000206111374
:1000D0003006110611000000000001010016070D96
:1000E0003755070D17250000000202010000030725
:1000F0000F1327070F050D00101525250101000519
:10010000030E1122030E030E00101C283001010003
:1001100006020485A50204576D0205050B0B0100BC
:1001200000070F150F15010101010207070D0D0052
:1001300000010C020485A50204576D0206060C0C92
:100140000100000F070E070E010101010000010B65
:100150001100010311241FBECFE5D4E0DEBFCDBFE7
:1001600010E0A0E6B0E0E8EBFFE102C005900D92E0
:10017000AA36B107D9F711E0AAE6B0E001C01D9296
:10018000A937B107E1F78ED115CF3ACF9C01E1999C
:10019000FECF3FBB2EBBE09A8DB308959C01E19941
:1001A000FECF3FBB2EBB6DBB0FB6F894E29AE19A2F
:1001B0000FBE08958FE193E09BBD8ABD89E08EBD9F
:1001C00080E189BF0895882311F4979A089597983C
:1001D000089530E020E0A0EABFE017C0979890E0D3
:1001E00006C0FD013197F1F7B29B21E09F5F9817A0
:1001F000C0F3979A90E006C0FD013197F1F7B29BEA
:1002000021E09F5F9617C0F33F5F341738F32093C8
:100210006A0008950F931F93CF93DF938B01A0E0A3
:10022000B0E050E0642F70E090E0C0EADFE01DC075
:10023000979820E030E007C0FE013197F1F7B29BBC
:1002400051E02F5F3F4F28173907B0F3979A20E00E
:1002500030E007C0FE013197F1F7B29B51E02F5F0C
:100260003F4F28173907B0F31196A617B70700F3C9
:1002700020E030E0E0EAFFE007C0CF010197F1F7AE
:10028000B29B51E02F5F3F4F20173107B0F35093DF
:100290006A00DF91CF911F910F910895B29BFECF1D
:1002A00084EF91E020E931E0F9013197F1F701970E
:1002B000D9F70895F89490E0019641E050E002C02B
:1002C000440F551F8A95E2F720E030E065E3862F62
:1002D0008A95F1F783B390E084239523892B31F03D
:1002E0002F5F3F4F8DE12C34380789F720E030E055
:1002F00065E3862F8A95F1F783B390E084239523F5
:10030000892B31F42F5F3F4F8DE12C34380789F76B
:1003100020E030E065E383B390E084239523892BCC
:1003200041F0862F8A95F1F72F5F3F4F2F3F310520
:1003300091F778942B343105D0F0C9018B5490405B
:10034000C29710F481E00895C9018D579040C2977B
:1003500010F482E00895C9018F5A9040C29710F4BA
:1003600083E00895213E310510F084E0089580E097
:1003700008950F931F93CF93DF93E0E6F1E010828F
:100380001182128213821482359681E0E937F807D0
:10039000B1F7B29BFECF84EF91E020E931E0F901A3
:1003A0003197F1F70197D9F701E0C0E9D1E08AE58B
:1003B00091E0FAD78823C1F181E07CDF182F82E039
:1003C00079DF10925F01412F50E0682F70E0FB0150
:1003D000EE0FFF1FE60FF71FEE0FFF1F9A01220F10
:1003E000331FCA01A5E0880F991FAA95E1F7821B68
:1003F000930BE80FF91FEC53FF4FAAE5B1E086E03D
:100400000D9001928150E1F7FA01EE0FFF1FEE0F00
:10041000FF1FE40FF51FE60FF71FE05AFE4F0083A2
:1004200089E169E14AE0D5DE84E664EF71E0402FBE
:10043000F1DE80916A00882309F4B9CF013011F010
:1004400001E001C002E088E893E1FE013197F1F795
:100450000197D9F7B299ABCF8BE190E064EC70E0F3
:1004600046E950E02EEC30E054DD82E090E060E6BA
:1004700071E049E150E02EEC30E04BDD89E169E1CB
:100480004AE0A7DEB29BFECF84EF91E020E931E0A5
:10049000F9013197F1F70197D9F7DF91CF911F91CA
:1004A0000F9108958F929F92AF92BF92CF92DF9259
:1004B000EF92FF920F931F93CF93DF9388E087BB58
:1004C00084E088BB14BA8CE085BB80E881BB80ECFB
:1004D00082BBE199FECF21E030E03FBB2EBBE09A2A
:1004E0008DB3873E09F1E0E6F1E0108211821282BD
:1004F00013821482359681E0E937F807B1F7E19964
:10050000FECF3FBB2EBB87EE8DBB0FB6F894E29AB1
:10051000E19A0FBE82E090E060E671E049E150E0D0
:100520002EEC30E0F6DC12C084EC90E06BE170E081
:1005300046E950E026EC30E0D2DC80E691E062E073
:1005400070E049E150E026EC30E0C9DC2AD7A0D0C9
:100550008FE193E09BBD8ABD89E08EBD80E189BFBC
:10056000B29BFECF84EF91E020E931E0F9013197B1
:10057000F1F70197D9F7789473E6D72E63E6C62E84
:1005800056E0852E4EE1942E30E9A32E31E0B32EB5
:1005900002C0C12ED02EB29BECDE81E08BDE082F94
:1005A00082E088DE182FC02FD0E0E82EFF24FE0165
:1005B000EE0FFF1FEE0FFF1FEC0FFD1FEE0DFF1DD7
:1005C000E05AFE4F80818130E1F4D01611F4C1165B
:1005D000C1F09798189DC0011124099D9001112424
:1005E000820F931F8C539F4F60E05FD05BD08823B6
:1005F000E9F788EE93E0F5013197F1F70197D9F724
:10060000979AFE01EE0FFF1FEE0FFF1FEC0FFD1F6D
:10061000EE0DFF1DE05AFE4F8081823009F0B9CF08
:100620009798189DC0011124099D90011124820FF3
:10063000931F8C539F4F60E038D034D08823E9F764
:10064000979AA7CF1F920F920FB60F9211242F9354
:100650003F934F935F936F937F938F939F93AF934A
:10066000BF93EF93FF9363D2882309F4E0D7FF9100
:10067000EF91BF91AF919F918F917F916F915F911A
:100680004F913F912F910F900FBE0F901F90189593
:10069000C398BB9A88E085BD85B5816085BD8DED29
:1006A00083BD0895809187000895CF93DF93EC0177
:1006B000662329F0809187008823E1F706C08091A6
:1006C0008700882311F080E02FC288818093880002
:1006D0008D8180938F008091880090E0FC0131979C
:1006E000E631F10508F01EC2ED5EFF4F09948B81E3
:1006F0009C8120E030E04CE0220F331F80FD216020
:10070000415019F096958795F7CFC901807F9F706A
:10071000A4E096958795AA95E1F780938900822FAA
:1007200048C16B817C81398140E050E08EEE97E8D2
:1007300020E1440F551F80FD4160215019F096952E
:100740008795F7CF932F80E0862B972B20E030E022
:1007500060E1220F331F80FD2160615019F09695F2
:100760008795F7CF82E0809388008DC089819A8138
:1007700040E050E020E1440F551F80FD41602150D2
:1007800019F096958795F7CF8B819C8120E030E01A
:1007900060E1220F331F80FD2160615019F09695B2
:1007A0008795F7CF5093890040938A0030938B0050
:1007B00082E0809388008BE880938C00832F809563
:1007C00042C189819A8140E050E020E1440F551FE9
:1007D00080FD4160215019F096958795F7CF8B8168
:1007E0009C8120E030E060E1220F331F80FD21601A
:1007F000615019F096958795F7CF509389004093F3
:100800008A00932F92959F70822F807F892B8093EF
:100810008B00C90180709F702070307F20953095CB
:10082000432F42954F709C01B4E036952795BA95B9
:10083000E1F7422B40938C0080959095A4E096952B
:100840008795AA95E1F7807F80938D0068C18981A3
:100850009A8140E050E020E1440F551F80FD416047
:10086000215019F096958795F7CF8B819C8120E0D8
:1008700030E060E1220F331F80FD2160615019F0EC
:1008800096958795F7CF5093890040938A003093CF
:100890008B0020938C0043C189819A8140E050E015
:1008A00020E1440F551F80FD4160215019F09695BD
:1008B0008795F7CF8B819C8160E070E020E1660F27
:1008C000771F80FD6160215019F096958795F7CFCD
:1008D0005093890040938A00362F3F70852F829570
:1008E0008F70242F2F702827CA01807F9070B4E06A
:1008F00096958795BA95E1F7282740705F70252770
:100900002295207F322B30938B00872F82958F701A
:1009100080938C00607F7F70A4E076956795AA95A0
:10092000E1F760938D0020918B0080918C00909175
:100930008D0082278927C2C080918600882311F408
:1009400030E401C030E03093860029812770220F07
:10095000220F220F8B819C8188739070F3E0969513
:100960008795FA95E1F7282B2068232B209389009F
:100970008B818295880F807E42C08091850088237C
:1009800011F430E401C030E03093850029812F70EC
:10099000220F220F8B819C8180739070E4E09695EA
:1009A0008795EA95E1F7282B2068232B209389006F
:1009B0008B818295807F23C080918400882311F4ED
:1009C00040E401C040E0409384002B813C8126FD3F
:1009D00002C090E801C090E02072307075E036955A
:1009E00027957A95E1F789818F71880F822B942B57
:1009F000892B809389008B81880F880F880F8093C3
:100A00008A008DC08B819C8120E030E049E0220F7C
:100A1000331F80FD2160415019F096958795F7CFDF
:100A20008FEF8093890080EC80938A00C9019695AE
:100A3000879596958795806880938B00822F829505
:100A4000880F880F807C80938C0069C089819A818F
:100A500060E070E028E0660F771F80FD6160215044
:100A600019F096958795F7CF8B819C8120E030E037
:100A700048E0220F331F80FD2160415019F0969508
:100A80008795F7CF8FEB809389008FEF80938A0053
:100A900080E880938B00C901969587958068809344
:100AA0008C00279522272795CB0196958795282B93
:100AB00020938D00862F87958827879580938E00B9
:100AC0002EC089819A8120E030E044E0220F331F5C
:100AD00080FD2160415019F096958795F7CF8B8165
:100AE0009C8140E050E06CE0440F551F80FD416068
:100AF000615019F096958795F7CFCA0180709F7065
:100B00002295207F292B2093890040938A0007C0DB
:100B10008B818295880F880F807C8093890081E08B
:100B20008093870080918700DF91CF910895809115
:100B30008700882309F432C4509164005F3F09F0B4
:100B40001BC280916300882309F416C2409175008E
:100B5000442309F440C08091710090917200019685
:100B60009093720080937100209173003091740013
:100B70008217930708F444C010927200109271001B
:100B800080918800883029F480E1809364008FE1AF
:100B90001FC0809188008F3021F4809364008AE127
:100BA00017C080918800803109F0E6C1242F30E021
:100BB0002F5F3F4F8091760090E0281739072CF483
:100BC00087E18093640089E203C05093640081E16F
:100BD00080937700D1C140916F004423A1F0209110
:100BE0006B0030916C0080916D0090916E00281721
:100BF000390748F42F5F3F4F30936C0020936B0010
:100C000080918700089580918F00809370001092EA
:100C10006C0010926B001092820010928100109272
:100C200080008091880090E0FC013197E631F10569
:100C300008F0A0C1E75DFF4F099480E380937F0037
:100C40008CE090E090937E0080937D0088E180931B
:100C50007C008CE080937B0080937A008093790005
:100C60001092780080937700442311F081E001C056
:100C700083E08093760084EF91E0909374008093FA
:100C8000730090936E0080936D0087EC71C184EBCC
:100C900080937F00442349F08DE290E090937E00A2
:100CA00080937D001092770009C08AE590E09093D0
:100CB0007E0080937D0080E2809377009BE090939C
:100CC0007C0082E280937B0090937A00909379007D
:100CD00081E08093780080937600109274001092E7
:100CE000730080E293E03FC18AE580937F008AE54C
:100CF00090E090937E0080937D009BE090937C0039
:100D00008DE180937B0090937A0089E08093790055
:100D100091E09093780085E276C08AE580937F0029
:100D20008AE590E090937E0080937D009BE0909315
:100D30007C008DE180937B0090937A0089E0809322
:100D4000790081E08093780080E28093770082E0F0
:100D5000809376008CEA93E022C084E480937F0045
:100D600082E290E090937E0080937D0098E09093E3
:100D70007C0089E180937B0090937A0090937900C6
:100D800081E08093780080E380937700442311F022
:100D900081E001C082E08093760088EC95E090933A
:100DA000740080937300DFC023E020937F0085E907
:100DB00090E090937E0080937D0020937C0085E9F5
:100DC00080937B0020937A0082E68093790091E003
:100DD000909378008BE017C023E020937F0089E494
:100DE00090E090937E0080937D0020937C0085E9C5
:100DF00080937B0020937A0082E68093790091E0D3
:100E0000909378008CE08093770090937600109216
:100E100074001092730084E893E0A5C022E120934F
:100E20007F0082E190E090937E0080937D0020938C
:100E300062009093610080936000109278008DE0D2
:100E40008093770081E08093760010927400109276
:100E5000730084E893E090936E0080936D008DEDB5
:100E600087C02BE020937F0085E390E090937E0085
:100E700080937D00209362008BE090E0909361006E
:100E800080936000109278008AE08093770082E07F
:100E900017C02BE020937F0085E390E090937E00C5
:100EA00080937D00209362008BE090E0909361003E
:100EB000809360001092780081E18093770083E056
:100EC0008093760080E991E09093740080937300A2
:100ED00083E399E048C0442311F01092640084EB4E
:100EE00080937F008AE590E090937E0080937D0060
:100EF00080E1809377009BE090937C0082E2809376
:100F00007B0090937A009093790081E08093780041
:100F100080937600109274001092730088EB91E039
:100F200022C08CE280937F008FE091E090937E005E
:100F300080937D0082E0809377009AE090937C001C
:100F400086E480937B0090937A008EE18093790011
:100F500081E0809378008093760010927400109264
:100F6000730080EB94E090936E0080936D0081EDB0
:100F700083BD02C01092870080918700882309F406
:100F8000F8C1109263008091880090E0FC013197D5
:100F9000E631F10508F0EBC1E15CFF4F09944091A7
:100FA0008200442309F08DC0909164009F3F49F472
:100FB00080917F008093620080917D0090917E00FF
:100FC0007CC080917700981708F067C080918800F6
:100FD0008330D9F5903170F48BE080936200E92F73
:100FE000E695E695E695F0E0E757FF4F208130E083
:100FF000892F19C0903131F48BE0809362008AE52B
:1010000090E05BC0953208F05CC0892F81502BE0E6
:1010100020936200E82FE695E695E695F0E0E75725
:10102000FF4F208130E090E0809590958770907020
:1010300002C0359527958A95E2F720FD03C089E027
:1010400090E03BC08DE190E038C0E92FE695E69551
:10105000E695F0E0E757FF4F208130E0892F90E0E0
:10106000809590958770907002C0359527958A95E8
:10107000E2F720FF07C080917C008093620080919E
:101080007B0006C080917A00809362008091790095
:10109000809360001092610014C0809178008823D2
:1010A00081F080917A008093620090917500809128
:1010B0007600981758F38FEF90E09093610080933B
:1010C000600080916200481780F4442351F48091BD
:1010D0008300882331F485B5886185BD81E08093E4
:1010E00083004F5F4093820044C120918000309183
:1010F000810080916000909161002817390708F401
:1011000010C1809164008F5F8093640090E04091F3
:1011100078002091770030E0240F311D821793076B
:101120009CF08FEF80936400809175008F5F8093B7
:10113000750090917600891721F410928700109223
:10114000750081E08093630010928200109281000C
:10115000109280000EC190918200809162009817D9
:1011600009F058C02091800030918100809160008A
:10117000909161002817390709F04CC080916400F4
:101180008F5F80936400909177008917E8F18FEF6B
:1011900080936400809188008F3021F080918800D6
:1011A000803119F5309175003F5F309375002091C3
:1011B0006F00222331F083E399E0909374008093D1
:1011C00073008091700090917600281738F49F5F2B
:1011D000909376002F5F20936F0009C0391739F480
:1011E000109287001092750002C01092870081E073
:1011F0008093630080918300882331F085B58F7ED2
:1012000085BDC398109283001092820010928100D5
:101210001092800080916300882309F0AAC0809119
:1012200088008F3029F080918800803109F03EC01D
:10123000409164004F3F71F0809188008F3011F42D
:101240004F3041F080918800803189F4473111F0AE
:101250004F3269F480917F008093620080917D001D
:1012600090917E00909361008093600044C08BE079
:10127000809362008BE090E0909361008093600027
:10128000E42FE695E695E695F0E0E757FF4F2081DD
:1012900030E0842F90E0809590958770907002C028
:1012A000359527958A95E2F7217023C080916400D7
:1012B0008F3F11F421E014C0E82FE695E695E695FE
:1012C000F0E0E757FF4F208130E090E08095909567
:1012D0008770907002C0359527958A95E2F7217046
:1012E00080918800873029F480E0222309F481E08E
:1012F000282F222359F09091820080916200981744
:1013000030F120918000309181000BC0209180004D
:101310003091810080916000909161002817390719
:10132000A0F42115310551F480918300882331F018
:1013300085B58F7E85BDC398109283002F5F3F4F88
:10134000309381002093800014C0909182009923F3
:1013500051F480918300882331F485B5886185BD7F
:1013600081E0809383009F5F9093820002C010927F
:10137000870080918700882389F490916F00809185
:101380007000981738F49F5F90936F0081E080930E
:10139000870004C01092700010926F008091870047
:1013A000089596988E980895FC018091AF00882347
:1013B00009F47CC08091B000823051F1833009F093
:1013C00054C02091B3003091B4008091B30090914B
:1013D000B400232F332780959095907028173907F4
:1013E00009F061C08091B3009091B4009070909327
:1013F000B4008093B3002091B3003091B400809189
:10140000B5009091B600982F8827822B932B29C086
:101410002091B3003091B4008091B3009091B4005A
:10142000232F332780959095907028173907A1F0C6
:101430008091B1009091B2008E5E9748A1F58BE04B
:101440008093B0008091B3009091B400892F9927C8
:101450009093B2008093B1008091B3009091B4005A
:1014600090709093B4008093B3008091B00080831B
:101470008091B1009091B200928381838091B300FA
:101480009091B400948383838091B70085831092F8
:10149000B4001092B3001092B2001092B1001092FA
:1014A000B70081E001C080E01092AF000895F82FEE
:1014B00060919D007091A700671738F18091A80096
:1014C000681718F58091AD002F2F30E04091B800DB
:1014D0005091B900882381F0862F90E0871B9109F5
:1014E00002C0220F331F8A95E2F7422B532B5093F1
:1014F000B9004093B80069C0440F551F242B352B09
:101500003093B9002093B80060C07091A9006717AC
:1015100018F18091AA006817F8F48091AD002F2F80
:1015200030E04091BA005091BB00882381F0862FB3
:1015300090E0871B910902C0220F331F8A95E2F7C2
:10154000422B532B5093BB004093BA003EC0440F34
:10155000551F242B352B35C080919E008330D1F44C
:10156000613198F1653188F58F2F90E0262F30E0BA
:101570002151304002C0880F991F2A95E2F720912F
:10158000BC003091BD00282B392B3093BD00209337
:10159000BC001BC08530C9F46431B8F06831A8F4D0
:1015A0008F2F90E0262F30E02850304002C0880F67
:1015B000991F2A95E2F72091BA003091BB00282BA1
:1015C000392B3093BB002093BA0080919E00853068
:1015D00051F5603340F5262F30E0E62FE695E6958D
:1015E000E695FF2381F0F0E0E254FF4F2770307062
:1015F00081E090E002C0880F991F2A95E2F72081D0
:10160000282B208310C0F0E0E254FF4F2770307089
:1016100081E090E002C0880F991F2A95E2F780953B
:101620002081822380836F5F60939D00089590B333
:101630008091AF00882309F046C4907480919C008B
:101640008823A1F540919900992321F44F5F40939D
:10165000990039C44423D9F081E080939C008093A1
:101660009A0010929B001092BB001092BA00109248
:10167000B9001092B8008FEF80939D0081E090E058
:101680009093980080939700109293001CC48091CF
:101690009500909196002FEF8F3F920709F413C4A5
:1016A000019690939600809395000DC480919A00C6
:1016B000882309F42CC1409199009923B9F08091B5
:1016C00097009091980001969093980080939700CE
:1016D0004252453120F051E08B34950720F48F546D
:1016E000924008F4C9C28091B000E6C1842F8A52AA
:1016F0008D3060F480919700909198008930910529
:1017000028F00F9718F46AEA70E0C5C08091B00025
:10171000843171F44B3660F04E3F50F48091970065
:10172000909198008134910518F08B3B910570F0F1
:10173000842F8B568339B0F4809197009091980054
:101740008533910530F08038910530F46BEB70E013
:10175000A2C08A31910530F08134910518F46CEC07
:1017600070E099C0842F8252853170F48091970087
:101770009091980051E0813B950730F08C58924051
:1017800018F46DED70E087C0842F8055853168F4C2
:1017900080919700909198008035910530F08536C2
:1017A000910518F46EEE70E076C0842F8C53803172
:1017B00060F480919700909198008D31910528F008
:1017C000879718F46FEF70E066C0542F5250533073
:1017D00068F480919700909198008538910530F0D9
:1017E000863A910518F460E171E055C0842F8F505E
:1017F000873018F08F508D3020F520919700309170
:101800009800C9010F97079720F0C9014E970D97CF
:10181000C0F430939200209391004651453128F056
:10182000265130402531310530F41092900080E48B
:101830008093930003C081E08093900061E271E0A7
:101840002AC0533068F480919700909198008434B6
:10185000910530F08E34910518F462E371E01BC0FD
:1018600047504830A0F480919700909198008B32B7
:10187000910568F08134910550F490939200809323
:10188000910081E08093900063E471E004C01092C5
:101890009C0060E070E080919C00882329F08EE934
:1018A00090E041E150E012D310929D008091AE0093
:1018B000282F30E080FF21C080919E008930E9F020
:1018C00040919700509198008091A00090E084177B
:1018D000950750F4880F991F8417950728F03695BF
:1018E0002795822F809507C080919000882329F446
:1018F00036952795822F8170DADD81E080939900FB
:10190000109298001092970010929A00B5C18091A1
:101910009B00882309F49FC1992309F4D6C06091E4
:101920009D00E091AB006E1799F48091AC0081307E
:1019300079F4909199008091A300981708F4BCC0A5
:101940008091A400891708F4B7C01092AC0094C12C
:1019500040919700509198004F5F5F4F50939800CF
:101960004093970070919E007130C1F44F30510543
:1019700008F44DC06B3008F44AC06F5F6093AB0051
:1019800061508091A900680F6F5F6093AA008DE09D
:1019900090E0909398008093970097C07F30B9F5BE
:1019A0008091AC00882399F58091A20090E0880F87
:1019B000991F8417950730F4683020F08AE08093EF
:1019C000AB003DC06A3008F457C180E180939E00AF
:1019D00099E09093A70081E18093A80081E0809333
:1019E000A9009093AA002091BA003091BB00C901D0
:1019F00080709370892B09F43FC13093B800109226
:101A0000B90030703093BB002093BA0035C180918B
:101A1000AE0080FF18C08091A20090E0880F991F4F
:101A20008417950780F4262F30E08E2F90E00297E0
:101A30002817390744F08091AC00882321F481E015
:101A40008093AC0042C04B54514008F415C1262F7E
:101A500030E08E2F90E001972817390741F48091EC
:101A6000AC00882321F46F5F60939D0005C1723044
:101A700019F5862F80518230F8F441E04093AC0094
:101A800084E180939E006093AB008091B8009091B8
:101A9000B9009C0154E0369527955A95E1F73093AB
:101AA000BB002093BA008F7090709093B900809320
:101AB000B80040939C00E0C010929C0010929900E6
:101AC0001092980010929700D7C08091AE00282FF6
:101AD00030E080FF4CC0909199008091A000891760
:101AE000B0F436952795822F80958170E0DC809147
:101AF000AE0090E0969587958170D9DC8091AE001C
:101B000090E09695879581708093900027C0809192
:101B10009F009817E8F020919100309192008091F9
:101B2000A20090E08217930770F4880F991F821724
:101B3000930748F090E080919000882309F491E0A9
:101B40009093900002C090919000892FB0DC06C065
:101B500010929C001092980010929700809197002C
:101B60009091980090939200809391004FC0809143
:101B70009E00833079F580919D00803159F58091E8
:101B800099008750893008F05EC02091970030910D
:101B900098002035310568F02536310550F4109253
:101BA0009B001092BD001092BC0081E180939D00CB
:101BB00050C08AE080939E0080E18093A90080E27B
:101BC0008093AA008093AB0023513040253131052A
:101BD000C0F51AC04091990080919F004817C8F045
:101BE0008091A0008417A8F0209197003091980070
:101BF0008091A10090E02817390758F08091A20049
:101C000090E08217930728F081E051DC10929B004E
:101C100020C08091A3004817B0F08091A4008417E1
:101C200090F020919700309198008091A50090E06D
:101C30002817390740F08091A60090E0821793079B
:101C400010F080E0E2CF10929C0010929800109269
:101C5000970081E005C0992331F4809199008F5F4E
:101C60008093990009C081E080939B0081E090E01F
:101C7000909398008093970080919C00882309F4AA
:101C800022C140919D008091AB00481709F01BC113
:101C90008091AC00882309F016C1609165007091B5
:101CA00066002091BA003091BB006217730769F497
:101CB00080919500909196008054964030F48091E8
:101CC00094008F5F8093940002C010929400509112
:101CD0009E00513031F4809194008150823098F40C
:101CE0000DC0553029F480919400813061F406C014
:101CF0005A3049F48091940080FF05C010929600FC
:101D00001092950093C081E08093AF005F3029F47A
:101D10002F5F314009F05DC00EC0503179F48091E1
:101D2000B8009091B9008F3F910509F052C02E3F45
:101D3000310509F04EC01092AF0078C0523001F565
:101D4000442309F046C080919500909196008056FA
:101D50009940E8F580916700909168009093B900F0
:101D60008093B8007093BB006093BA008091B70075
:101D700081608093B700109296001092950029C060
:101D8000553039F58091BE009091BF004091C00060
:101D9000282F2F7082958F702827892F8F702827E2
:101DA00092959F70292730E0842F90E08F7090707B
:101DB0002817390711F01092AF008091C100482711
:101DC0008091C20048278091C300481711F01092FB
:101DD000AF005093B0008091B8009091B9009093FB
:101DE000B2008093B10090936800809367005730F1
:101DF00069F42091930030E08091BA009091BB008B
:101E0000822B932B9093BB008093BA008091BA00F1
:101E10009091BB009093B4008093B3008091BC007C
:101E20009091BD009093B6008093B5008091AF0073
:101E30008823B1F12091B3003091B4008091650006
:101E40009091660082179307B9F42091B100309108
:101E5000B20080916700909168008217930761F447
:101E60008091950090919600885B9B4028F480912A
:101E7000B70081608093B7008091B8009091B9005D
:101E800090936800809367008091BA009091BB00A6
:101E900090936600809365001092960010929500D2
:101EA00010929C001092BB001092BA001092990000
:101EB00010929800109297008091B000843119F42C
:101EC00083EB809399008091AF000895FB01DC01C2
:101ED00002C005900D9241505040D8F70895A0E0FF
:101EE000B0E0E4E7FFE039C07C01EB018A01690161
:101EF00009C0CE012196F6010995F70181937F0172
:101F00000150104001151105A1F7CDB7DEB7E8E08B
:101F100040C0A0E0B0E0EEE8FFE01FC0EC017B01B4
:101F20008A01690109C0CE012196F70161917F0103
:101F3000F60109950150104001151105A1F7CDB723
:101F4000DEB7E8E026C02F923F924F925F926F92E9
:101F50007F928F929F92AF92BF92CF92DF92EF9239
:101F6000FF920F931F93CF93DF93CDB7DEB7CA1BBA
:101F7000DB0B0FB6F894DEBF0FBECDBF09942A88E5
:101F8000398848885F846E847D848C849B84AA848D
:101F9000B984C884DF80EE80FD800C811B81AA811A
:101FA000B981CE0FD11D0FB6F894DEBF0FBECDBFE5
:081FB000ED010895F894FFCF44
:0A1FB800FF00FF01FFFFFFFFFF0025
:00000001FF
/Servo-Controlled IR-Transmitter/Software/irsnd.h
New file
0,0 → 1,47
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* irsnd.h
*
* Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de
*
* $Id: irsnd.h,v 1.3 2010/06/10 10:05:56 fm Exp $
*
* ATMEGA88 @ 8 MHz
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
#ifndef _WC_IRSND_H_
#define _WC_IRSND_H_
 
/**
* Initialize ISND encoder
* @details Configures ISDN output pin
*/
extern void irsnd_init (void);
 
/**
* Check if sender is busy
* @details checks if sender is busy
* @return TRUE: sender is busy, FALSE: sender is not busy
*/
extern uint8_t irsnd_is_busy (void);
 
/**
* Send IRMP data
* @details sends IRMP data
* @param pointer to IRMP data structure
* @return TRUE: successful, FALSE: failed
*/
extern uint8_t irsnd_send_data (IRMP_DATA *, uint8_t);
 
/**
* ISR routine
* @details ISR routine, called 10000 times per second
*/
extern uint8_t irsnd_ISR (void);
 
#endif /* _WC_IRSND_H_ */
/Servo-Controlled IR-Transmitter/Software/main.c
New file
0,0 → 1,335
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* main.c - Servo controlled infrared transmitter
*
* Copyright (c) 2010-0xFFFF Stefan Pendsa
* Based on the nice IR decoder/encoder routines (IRMP/IRSND) from Frank Meyer => http://www.mikrocontroller.net/articles/IRMP
*
* ATMEGA8 @ 16 MHz
*
* Fuses: lfuse:0xAE hfuse:0xD9
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include "irmp.h"
#include "irsndconfig.h"
#include "irsnd.h"
 
#ifndef F_CPU
#error F_CPU unkown
#endif
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Global variables
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
unsigned char key=0; // goes 1 when key was pressed
unsigned char ee_dummy EEMEM; // don't use the first byte in EEPROM, causes problems on some old AVRs...
unsigned char ee_check EEMEM; // Check-Byte to see if EEPROM is initialized
unsigned char active[5][5]; // Array to see which servo-combinations were populated with valid IR-codes
unsigned char ee_active[5][5] EEMEM; // Array to see which servo-combinations were populated with valid IR-codes (in EEPROM)
 
IRMP_DATA ir_data[5][5]; // Array with IR-codes for every servo-combination
IRMP_DATA ee_ir_data[5][5] EEMEM; // Array with IR-codes for every servo-combination (in EEPROM)
IRMP_DATA ir_temp; // Received IR-codes goes into here
 
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* timer 1 initialization
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
void timer_init (void)
{
OCR1A = (F_CPU / F_INTERRUPTS) - 1; // compare value: 1/10000 of CPU frequency
TCCR1B = (1 << WGM12) | (1 << CS10); // switch CTC Mode on, set prescaler to 1
 
#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega64__) || defined (__AVR_ATmega162__)
TIMSK = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare (use TIMSK for ATMEGA162)
#else
TIMSK1 = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare (use TIMSK for ATMEGA162)
#endif // __AVR...
}
 
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* timer 1 compare handler, called every 1/20000 sec
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
ISR(TIMER1_COMPA_vect)
{
if (!irsnd_ISR()) // call irsnd ISR
{ // if not busy...
irmp_ISR(); // call irmp ISR
}
}
 
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* LED control: 0 = off, >0 = on
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
void LED(unsigned char bit)
{
if (bit == 0) PORTD |= 1<<PORTD7;
else PORTD &= ~(1<<PORTD7);
}
 
 
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* LED Flash (on for time1, off for time2, repeated). Keypressing is checked in background
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
void Flash(unsigned char time1, unsigned char time2, unsigned char repeat)
{
unsigned char i,j;
key = 0;
for (i=0;i<repeat;i++)
{
PORTD &= ~(1<<PORTD7);
for (j=0;j<time1;j++)
{
_delay_ms(1);
if (!(PINB & (1<<PINB2))) key = 1;
}
PORTD |= 1<<PORTD7;
for (j=0;j<time2;j++)
{
_delay_ms(1);
if (!(PINB & (1<<PINB2))) key = 1;
}
}
}
 
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* LED Flash2 (on/off for time1, repeated, followed by delay of time2). Keypressing is checked in background
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
void Flash2(unsigned char time1, unsigned int time2, unsigned char repeat)
{
unsigned int i,j;
key = 0;
 
for (i=0;i<repeat;i++)
{
PORTD &= ~(1<<PORTD7);
for (j=0;j<time1;j++)
{
_delay_ms(1);
if (!(PINB & (1<<PINB2))) key = 1;
}
PORTD |= 1<<PORTD7;
for (j=0;j<time1;j++)
{
_delay_ms(1);
if (!(PINB & (1<<PINB2))) key = 1;
}
}
 
for (j=0;j<time2;j++)
{
_delay_ms(1);
if (!(PINB & (1<<PINB2))) key = 1;
}
}
 
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Waits for button release followed by a debounce delay
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
void WaitForKeyRelease(void)
{
while(!(PINB & (1<<PINB2)));
_delay_ms(50);
}
 
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Get position from servo inputs 1 and 2. Returns 1/2/3 for down/middle/up and 0 for invalid signal
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
unsigned char Servo(unsigned char chan)
{
cli();
unsigned int i=0;
 
for (i=0;i<7500;i++) // wait max. 75 ms for signal going down
{
_delay_us(10);
if (!(PINC & (1<<(chan+1)))) break;
}
 
for (i=0;i<7500;i++) // wait max. 75 ms for signal going up
{
_delay_us(10);
if (PINC & (1<<(chan+1))) break;
}
 
for (i=0;i<255;i++) // measure time until signal goes down
{
if (!(PINC & (1<<(chan+1)))) break;
_delay_us(10);
}
 
 
sei();
if (i < 75) return 0; // 0,00 - 0,74 ms => 0 (switch to GND)
else if (i > 74 && i < 125) return 1; // 0,75 - 1,24 ms => 1 (stick down)
else if (i > 124 && i < 175) return 2; // 1,25 - 1,74 ms => 2 (stick middle)
else if (i > 174 && i < 225) return 3; // 1,75 - 2,24 ms => 3 (stick up)
else if (i > 224) return 4; // 2,25 - ever ms => 4 (switch to VCC or open input)
return 0;
}
 
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Learning-Mode: When an IR signal arrives, it is saved in an array position related to the actual servo positions
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
void Learn(void)
{
unsigned char i,j,Servo1,Servo2,mode=1;
for (i=0;i<5;i++) // first, forget every assignment
{
for (j=0;j<5;j++)
{
active[i][j] = 0;
}
}
 
WaitForKeyRelease();
 
while(1)
{
if (irmp_get_data (&ir_temp)) // when IR code is decoded,
{
Servo1 = Servo(1); // get Servo positions
Servo2 = Servo(2);
ir_temp.flags = 0; // ignore reapeat-flag
ir_data[Servo1][Servo2] = ir_temp; // populate the array
active[Servo1][Servo2] = mode; // and flag it with the actually mode
Flash(25,25,10); // fast flash LED 10 times to indicate a learned code
}
 
Flash2(100,500,mode); // slow flash LED whole time to indicate we are in learning mode (flashing 1 or 2 times, depends on mode)
 
if (key) // toggle mode: single -> multi -> single -> multi ...
{
if (mode == 1) mode = 2;
else mode = 1;
 
_delay_ms(500);
if (!(PINB & (1<<PINB2))) break; // Leave learning mode when button is pressed for 500 ms
}
 
}
 
// Write to EEPROM
eeprom_write_block(&ir_data,&ee_ir_data,sizeof(unsigned char)*25*6);
eeprom_write_block(&active,&ee_active,sizeof(unsigned char)*25);
 
Flash(25,25,10); // fast flash LED 10 times to indicate that we are leaving the learning mode
WaitForKeyRelease();
}
 
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* MAIN: main routine
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
int main (void)
{
unsigned char i,j,Servo1,Servo2,Servo1old=99,Servo2old=99;
 
DDRB = 0b00001000; // IRED output, Switch input
PORTB = 0b00000100; // PullUp for Switch
 
DDRC = 0b00000000; // Input for Servo-Signals
PORTC = 0b00001100; // PullUp for (unused) Servos
 
DDRD = 0b10000000; // Input for received IR, output for LED
PORTD = 0b11000000; // PullUp for received IR, LED off
 
if (eeprom_read_byte(&ee_check)!=0xE7) // When EEPROM is uninitialized, do it now
{
for (i=0;i<5;i++)
{
for (j=0;j<5;j++)
{
active[i][j] = 0;
}
}
eeprom_write_byte(&ee_check, 0xE7);
eeprom_write_block(&active,&ee_active,sizeof(unsigned char)*25);
}
 
else // else, read in the contents
{
eeprom_read_block(&ir_data,&ee_ir_data,sizeof(unsigned char)*25*6);
eeprom_read_block(&active,&ee_active,sizeof(unsigned char)*25);
}
 
 
irmp_init(); // initialize irmp
irsnd_init(); // initialize irsnd
timer_init(); // initialize timer
WaitForKeyRelease();
sei (); // enable interrupts
 
 
while(1) // Main loop
{
if (!(PINB & (1<<PINB2))) Learn(); // Enter learning mode when the button is pressed
 
Servo1 = Servo(1); // get servo positions
Servo2 = Servo(2);
 
// when the actual posision was saved before, and the inputs are in a new position, send out its IR-code (single mode)
if (active[Servo1][Servo2] == 1 && (Servo1old != Servo1 || Servo2old != Servo2))
{
LED(1); // light up LED while sending IR-code
irsnd_send_data(&ir_data[Servo1][Servo2],FALSE);
while (irsnd_is_busy()); // wait until the frame was sent
_delay_ms(100);
LED(0);
}
 
if (active[Servo1][Servo2] == 2) // when the actual position was saved before, send out its IR-code (multi-mode)
{
LED(1); // light up LED while sending IR-code
irsnd_send_data(&ir_data[Servo1][Servo2],FALSE);
while (irsnd_is_busy()); // wait until the frame was sent
LED(0);
}
 
Servo1old = Servo1; // save old positions for single-mode
Servo2old = Servo2;
}
 
}
 
 
/Servo-Controlled IR-Transmitter/Software/irmp.c
New file
0,0 → 1,3323
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* irmp.c - infrared multi-protocol decoder, supports several remote control protocols
*
* Copyright (c) 2009-2010 Frank Meyer - frank(at)fli4l.de
*
* $Id: irmp.c,v 1.84 2010/11/09 19:18:32 fm Exp $
*
* ATMEGA88 @ 8 MHz
*
* Typical manufacturers:
*
* SIRCS - Sony
* NEC - NEC, Yamaha, Canon, Tevion, Harman/Kardon, Hitachi, JVC, Pioneer, Toshiba, Xoro, Orion, and many other Japanese manufacturers
* SAMSUNG - Samsung
* SAMSUNG32 - Samsung
* MATSUSHITA - Matsushita
* KASEIKYO - Panasonic, Denon & other Japanese manufacturers (members of "Japan's Association for Electric Home Application")
* RECS80 - Philips, Nokia, Thomson, Nordmende, Telefunken, Saba
* RC5 - Philips and other European manufacturers
* DENON - Denon
* RC6 - Philips and other European manufacturers
* APPLE - Apple
* NUBERT - Nubert Subwoofer System
* B&O - Bang & Olufsen
* PANASONIC - Panasonic (older, yet not implemented)
* GRUNDIG - Grundig
* NOKIA - Nokia
* SIEMENS - Siemens, e.g. Gigaset M740AV
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* SIRCS
* -----
*
* frame: 1 start bit + 12-20 data bits + no stop bit
* data: 7 command bits + 5 address bits + 0 to 8 additional bits
*
* start bit: data "0": data "1": stop bit:
* -----------------_________ ------_____ ------------______
* 2400us 600us 600us 600us 1200us 600 us no stop bit
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* NEC + extended NEC
* -------------------------
*
* frame: 1 start bit + 32 data bits + 1 stop bit
* data NEC: 8 address bits + 8 inverted address bits + 8 command bits + 8 inverted command bits
* data extended NEC: 16 address bits + 8 command bits + 8 inverted command bits
*
* start bit: data "0": data "1": stop bit:
* -----------------_________ ------______ ------________________ ------______....
* 9000us 4500us 560us 560us 560us 1690 us 560us
*
*
* Repetition frame:
*
* -----------------_________------______ .... ~100ms Pause, then repeat
* 9000us 2250us 560us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* SAMSUNG
* -------
*
* frame: 1 start bit + 16 data(1) bits + 1 sync bit + additional 20 data(2) bits + 1 stop bit
* data(1): 16 address bits
* data(2): 4 ID bits + 8 command bits + 8 inverted command bits
*
* start bit: data "0": data "1": sync bit: stop bit:
* ----------______________ ------______ ------________________ ------______________ ------______....
* 4500us 4500us 550us 450us 550us 1450us 550us 4500us 550us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* SAMSUNG32
* ----------
*
* frame: 1 start bit + 32 data bits + 1 stop bit
* data: 16 address bits + 16 command bits
*
* start bit: data "0": data "1": stop bit:
* ----------______________ ------______ ------________________ ------______....
* 4500us 4500us 550us 450us 550us 1450us 550us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* MATSUSHITA
* ----------
*
* frame: 1 start bit + 24 data bits + 1 stop bit
* data: 6 custom bits + 6 command bits + 12 address bits
*
* start bit: data "0": data "1": stop bit:
* ----------_________ ------______ ------________________ ------______....
* 3488us 3488us 872us 872us 872us 2616us 872us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* KASEIKYO
* --------
*
* frame: 1 start bit + 48 data bits + 1 stop bit
* data: 16 manufacturer bits + 4 parity bits + 4 genre1 bits + 4 genre2 bits + 10 command bits + 2 id bits + 8 parity bits
*
* start bit: data "0": data "1": stop bit:
* ----------______ ------______ ------________________ ------______....
* 3380us 1690us 423us 423us 423us 1269us 423us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* RECS80
* ------
*
* frame: 2 start bits + 10 data bits + 1 stop bit
* data: 1 toggle bit + 3 address bits + 6 command bits
*
* start bit: data "0": data "1": stop bit:
* -----_____________________ -----____________ -----______________ ------_______....
* 158us 7432us 158us 4902us 158us 7432us 158us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* RECS80EXT
* ---------
*
* frame: 2 start bits + 11 data bits + 1 stop bit
* data: 1 toggle bit + 4 address bits + 6 command bits
*
* start bit: data "0": data "1": stop bit:
* -----_____________________ -----____________ -----______________ ------_______....
* 158us 3637us 158us 4902us 158us 7432us 158us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* RC5 + RC5X
* ----------
*
* RC5 frame: 2 start bits + 12 data bits + no stop bit
* RC5 data: 1 toggle bit + 5 address bits + 6 command bits
* RC5X frame: 1 start bit + 13 data bits + no stop bit
* RC5X data: 1 inverted command bit + 1 toggle bit + 5 address bits + 6 command bits
*
* start bit: data "0": data "1":
* ______----- ------______ ______------
* 889us 889us 889us 889us 889us 889us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* DENON
* -----
*
* frame: 0 start bits + 16 data bits + stop bit + 65ms pause + 16 inverted data bits + stop bit
* data: 5 address bits + 10 command bits
*
* data "0": data "1":
* ------________________ ------______________
* 275us 775us 275us 1900us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* RC6
* ---
*
* RC6 frame: 1 start bit + 1 bit "1" + 3 mode bits + 1 toggle bit + 16 data bits + 2666 µs pause
* RC6 data: 8 address bits + 8 command bits
*
* start bit toggle bit "0": toggle bit "1": data/mode "0": data/mode "1":
* ____________------- _______------- -------_______ _______------- -------_______
* 2666us 889us 889us 889us 889us 889us 444us 444us 444us 444us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* APPLE
* -----
*
* frame: 1 start bit + 32 data bits + 1 stop bit
* data: 16 address bits + 11100000 + 8 command bits
*
* start bit: data "0": data "1": stop bit:
* -----------------_________ ------______ ------________________ ------______....
* 9000us 4500us 560us 560us 560us 1690 us 560us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* NUBERT (subwoofer system)
* -------------------------
*
* frame: 1 start bit + 10 data bits + 1 stop bit
* data: 0 address bits + 10 command bits ?
*
* start bit: data "0": data "1": stop bit:
* ----------_____ ------______ ------________________ ------______....
* 1340us 340us 500us 1300us 1340us 340us 500us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* BANG_OLUFSEN
* ------------
*
* frame: 4 start bits + 16 data bits + 1 trailer bit + 1 stop bit
* data: 0 address bits + 16 command bits
*
* 1st start bit: 2nd start bit: 3rd start bit: 4th start bit:
* -----________ -----________ -----_____________ -----________
* 210us 3000us 210us 3000us 210us 15000us 210us 3000us
*
* data "0": data "1": data "repeat bit": trailer bit: stop bit:
* -----________ -----_____________ -----___________ -----_____________ -----____...
* 210us 3000us 210us 9000us 210us 6000us 210us 12000us 210us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* GRUNDIG
* -------
*
* packet: 1 start frame + 19,968ms pause + N info frames + 117,76ms pause + 1 stop frame
* frame: 1 pre bit + 1 start bit + 9 data bits + no stop bit
* pause between info frames: 117,76ms
*
* data of start frame: 9 x 1
* data of info frame: 9 command bits
* data of stop frame: 9 x 1
*
* pre bit: start bit data "0": data "1":
* ------____________ ------______ ______------ ------______
* 528us 2639us 528us 528us 528us 528us 528us 528us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* NOKIA:
* ------
*
* Timing similar to Grundig, but 16 data bits:
* frame: 1 pre bit + 1 start bit + 8 command bits + 8 address bits + no stop bit
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* SIEMENS:
* --------
*
* SIEMENS frame: 1 start bit + 22 data bits + no stop bit
* SIEMENS data: 13 address bits + 1 repeat bit + 7 data bits + 1 unknown bit
*
* start bit data "0": data "1":
* -------_______ _______------- -------_______
* 250us 250us 250us 250us 250us 250us
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* PANASONIC (older protocol, yet not implemented, see also MATSUSHITA, timing very similar)
* -----------------------------------------------------------------------------------------
*
* frame: 1 start bit + 22 data bits + 1 stop bit
* 22 data bits = 5 custom bits + 6 data bits + 5 inverted custom bits + 6 inverted data bits
*
* European version: T = 456us
* USA & Canada version: T = 422us
*
* start bit: data "0": data "1": stop bit:
* 8T 8T 2T 2T 2T 6T 2T
* -------------____________ ------_____ ------_____________ ------_______....
* 3648us 3648us 912us 912us 912us 2736us 912us (Europe)
* 3376us 3376us 844us 844us 844us 2532us 844us (US)
*
*---------------------------------------------------------------------------------------------------------------------------------------------------
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
#if defined(__PCM__) || defined(__PCB__) || defined(__PCH__) // CCS PIC Compiler instead of AVR
#define PIC_CCS_COMPILER
#endif
 
#ifdef unix // test on linux/unix
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
 
#define ANALYZE
#define PROGMEM
#define memcpy_P memcpy
 
#else // not unix:
 
#ifdef WIN32
#include <stdio.h>
#include <string.h>
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
#define ANALYZE
#define PROGMEM
#define memcpy_P memcpy
 
#else
 
#ifndef CODEVISION
 
#ifdef PIC_CCS_COMPILER
 
#include <string.h>
typedef unsigned int8 uint8_t;
typedef unsigned int16 uint16_t;
#define PROGMEM
#define memcpy_P memcpy
 
#else // AVR:
 
#include <inttypes.h>
#include <stdio.h>
#include <string.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
 
#endif // PIC_CCS_COMPILER
#endif // CODEVISION
 
#endif // windows
#endif // unix
 
#ifndef IRMP_USE_AS_LIB
#include "irmpconfig.h"
#endif
#include "irmp.h"
 
#if IRMP_SUPPORT_GRUNDIG_PROTOCOL == 1 || IRMP_SUPPORT_NOKIA_PROTOCOL == 1
#define IRMP_SUPPORT_GRUNDIG_OR_NOKIA_PROTOCOL 1
#else
#define IRMP_SUPPORT_GRUNDIG_OR_NOKIA_PROTOCOL 0
#endif
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 || IRMP_SUPPORT_RC6_PROTOCOL == 1 || IRMP_SUPPORT_GRUNDIG_OR_NOKIA_PROTOCOL == 1 || IRMP_SUPPORT_SIEMENS_PROTOCOL == 1
#define IRMP_SUPPORT_MANCHESTER 1
#else
#define IRMP_SUPPORT_MANCHESTER 0
#endif
 
#define IRMP_KEY_REPETITION_LEN (uint16_t)(F_INTERRUPTS * 150.0e-3 + 0.5) // autodetect key repetition within 150 msec
 
#define MIN_TOLERANCE_00 1.0 // -0%
#define MAX_TOLERANCE_00 1.0 // +0%
 
#define MIN_TOLERANCE_05 0.95 // -5%
#define MAX_TOLERANCE_05 1.05 // +5%
 
#define MIN_TOLERANCE_10 0.9 // -10%
#define MAX_TOLERANCE_10 1.1 // +10%
 
#define MIN_TOLERANCE_15 0.85 // -15%
#define MAX_TOLERANCE_15 1.15 // +15%
 
#define MIN_TOLERANCE_20 0.8 // -20%
#define MAX_TOLERANCE_20 1.2 // +20%
 
#define MIN_TOLERANCE_30 0.7 // -30%
#define MAX_TOLERANCE_30 1.3 // +30%
 
#define MIN_TOLERANCE_40 0.6 // -40%
#define MAX_TOLERANCE_40 1.4 // +40%
 
#define MIN_TOLERANCE_50 0.5 // -50%
#define MAX_TOLERANCE_50 1.5 // +50%
 
#define MIN_TOLERANCE_60 0.4 // -60%
#define MAX_TOLERANCE_60 1.6 // +60%
 
#define MIN_TOLERANCE_70 0.3 // -70%
#define MAX_TOLERANCE_70 1.7 // +70%
 
#define SIRCS_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define SIRCS_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define SIRCS_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define SIRCS_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SIRCS_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) // only 5% to avoid conflict with RC6
#define SIRCS_1_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define SIRCS_1_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SIRCS_1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define SIRCS_0_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define SIRCS_0_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SIRCS_0_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define SIRCS_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define SIRCS_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SIRCS_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
 
#define NEC_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define NEC_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NEC_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define NEC_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define NEC_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NEC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define NEC_REPEAT_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define NEC_REPEAT_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NEC_REPEAT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define NEC_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define NEC_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NEC_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define NEC_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define NEC_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NEC_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define NEC_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define NEC_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NEC_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
// autodetect nec repetition frame within 50 msec:
// NEC seems to send the first repetition frame after 40ms, further repetition frames after 100 ms
#if 0
#define NEC_FRAME_REPEAT_PAUSE_LEN_MAX (uint16_t)(F_INTERRUPTS * NEC_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
#else
#define NEC_FRAME_REPEAT_PAUSE_LEN_MAX (uint16_t)(F_INTERRUPTS * 100.0e-3 * MAX_TOLERANCE_20 + 0.5)
#endif
 
#define SAMSUNG_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define SAMSUNG_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define SAMSUNG_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define SAMSUNG_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SAMSUNG_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define SAMSUNG_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)
#define SAMSUNG_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SAMSUNG_PULSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)
#define SAMSUNG_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)
#define SAMSUNG_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SAMSUNG_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)
#define SAMSUNG_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)
#define SAMSUNG_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * SAMSUNG_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)
 
#define MATSUSHITA_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define MATSUSHITA_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define MATSUSHITA_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define MATSUSHITA_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * MATSUSHITA_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define MATSUSHITA_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define MATSUSHITA_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * MATSUSHITA_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define MATSUSHITA_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define MATSUSHITA_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * MATSUSHITA_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define MATSUSHITA_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define MATSUSHITA_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * MATSUSHITA_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
 
#define KASEIKYO_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define KASEIKYO_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define KASEIKYO_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define KASEIKYO_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define KASEIKYO_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MIN_TOLERANCE_50 + 0.5) - 1)
#define KASEIKYO_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_PULSE_TIME * MAX_TOLERANCE_50 + 0.5) + 1)
#define KASEIKYO_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)
#define KASEIKYO_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)
#define KASEIKYO_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MIN_TOLERANCE_50 + 0.5) - 1)
#define KASEIKYO_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * KASEIKYO_0_PAUSE_TIME * MAX_TOLERANCE_50 + 0.5) + 1)
 
#define RECS80_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MIN_TOLERANCE_00 + 0.5) - 1)
#define RECS80_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RECS80_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RECS80_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RECS80_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RECS80_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RECS80_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RECS80_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RECS80_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RECS80_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
 
#define RC5_START_BIT_LEN_MIN ((uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RC5_START_BIT_LEN_MAX ((uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RC5_BIT_LEN_MIN ((uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RC5_BIT_LEN_MAX ((uint8_t)(F_INTERRUPTS * RC5_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
 
#define DENON_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define DENON_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * DENON_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define DENON_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define DENON_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * DENON_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define DENON_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define DENON_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * DENON_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
 
#define RC6_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RC6_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RC6_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RC6_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RC6_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RC6_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RC6_TOGGLE_BIT_LEN_MIN ((uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RC6_TOGGLE_BIT_LEN_MAX ((uint8_t)(F_INTERRUPTS * RC6_TOGGLE_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RC6_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RC6_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_30 + 0.5) + 1) // pulses: 300 - 700
#define RC6_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MIN_TOLERANCE_10 + 0.5) - 1) // pauses: 300 - 600
#define RC6_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RC6_BIT_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
 
#define RECS80EXT_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MIN_TOLERANCE_00 + 0.5) - 1)
#define RECS80EXT_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PULSE_TIME * MAX_TOLERANCE_00 + 0.5) + 1)
#define RECS80EXT_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_05 + 0.5) - 1)
#define RECS80EXT_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80EXT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1)
#define RECS80EXT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RECS80EXT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80EXT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RECS80EXT_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RECS80EXT_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80EXT_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RECS80EXT_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RECS80EXT_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RECS80EXT_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
 
#define NUBERT_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NUBERT_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NUBERT_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NUBERT_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NUBERT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NUBERT_1_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NUBERT_1_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NUBERT_1_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NUBERT_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NUBERT_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NUBERT_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NUBERT_0_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NUBERT_0_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NUBERT_0_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NUBERT_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NUBERT_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NUBERT_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
 
#define BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_START_BIT2_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_START_BIT2_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT2_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_START_BIT3_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_START_BIT3_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX ((PAUSE_LEN)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT3_PAUSE_TIME * MAX_TOLERANCE_05 + 0.5) + 1) // value must be below IRMP_TIMEOUT
#define BANG_OLUFSEN_START_BIT4_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_START_BIT4_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_START_BIT4_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_1_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_R_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_R_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_R_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * BANG_OLUFSEN_TRAILER_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
 
#define GRUNDIG_OR_NOKIA_START_BIT_LEN_MIN ((uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_BIT_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define GRUNDIG_OR_NOKIA_START_BIT_LEN_MAX ((uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_BIT_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define GRUNDIG_OR_NOKIA_BIT_LEN_MIN ((uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_BIT_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define GRUNDIG_OR_NOKIA_BIT_LEN_MAX ((uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_BIT_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_PRE_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) + 1)
#define GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * GRUNDIG_OR_NOKIA_PRE_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
 
#define SIEMENS_START_BIT_LEN_MIN ((uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME * 1 + 0.5) - 1)
#define SIEMENS_START_BIT_LEN_MAX ((uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME * 1 + 0.5) + 1)
#define SIEMENS_BIT_LEN_MIN ((uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME * 1 + 0.5) - 1)
#define SIEMENS_BIT_LEN_MAX ((uint8_t)(F_INTERRUPTS * SIEMENS_BIT_TIME * 1 + 0.5) + 1)
 
#define FDC_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define FDC_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * FDC_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define FDC_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define FDC_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * FDC_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define FDC_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * FDC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define FDC_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * FDC_PULSE_TIME * MAX_TOLERANCE_50 + 0.5) + 1)
#define FDC_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define FDC_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * FDC_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#if 0
#define FDC_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1) // could be negative: 255
#else
#define FDC_0_PAUSE_LEN_MIN (1) // simply use 1
#endif
#define FDC_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * FDC_0_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
 
#define RCCAR_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RCCAR_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PULSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RCCAR_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME * MIN_TOLERANCE_10 + 0.5) - 1)
#define RCCAR_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RCCAR_START_BIT_PAUSE_TIME * MAX_TOLERANCE_10 + 0.5) + 1)
#define RCCAR_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define RCCAR_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RCCAR_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define RCCAR_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)
#define RCCAR_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RCCAR_1_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)
#define RCCAR_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME * MIN_TOLERANCE_30 + 0.5) - 1)
#define RCCAR_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * RCCAR_0_PAUSE_TIME * MAX_TOLERANCE_30 + 0.5) + 1)
 
#define JVC_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define JVC_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define JVC_REPEAT_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * (JVC_FRAME_REPEAT_PAUSE_TIME - IRMP_TIMEOUT_TIME) * MIN_TOLERANCE_40 + 0.5) - 1) // HACK!
#define JVC_REPEAT_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * (JVC_FRAME_REPEAT_PAUSE_TIME - IRMP_TIMEOUT_TIME) * MAX_TOLERANCE_70 + 0.5) - 1) // HACK!
#define JVC_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * JVC_PULSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define JVC_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * JVC_PULSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define JVC_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define JVC_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * JVC_1_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
#define JVC_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME * MIN_TOLERANCE_40 + 0.5) - 1)
#define JVC_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * JVC_0_PAUSE_TIME * MAX_TOLERANCE_40 + 0.5) + 1)
// autodetect JVC repetition frame within 50 msec:
#define JVC_FRAME_REPEAT_PAUSE_LEN_MAX (uint16_t)(F_INTERRUPTS * JVC_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
 
#define NIKON_START_BIT_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NIKON_START_BIT_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NIKON_START_BIT_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NIKON_START_BIT_PAUSE_LEN_MIN ((uint16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NIKON_START_BIT_PAUSE_LEN_MAX ((uint16_t)(F_INTERRUPTS * NIKON_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NIKON_REPEAT_START_BIT_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NIKON_REPEAT_START_BIT_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NIKON_REPEAT_START_BIT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NIKON_PULSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NIKON_PULSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NIKON_PULSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NIKON_PULSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NIKON_1_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NIKON_1_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NIKON_1_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NIKON_0_PAUSE_LEN_MIN ((uint8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME * MIN_TOLERANCE_20 + 0.5) - 1)
#define NIKON_0_PAUSE_LEN_MAX ((uint8_t)(F_INTERRUPTS * NIKON_0_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5) + 1)
#define NIKON_FRAME_REPEAT_PAUSE_LEN_MAX (uint16_t)(F_INTERRUPTS * NIKON_FRAME_REPEAT_PAUSE_TIME * MAX_TOLERANCE_20 + 0.5)
 
#define AUTO_FRAME_REPETITION_LEN (uint16_t)(F_INTERRUPTS * AUTO_FRAME_REPETITION_TIME + 0.5) // use uint16_t!
 
#ifdef ANALYZE
#define ANALYZE_PUTCHAR(a) { if (! silent) { putchar (a); } }
#define ANALYZE_ONLY_NORMAL_PUTCHAR(a) { if (! silent && !verbose) { putchar (a); } }
#define ANALYZE_PRINTF(...) { if (verbose) { printf (__VA_ARGS__); } }
#define ANALYZE_NEWLINE() { if (verbose) { putchar ('\n'); } }
static int silent;
static int time_counter;
static int verbose;
#else
#define ANALYZE_PUTCHAR(a)
#define ANALYZE_ONLY_NORMAL_PUTCHAR(a)
#define ANALYZE_PRINTF(...)
#define ANALYZE_NEWLINE()
#endif
 
#if IRMP_LOGGING == 1
#define BAUD 9600L
#include <util/setbaud.h>
 
#ifdef UBRR0H
 
#define UART0_UBRRH UBRR0H
#define UART0_UBRRL UBRR0L
#define UART0_UCSRA UCSR0A
#define UART0_UCSRB UCSR0B
#define UART0_UCSRC UCSR0C
#define UART0_UDRE_BIT_VALUE (1<<UDRE0)
#define UART0_UCSZ1_BIT_VALUE (1<<UCSZ01)
#define UART0_UCSZ0_BIT_VALUE (1<<UCSZ00)
#ifdef URSEL0
#define UART0_URSEL_BIT_VALUE (1<<URSEL0)
#else
#define UART0_URSEL_BIT_VALUE (0)
#endif
#define UART0_TXEN_BIT_VALUE (1<<TXEN0)
#define UART0_UDR UDR0
#define UART0_U2X U2X0
 
#else
 
#define UART0_UBRRH UBRRH
#define UART0_UBRRL UBRRL
#define UART0_UCSRA UCSRA
#define UART0_UCSRB UCSRB
#define UART0_UCSRC UCSRC
#define UART0_UDRE_BIT_VALUE (1<<UDRE)
#define UART0_UCSZ1_BIT_VALUE (1<<UCSZ1)
#define UART0_UCSZ0_BIT_VALUE (1<<UCSZ0)
#ifdef URSEL
#define UART0_URSEL_BIT_VALUE (1<<URSEL)
#else
#define UART0_URSEL_BIT_VALUE (0)
#endif
#define UART0_TXEN_BIT_VALUE (1<<TXEN)
#define UART0_UDR UDR
#define UART0_U2X U2X
 
#endif
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Initialize UART
* @details Initializes UART
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
void
irmp_uart_init (void)
{
UART0_UBRRH = UBRRH_VALUE; // set baud rate
UART0_UBRRL = UBRRL_VALUE;
 
#if USE_2X
UART0_UCSRA |= (1<<UART0_U2X);
#else
UART0_UCSRA &= ~(1<<UART0_U2X);
#endif
 
UART0_UCSRC = UART0_UCSZ1_BIT_VALUE | UART0_UCSZ0_BIT_VALUE | UART0_URSEL_BIT_VALUE;
UART0_UCSRB |= UART0_TXEN_BIT_VALUE; // enable UART TX
}
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Send character
* @details Sends character
* @param ch character to be transmitted
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
void
irmp_uart_putc (unsigned char ch)
{
while (!(UART0_UCSRA & UART0_UDRE_BIT_VALUE))
{
;
}
 
UART0_UDR = ch;
}
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Log IR signal
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
#define STARTCYCLES 2 // min count of zeros before start of logging
#define ENDBITS 1000 // number of sequenced highbits to detect end
#define DATALEN 700 // log buffer size
 
static void
irmp_log (uint8_t val)
{
static uint8_t buf[DATALEN]; // logging buffer
static uint16_t buf_idx; // number of written bits
static uint8_t startcycles; // current number of start-zeros
static uint16_t cnt; // counts sequenced highbits - to detect end
 
if (! val && (startcycles < STARTCYCLES) && !buf_idx) // prevent that single random zeros init logging
{
startcycles++;
}
else
{
startcycles = 0;
 
if (! val || (val && buf_idx != 0)) // start or continue logging on "0", "1" cannot init logging
{
if (buf_idx < DATALEN * 8) // index in range?
{ // yes
if (val)
{
buf[(buf_idx / 8)] |= (1<<(buf_idx % 8)); // set bit
}
else
{
buf[(buf_idx / 8)] &= ~(1<<(buf_idx % 8)); // reset bit
}
 
buf_idx++;
}
 
if (val)
{ // if high received then look at log-stop condition
cnt++;
 
if (cnt > ENDBITS)
{ // if stop condition is true, output on uart
uint16_t i;
 
for (i = 0; i < STARTCYCLES; i++)
{
irmp_uart_putc ('0'); // the ignored starting zeros
}
 
for (i = 0; i < (buf_idx - ENDBITS + 20) / 8; i++) // transform bitset into uart chars
{
uint8_t d = buf[i];
uint8_t j;
 
for (j = 0; j < 8; j++)
{
irmp_uart_putc ((d & 1) + '0');
d >>= 1;
}
}
 
irmp_uart_putc ('\n');
buf_idx = 0;
}
}
else
{
cnt = 0;
}
}
}
}
 
#else
#define irmp_log(val)
#endif
 
typedef struct
{
uint8_t protocol; // ir protocol
uint8_t pulse_1_len_min; // minimum length of pulse with bit value 1
uint8_t pulse_1_len_max; // maximum length of pulse with bit value 1
uint8_t pause_1_len_min; // minimum length of pause with bit value 1
uint8_t pause_1_len_max; // maximum length of pause with bit value 1
uint8_t pulse_0_len_min; // minimum length of pulse with bit value 0
uint8_t pulse_0_len_max; // maximum length of pulse with bit value 0
uint8_t pause_0_len_min; // minimum length of pause with bit value 0
uint8_t pause_0_len_max; // maximum length of pause with bit value 0
uint8_t address_offset; // address offset
uint8_t address_end; // end of address
uint8_t command_offset; // command offset
uint8_t command_end; // end of command
uint8_t complete_len; // complete length of frame
uint8_t stop_bit; // flag: frame has stop bit
uint8_t lsb_first; // flag: LSB first
uint8_t flags; // some flags
} IRMP_PARAMETER;
 
#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER sircs_param =
{
IRMP_SIRCS_PROTOCOL, // protocol: ir protocol
SIRCS_1_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
SIRCS_1_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
SIRCS_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
SIRCS_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
SIRCS_0_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
SIRCS_0_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
SIRCS_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
SIRCS_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
SIRCS_ADDRESS_OFFSET, // address_offset: address offset
SIRCS_ADDRESS_OFFSET + SIRCS_ADDRESS_LEN, // address_end: end of address
SIRCS_COMMAND_OFFSET, // command_offset: command offset
SIRCS_COMMAND_OFFSET + SIRCS_COMMAND_LEN, // command_end: end of command
SIRCS_COMPLETE_DATA_LEN, // complete_len: complete length of frame
SIRCS_STOP_BIT, // stop_bit: flag: frame has stop bit
SIRCS_LSB, // lsb_first: flag: LSB first
SIRCS_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_NEC_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER nec_param =
{
IRMP_NEC_PROTOCOL, // protocol: ir protocol
NEC_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
NEC_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
NEC_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
NEC_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
NEC_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
NEC_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
NEC_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
NEC_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
NEC_ADDRESS_OFFSET, // address_offset: address offset
NEC_ADDRESS_OFFSET + NEC_ADDRESS_LEN, // address_end: end of address
NEC_COMMAND_OFFSET, // command_offset: command offset
NEC_COMMAND_OFFSET + NEC_COMMAND_LEN, // command_end: end of command
NEC_COMPLETE_DATA_LEN, // complete_len: complete length of frame
NEC_STOP_BIT, // stop_bit: flag: frame has stop bit
NEC_LSB, // lsb_first: flag: LSB first
NEC_FLAGS // flags: some flags
};
 
static PROGMEM IRMP_PARAMETER nec_rep_param =
{
IRMP_NEC_PROTOCOL, // protocol: ir protocol
NEC_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
NEC_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
NEC_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
NEC_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
NEC_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
NEC_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
NEC_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
NEC_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
0, // address_offset: address offset
0, // address_end: end of address
0, // command_offset: command offset
0, // command_end: end of command
0, // complete_len: complete length of frame
NEC_STOP_BIT, // stop_bit: flag: frame has stop bit
NEC_LSB, // lsb_first: flag: LSB first
NEC_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER samsung_param =
{
IRMP_SAMSUNG_PROTOCOL, // protocol: ir protocol
SAMSUNG_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
SAMSUNG_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
SAMSUNG_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
SAMSUNG_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
SAMSUNG_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
SAMSUNG_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
SAMSUNG_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
SAMSUNG_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
SAMSUNG_ADDRESS_OFFSET, // address_offset: address offset
SAMSUNG_ADDRESS_OFFSET + SAMSUNG_ADDRESS_LEN, // address_end: end of address
SAMSUNG_COMMAND_OFFSET, // command_offset: command offset
SAMSUNG_COMMAND_OFFSET + SAMSUNG_COMMAND_LEN, // command_end: end of command
SAMSUNG_COMPLETE_DATA_LEN, // complete_len: complete length of frame
SAMSUNG_STOP_BIT, // stop_bit: flag: frame has stop bit
SAMSUNG_LSB, // lsb_first: flag: LSB first
SAMSUNG_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER matsushita_param =
{
IRMP_MATSUSHITA_PROTOCOL, // protocol: ir protocol
MATSUSHITA_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
MATSUSHITA_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
MATSUSHITA_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
MATSUSHITA_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
MATSUSHITA_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
MATSUSHITA_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
MATSUSHITA_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
MATSUSHITA_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
MATSUSHITA_ADDRESS_OFFSET, // address_offset: address offset
MATSUSHITA_ADDRESS_OFFSET + MATSUSHITA_ADDRESS_LEN, // address_end: end of address
MATSUSHITA_COMMAND_OFFSET, // command_offset: command offset
MATSUSHITA_COMMAND_OFFSET + MATSUSHITA_COMMAND_LEN, // command_end: end of command
MATSUSHITA_COMPLETE_DATA_LEN, // complete_len: complete length of frame
MATSUSHITA_STOP_BIT, // stop_bit: flag: frame has stop bit
MATSUSHITA_LSB, // lsb_first: flag: LSB first
MATSUSHITA_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER kaseikyo_param =
{
IRMP_KASEIKYO_PROTOCOL, // protocol: ir protocol
KASEIKYO_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
KASEIKYO_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
KASEIKYO_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
KASEIKYO_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
KASEIKYO_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
KASEIKYO_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
KASEIKYO_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
KASEIKYO_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
KASEIKYO_ADDRESS_OFFSET, // address_offset: address offset
KASEIKYO_ADDRESS_OFFSET + KASEIKYO_ADDRESS_LEN, // address_end: end of address
KASEIKYO_COMMAND_OFFSET, // command_offset: command offset
KASEIKYO_COMMAND_OFFSET + KASEIKYO_COMMAND_LEN, // command_end: end of command
KASEIKYO_COMPLETE_DATA_LEN, // complete_len: complete length of frame
KASEIKYO_STOP_BIT, // stop_bit: flag: frame has stop bit
KASEIKYO_LSB, // lsb_first: flag: LSB first
KASEIKYO_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_RECS80_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER recs80_param =
{
IRMP_RECS80_PROTOCOL, // protocol: ir protocol
RECS80_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
RECS80_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
RECS80_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
RECS80_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
RECS80_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
RECS80_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
RECS80_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
RECS80_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
RECS80_ADDRESS_OFFSET, // address_offset: address offset
RECS80_ADDRESS_OFFSET + RECS80_ADDRESS_LEN, // address_end: end of address
RECS80_COMMAND_OFFSET, // command_offset: command offset
RECS80_COMMAND_OFFSET + RECS80_COMMAND_LEN, // command_end: end of command
RECS80_COMPLETE_DATA_LEN, // complete_len: complete length of frame
RECS80_STOP_BIT, // stop_bit: flag: frame has stop bit
RECS80_LSB, // lsb_first: flag: LSB first
RECS80_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER rc5_param =
{
IRMP_RC5_PROTOCOL, // protocol: ir protocol
RC5_BIT_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
RC5_BIT_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
RC5_BIT_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
RC5_BIT_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
1, // tricky: use this as stop bit length // pulse_0_len_min: minimum length of pulse with bit value 0
1, // pulse_0_len_max: maximum length of pulse with bit value 0
1, // pause_0_len_min: minimum length of pause with bit value 0
1, // pause_0_len_max: maximum length of pause with bit value 0
RC5_ADDRESS_OFFSET, // address_offset: address offset
RC5_ADDRESS_OFFSET + RC5_ADDRESS_LEN, // address_end: end of address
RC5_COMMAND_OFFSET, // command_offset: command offset
RC5_COMMAND_OFFSET + RC5_COMMAND_LEN, // command_end: end of command
RC5_COMPLETE_DATA_LEN, // complete_len: complete length of frame
RC5_STOP_BIT, // stop_bit: flag: frame has stop bit
RC5_LSB, // lsb_first: flag: LSB first
RC5_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_DENON_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER denon_param =
{
IRMP_DENON_PROTOCOL, // protocol: ir protocol
DENON_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
DENON_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
DENON_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
DENON_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
DENON_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
DENON_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
DENON_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
DENON_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
DENON_ADDRESS_OFFSET, // address_offset: address offset
DENON_ADDRESS_OFFSET + DENON_ADDRESS_LEN, // address_end: end of address
DENON_COMMAND_OFFSET, // command_offset: command offset
DENON_COMMAND_OFFSET + DENON_COMMAND_LEN, // command_end: end of command
DENON_COMPLETE_DATA_LEN, // complete_len: complete length of frame
DENON_STOP_BIT, // stop_bit: flag: frame has stop bit
DENON_LSB, // lsb_first: flag: LSB first
DENON_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_RC6_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER rc6_param =
{
IRMP_RC6_PROTOCOL, // protocol: ir protocol
RC6_BIT_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
RC6_BIT_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
RC6_BIT_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
RC6_BIT_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
1, // tricky: use this as stop bit length // pulse_0_len_min: minimum length of pulse with bit value 0
1, // pulse_0_len_max: maximum length of pulse with bit value 0
1, // pause_0_len_min: minimum length of pause with bit value 0
1, // pause_0_len_max: maximum length of pause with bit value 0
RC6_ADDRESS_OFFSET, // address_offset: address offset
RC6_ADDRESS_OFFSET + RC6_ADDRESS_LEN, // address_end: end of address
RC6_COMMAND_OFFSET, // command_offset: command offset
RC6_COMMAND_OFFSET + RC6_COMMAND_LEN, // command_end: end of command
RC6_COMPLETE_DATA_LEN_SHORT, // complete_len: complete length of frame
RC6_STOP_BIT, // stop_bit: flag: frame has stop bit
RC6_LSB, // lsb_first: flag: LSB first
RC6_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER recs80ext_param =
{
IRMP_RECS80EXT_PROTOCOL, // protocol: ir protocol
RECS80EXT_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
RECS80EXT_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
RECS80EXT_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
RECS80EXT_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
RECS80EXT_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
RECS80EXT_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
RECS80EXT_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
RECS80EXT_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
RECS80EXT_ADDRESS_OFFSET, // address_offset: address offset
RECS80EXT_ADDRESS_OFFSET + RECS80EXT_ADDRESS_LEN, // address_end: end of address
RECS80EXT_COMMAND_OFFSET, // command_offset: command offset
RECS80EXT_COMMAND_OFFSET + RECS80EXT_COMMAND_LEN, // command_end: end of command
RECS80EXT_COMPLETE_DATA_LEN, // complete_len: complete length of frame
RECS80EXT_STOP_BIT, // stop_bit: flag: frame has stop bit
RECS80EXT_LSB, // lsb_first: flag: LSB first
RECS80EXT_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER nubert_param =
{
IRMP_NUBERT_PROTOCOL, // protocol: ir protocol
NUBERT_1_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
NUBERT_1_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
NUBERT_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
NUBERT_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
NUBERT_0_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
NUBERT_0_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
NUBERT_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
NUBERT_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
NUBERT_ADDRESS_OFFSET, // address_offset: address offset
NUBERT_ADDRESS_OFFSET + NUBERT_ADDRESS_LEN, // address_end: end of address
NUBERT_COMMAND_OFFSET, // command_offset: command offset
NUBERT_COMMAND_OFFSET + NUBERT_COMMAND_LEN, // command_end: end of command
NUBERT_COMPLETE_DATA_LEN, // complete_len: complete length of frame
NUBERT_STOP_BIT, // stop_bit: flag: frame has stop bit
NUBERT_LSB, // lsb_first: flag: LSB first
NUBERT_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER bang_olufsen_param =
{
IRMP_BANG_OLUFSEN_PROTOCOL, // protocol: ir protocol
BANG_OLUFSEN_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
BANG_OLUFSEN_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
BANG_OLUFSEN_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
BANG_OLUFSEN_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
BANG_OLUFSEN_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
BANG_OLUFSEN_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
BANG_OLUFSEN_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
BANG_OLUFSEN_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
BANG_OLUFSEN_ADDRESS_OFFSET, // address_offset: address offset
BANG_OLUFSEN_ADDRESS_OFFSET + BANG_OLUFSEN_ADDRESS_LEN, // address_end: end of address
BANG_OLUFSEN_COMMAND_OFFSET, // command_offset: command offset
BANG_OLUFSEN_COMMAND_OFFSET + BANG_OLUFSEN_COMMAND_LEN, // command_end: end of command
BANG_OLUFSEN_COMPLETE_DATA_LEN, // complete_len: complete length of frame
BANG_OLUFSEN_STOP_BIT, // stop_bit: flag: frame has stop bit
BANG_OLUFSEN_LSB, // lsb_first: flag: LSB first
BANG_OLUFSEN_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_GRUNDIG_OR_NOKIA_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER grundig_param =
{
IRMP_GRUNDIG_PROTOCOL, // protocol: ir protocol
GRUNDIG_OR_NOKIA_BIT_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
GRUNDIG_OR_NOKIA_BIT_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
GRUNDIG_OR_NOKIA_BIT_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
GRUNDIG_OR_NOKIA_BIT_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
1, // tricky: use this as stop bit length // pulse_0_len_min: minimum length of pulse with bit value 0
1, // pulse_0_len_max: maximum length of pulse with bit value 0
1, // pause_0_len_min: minimum length of pause with bit value 0
1, // pause_0_len_max: maximum length of pause with bit value 0
GRUNDIG_ADDRESS_OFFSET, // address_offset: address offset
GRUNDIG_ADDRESS_OFFSET + GRUNDIG_ADDRESS_LEN, // address_end: end of address
GRUNDIG_COMMAND_OFFSET, // command_offset: command offset
GRUNDIG_COMMAND_OFFSET + GRUNDIG_COMMAND_LEN + 1, // command_end: end of command (USE 1 bit MORE to STORE NOKIA DATA!)
NOKIA_COMPLETE_DATA_LEN, // complete_len: complete length of frame, here: NOKIA instead of GRUNDIG!
GRUNDIG_OR_NOKIA_STOP_BIT, // stop_bit: flag: frame has stop bit
GRUNDIG_OR_NOKIA_LSB, // lsb_first: flag: LSB first
GRUNDIG_OR_NOKIA_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_SIEMENS_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER siemens_param =
{
IRMP_SIEMENS_PROTOCOL, // protocol: ir protocol
SIEMENS_BIT_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
SIEMENS_BIT_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
SIEMENS_BIT_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
SIEMENS_BIT_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
1, // tricky: use this as stop bit length // pulse_0_len_min: minimum length of pulse with bit value 0
1, // pulse_0_len_max: maximum length of pulse with bit value 0
1, // pause_0_len_min: minimum length of pause with bit value 0
1, // pause_0_len_max: maximum length of pause with bit value 0
SIEMENS_ADDRESS_OFFSET, // address_offset: address offset
SIEMENS_ADDRESS_OFFSET + SIEMENS_ADDRESS_LEN, // address_end: end of address
SIEMENS_COMMAND_OFFSET, // command_offset: command offset
SIEMENS_COMMAND_OFFSET + SIEMENS_COMMAND_LEN, // command_end: end of command
SIEMENS_COMPLETE_DATA_LEN, // complete_len: complete length of frame
SIEMENS_STOP_BIT, // stop_bit: flag: frame has stop bit
SIEMENS_LSB, // lsb_first: flag: LSB first
SIEMENS_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_FDC_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER fdc_param =
{
IRMP_FDC_PROTOCOL, // protocol: ir protocol
FDC_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
FDC_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
FDC_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
FDC_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
FDC_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
FDC_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
FDC_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
FDC_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
FDC_ADDRESS_OFFSET, // address_offset: address offset
FDC_ADDRESS_OFFSET + FDC_ADDRESS_LEN, // address_end: end of address
FDC_COMMAND_OFFSET, // command_offset: command offset
FDC_COMMAND_OFFSET + FDC_COMMAND_LEN, // command_end: end of command
FDC_COMPLETE_DATA_LEN, // complete_len: complete length of frame
FDC_STOP_BIT, // stop_bit: flag: frame has stop bit
FDC_LSB, // lsb_first: flag: LSB first
FDC_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER rccar_param =
{
IRMP_RCCAR_PROTOCOL, // protocol: ir protocol
RCCAR_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
RCCAR_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
RCCAR_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
RCCAR_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
RCCAR_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
RCCAR_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
RCCAR_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
RCCAR_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
RCCAR_ADDRESS_OFFSET, // address_offset: address offset
RCCAR_ADDRESS_OFFSET + RCCAR_ADDRESS_LEN, // address_end: end of address
RCCAR_COMMAND_OFFSET, // command_offset: command offset
RCCAR_COMMAND_OFFSET + RCCAR_COMMAND_LEN, // command_end: end of command
RCCAR_COMPLETE_DATA_LEN, // complete_len: complete length of frame
RCCAR_STOP_BIT, // stop_bit: flag: frame has stop bit
RCCAR_LSB, // lsb_first: flag: LSB first
RCCAR_FLAGS // flags: some flags
};
 
#endif
 
#if IRMP_SUPPORT_NIKON_PROTOCOL == 1
 
static PROGMEM IRMP_PARAMETER nikon_param =
{
IRMP_NIKON_PROTOCOL, // protocol: ir protocol
NIKON_PULSE_LEN_MIN, // pulse_1_len_min: minimum length of pulse with bit value 1
NIKON_PULSE_LEN_MAX, // pulse_1_len_max: maximum length of pulse with bit value 1
NIKON_1_PAUSE_LEN_MIN, // pause_1_len_min: minimum length of pause with bit value 1
NIKON_1_PAUSE_LEN_MAX, // pause_1_len_max: maximum length of pause with bit value 1
NIKON_PULSE_LEN_MIN, // pulse_0_len_min: minimum length of pulse with bit value 0
NIKON_PULSE_LEN_MAX, // pulse_0_len_max: maximum length of pulse with bit value 0
NIKON_0_PAUSE_LEN_MIN, // pause_0_len_min: minimum length of pause with bit value 0
NIKON_0_PAUSE_LEN_MAX, // pause_0_len_max: maximum length of pause with bit value 0
NIKON_ADDRESS_OFFSET, // address_offset: address offset
NIKON_ADDRESS_OFFSET + NIKON_ADDRESS_LEN, // address_end: end of address
NIKON_COMMAND_OFFSET, // command_offset: command offset
NIKON_COMMAND_OFFSET + NIKON_COMMAND_LEN, // command_end: end of command
NIKON_COMPLETE_DATA_LEN, // complete_len: complete length of frame
NIKON_STOP_BIT, // stop_bit: flag: frame has stop bit
NIKON_LSB, // lsb_first: flag: LSB first
NIKON_FLAGS // flags: some flags
};
 
#endif
 
static uint8_t irmp_bit; // current bit position
static IRMP_PARAMETER irmp_param;
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)
static IRMP_PARAMETER irmp_param2;
#endif
 
static volatile uint8_t irmp_ir_detected;
static volatile uint8_t irmp_protocol;
static volatile uint16_t irmp_address;
static volatile uint16_t irmp_command;
static volatile uint16_t irmp_id; // only used for SAMSUNG protocol
static volatile uint8_t irmp_flags;
 
#ifdef ANALYZE
static uint8_t IRMP_PIN;
#endif
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Initialize IRMP decoder
* @details Configures IRMP input pin
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#ifndef ANALYZE
void
irmp_init (void)
{
#ifndef PIC_CCS_COMPILER
IRMP_PORT &= ~(1<<IRMP_BIT); // deactivate pullup
IRMP_DDR &= ~(1<<IRMP_BIT); // set pin to input
#endif // PIC_CCS_COMPILER
 
#if IRMP_LOGGING == 1
irmp_uart_init ();
#endif
}
#endif
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* Get IRMP data
* @details gets decoded IRMP data
* @param pointer in order to store IRMP data
* @return TRUE: successful, FALSE: failed
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
uint8_t
irmp_get_data (IRMP_DATA * irmp_data_p)
{
uint8_t rtc = FALSE;
 
if (irmp_ir_detected)
{
switch (irmp_protocol)
{
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
case IRMP_SAMSUNG_PROTOCOL:
if ((irmp_command >> 8) == (~irmp_command & 0x00FF))
{
irmp_command &= 0xff;
irmp_command |= irmp_id << 8;
rtc = TRUE;
}
break;
#endif
#if IRMP_SUPPORT_NEC_PROTOCOL == 1
case IRMP_NEC_PROTOCOL:
if ((irmp_command >> 8) == (~irmp_command & 0x00FF))
{
irmp_command &= 0xff;
rtc = TRUE;
}
else if (irmp_address == 0x87EE)
{
ANALYZE_PRINTF ("Switching to APPLE protocol\n");
irmp_protocol = IRMP_APPLE_PROTOCOL;
irmp_address = (irmp_command & 0xFF00) >> 8;
irmp_command &= 0x00FF;
rtc = TRUE;
}
break;
#endif
#if IRMP_SUPPORT_SIEMENS_PROTOCOL == 1
case IRMP_SIEMENS_PROTOCOL:
if (((irmp_command >> 1) & 0x0001) == (~irmp_command & 0x0001))
{
irmp_command >>= 1;
rtc = TRUE;
}
break;
#endif
#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1
case IRMP_RCCAR_PROTOCOL:
// frame in irmp_data:
// Bit 12 11 10 9 8 7 6 5 4 3 2 1 0
// V D7 D6 D5 D4 D3 D2 D1 D0 A1 A0 C1 C0 // 10 9 8 7 6 5 4 3 2 1 0
irmp_address = (irmp_command & 0x000C) >> 2; // addr: 0 0 0 0 0 0 0 0 0 A1 A0
irmp_command = ((irmp_command & 0x1000) >> 2) | // V-Bit: V 0 0 0 0 0 0 0 0 0 0
((irmp_command & 0x0003) << 8) | // C-Bits: 0 C1 C0 0 0 0 0 0 0 0 0
((irmp_command & 0x0FF0) >> 4); // D-Bits: D7 D6 D5 D4 D3 D2 D1 D0
rtc = TRUE; // Summe: V C1 C0 D7 D6 D5 D4 D3 D2 D1 D0
break;
#endif
default:
rtc = TRUE;
}
 
if (rtc)
{
irmp_data_p->protocol = irmp_protocol;
irmp_data_p->address = irmp_address;
irmp_data_p->command = irmp_command;
irmp_data_p->flags = irmp_flags;
irmp_command = 0;
irmp_address = 0;
irmp_flags = 0;
}
 
irmp_ir_detected = FALSE;
}
 
return rtc;
}
 
// these statics must not be volatile, because they are only used by irmp_store_bit(), which is called by irmp_ISR()
static uint16_t irmp_tmp_address; // ir address
static uint16_t irmp_tmp_command; // ir command
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)
static uint16_t irmp_tmp_address2; // ir address
static uint16_t irmp_tmp_command2; // ir command
#endif
 
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
static uint16_t irmp_tmp_id; // ir id (only SAMSUNG)
#endif
#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
static uint8_t xor_check[6]; // check kaseikyo "parity" bits
#endif
 
static uint8_t irmp_bit; // current bit position
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* store bit
* @details store bit in temp address or temp command
* @param value to store: 0 or 1
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
// verhindert, dass irmp_store_bit() inline compiliert wird:
// static void irmp_store_bit (uint8_t) __attribute__ ((noinline));
 
static void
irmp_store_bit (uint8_t value)
{
 
if (irmp_bit >= irmp_param.address_offset && irmp_bit < irmp_param.address_end)
{
if (irmp_param.lsb_first)
{
irmp_tmp_address |= (((uint16_t) (value)) << (irmp_bit - irmp_param.address_offset)); // CV wants cast
}
else
{
irmp_tmp_address <<= 1;
irmp_tmp_address |= value;
}
}
else if (irmp_bit >= irmp_param.command_offset && irmp_bit < irmp_param.command_end)
{
if (irmp_param.lsb_first)
{
irmp_tmp_command |= (((uint16_t) (value)) << (irmp_bit - irmp_param.command_offset)); // CV wants cast
}
else
{
irmp_tmp_command <<= 1;
irmp_tmp_command |= value;
}
}
 
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
else if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit >= SAMSUNG_ID_OFFSET && irmp_bit < SAMSUNG_ID_OFFSET + SAMSUNG_ID_LEN)
{
irmp_tmp_id |= (((uint16_t) (value)) << (irmp_bit - SAMSUNG_ID_OFFSET)); // store with LSB first
}
#endif
 
#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
else if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL && irmp_bit >= 20 && irmp_bit < 24)
{
irmp_tmp_command |= (((uint16_t) (value)) << (irmp_bit - 8)); // store 4 system bits in upper nibble with LSB first
}
 
if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL && irmp_bit < KASEIKYO_COMPLETE_DATA_LEN)
{
if (value)
{
xor_check[irmp_bit / 8] |= 1 << (irmp_bit % 8);
}
else
{
xor_check[irmp_bit / 8] &= ~(1 << (irmp_bit % 8));
}
}
 
#endif
 
irmp_bit++;
}
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* store bit
* @details store bit in temp address or temp command
* @param value to store: 0 or 1
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)
static void
irmp_store_bit2 (uint8_t value)
{
uint8_t irmp_bit2;
 
if (irmp_param.protocol)
{
irmp_bit2 = irmp_bit - 2;
}
else
{
irmp_bit2 = irmp_bit - 1;
}
 
if (irmp_bit2 >= irmp_param2.address_offset && irmp_bit2 < irmp_param2.address_end)
{
irmp_tmp_address2 |= (((uint16_t) (value)) << (irmp_bit2 - irmp_param2.address_offset)); // CV wants cast
}
else if (irmp_bit2 >= irmp_param2.command_offset && irmp_bit2 < irmp_param2.command_end)
{
irmp_tmp_command2 |= (((uint16_t) (value)) << (irmp_bit2 - irmp_param2.command_offset)); // CV wants cast
}
}
#endif // IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* ISR routine
* @details ISR routine, called 10000 times per second
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
uint8_t
irmp_ISR (void)
{
static uint8_t irmp_start_bit_detected; // flag: start bit detected
static uint8_t wait_for_space; // flag: wait for data bit space
static uint8_t wait_for_start_space; // flag: wait for start bit space
static uint8_t irmp_pulse_time; // count bit time for pulse
static PAUSE_LEN irmp_pause_time; // count bit time for pause
static uint16_t last_irmp_address = 0xFFFF; // save last irmp address to recognize key repetition
static uint16_t last_irmp_command = 0xFFFF; // save last irmp command to recognize key repetition
static uint16_t repetition_len; // SIRCS repeats frame 2-5 times with 45 ms pause
static uint8_t repetition_frame_number;
#if IRMP_SUPPORT_DENON_PROTOCOL == 1
static uint16_t last_irmp_denon_command; // save last irmp command to recognize DENON frame repetition
#endif
#if IRMP_SUPPORT_RC5_PROTOCOL == 1
static uint8_t rc5_cmd_bit6; // bit 6 of RC5 command is the inverted 2nd start bit
#endif
#if IRMP_SUPPORT_MANCHESTER == 1
static PAUSE_LEN last_pause; // last pause value
#endif
#if IRMP_SUPPORT_MANCHESTER == 1 || IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
static uint8_t last_value; // last bit value
#endif
uint8_t irmp_input; // input value
 
#ifdef ANALYZE
time_counter++;
#endif
 
irmp_input = input(IRMP_PIN);
 
irmp_log(irmp_input); // log ir signal, if IRMP_LOGGING defined
 
if (! irmp_ir_detected) // ir code already detected?
{ // no...
if (! irmp_start_bit_detected) // start bit detected?
{ // no...
if (! irmp_input) // receiving burst?
{ // yes...
#ifdef ANALYZE
if (! irmp_pulse_time)
{
ANALYZE_PRINTF("%8d [starting pulse]\n", time_counter);
}
#endif
irmp_pulse_time++; // increment counter
}
else
{ // no...
if (irmp_pulse_time) // it's dark....
{ // set flags for counting the time of darkness...
irmp_start_bit_detected = 1;
wait_for_start_space = 1;
wait_for_space = 0;
irmp_tmp_command = 0;
irmp_tmp_address = 0;
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)
irmp_tmp_command2 = 0;
irmp_tmp_address2 = 0;
#endif
 
irmp_bit = 0xff;
irmp_pause_time = 1; // 1st pause: set to 1, not to 0!
#if IRMP_SUPPORT_RC5_PROTOCOL == 1
rc5_cmd_bit6 = 0; // fm 2010-03-07: bugfix: reset it after incomplete RC5 frame!
#endif
}
else
{
if (repetition_len < 0xFFFF) // avoid overflow of counter
{
repetition_len++;
}
}
}
}
else
{
if (wait_for_start_space) // we have received start bit...
{ // ...and are counting the time of darkness
if (irmp_input) // still dark?
{ // yes
irmp_pause_time++; // increment counter
 
#if IRMP_SUPPORT_NIKON_PROTOCOL == 1
if (((irmp_pulse_time < NIKON_START_BIT_PULSE_LEN_MIN || irmp_pulse_time > NIKON_START_BIT_PULSE_LEN_MAX) && irmp_pause_time > IRMP_TIMEOUT_LEN) ||
irmp_pause_time > IRMP_TIMEOUT_NIKON_LEN)
#else
if (irmp_pause_time > IRMP_TIMEOUT_LEN) // timeout?
#endif
{ // yes...
#if IRMP_SUPPORT_JVC_PROTOCOL == 1
if (irmp_protocol == IRMP_JVC_PROTOCOL) // don't show eror if JVC protocol, irmp_pulse_time has been set below!
{
;
}
else
#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1
{
ANALYZE_PRINTF ("%8d error 1: pause after start bit pulse %d too long: %d\n", time_counter, irmp_pulse_time, irmp_pause_time);
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
}
irmp_start_bit_detected = 0; // reset flags, let's wait for another start bit
irmp_pulse_time = 0;
irmp_pause_time = 0;
}
}
else
{ // receiving first data pulse!
IRMP_PARAMETER * irmp_param_p = (IRMP_PARAMETER *) 0;
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)
irmp_param2.protocol = 0;
#endif
 
ANALYZE_PRINTF ("%8d [start-bit: pulse = %2d, pause = %2d]\n", time_counter, irmp_pulse_time, irmp_pause_time);
 
#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
if (irmp_pulse_time >= SIRCS_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SIRCS_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= SIRCS_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SIRCS_START_BIT_PAUSE_LEN_MAX)
{ // it's SIRCS
ANALYZE_PRINTF ("protocol = SIRCS, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
SIRCS_START_BIT_PULSE_LEN_MIN, SIRCS_START_BIT_PULSE_LEN_MAX,
SIRCS_START_BIT_PAUSE_LEN_MIN, SIRCS_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) (IRMP_PARAMETER *) &sircs_param;
}
else
#endif // IRMP_SUPPORT_SIRCS_PROTOCOL == 1
 
#if IRMP_SUPPORT_JVC_PROTOCOL == 1
if (irmp_protocol == IRMP_JVC_PROTOCOL && // last protocol was JVC, awaiting repeat frame
irmp_pulse_time >= JVC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= JVC_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= JVC_REPEAT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= JVC_REPEAT_START_BIT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("protocol = NEC or JVC repeat frame, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
JVC_START_BIT_PULSE_LEN_MIN, JVC_START_BIT_PULSE_LEN_MAX,
JVC_REPEAT_START_BIT_PAUSE_LEN_MIN, JVC_REPEAT_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &nec_param; // tricky: use nec parameters
}
else
#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1
 
#if IRMP_SUPPORT_NEC_PROTOCOL == 1
if (irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= NEC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_START_BIT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("protocol = NEC, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX,
NEC_START_BIT_PAUSE_LEN_MIN, NEC_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &nec_param;
}
else if (irmp_pulse_time >= NEC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NEC_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= NEC_REPEAT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NEC_REPEAT_START_BIT_PAUSE_LEN_MAX)
{ // it's NEC
ANALYZE_PRINTF ("protocol = NEC (repetition frame), start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX,
NEC_REPEAT_START_BIT_PAUSE_LEN_MIN, NEC_REPEAT_START_BIT_PAUSE_LEN_MAX);
 
irmp_param_p = (IRMP_PARAMETER *) &nec_rep_param;
}
else
#endif // IRMP_SUPPORT_NEC_PROTOCOL == 1
 
#if IRMP_SUPPORT_NIKON_PROTOCOL == 1
if (irmp_pulse_time >= NIKON_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NIKON_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= NIKON_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NIKON_START_BIT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("protocol = NIKON, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
NIKON_START_BIT_PULSE_LEN_MIN, NIKON_START_BIT_PULSE_LEN_MAX,
NIKON_START_BIT_PAUSE_LEN_MIN, NIKON_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &nikon_param;
}
else
#endif // IRMP_SUPPORT_NIKON_PROTOCOL == 1
 
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
if (irmp_pulse_time >= SAMSUNG_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= SAMSUNG_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_START_BIT_PAUSE_LEN_MAX)
{ // it's SAMSUNG
ANALYZE_PRINTF ("protocol = SAMSUNG, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
SAMSUNG_START_BIT_PULSE_LEN_MIN, SAMSUNG_START_BIT_PULSE_LEN_MAX,
SAMSUNG_START_BIT_PAUSE_LEN_MIN, SAMSUNG_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &samsung_param;
}
else
#endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
 
#if IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
if (irmp_pulse_time >= MATSUSHITA_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= MATSUSHITA_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= MATSUSHITA_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= MATSUSHITA_START_BIT_PAUSE_LEN_MAX)
{ // it's MATSUSHITA
ANALYZE_PRINTF ("protocol = MATSUSHITA, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
MATSUSHITA_START_BIT_PULSE_LEN_MIN, MATSUSHITA_START_BIT_PULSE_LEN_MAX,
MATSUSHITA_START_BIT_PAUSE_LEN_MIN, MATSUSHITA_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &matsushita_param;
}
else
#endif // IRMP_SUPPORT_MATSUSHITA_PROTOCOL == 1
 
#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
if (irmp_pulse_time >= KASEIKYO_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= KASEIKYO_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= KASEIKYO_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= KASEIKYO_START_BIT_PAUSE_LEN_MAX)
{ // it's KASEIKYO
ANALYZE_PRINTF ("protocol = KASEIKYO, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
KASEIKYO_START_BIT_PULSE_LEN_MIN, KASEIKYO_START_BIT_PULSE_LEN_MAX,
KASEIKYO_START_BIT_PAUSE_LEN_MIN, KASEIKYO_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &kaseikyo_param;
}
else
#endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
 
#if IRMP_SUPPORT_RECS80_PROTOCOL == 1
if (irmp_pulse_time >= RECS80_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RECS80_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= RECS80_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RECS80_START_BIT_PAUSE_LEN_MAX)
{ // it's RECS80
ANALYZE_PRINTF ("protocol = RECS80, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
RECS80_START_BIT_PULSE_LEN_MIN, RECS80_START_BIT_PULSE_LEN_MAX,
RECS80_START_BIT_PAUSE_LEN_MIN, RECS80_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &recs80_param;
}
else
#endif // IRMP_SUPPORT_RECS80_PROTOCOL == 1
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1
if (((irmp_pulse_time >= RC5_START_BIT_LEN_MIN && irmp_pulse_time <= RC5_START_BIT_LEN_MAX) ||
(irmp_pulse_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX)) &&
((irmp_pause_time >= RC5_START_BIT_LEN_MIN && irmp_pause_time <= RC5_START_BIT_LEN_MAX) ||
(irmp_pause_time >= 2 * RC5_START_BIT_LEN_MIN && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX)))
{ // it's RC5
#if IRMP_SUPPORT_FDC_PROTOCOL == 1
if (irmp_pulse_time >= FDC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= FDC_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= FDC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= FDC_START_BIT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("protocol = RC5 or FDC\n");
ANALYZE_PRINTF ("FDC start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
FDC_START_BIT_PULSE_LEN_MIN, FDC_START_BIT_PULSE_LEN_MAX,
FDC_START_BIT_PAUSE_LEN_MIN, FDC_START_BIT_PAUSE_LEN_MAX);
ANALYZE_PRINTF ("RC5 start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,
RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX);
memcpy_P (&irmp_param2, &fdc_param, sizeof (IRMP_PARAMETER));
}
else
#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1
#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1
if (irmp_pulse_time >= RCCAR_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= RCCAR_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_START_BIT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("protocol = RC5 or RCCAR\n");
ANALYZE_PRINTF ("RCCAR start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
RCCAR_START_BIT_PULSE_LEN_MIN, RCCAR_START_BIT_PULSE_LEN_MAX,
RCCAR_START_BIT_PAUSE_LEN_MIN, RCCAR_START_BIT_PAUSE_LEN_MAX);
ANALYZE_PRINTF ("RC5 start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,
RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX);
memcpy_P (&irmp_param2, &rccar_param, sizeof (IRMP_PARAMETER));
}
else
#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1
{
ANALYZE_PRINTF ("protocol = RC5, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,
RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX);
}
 
irmp_param_p = (IRMP_PARAMETER *) &rc5_param;
last_pause = irmp_pause_time;
 
if ((irmp_pulse_time > RC5_START_BIT_LEN_MAX && irmp_pulse_time <= 2 * RC5_START_BIT_LEN_MAX) ||
(irmp_pause_time > RC5_START_BIT_LEN_MAX && irmp_pause_time <= 2 * RC5_START_BIT_LEN_MAX))
{
last_value = 0;
rc5_cmd_bit6 = 1<<6;
}
else
{
last_value = 1;
}
}
else
#endif // IRMP_SUPPORT_RC5_PROTOCOL == 1
 
#if IRMP_SUPPORT_DENON_PROTOCOL == 1
if ( (irmp_pulse_time >= DENON_PULSE_LEN_MIN && irmp_pulse_time <= DENON_PULSE_LEN_MAX) &&
((irmp_pause_time >= DENON_1_PAUSE_LEN_MIN && irmp_pause_time <= DENON_1_PAUSE_LEN_MAX) ||
(irmp_pause_time >= DENON_0_PAUSE_LEN_MIN && irmp_pause_time <= DENON_0_PAUSE_LEN_MAX)))
{ // it's DENON
ANALYZE_PRINTF ("protocol = DENON, start bit timings: pulse: %3d - %3d, pause: %3d - %3d or %3d - %3d\n",
DENON_PULSE_LEN_MIN, DENON_PULSE_LEN_MAX,
DENON_1_PAUSE_LEN_MIN, DENON_1_PAUSE_LEN_MAX,
DENON_0_PAUSE_LEN_MIN, DENON_0_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &denon_param;
}
else
#endif // IRMP_SUPPORT_DENON_PROTOCOL == 1
 
#if IRMP_SUPPORT_RC6_PROTOCOL == 1
if (irmp_pulse_time >= RC6_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RC6_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= RC6_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RC6_START_BIT_PAUSE_LEN_MAX)
{ // it's RC6
ANALYZE_PRINTF ("protocol = RC6, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
RC6_START_BIT_PULSE_LEN_MIN, RC6_START_BIT_PULSE_LEN_MAX,
RC6_START_BIT_PAUSE_LEN_MIN, RC6_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &rc6_param;
last_pause = 0;
last_value = 1;
}
else
#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1
 
#if IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
if (irmp_pulse_time >= RECS80EXT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RECS80EXT_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= RECS80EXT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RECS80EXT_START_BIT_PAUSE_LEN_MAX)
{ // it's RECS80EXT
ANALYZE_PRINTF ("protocol = RECS80EXT, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
RECS80EXT_START_BIT_PULSE_LEN_MIN, RECS80EXT_START_BIT_PULSE_LEN_MAX,
RECS80EXT_START_BIT_PAUSE_LEN_MIN, RECS80EXT_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &recs80ext_param;
}
else
#endif // IRMP_SUPPORT_RECS80EXT_PROTOCOL == 1
 
#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1
if (irmp_pulse_time >= NUBERT_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= NUBERT_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= NUBERT_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= NUBERT_START_BIT_PAUSE_LEN_MAX)
{ // it's NUBERT
ANALYZE_PRINTF ("protocol = NUBERT, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
NUBERT_START_BIT_PULSE_LEN_MIN, NUBERT_START_BIT_PULSE_LEN_MAX,
NUBERT_START_BIT_PAUSE_LEN_MIN, NUBERT_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &nubert_param;
}
else
#endif // IRMP_SUPPORT_NUBERT_PROTOCOL == 1
 
#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
if (irmp_pulse_time >= BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN && irmp_pulse_time <= BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX &&
irmp_pause_time >= BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX)
{ // it's BANG_OLUFSEN
ANALYZE_PRINTF ("protocol = BANG_OLUFSEN\n");
ANALYZE_PRINTF ("start bit 1 timings: pulse: %3d - %3d, pause: %3d - %3d\n",
BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX,
BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX);
ANALYZE_PRINTF ("start bit 2 timings: pulse: %3d - %3d, pause: %3d - %3d\n",
BANG_OLUFSEN_START_BIT2_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PULSE_LEN_MAX,
BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MAX);
ANALYZE_PRINTF ("start bit 3 timings: pulse: %3d - %3d, pause: %3d - %3d\n",
BANG_OLUFSEN_START_BIT3_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PULSE_LEN_MAX,
BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX);
ANALYZE_PRINTF ("start bit 4 timings: pulse: %3d - %3d, pause: %3d - %3d\n",
BANG_OLUFSEN_START_BIT4_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT4_PULSE_LEN_MAX,
BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &bang_olufsen_param;
last_value = 0;
}
else
#endif // IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
 
#if IRMP_SUPPORT_GRUNDIG_OR_NOKIA_PROTOCOL == 1
if (irmp_pulse_time >= GRUNDIG_OR_NOKIA_START_BIT_LEN_MIN && irmp_pulse_time <= GRUNDIG_OR_NOKIA_START_BIT_LEN_MAX &&
irmp_pause_time >= GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN_MIN && irmp_pause_time <= GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN_MAX)
{ // it's GRUNDIG
ANALYZE_PRINTF ("protocol = GRUNDIG, pre bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
GRUNDIG_OR_NOKIA_START_BIT_LEN_MIN, GRUNDIG_OR_NOKIA_START_BIT_LEN_MAX,
GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN_MIN, GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &grundig_param;
last_pause = irmp_pause_time;
last_value = 1;
}
else
#endif // IRMP_SUPPORT_GRUNDIG_OR_NOKIA_PROTOCOL == 1
 
#if IRMP_SUPPORT_SIEMENS_PROTOCOL == 1
if (((irmp_pulse_time >= SIEMENS_START_BIT_LEN_MIN && irmp_pulse_time <= SIEMENS_START_BIT_LEN_MAX) ||
(irmp_pulse_time >= 2 * SIEMENS_START_BIT_LEN_MIN && irmp_pulse_time <= 2 * SIEMENS_START_BIT_LEN_MAX)) &&
((irmp_pause_time >= SIEMENS_START_BIT_LEN_MIN && irmp_pause_time <= SIEMENS_START_BIT_LEN_MAX) ||
(irmp_pause_time >= 2 * SIEMENS_START_BIT_LEN_MIN && irmp_pause_time <= 2 * SIEMENS_START_BIT_LEN_MAX)))
{ // it's SIEMENS
ANALYZE_PRINTF ("protocol = SIEMENS, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
SIEMENS_START_BIT_LEN_MIN, SIEMENS_START_BIT_LEN_MAX,
SIEMENS_START_BIT_LEN_MIN, SIEMENS_START_BIT_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &siemens_param;
last_pause = irmp_pause_time;
last_value = 1;
}
else
#endif // IRMP_SUPPORT_SIEMENS_PROTOCOL == 1
#if IRMP_SUPPORT_FDC_PROTOCOL == 1
if (irmp_pulse_time >= FDC_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= FDC_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= FDC_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= FDC_START_BIT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("protocol = FDC, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
FDC_START_BIT_PULSE_LEN_MIN, FDC_START_BIT_PULSE_LEN_MAX,
FDC_START_BIT_PAUSE_LEN_MIN, FDC_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &fdc_param;
}
else
#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1
#if IRMP_SUPPORT_RCCAR_PROTOCOL == 1
if (irmp_pulse_time >= RCCAR_START_BIT_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_START_BIT_PULSE_LEN_MAX &&
irmp_pause_time >= RCCAR_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_START_BIT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("protocol = RCCAR, start bit timings: pulse: %3d - %3d, pause: %3d - %3d\n",
RCCAR_START_BIT_PULSE_LEN_MIN, RCCAR_START_BIT_PULSE_LEN_MAX,
RCCAR_START_BIT_PAUSE_LEN_MIN, RCCAR_START_BIT_PAUSE_LEN_MAX);
irmp_param_p = (IRMP_PARAMETER *) &rccar_param;
}
else
#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1
{
ANALYZE_PRINTF ("protocol = UNKNOWN\n");
irmp_start_bit_detected = 0; // wait for another start bit...
}
 
if (irmp_start_bit_detected)
{
memcpy_P (&irmp_param, irmp_param_p, sizeof (IRMP_PARAMETER));
 
#ifdef ANALYZE
if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER))
{
ANALYZE_PRINTF ("pulse_1: %3d - %3d\n", irmp_param.pulse_1_len_min, irmp_param.pulse_1_len_max);
ANALYZE_PRINTF ("pause_1: %3d - %3d\n", irmp_param.pause_1_len_min, irmp_param.pause_1_len_max);
}
else
{
ANALYZE_PRINTF ("pulse: %3d - %3d or %3d - %3d\n", irmp_param.pulse_1_len_min, irmp_param.pulse_1_len_max,
irmp_param.pulse_1_len_max + 1, 2 * irmp_param.pulse_1_len_max);
ANALYZE_PRINTF ("pause: %3d - %3d or %3d - %3d\n", irmp_param.pause_1_len_min, irmp_param.pause_1_len_max,
irmp_param.pause_1_len_max + 1, 2 * irmp_param.pause_1_len_max);
}
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)
if (irmp_param2.protocol)
{
ANALYZE_PRINTF ("pulse_0: %3d - %3d\n", irmp_param2.pulse_0_len_min, irmp_param2.pulse_0_len_max);
ANALYZE_PRINTF ("pause_0: %3d - %3d\n", irmp_param2.pause_0_len_min, irmp_param2.pause_0_len_max);
ANALYZE_PRINTF ("pulse_1: %3d - %3d\n", irmp_param2.pulse_1_len_min, irmp_param2.pulse_1_len_max);
ANALYZE_PRINTF ("pause_1: %3d - %3d\n", irmp_param2.pause_1_len_min, irmp_param2.pause_1_len_max);
}
#endif
 
 
#if IRMP_SUPPORT_RC6_PROTOCOL == 1
if (irmp_param.protocol == IRMP_RC6_PROTOCOL)
{
ANALYZE_PRINTF ("pulse_toggle: %3d - %3d\n", RC6_TOGGLE_BIT_LEN_MIN, RC6_TOGGLE_BIT_LEN_MAX);
}
#endif
 
if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER))
{
ANALYZE_PRINTF ("pulse_0: %3d - %3d\n", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max);
ANALYZE_PRINTF ("pause_0: %3d - %3d\n", irmp_param.pause_0_len_min, irmp_param.pause_0_len_max);
}
 
#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
if (irmp_param.protocol == IRMP_BANG_OLUFSEN_PROTOCOL)
{
ANALYZE_PRINTF ("pulse_r: %3d - %3d\n", irmp_param.pulse_0_len_min, irmp_param.pulse_0_len_max);
ANALYZE_PRINTF ("pause_r: %3d - %3d\n", BANG_OLUFSEN_R_PAUSE_LEN_MIN, BANG_OLUFSEN_R_PAUSE_LEN_MAX);
}
#endif
 
ANALYZE_PRINTF ("command_offset: %2d\n", irmp_param.command_offset);
ANALYZE_PRINTF ("command_len: %3d\n", irmp_param.command_end - irmp_param.command_offset);
ANALYZE_PRINTF ("complete_len: %3d\n", irmp_param.complete_len);
ANALYZE_PRINTF ("stop_bit: %3d\n", irmp_param.stop_bit);
#endif // ANALYZE
}
 
irmp_bit = 0;
 
#if IRMP_SUPPORT_MANCHESTER == 1
if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) && irmp_param.protocol != IRMP_RC6_PROTOCOL) // Manchester, but not RC6
{
if (irmp_pause_time > irmp_param.pulse_1_len_max && irmp_pause_time <= 2 * irmp_param.pulse_1_len_max)
{
ANALYZE_PRINTF ("%8d [bit %2d: pulse = %3d, pause = %3d] ", time_counter, irmp_bit, irmp_pulse_time, irmp_pause_time);
ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '0' : '1');
ANALYZE_NEWLINE ();
irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 0 : 1);
}
else if (! last_value) // && irmp_pause_time >= irmp_param.pause_1_len_min && irmp_pause_time <= irmp_param.pause_1_len_max)
{
ANALYZE_PRINTF ("%8d [bit %2d: pulse = %3d, pause = %3d] ", time_counter, irmp_bit, irmp_pulse_time, irmp_pause_time);
 
ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '1' : '0');
ANALYZE_NEWLINE ();
irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 1 : 0);
}
}
else
#endif // IRMP_SUPPORT_MANCHESTER == 1
 
#if IRMP_SUPPORT_DENON_PROTOCOL == 1
if (irmp_param.protocol == IRMP_DENON_PROTOCOL)
{
ANALYZE_PRINTF ("%8d [bit %2d: pulse = %3d, pause = %3d] ", time_counter, irmp_bit, irmp_pulse_time, irmp_pause_time);
 
if (irmp_pause_time >= DENON_1_PAUSE_LEN_MIN && irmp_pause_time <= DENON_1_PAUSE_LEN_MAX)
{ // pause timings correct for "1"?
ANALYZE_PUTCHAR ('1'); // yes, store 1
ANALYZE_NEWLINE ();
irmp_store_bit (1);
}
else // if (irmp_pause_time >= DENON_0_PAUSE_LEN_MIN && irmp_pause_time <= DENON_0_PAUSE_LEN_MAX)
{ // pause timings correct for "0"?
ANALYZE_PUTCHAR ('0'); // yes, store 0
ANALYZE_NEWLINE ();
irmp_store_bit (0);
}
}
else
#endif // IRMP_SUPPORT_DENON_PROTOCOL == 1
{
; // else do nothing
}
 
irmp_pulse_time = 1; // set counter to 1, not 0
irmp_pause_time = 0;
wait_for_start_space = 0;
}
}
else if (wait_for_space) // the data section....
{ // counting the time of darkness....
uint8_t got_light = FALSE;
 
if (irmp_input) // still dark?
{ // yes...
if (irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 1)
{
if (irmp_pulse_time >= irmp_param.pulse_0_len_min && irmp_pulse_time <= irmp_param.pulse_0_len_max)
{
#ifdef ANALYZE
if (! (irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER))
{
ANALYZE_PRINTF ("stop bit detected\n");
}
#endif
irmp_param.stop_bit = 0;
}
else
{
ANALYZE_PRINTF ("stop bit timing wrong\n");
 
irmp_start_bit_detected = 0; // wait for another start bit...
irmp_pulse_time = 0;
irmp_pause_time = 0;
}
}
else
{
irmp_pause_time++; // increment counter
 
#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
if (irmp_param.protocol == IRMP_SIRCS_PROTOCOL && // Sony has a variable number of bits:
irmp_pause_time > SIRCS_PAUSE_LEN_MAX && // minimum is 12
irmp_bit >= 12 - 1) // pause too long?
{ // yes, break and close this frame
irmp_param.complete_len = irmp_bit + 1; // set new complete length
got_light = TRUE; // this is a lie, but helps (generates stop bit)
irmp_param.command_end = irmp_param.command_offset + irmp_bit + 1; // correct command length
irmp_pause_time = SIRCS_PAUSE_LEN_MAX - 1; // correct pause length
}
else
#endif
#if IRMP_SUPPORT_GRUNDIG_OR_NOKIA_PROTOCOL == 1
if (irmp_param.protocol == IRMP_GRUNDIG_PROTOCOL && !irmp_param.stop_bit)
{
if (irmp_pause_time > 2 * irmp_param.pause_1_len_max && irmp_bit >= GRUNDIG_COMPLETE_DATA_LEN - 2)
{ // special manchester decoder
irmp_param.complete_len = GRUNDIG_COMPLETE_DATA_LEN; // correct complete len
got_light = TRUE; // this is a lie, but generates a stop bit ;-)
irmp_param.stop_bit = TRUE; // set flag
}
else if (irmp_bit >= GRUNDIG_COMPLETE_DATA_LEN)
{
ANALYZE_PRINTF ("Switching to NOKIA protocol\n");
irmp_param.protocol = IRMP_NOKIA_PROTOCOL; // change protocol
irmp_param.address_offset = NOKIA_ADDRESS_OFFSET;
irmp_param.address_end = NOKIA_ADDRESS_OFFSET + NOKIA_ADDRESS_LEN;
irmp_param.command_offset = NOKIA_COMMAND_OFFSET;
irmp_param.command_end = NOKIA_COMMAND_OFFSET + NOKIA_COMMAND_LEN;
 
if (irmp_tmp_command & 0x300)
{
irmp_tmp_address = (irmp_tmp_command >> 8);
irmp_tmp_command &= 0xFF;
}
}
}
else
#endif
#if IRMP_SUPPORT_MANCHESTER == 1
if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER) &&
irmp_pause_time > 2 * irmp_param.pause_1_len_max && irmp_bit >= irmp_param.complete_len - 2 && !irmp_param.stop_bit)
{ // special manchester decoder
got_light = TRUE; // this is a lie, but generates a stop bit ;-)
irmp_param.stop_bit = TRUE; // set flag
}
else
#endif // IRMP_SUPPORT_MANCHESTER == 1
if (irmp_pause_time > IRMP_TIMEOUT_LEN) // timeout?
{ // yes...
if (irmp_bit == irmp_param.complete_len - 1 && irmp_param.stop_bit == 0)
{
irmp_bit++;
}
#if IRMP_SUPPORT_JVC_PROTOCOL == 1
else if (irmp_param.protocol == IRMP_NEC_PROTOCOL && (irmp_bit == 16 || irmp_bit == 17)) // it was a JVC stop bit
{
ANALYZE_PRINTF ("Switching to JVC protocol\n");
irmp_param.stop_bit = TRUE; // set flag
irmp_param.protocol = IRMP_JVC_PROTOCOL; // switch protocol
irmp_param.complete_len = irmp_bit; // patch length: 16 or 17
irmp_tmp_command = (irmp_tmp_address >> 4); // set command: upper 12 bits are command bits
irmp_tmp_address = irmp_tmp_address & 0x000F; // lower 4 bits are address bits
irmp_start_bit_detected = 1; // tricky: don't wait for another start bit...
}
#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1
else
{
ANALYZE_PRINTF ("error 2: pause %d after data bit %d too long\n", irmp_pause_time, irmp_bit);
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
 
irmp_start_bit_detected = 0; // wait for another start bit...
irmp_pulse_time = 0;
irmp_pause_time = 0;
}
}
}
}
else
{ // got light now!
got_light = TRUE;
}
 
if (got_light)
{
ANALYZE_PRINTF ("%8d [bit %2d: pulse = %3d, pause = %3d] ", time_counter, irmp_bit, irmp_pulse_time, irmp_pause_time);
 
#if IRMP_SUPPORT_MANCHESTER == 1
if ((irmp_param.flags & IRMP_PARAM_FLAG_IS_MANCHESTER)) // Manchester
{
if (irmp_pulse_time > irmp_param.pulse_1_len_max /* && irmp_pulse_time <= 2 * irmp_param.pulse_1_len_max */)
{
#if IRMP_SUPPORT_RC6_PROTOCOL == 1
if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_bit == 4 && irmp_pulse_time > RC6_TOGGLE_BIT_LEN_MIN) // RC6 toggle bit
{
ANALYZE_PUTCHAR ('T');
if (irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_LONG) // RC6 mode 6A
{
irmp_store_bit (1);
last_value = 1;
}
else // RC6 mode 0
{
irmp_store_bit (0);
last_value = 0;
}
ANALYZE_NEWLINE ();
}
else
#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1
{
ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '0' : '1');
irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 0 : 1 );
 
#if IRMP_SUPPORT_RC6_PROTOCOL == 1
if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_bit == 4 && irmp_pulse_time > RC6_TOGGLE_BIT_LEN_MIN) // RC6 toggle bit
{
ANALYZE_PUTCHAR ('T');
irmp_store_bit (1);
 
if (irmp_pause_time > 2 * irmp_param.pause_1_len_max)
{
last_value = 0;
}
else
{
last_value = 1;
}
ANALYZE_NEWLINE ();
}
else
#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1
{
ANALYZE_PUTCHAR ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? '1' : '0');
irmp_store_bit ((irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 1 : 0 );
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)
if (! irmp_param2.protocol)
#endif
{
ANALYZE_NEWLINE ();
}
last_value = (irmp_param.flags & IRMP_PARAM_FLAG_1ST_PULSE_IS_1) ? 1 : 0;
}
}
}
else if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max)
{
uint8_t manchester_value;
 
if (last_pause > irmp_param.pause_1_len_max && last_pause <= 2 * irmp_param.pause_1_len_max)
{
manchester_value = last_value ? 0 : 1;
last_value = manchester_value;
}
else
{
manchester_value = last_value;
}
 
ANALYZE_PUTCHAR (manchester_value + '0');
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && (IRMP_SUPPORT_FDC_PROTOCOL == 1 || IRMP_SUPPORT_RCCAR_PROTOCOL == 1)
if (! irmp_param2.protocol)
#endif
{
ANALYZE_NEWLINE ();
}
 
#if IRMP_SUPPORT_RC6_PROTOCOL == 1
if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_bit == 1 && manchester_value == 1) // RC6 mode != 0 ???
{
ANALYZE_PRINTF ("Switching to RC6A protocol\n");
irmp_param.complete_len = RC6_COMPLETE_DATA_LEN_LONG;
irmp_param.address_offset = 5;
irmp_param.address_end = irmp_param.address_offset + 15;
irmp_param.command_offset = irmp_param.address_end + 1; // skip 1 system bit, changes like a toggle bit
irmp_param.command_end = irmp_param.command_offset + 16 - 1;
irmp_tmp_address = 1; // addr 0 - 32767 --> 32768 - 65535
}
#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1
 
irmp_store_bit (manchester_value);
}
else
{
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_FDC_PROTOCOL == 1
if (irmp_param2.protocol == IRMP_FDC_PROTOCOL &&
irmp_pulse_time >= FDC_PULSE_LEN_MIN && irmp_pulse_time <= FDC_PULSE_LEN_MAX &&
((irmp_pause_time >= FDC_1_PAUSE_LEN_MIN && irmp_pause_time <= FDC_1_PAUSE_LEN_MAX) ||
(irmp_pause_time >= FDC_0_PAUSE_LEN_MIN && irmp_pause_time <= FDC_0_PAUSE_LEN_MAX)))
{
ANALYZE_PUTCHAR ('?');
irmp_param.protocol = 0; // switch to FDC, see below
}
else
#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_RCCAR_PROTOCOL == 1
if (irmp_param2.protocol == IRMP_RCCAR_PROTOCOL &&
irmp_pulse_time >= RCCAR_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_PULSE_LEN_MAX &&
((irmp_pause_time >= RCCAR_1_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_1_PAUSE_LEN_MAX) ||
(irmp_pause_time >= RCCAR_0_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_0_PAUSE_LEN_MAX)))
{
ANALYZE_PUTCHAR ('?');
irmp_param.protocol = 0; // switch to RCCAR, see below
}
else
#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1
{
ANALYZE_PUTCHAR ('?');
ANALYZE_NEWLINE ();
ANALYZE_PRINTF ("error 3 manchester: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time);
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
irmp_start_bit_detected = 0; // reset flags and wait for next start bit
irmp_pause_time = 0;
}
}
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_FDC_PROTOCOL == 1
if (irmp_param2.protocol == IRMP_FDC_PROTOCOL && irmp_pulse_time >= FDC_PULSE_LEN_MIN && irmp_pulse_time <= FDC_PULSE_LEN_MAX)
{
if (irmp_pause_time >= FDC_1_PAUSE_LEN_MIN && irmp_pause_time <= FDC_1_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF (" 1 (FDC)\n");
irmp_store_bit2 (1);
}
else if (irmp_pause_time >= FDC_0_PAUSE_LEN_MIN && irmp_pause_time <= FDC_0_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF (" 0 (FDC)\n");
irmp_store_bit2 (0);
}
 
if (! irmp_param.protocol)
{
ANALYZE_PRINTF ("Switching to FDC protocol\n");
memcpy (&irmp_param, &irmp_param2, sizeof (IRMP_PARAMETER));
irmp_param2.protocol = 0;
irmp_tmp_address = irmp_tmp_address2;
irmp_tmp_command = irmp_tmp_command2;
}
}
#endif // IRMP_SUPPORT_FDC_PROTOCOL == 1
#if IRMP_SUPPORT_RC5_PROTOCOL == 1 && IRMP_SUPPORT_RCCAR_PROTOCOL == 1
if (irmp_param2.protocol == IRMP_RCCAR_PROTOCOL && irmp_pulse_time >= RCCAR_PULSE_LEN_MIN && irmp_pulse_time <= RCCAR_PULSE_LEN_MAX)
{
if (irmp_pause_time >= RCCAR_1_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_1_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF (" 1 (RCCAR)\n");
irmp_store_bit2 (1);
}
else if (irmp_pause_time >= RCCAR_0_PAUSE_LEN_MIN && irmp_pause_time <= RCCAR_0_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF (" 0 (RCCAR)\n");
irmp_store_bit2 (0);
}
 
if (! irmp_param.protocol)
{
ANALYZE_PRINTF ("Switching to RCCAR protocol\n");
memcpy (&irmp_param, &irmp_param2, sizeof (IRMP_PARAMETER));
irmp_param2.protocol = 0;
irmp_tmp_address = irmp_tmp_address2;
irmp_tmp_command = irmp_tmp_command2;
}
}
#endif // IRMP_SUPPORT_RCCAR_PROTOCOL == 1
 
last_pause = irmp_pause_time;
wait_for_space = 0;
}
else
#endif // IRMP_SUPPORT_MANCHESTER == 1
 
 
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
if (irmp_param.protocol == IRMP_SAMSUNG_PROTOCOL && irmp_bit == 16) // Samsung: 16th bit
{
if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX &&
irmp_pause_time >= SAMSUNG_START_BIT_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_START_BIT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("SYNC\n");
wait_for_space = 0;
irmp_tmp_id = 0;
irmp_bit++;
}
else if (irmp_pulse_time >= SAMSUNG_PULSE_LEN_MIN && irmp_pulse_time <= SAMSUNG_PULSE_LEN_MAX)
{
irmp_param.protocol = IRMP_SAMSUNG32_PROTOCOL;
irmp_param.command_offset = SAMSUNG32_COMMAND_OFFSET;
irmp_param.command_end = SAMSUNG32_COMMAND_OFFSET + SAMSUNG32_COMMAND_LEN;
irmp_param.complete_len = SAMSUNG32_COMPLETE_DATA_LEN;
 
if (irmp_pause_time >= SAMSUNG_1_PAUSE_LEN_MIN && irmp_pause_time <= SAMSUNG_1_PAUSE_LEN_MAX)
{
ANALYZE_PUTCHAR ('1');
ANALYZE_NEWLINE ();
irmp_store_bit (1);
wait_for_space = 0;
}
else
{
ANALYZE_PUTCHAR ('0');
ANALYZE_NEWLINE ();
irmp_store_bit (0);
wait_for_space = 0;
}
 
ANALYZE_PRINTF ("Switching to SAMSUNG32 protocol\n");
}
else
{ // timing incorrect!
ANALYZE_PRINTF ("error 3 Samsung: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time);
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
irmp_start_bit_detected = 0; // reset flags and wait for next start bit
irmp_pause_time = 0;
}
}
else
#endif // IRMP_SUPPORT_SAMSUNG_PROTOCOL
 
#if IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1
if (irmp_param.protocol == IRMP_BANG_OLUFSEN_PROTOCOL)
{
if (irmp_pulse_time >= BANG_OLUFSEN_PULSE_LEN_MIN && irmp_pulse_time <= BANG_OLUFSEN_PULSE_LEN_MAX)
{
if (irmp_bit == 1) // Bang & Olufsen: 3rd bit
{
if (irmp_pause_time >= BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("3rd start bit\n");
wait_for_space = 0;
irmp_bit++;
}
else
{ // timing incorrect!
ANALYZE_PRINTF ("error 3a B&O: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time);
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
irmp_start_bit_detected = 0; // reset flags and wait for next start bit
irmp_pause_time = 0;
}
}
else if (irmp_bit == 19) // Bang & Olufsen: trailer bit
{
if (irmp_pause_time >= BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_TRAILER_BIT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("trailer bit\n");
wait_for_space = 0;
irmp_bit++;
}
else
{ // timing incorrect!
ANALYZE_PRINTF ("error 3b B&O: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time);
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
irmp_start_bit_detected = 0; // reset flags and wait for next start bit
irmp_pause_time = 0;
}
}
else
{
if (irmp_pause_time >= BANG_OLUFSEN_1_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_1_PAUSE_LEN_MAX)
{ // pulse & pause timings correct for "1"?
ANALYZE_PUTCHAR ('1');
ANALYZE_NEWLINE ();
irmp_store_bit (1);
last_value = 1;
wait_for_space = 0;
}
else if (irmp_pause_time >= BANG_OLUFSEN_0_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_0_PAUSE_LEN_MAX)
{ // pulse & pause timings correct for "0"?
ANALYZE_PUTCHAR ('0');
ANALYZE_NEWLINE ();
irmp_store_bit (0);
last_value = 0;
wait_for_space = 0;
}
else if (irmp_pause_time >= BANG_OLUFSEN_R_PAUSE_LEN_MIN && irmp_pause_time <= BANG_OLUFSEN_R_PAUSE_LEN_MAX)
{
ANALYZE_PUTCHAR (last_value + '0');
ANALYZE_NEWLINE ();
irmp_store_bit (last_value);
wait_for_space = 0;
}
else
{ // timing incorrect!
ANALYZE_PRINTF ("error 3c B&O: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time);
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
irmp_start_bit_detected = 0; // reset flags and wait for next start bit
irmp_pause_time = 0;
}
}
}
else
{ // timing incorrect!
ANALYZE_PRINTF ("error 3d B&O: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time);
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
irmp_start_bit_detected = 0; // reset flags and wait for next start bit
irmp_pause_time = 0;
}
}
else
#endif // IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL
 
if (irmp_pulse_time >= irmp_param.pulse_1_len_min && irmp_pulse_time <= irmp_param.pulse_1_len_max &&
irmp_pause_time >= irmp_param.pause_1_len_min && irmp_pause_time <= irmp_param.pause_1_len_max)
{ // pulse & pause timings correct for "1"?
ANALYZE_PUTCHAR ('1');
ANALYZE_NEWLINE ();
irmp_store_bit (1);
wait_for_space = 0;
}
else if (irmp_pulse_time >= irmp_param.pulse_0_len_min && irmp_pulse_time <= irmp_param.pulse_0_len_max &&
irmp_pause_time >= irmp_param.pause_0_len_min && irmp_pause_time <= irmp_param.pause_0_len_max)
{ // pulse & pause timings correct for "0"?
ANALYZE_PUTCHAR ('0');
ANALYZE_NEWLINE ();
irmp_store_bit (0);
wait_for_space = 0;
}
else
{ // timing incorrect!
ANALYZE_PRINTF ("error 3: timing not correct: data bit %d, pulse: %d, pause: %d\n", irmp_bit, irmp_pulse_time, irmp_pause_time);
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
irmp_start_bit_detected = 0; // reset flags and wait for next start bit
irmp_pause_time = 0;
}
 
irmp_pulse_time = 1; // set counter to 1, not 0
}
}
else
{ // counting the pulse length ...
if (! irmp_input) // still light?
{ // yes...
irmp_pulse_time++; // increment counter
}
else
{ // now it's dark!
wait_for_space = 1; // let's count the time (see above)
irmp_pause_time = 1; // set pause counter to 1, not 0
}
}
 
if (irmp_start_bit_detected && irmp_bit == irmp_param.complete_len && irmp_param.stop_bit == 0) // enough bits received?
{
if (last_irmp_command == irmp_tmp_command && repetition_len < AUTO_FRAME_REPETITION_LEN)
{
repetition_frame_number++;
}
else
{
repetition_frame_number = 0;
}
 
#if IRMP_SUPPORT_SIRCS_PROTOCOL == 1
// if SIRCS protocol and the code will be repeated within 50 ms, we will ignore 2nd and 3rd repetition frame
if (irmp_param.protocol == IRMP_SIRCS_PROTOCOL && (repetition_frame_number == 1 || repetition_frame_number == 2))
{
ANALYZE_PRINTF ("code skipped: SIRCS auto repetition frame #%d, counter = %d, auto repetition len = %d\n",
repetition_frame_number + 1, repetition_len, AUTO_FRAME_REPETITION_LEN);
repetition_len = 0;
}
else
#endif
 
#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
// if KASEIKYO protocol and the code will be repeated within 50 ms, we will ignore 2nd repetition frame
if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL && repetition_frame_number == 1)
{
ANALYZE_PRINTF ("code skipped: KASEIKYO auto repetition frame #%d, counter = %d, auto repetition len = %d\n",
repetition_frame_number + 1, repetition_len, AUTO_FRAME_REPETITION_LEN);
repetition_len = 0;
}
else
#endif
 
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
// if SAMSUNG32 protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame
if (irmp_param.protocol == IRMP_SAMSUNG32_PROTOCOL && (repetition_frame_number & 0x01))
{
ANALYZE_PRINTF ("code skipped: SAMSUNG32 auto repetition frame #%d, counter = %d, auto repetition len = %d\n",
repetition_frame_number + 1, repetition_len, AUTO_FRAME_REPETITION_LEN);
repetition_len = 0;
}
else
#endif
 
#if IRMP_SUPPORT_NUBERT_PROTOCOL == 1
// if NUBERT protocol and the code will be repeated within 50 ms, we will ignore every 2nd frame
if (irmp_param.protocol == IRMP_NUBERT_PROTOCOL && (repetition_frame_number & 0x01))
{
ANALYZE_PRINTF ("code skipped: NUBERT auto repetition frame #%d, counter = %d, auto repetition len = %d\n",
repetition_frame_number + 1, repetition_len, AUTO_FRAME_REPETITION_LEN);
repetition_len = 0;
}
else
#endif
 
{
ANALYZE_PRINTF ("%8d code detected, length = %d\n", time_counter, irmp_bit);
irmp_ir_detected = TRUE;
 
#if IRMP_SUPPORT_DENON_PROTOCOL == 1
if (irmp_param.protocol == IRMP_DENON_PROTOCOL)
{ // check for repetition frame
if ((~irmp_tmp_command & 0x3FF) == last_irmp_denon_command) // command bits must be inverted
{
irmp_tmp_command = last_irmp_denon_command; // use command received before!
 
irmp_protocol = irmp_param.protocol; // store protocol
irmp_address = irmp_tmp_address; // store address
irmp_command = irmp_tmp_command ; // store command
}
else
{
ANALYZE_PRINTF ("waiting for inverted command repetition\n");
irmp_ir_detected = FALSE;
last_irmp_denon_command = irmp_tmp_command;
}
}
else
#endif // IRMP_SUPPORT_DENON_PROTOCOL
 
#if IRMP_SUPPORT_GRUNDIG_PROTOCOL == 1
if (irmp_param.protocol == IRMP_GRUNDIG_PROTOCOL && irmp_tmp_command == 0x01ff)
{ // Grundig start frame?
ANALYZE_PRINTF ("Detected GRUNDIG start frame, ignoring it\n");
irmp_ir_detected = FALSE;
}
else
#endif // IRMP_SUPPORT_GRUNDIG_PROTOCOL
 
#if IRMP_SUPPORT_NOKIA_PROTOCOL == 1
if (irmp_param.protocol == IRMP_NOKIA_PROTOCOL && irmp_tmp_address == 0x00ff && irmp_tmp_command == 0x00fe)
{ // Nokia start frame?
ANALYZE_PRINTF ("Detected NOKIA start frame, ignoring it\n");
irmp_ir_detected = FALSE;
}
else
#endif // IRMP_SUPPORT_NOKIA_PROTOCOL
{
#if IRMP_SUPPORT_NEC_PROTOCOL == 1
if (irmp_param.protocol == IRMP_NEC_PROTOCOL && irmp_bit == 0) // repetition frame
{
if (repetition_len < NEC_FRAME_REPEAT_PAUSE_LEN_MAX)
{
ANALYZE_PRINTF ("Detected NEC repetition frame, repetition_len = %d\n", repetition_len);
irmp_tmp_address = last_irmp_address; // address is last address
irmp_tmp_command = last_irmp_command; // command is last command
irmp_flags |= IRMP_FLAG_REPETITION;
repetition_len = 0;
}
else
{
ANALYZE_PRINTF ("Detected NEC repetition frame, ignoring it: timeout occured, repetition_len = %d > %d\n",
repetition_len, NEC_FRAME_REPEAT_PAUSE_LEN_MAX);
irmp_ir_detected = FALSE;
}
}
#endif // IRMP_SUPPORT_NEC_PROTOCOL
 
#if IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
if (irmp_param.protocol == IRMP_KASEIKYO_PROTOCOL)
{
uint8_t xor;
// ANALYZE_PRINTF ("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n",
// xor_check[0], xor_check[1], xor_check[2], xor_check[3], xor_check[4], xor_check[5]);
 
xor = (xor_check[0] & 0x0F) ^ ((xor_check[0] & 0xF0) >> 4) ^ (xor_check[1] & 0x0F) ^ ((xor_check[1] & 0xF0) >> 4);
 
if (xor != (xor_check[2] & 0x0F))
{
ANALYZE_PRINTF ("error 4: wrong XOR check for customer id: 0x%1x 0x%1x\n", xor, xor_check[2] & 0x0F);
irmp_ir_detected = FALSE;
}
 
xor = xor_check[2] ^ xor_check[3] ^ xor_check[4];
 
if (xor != xor_check[5])
{
ANALYZE_PRINTF ("error 4: wrong XOR check for data bits: 0x%02x 0x%02x\n", xor, xor_check[5]);
irmp_ir_detected = FALSE;
}
}
#endif // IRMP_SUPPORT_KASEIKYO_PROTOCOL == 1
 
#if IRMP_SUPPORT_RC6_PROTOCOL == 1
if (irmp_param.protocol == IRMP_RC6_PROTOCOL && irmp_param.complete_len == RC6_COMPLETE_DATA_LEN_LONG) // RC6 mode = 6?
{
irmp_protocol = IRMP_RC6A_PROTOCOL;
}
else
#endif // IRMP_SUPPORT_RC6_PROTOCOL == 1
 
irmp_protocol = irmp_param.protocol;
 
#if IRMP_SUPPORT_FDC_PROTOCOL == 1
if (irmp_param.protocol == IRMP_FDC_PROTOCOL)
{
if (irmp_tmp_command & 0x000F) // released key?
{
irmp_tmp_command = (irmp_tmp_command >> 4) | 0x80; // yes, set bit 7
}
else
{
irmp_tmp_command >>= 4; // no, it's a pressed key
}
irmp_tmp_command |= (irmp_tmp_address << 2) & 0x0F00; // 000000CCCCAAAAAA -> 0000CCCC00000000
irmp_tmp_address &= 0x003F;
}
#endif
 
irmp_address = irmp_tmp_address; // store address
#if IRMP_SUPPORT_NEC_PROTOCOL == 1
last_irmp_address = irmp_tmp_address; // store as last address, too
#endif
 
#if IRMP_SUPPORT_RC5_PROTOCOL == 1
if (irmp_param.protocol == IRMP_RC5_PROTOCOL)
{
irmp_tmp_command |= rc5_cmd_bit6; // store bit 6
}
#endif
irmp_command = irmp_tmp_command; // store command
 
#if IRMP_SUPPORT_SAMSUNG_PROTOCOL == 1
irmp_id = irmp_tmp_id;
#endif
}
}
 
if (irmp_ir_detected)
{
if (last_irmp_command == irmp_command &&
last_irmp_address == irmp_address &&
repetition_len < IRMP_KEY_REPETITION_LEN)
{
irmp_flags |= IRMP_FLAG_REPETITION;
}
 
last_irmp_address = irmp_tmp_address; // store as last address, too
last_irmp_command = irmp_tmp_command; // store as last command, too
 
repetition_len = 0;
}
else
{
ANALYZE_ONLY_NORMAL_PUTCHAR ('\n');
}
 
irmp_start_bit_detected = 0; // and wait for next start bit
irmp_tmp_command = 0;
irmp_pulse_time = 0;
irmp_pause_time = 0;
 
#if IRMP_SUPPORT_JVC_PROTOCOL == 1
if (irmp_protocol == IRMP_JVC_PROTOCOL) // the stop bit of JVC frame is also start bit of next frame
{ // set pulse time here!
irmp_pulse_time = ((uint8_t)(F_INTERRUPTS * JVC_START_BIT_PULSE_TIME));
}
#endif // IRMP_SUPPORT_JVC_PROTOCOL == 1
}
}
}
return (irmp_ir_detected);
}
 
#ifdef ANALYZE
 
/*---------------------------------------------------------------------------------------------------------------------------------------------------
* main functions - for Unix/Linux + Windows only!
*
* AVR: see main.c!
*
* Compile it under linux with:
* cc irmp.c -o irmp
*
* usage: ./irmp [-v|-s|-a|-l|-p] < file
*
* options:
* -v verbose
* -s silent
* -a analyze
* -l list pulse/pauses
* -p print timings
*---------------------------------------------------------------------------------------------------------------------------------------------------
*/
 
static void
print_timings (void)
{
printf ("IRMP_TIMEOUT_LEN: %d [%d byte(s)]\n", IRMP_TIMEOUT_LEN, sizeof (PAUSE_LEN));
printf ("IRMP_KEY_REPETITION_LEN %d\n", IRMP_KEY_REPETITION_LEN);
puts ("");
printf ("PROTOCOL S S-PULSE S-PAUSE PULSE-0 PAUSE-0 PULSE-1 PAUSE-1\n");
printf ("====================================================================================\n");
printf ("SIRCS 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
SIRCS_START_BIT_PULSE_LEN_MIN, SIRCS_START_BIT_PULSE_LEN_MAX, SIRCS_START_BIT_PAUSE_LEN_MIN, SIRCS_START_BIT_PAUSE_LEN_MAX,
SIRCS_0_PULSE_LEN_MIN, SIRCS_0_PULSE_LEN_MAX, SIRCS_PAUSE_LEN_MIN, SIRCS_PAUSE_LEN_MAX,
SIRCS_1_PULSE_LEN_MIN, SIRCS_1_PULSE_LEN_MAX, SIRCS_PAUSE_LEN_MIN, SIRCS_PAUSE_LEN_MAX);
 
printf ("NEC 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX, NEC_START_BIT_PAUSE_LEN_MIN, NEC_START_BIT_PAUSE_LEN_MAX,
NEC_PULSE_LEN_MIN, NEC_PULSE_LEN_MAX, NEC_0_PAUSE_LEN_MIN, NEC_0_PAUSE_LEN_MAX,
NEC_PULSE_LEN_MIN, NEC_PULSE_LEN_MAX, NEC_1_PAUSE_LEN_MIN, NEC_1_PAUSE_LEN_MAX);
 
printf ("NEC (rep) 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
NEC_START_BIT_PULSE_LEN_MIN, NEC_START_BIT_PULSE_LEN_MAX, NEC_REPEAT_START_BIT_PAUSE_LEN_MIN, NEC_REPEAT_START_BIT_PAUSE_LEN_MAX,
NEC_PULSE_LEN_MIN, NEC_PULSE_LEN_MAX, NEC_0_PAUSE_LEN_MIN, NEC_0_PAUSE_LEN_MAX,
NEC_PULSE_LEN_MIN, NEC_PULSE_LEN_MAX, NEC_1_PAUSE_LEN_MIN, NEC_1_PAUSE_LEN_MAX);
 
printf ("SAMSUNG 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
SAMSUNG_START_BIT_PULSE_LEN_MIN, SAMSUNG_START_BIT_PULSE_LEN_MAX, SAMSUNG_START_BIT_PAUSE_LEN_MIN, SAMSUNG_START_BIT_PAUSE_LEN_MAX,
SAMSUNG_PULSE_LEN_MIN, SAMSUNG_PULSE_LEN_MAX, SAMSUNG_0_PAUSE_LEN_MIN, SAMSUNG_0_PAUSE_LEN_MAX,
SAMSUNG_PULSE_LEN_MIN, SAMSUNG_PULSE_LEN_MAX, SAMSUNG_1_PAUSE_LEN_MIN, SAMSUNG_1_PAUSE_LEN_MAX);
 
printf ("MATSUSHITA 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
MATSUSHITA_START_BIT_PULSE_LEN_MIN, MATSUSHITA_START_BIT_PULSE_LEN_MAX, MATSUSHITA_START_BIT_PAUSE_LEN_MIN, MATSUSHITA_START_BIT_PAUSE_LEN_MAX,
MATSUSHITA_PULSE_LEN_MIN, MATSUSHITA_PULSE_LEN_MAX, MATSUSHITA_0_PAUSE_LEN_MIN, MATSUSHITA_0_PAUSE_LEN_MAX,
MATSUSHITA_PULSE_LEN_MIN, MATSUSHITA_PULSE_LEN_MAX, MATSUSHITA_1_PAUSE_LEN_MIN, MATSUSHITA_1_PAUSE_LEN_MAX);
 
printf ("KASEIKYO 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
KASEIKYO_START_BIT_PULSE_LEN_MIN, KASEIKYO_START_BIT_PULSE_LEN_MAX, KASEIKYO_START_BIT_PAUSE_LEN_MIN, KASEIKYO_START_BIT_PAUSE_LEN_MAX,
KASEIKYO_PULSE_LEN_MIN, KASEIKYO_PULSE_LEN_MAX, KASEIKYO_0_PAUSE_LEN_MIN, KASEIKYO_0_PAUSE_LEN_MAX,
KASEIKYO_PULSE_LEN_MIN, KASEIKYO_PULSE_LEN_MAX, KASEIKYO_1_PAUSE_LEN_MIN, KASEIKYO_1_PAUSE_LEN_MAX);
 
printf ("RECS80 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
RECS80_START_BIT_PULSE_LEN_MIN, RECS80_START_BIT_PULSE_LEN_MAX, RECS80_START_BIT_PAUSE_LEN_MIN, RECS80_START_BIT_PAUSE_LEN_MAX,
RECS80_PULSE_LEN_MIN, RECS80_PULSE_LEN_MAX, RECS80_0_PAUSE_LEN_MIN, RECS80_0_PAUSE_LEN_MAX,
RECS80_PULSE_LEN_MIN, RECS80_PULSE_LEN_MAX, RECS80_1_PAUSE_LEN_MIN, RECS80_1_PAUSE_LEN_MAX);
 
printf ("RC5 1 %3d - %3d %3d - %3d %3d - %3d\n",
RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX, RC5_START_BIT_LEN_MIN, RC5_START_BIT_LEN_MAX,
RC5_BIT_LEN_MIN, RC5_BIT_LEN_MAX);
 
printf ("DENON 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
DENON_PULSE_LEN_MIN, DENON_PULSE_LEN_MAX,
DENON_PULSE_LEN_MIN, DENON_PULSE_LEN_MAX, DENON_0_PAUSE_LEN_MIN, DENON_0_PAUSE_LEN_MAX,
DENON_PULSE_LEN_MIN, DENON_PULSE_LEN_MAX, DENON_1_PAUSE_LEN_MIN, DENON_1_PAUSE_LEN_MAX);
 
printf ("RC6 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
RC6_START_BIT_PULSE_LEN_MIN, RC6_START_BIT_PULSE_LEN_MAX, RC6_START_BIT_PAUSE_LEN_MIN, RC6_START_BIT_PAUSE_LEN_MAX,
RC6_BIT_PULSE_LEN_MIN, RC6_BIT_PULSE_LEN_MAX, RC6_BIT_PAUSE_LEN_MIN, RC6_BIT_PAUSE_LEN_MAX);
 
printf ("RECS80EXT 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
RECS80EXT_START_BIT_PULSE_LEN_MIN, RECS80EXT_START_BIT_PULSE_LEN_MAX, RECS80EXT_START_BIT_PAUSE_LEN_MIN, RECS80EXT_START_BIT_PAUSE_LEN_MAX,
RECS80EXT_PULSE_LEN_MIN, RECS80EXT_PULSE_LEN_MAX, RECS80EXT_0_PAUSE_LEN_MIN, RECS80EXT_0_PAUSE_LEN_MAX,
RECS80EXT_PULSE_LEN_MIN, RECS80EXT_PULSE_LEN_MAX, RECS80EXT_1_PAUSE_LEN_MIN, RECS80EXT_1_PAUSE_LEN_MAX);
 
printf ("NUBERT 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
NUBERT_START_BIT_PULSE_LEN_MIN, NUBERT_START_BIT_PULSE_LEN_MAX, NUBERT_START_BIT_PAUSE_LEN_MIN, NUBERT_START_BIT_PAUSE_LEN_MAX,
NUBERT_0_PULSE_LEN_MIN, NUBERT_0_PULSE_LEN_MAX, NUBERT_0_PAUSE_LEN_MIN, NUBERT_0_PAUSE_LEN_MAX,
NUBERT_1_PULSE_LEN_MIN, NUBERT_1_PULSE_LEN_MAX, NUBERT_1_PAUSE_LEN_MIN, NUBERT_1_PAUSE_LEN_MAX);
 
printf ("BANG_OLUFSEN 1 %3d - %3d %3d - %3d\n",
BANG_OLUFSEN_START_BIT1_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PULSE_LEN_MAX,
BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT1_PAUSE_LEN_MAX);
 
printf ("BANG_OLUFSEN 2 %3d - %3d %3d - %3d\n",
BANG_OLUFSEN_START_BIT2_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PULSE_LEN_MAX,
BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT2_PAUSE_LEN_MAX);
 
printf ("BANG_OLUFSEN 3 %3d - %3d %3d - %3d\n",
BANG_OLUFSEN_START_BIT3_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PULSE_LEN_MAX,
BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT3_PAUSE_LEN_MAX);
 
printf ("BANG_OLUFSEN 4 %3d - %3d %3d - %3d\n",
BANG_OLUFSEN_START_BIT4_PULSE_LEN_MIN, BANG_OLUFSEN_START_BIT4_PULSE_LEN_MAX,
BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MIN, BANG_OLUFSEN_START_BIT4_PAUSE_LEN_MAX);
 
printf ("BANG_OLUFSEN - %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
BANG_OLUFSEN_PULSE_LEN_MIN, BANG_OLUFSEN_PULSE_LEN_MAX, BANG_OLUFSEN_0_PAUSE_LEN_MIN, BANG_OLUFSEN_0_PAUSE_LEN_MAX,
BANG_OLUFSEN_PULSE_LEN_MIN, BANG_OLUFSEN_PULSE_LEN_MAX, BANG_OLUFSEN_1_PAUSE_LEN_MIN, BANG_OLUFSEN_1_PAUSE_LEN_MAX);
 
printf ("GRUNDIG/NOKIA 1 %3d - %3d %3d - %3d %3d - %3d\n",
GRUNDIG_OR_NOKIA_START_BIT_LEN_MIN, GRUNDIG_OR_NOKIA_START_BIT_LEN_MAX, GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN_MIN, GRUNDIG_OR_NOKIA_PRE_PAUSE_LEN_MAX,
GRUNDIG_OR_NOKIA_BIT_LEN_MIN, GRUNDIG_OR_NOKIA_BIT_LEN_MAX);
 
printf ("SIEMENS 1 %3d - %3d %3d - %3d %3d - %3d\n",
SIEMENS_START_BIT_LEN_MIN, SIEMENS_START_BIT_LEN_MAX, SIEMENS_START_BIT_LEN_MIN, SIEMENS_START_BIT_LEN_MAX,
SIEMENS_BIT_LEN_MIN, SIEMENS_BIT_LEN_MAX);
 
printf ("FDC 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
FDC_START_BIT_PULSE_LEN_MIN, FDC_START_BIT_PULSE_LEN_MAX, FDC_START_BIT_PAUSE_LEN_MIN, FDC_START_BIT_PAUSE_LEN_MAX,
FDC_PULSE_LEN_MIN, FDC_PULSE_LEN_MAX, FDC_0_PAUSE_LEN_MIN, FDC_0_PAUSE_LEN_MAX,
FDC_PULSE_LEN_MIN, FDC_PULSE_LEN_MAX, FDC_1_PAUSE_LEN_MIN, FDC_1_PAUSE_LEN_MAX);
 
printf ("RCCAR 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
RCCAR_START_BIT_PULSE_LEN_MIN, RCCAR_START_BIT_PULSE_LEN_MAX, RCCAR_START_BIT_PAUSE_LEN_MIN, RCCAR_START_BIT_PAUSE_LEN_MAX,
RCCAR_PULSE_LEN_MIN, RCCAR_PULSE_LEN_MAX, RCCAR_0_PAUSE_LEN_MIN, RCCAR_0_PAUSE_LEN_MAX,
RCCAR_PULSE_LEN_MIN, RCCAR_PULSE_LEN_MAX, RCCAR_1_PAUSE_LEN_MIN, RCCAR_1_PAUSE_LEN_MAX);
 
printf ("NIKON 1 %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d %3d - %3d\n",
NIKON_START_BIT_PULSE_LEN_MIN, NIKON_START_BIT_PULSE_LEN_MAX, NIKON_START_BIT_PAUSE_LEN_MIN, NIKON_START_BIT_PAUSE_LEN_MAX,
NIKON_PULSE_LEN_MIN, NIKON_PULSE_LEN_MAX, NIKON_0_PAUSE_LEN_MIN, NIKON_0_PAUSE_LEN_MAX,
NIKON_PULSE_LEN_MIN, NIKON_PULSE_LEN_MAX, NIKON_1_PAUSE_LEN_MIN, NIKON_1_PAUSE_LEN_MAX);
 
}
 
void
print_spectrum (char * text, int * buf, int is_pulse)
{
int i;
int j;
int min;
int max;
int max_value = 0;
int value;
int sum = 0;
int counter = 0;
double average = 0;
double tolerance;
 
puts ("-------------------------------------------------------------------------------");
printf ("%s:\n", text);
 
for (i = 0; i < 256; i++)
{
if (buf[i] > max_value)
{
max_value = buf[i];
}
}
 
for (i = 0; i < 100; i++)
{
if (buf[i] > 0)
{
printf ("%3d ", i);
value = (buf[i] * 60) / max_value;
 
for (j = 0; j < value; j++)
{
putchar ('o');
}
printf (" %d\n", buf[i]);
 
sum += i * buf[i];
counter += buf[i];
}
else
{
max = i - 1;
 
if (counter > 0)
{
average = (float) sum / (float) counter;
 
if (is_pulse)
{
printf ("pulse ");
}
else
{
printf ("pause ");
}
 
printf ("avg: %4.1f=%6.1f us, ", average, (1000000. * average) / (float) F_INTERRUPTS);
printf ("min: %2d=%6.1f us, ", min, (1000000. * min) / (float) F_INTERRUPTS);
printf ("max: %2d=%6.1f us, ", max, (1000000. * max) / (float) F_INTERRUPTS);
 
tolerance = (max - average);
 
if (average - min > tolerance)
{
tolerance = average - min;
}
 
tolerance = tolerance * 100 / average;
printf ("tol: %4.1f%%\n", tolerance);
}
 
counter = 0;
sum = 0;
min = i + 1;
}
}
}
 
#define STATE_LEFT_SHIFT 0x01
#define STATE_RIGHT_SHIFT 0x02
#define STATE_LEFT_CTRL 0x04
#define STATE_LEFT_ALT 0x08
#define STATE_RIGHT_ALT 0x10
 
#define KEY_ESCAPE 0x1B // keycode = 0x006e
#define KEY_MENUE 0x80 // keycode = 0x0070
#define KEY_BACK 0x81 // keycode = 0x0071
#define KEY_FORWARD 0x82 // keycode = 0x0072
#define KEY_ADDRESS 0x83 // keycode = 0x0073
#define KEY_WINDOW 0x84 // keycode = 0x0074
#define KEY_1ST_PAGE 0x85 // keycode = 0x0075
#define KEY_STOP 0x86 // keycode = 0x0076
#define KEY_MAIL 0x87 // keycode = 0x0077
#define KEY_FAVORITES 0x88 // keycode = 0x0078
#define KEY_NEW_PAGE 0x89 // keycode = 0x0079
#define KEY_SETUP 0x8A // keycode = 0x007a
#define KEY_FONT 0x8B // keycode = 0x007b
#define KEY_PRINT 0x8C // keycode = 0x007c
#define KEY_ON_OFF 0x8E // keycode = 0x007c
 
#define KEY_INSERT 0x90 // keycode = 0x004b
#define KEY_DELETE 0x91 // keycode = 0x004c
#define KEY_LEFT 0x92 // keycode = 0x004f
#define KEY_HOME 0x93 // keycode = 0x0050
#define KEY_END 0x94 // keycode = 0x0051
#define KEY_UP 0x95 // keycode = 0x0053
#define KEY_DOWN 0x96 // keycode = 0x0054
#define KEY_PAGE_UP 0x97 // keycode = 0x0055
#define KEY_PAGE_DOWN 0x98 // keycode = 0x0056
#define KEY_RIGHT 0x99 // keycode = 0x0059
#define KEY_MOUSE_1 0x9E // keycode = 0x0400
#define KEY_MOUSE_2 0x9F // keycode = 0x0800
 
static uint8_t
get_fdc_key (uint16_t cmd)
{
static uint8_t key_table[128] =
{
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0, '^', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'ß', '´', 0, '\b',
'\t','q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 'ü', '+', 0, 0, 'a',
's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', '#', '\r', 0, '<', 'y', 'x',
'c', 'v', 'b', 'n', 'm', ',', '.', '-', 0, 0, 0, 0, 0, ' ', 0, 0,
 
0, '°', '!', '"', '§', '$', '%', '&', '/', '(', ')', '=', '?', '`', 0, '\b',
'\t','Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', 'Ü', '*', 0, 0, 'A',
'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'Ö', 'Ä', '\'','\r', 0, '>', 'Y', 'X',
'C', 'V', 'B', 'N', 'M', ';', ':', '_', 0, 0, 0, 0, 0, ' ', 0, 0
};
static uint8_t state;
 
uint8_t key = 0;
 
switch (cmd)
{
case 0x002C: state |= STATE_LEFT_SHIFT; break; // pressed left shift
case 0x00AC: state &= ~STATE_LEFT_SHIFT; break; // released left shift
case 0x0039: state |= STATE_RIGHT_SHIFT; break; // pressed right shift
case 0x00B9: state &= ~STATE_RIGHT_SHIFT; break; // released right shift
case 0x003A: state |= STATE_LEFT_CTRL; break; // pressed left ctrl
case 0x00BA: state &= ~STATE_LEFT_CTRL; break; // released left ctrl
case 0x003C: state |= STATE_LEFT_ALT; break; // pressed left alt
case 0x00BC: state &= ~STATE_LEFT_ALT; break; // released left alt
case 0x003E: state |= STATE_RIGHT_ALT; break; // pressed left alt
case 0x00BE: state &= ~STATE_RIGHT_ALT; break; // released left alt
 
case 0x006e: key = KEY_ESCAPE; break;
case 0x004b: key = KEY_INSERT; break;
case 0x004c: key = KEY_DELETE; break;
case 0x004f: key = KEY_LEFT; break;
case 0x0050: key = KEY_HOME; break;
case 0x0051: key = KEY_END; break;
case 0x0053: key = KEY_UP; break;
case 0x0054: key = KEY_DOWN; break;
case 0x0055: key = KEY_PAGE_UP; break;
case 0x0056: key = KEY_PAGE_DOWN; break;
case 0x0059: key = KEY_RIGHT; break;
case 0x0400: key = KEY_MOUSE_1; break;
case 0x0800: key = KEY_MOUSE_2; break;
 
default:
{
if (!(cmd & 0x80)) // pressed key
{
if (cmd >= 0x70 && cmd <= 0x7F) // function keys
{
key = cmd + 0x10; // 7x -> 8x
}
else if (cmd < 64) // key listed in key_table
{
if (state & (STATE_LEFT_ALT | STATE_RIGHT_ALT))
{
switch (cmd)
{
case 0x0003: key = '²'; break;
case 0x0008: key = '{'; break;
case 0x0009: key = '['; break;
case 0x000A: key = ']'; break;
case 0x000B: key = '}'; break;
case 0x000C: key = '\\'; break;
case 0x001C: key = '~'; break;
case 0x002D: key = '|'; break;
case 0x0034: key = 'µ'; break;
}
}
else if (state & (STATE_LEFT_CTRL))
{
if (key_table[cmd] >= 'a' && key_table[cmd] <= 'z')
{
key = key_table[cmd] - 'a' + 1;
}
else
{
key = key_table[cmd];
}
}
else
{
int idx = cmd + ((state & (STATE_LEFT_SHIFT | STATE_RIGHT_SHIFT)) ? 64 : 0);
 
if (key_table[idx])
{
key = key_table[idx];
}
}
}
}
break;
}
}
 
return (key);
}
 
static int analyze = FALSE;
static int list = FALSE;
static IRMP_DATA irmp_data;
 
static void
next_tick (void)
{
if (! analyze && ! list)
{
(void) irmp_ISR ();
 
if (irmp_get_data (&irmp_data))
{
uint8_t key;
 
ANALYZE_ONLY_NORMAL_PUTCHAR (' ');
 
if (verbose)
{
printf ("%8d ", time_counter);
}
 
if (irmp_data.protocol == IRMP_FDC_PROTOCOL && (key = get_fdc_key (irmp_data.command)) != 0)
{
if ((key >= 0x20 && key < 0x7F) || key >= 0xA0)
{
printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x, key = '%c'\n",
irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags, key, key);
}
else if (key == '\r' || key == '\t' || key == KEY_ESCAPE || (key >= 0x80 && key <= 0x9F)) // function keys
{
char * p = (char *) NULL;
 
switch (key)
{
case '\t' : p = "TAB"; break;
case '\r' : p = "CR"; break;
case KEY_ESCAPE : p = "ESCAPE"; break;
case KEY_MENUE : p = "MENUE"; break;
case KEY_BACK : p = "BACK"; break;
case KEY_FORWARD : p = "FORWARD"; break;
case KEY_ADDRESS : p = "ADDRESS"; break;
case KEY_WINDOW : p = "WINDOW"; break;
case KEY_1ST_PAGE : p = "1ST_PAGE"; break;
case KEY_STOP : p = "STOP"; break;
case KEY_MAIL : p = "MAIL"; break;
case KEY_FAVORITES : p = "FAVORITES"; break;
case KEY_NEW_PAGE : p = "NEW_PAGE"; break;
case KEY_SETUP : p = "SETUP"; break;
case KEY_FONT : p = "FONT"; break;
case KEY_PRINT : p = "PRINT"; break;
case KEY_ON_OFF : p = "ON_OFF"; break;
 
case KEY_INSERT : p = "INSERT"; break;
case KEY_DELETE : p = "DELETE"; break;
case KEY_LEFT : p = "LEFT"; break;
case KEY_HOME : p = "HOME"; break;
case KEY_END : p = "END"; break;
case KEY_UP : p = "UP"; break;
case KEY_DOWN : p = "DOWN"; break;
case KEY_PAGE_UP : p = "PAGE_UP"; break;
case KEY_PAGE_DOWN : p = "PAGE_DOWN"; break;
case KEY_RIGHT : p = "RIGHT"; break;
case KEY_MOUSE_1 : p = "KEY_MOUSE_1"; break;
case KEY_MOUSE_2 : p = "KEY_MOUSE_2"; break;
default : p = "<UNKNWON>"; break;
}
 
printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x, key = %s\n",
irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags, key, p);
}
else
{
printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x, asc = 0x%02x\n",
irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags, key);
}
}
else
{
printf ("p = %2d, a = 0x%04x, c = 0x%04x, f = 0x%02x\n",
irmp_data.protocol, irmp_data.address, irmp_data.command, irmp_data.flags);
}
}
}
}
 
int
main (int argc, char ** argv)
{
int i;
int ch;
int last_ch = 0;
int pulse = 0;
int pause = 0;
 
int start_pulses[256];
int start_pauses[256];
int pulses[256];
int pauses[256];
 
int first_pulse = TRUE;
int first_pause = TRUE;
 
if (argc == 2)
{
if (! strcmp (argv[1], "-v"))
{
verbose = TRUE;
}
else if (! strcmp (argv[1], "-l"))
{
list = TRUE;
}
else if (! strcmp (argv[1], "-a"))
{
analyze = TRUE;
}
else if (! strcmp (argv[1], "-s"))
{
silent = TRUE;
}
else if (! strcmp (argv[1], "-p"))
{
print_timings ();
return (0);
}
}
 
for (i = 0; i < 256; i++)
{
start_pulses[i] = 0;
start_pauses[i] = 0;
pulses[i] = 0;
pauses[i] = 0;
}
 
IRMP_PIN = 0xFF;
 
while ((ch = getchar ()) != EOF)
{
if (ch == '_' || ch == '0')
{
if (last_ch != ch)
{
if (pause > 0)
{
if (list)
{
printf ("pause: %d\n", pause);
}
 
if (analyze)
{
if (first_pause)
{
if (pause < 256)
{
start_pauses[pause]++;
}
first_pause = FALSE;
}
else
{
if (pause < 256)
{
pauses[pause]++;
}
}
}
}
pause = 0;
}
pulse++;
IRMP_PIN = 0x00;
}
else if (ch == 0xaf || ch == '-' || ch == '1')
{
if (last_ch != ch)
{
if (list)
{
printf ("pulse: %d ", pulse);
}
 
if (analyze)
{
if (first_pulse)
{
if (pulse < 256)
{
start_pulses[pulse]++;
}
first_pulse = FALSE;
}
else
{
if (pulse < 256)
{
pulses[pulse]++;
}
}
}
pulse = 0;
}
 
pause++;
IRMP_PIN = 0xff;
}
else if (ch == '\n')
{
IRMP_PIN = 0xff;
 
if (list && pause > 0)
{
printf ("pause: %d\n", pause);
}
pause = 0;
 
if (! analyze)
{
for (i = 0; i < (int) ((8000.0 * F_INTERRUPTS) / 10000); i++) // newline: long pause of 800 msec
{
next_tick ();
}
}
first_pulse = TRUE;
first_pause = TRUE;
}
else if (ch == '#')
{
if (analyze)
{
while ((ch = getchar()) != '\n' && ch != EOF)
{
;
}
}
else
{
puts ("-------------------------------------------------------------------");
putchar (ch);
 
while ((ch = getchar()) != '\n' && ch != EOF)
{
if (ch != '\r') // ignore CR in DOS/Windows files
{
putchar (ch);
}
}
putchar ('\n');
}
 
}
 
last_ch = ch;
 
next_tick ();
}
 
if (analyze)
{
print_spectrum ("START PULSES", start_pulses, TRUE);
print_spectrum ("START PAUSES", start_pauses, FALSE);
print_spectrum ("PULSES", pulses, TRUE);
print_spectrum ("PAUSES", pauses, FALSE);
puts ("-------------------------------------------------------------------------------");
}
return 0;
}
 
#endif // ANALYZE
/Servo-Controlled IR-Transmitter/Software/servo-IR.aps
New file
0,0 → 1,0
<AVRStudio><MANAGEMENT><ProjectName>irsnd</ProjectName><Created>07-Jan-2010 20:23:49</Created><LastEdit>20-Dec-2010 11:23:34</LastEdit><ICON>241</ICON><ProjectType>0</ProjectType><Created>07-Jan-2010 20:23:49</Created><Version>4</Version><Build>4, 18, 0, 670</Build><ProjectTypeName>AVR GCC</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>default\servo-IR.elf</ObjectFile><EntryFile></EntryFile><SaveFolder>D:\Pendsa\IR\Software\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATmega88.xml</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><Triggers></Triggers></Debugger><AVRGCCPLUGIN><FILES><SOURCEFILE>main.c</SOURCEFILE><SOURCEFILE>irsnd.c</SOURCEFILE><SOURCEFILE>irmp.c</SOURCEFILE><HEADERFILE>irmp.h</HEADERFILE><HEADERFILE>irsnd.h</HEADERFILE><HEADERFILE>irsndconfig.h</HEADERFILE><HEADERFILE>irmpconfig.h</HEADERFILE></FILES><CONFIGS><CONFIG><NAME>default</NAME><USESEXTERNALMAKEFILE>NO</USESEXTERNALMAKEFILE><EXTERNALMAKEFILE></EXTERNALMAKEFILE><PART>atmega8</PART><HEX>1</HEX><LIST>1</LIST><MAP>1</MAP><OUTPUTFILENAME>servo-IR.elf</OUTPUTFILENAME><OUTPUTDIR>default\</OUTPUTDIR><ISDIRTY>0</ISDIRTY><OPTIONS/><INCDIRS/><LIBDIRS/><LIBS/><LINKOBJECTS/><OPTIONSFORALL>-Wall -gdwarf-2 -std=gnu99 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums</OPTIONSFORALL><LINKEROPTIONS></LINKEROPTIONS><SEGMENTS/></CONFIG></CONFIGS><LASTCONFIG>default</LASTCONFIG><USES_WINAVR>1</USES_WINAVR><GCC_LOC>C:\Programme\WinAVR-20081205\bin\avr-gcc.exe</GCC_LOC><MAKE_LOC>C:\Programme\WinAVR-20081205\utils\bin\make.exe</MAKE_LOC></AVRGCCPLUGIN><ProjectFiles><Files><Name>D:\Pendsa\IR\Software\irmp.h</Name><Name>D:\Pendsa\IR\Software\irsnd.h</Name><Name>D:\Pendsa\IR\Software\irsndconfig.h</Name><Name>D:\Pendsa\IR\Software\irmpconfig.h</Name><Name>D:\Pendsa\IR\Software\main.c</Name><Name>D:\Pendsa\IR\Software\irsnd.c</Name><Name>D:\Pendsa\IR\Software\irmp.c</Name></Files></ProjectFiles><IOView><usergroups/><sort sorted="0" column="0" ordername="1" orderaddress="1" ordergroup="1"/></IOView><Files><File00000><FileId>00000</FileId><FileName>irmp.h</FileName><Status>1</Status></File00000><File00001><FileId>00001</FileId><FileName>irsnd.c</FileName><Status>1</Status></File00001><File00002><FileId>00002</FileId><FileName>irsnd.h</FileName><Status>1</Status></File00002><File00003><FileId>00003</FileId><FileName>irsndconfig.h</FileName><Status>1</Status></File00003><File00004><FileId>00004</FileId><FileName>irmpconfig.h</FileName><Status>1</Status></File00004><File00005><FileId>00005</FileId><FileName>c:\programme\winavr-20081205\avr\include\avr\iom88.h</FileName><Status>1</Status></File00005><File00006><FileId>00006</FileId><FileName>c:\programme\winavr-20081205\avr\include\avr\common.h</FileName><Status>1</Status></File00006><File00007><FileId>00007</FileId><FileName>irmp.c</FileName><Status>1</Status></File00007><File00008><FileId>00008</FileId><FileName>main.c</FileName><Status>1</Status></File00008><File00009><FileId>00009</FileId><FileName>c:\programme\winavr-20081205\avr\include\util\delay.h</FileName><Status>1</Status></File00009></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio>
/Servo-Controlled IR-Transmitter/Hardware/IR-Transmitter.brd
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/Servo-Controlled IR-Transmitter/Hardware/IR-Transmitter.brd
New file
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: Hardware/Parts-Top.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: Hardware/Parts-Top.png
===================================================================
--- Hardware/Parts-Top.png (revision 0)
+++ Hardware/Parts-Top.png (revision 838)
/Hardware/Parts-Top.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: Hardware/Parts-Bottom.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: Hardware/Parts-Bottom.png
===================================================================
--- Hardware/Parts-Bottom.png (revision 0)
+++ Hardware/Parts-Bottom.png (revision 838)
/Hardware/Parts-Bottom.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: Hardware/IR-Transmitter.sch
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: Hardware/IR-Transmitter.sch
===================================================================
--- Hardware/IR-Transmitter.sch (revision 0)
+++ Hardware/IR-Transmitter.sch (revision 838)
/Hardware/IR-Transmitter.sch
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: Hardware/Layout.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: Hardware/Layout.png
===================================================================
--- Hardware/Layout.png (revision 0)
+++ Hardware/Layout.png (revision 838)
/Hardware/Layout.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: Hardware/Schematic.png
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: Hardware/Schematic.png
===================================================================
--- Hardware/Schematic.png (revision 0)
+++ Hardware/Schematic.png (revision 838)
/Hardware/Schematic.png
Property changes:
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: Doku.txt
===================================================================
--- Doku.txt (revision 0)
+++ Doku.txt (revision 838)
@@ -0,0 +1,75 @@
+Servo controlled infrared transmitter
+Based on the nice IR decoder/encoder routines (IRMP/IRSND) from Frank Meyer => http://www.mikrocontroller.net/articles/IRMP
+
+Application examples:
+- Remote control for a camera on a RC-model through normal servo channels.
+- Control for a TV at home. Doorbell connected to one input - switches the TV to a surveillance cam.
+- Control for a stereo at home. Motion sensor connected to one input - pump up the volume to scare a housebreaker.
+
+The idea for this project came up, to control a HD-camcorder on a Mikrokopter with a second radio-transmitter.
+Gas-Stick: Zooming Camera
+3-way Switch: Stop/Picture/Movie record
+Nick-Stick: Cameraholder-Nick
+Roll-Stick: Cameraholder-Roll
+
+
+Inputs:
+2 channels for servo-signals, switches or other TTL signals
+1 IR-Receiver to learn new codes (36 - 40 kHz)
+
+Output:
+Modulated infrared signal at 950 nm
+
+Controls:
+1 LED to indicate several operating modes
+1 button to enter/leave the learning mode and switch between single and multi mode
+
+Supply voltage:
+5V DC @ 50 mA
+
+
+Theory of operation:
+
+Each channel is seperated into 5 states, depending on the positive pulse width:
+0,00 - 0,74 ms => 0 (switch to GND)
+0,75 - 1,24 ms => 1 (stick down)
+1,25 - 1,74 ms => 2 (stick middle)
+1,75 - 2,24 ms => 3 (stick up)
+2,25 - more ms => 4 (switch to VCC or open input)
+
+Together with the second input, you get theoretically 25 different combinations, which all can be populated with learned IR-code.
+
+When using servo signals only, you have 3 states per channel, so 9 combinations.
+When using switch signals only, you have 2 states per channel, so 4 combinations.
+When mixing both signals, you have 2 states for the switch and 3 states for the servo, so 6 combinations.
+When using only one channel, you get 2 (switch) or 3 (servo) states.
+
+After power-up, the device checks the inputs the whole time. When a combination was learned with an IR-Code before, this code is sent out through the IR-Diode. Depending on which mode this combination was learned, it is sent out only once (single-mode), or as long as the combination stays active (multi-mode).
+When the device sends out IR-Code, the red LED lights up.
+
+
+Theory of learning:
+When you press the button on the device, it goes to learning-mode.
+In this mode, the LED flashes 1 or 2 times (depending of the actual mode) every half second, indicating that the device is waiting for IR-codes.
+When pressing the button again, you can choose between single- or multi-mode.
+
+When an IR-code is sent to the device, it looks at which state-combination the inputs are, and saves the IR-code for this combination.
+Saving is confirmed with fast flashing of the LED.
+You can now learn multiple combinations with different (or same) IR-codes, you can even mix up different IR-protocols and use different modes on different combinations.
+When you have learned enough, press the button for 2 seconds, to permanently save the data to the EEPROM. This is confirmed with fast LED-flashing.
+The device goes back to normal operation and is ready for orders.
+
+
+Currently supported IR-Protocols
+Protocol Used by
+===================
+GRUNDIG Grundig
+JVC JVC
+KASEIKYO Panasonic, Technics, Denon and more japanese manufacturer, which are member in "Japan's Association for Electric Home Application"
+NEC NEC, Yamaha, Canon, Tevion, Harman/Kardon, Hitachi, JVC, Pioneer, Toshiba, Xoro, Orion, NoName and much more japanese manufacturer
+NIKON Nikon
+NOKIA Nokia, e.g. D-Box
+RC5 Philips and more european manufacturer
+RECS80 Philips, Nokia, Thomson, Nordmende, Telefunken, Saba, Technisat
+SAMSUNG Samsung
+SIRCS Sony