X-Git-Url: http://cloudbase.mooo.com/gitweb/irmp.git/blobdiff_plain/5481e9cdedc6358a14c9dc3afae0d96afe7b762b..48664931c4d9371a7be6735227011e54954f79cc:/irsnd.c diff --git a/irsnd.c b/irsnd.c index c18db62..570b916 100644 --- a/irsnd.c +++ b/irsnd.c @@ -3,7 +3,7 @@ * * Copyright (c) 2010 Frank Meyer - frank(at)fli4l.de * - * $Id: irsnd.c,v 1.7 2010/04/14 13:21:39 fm Exp $ + * $Id: irsnd.c,v 1.19 2010/06/14 15:55:11 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 @@ -47,95 +47,72 @@ typedef unsigned short uint16_t; #endif // WIN32 #endif // unix -#include "irmpconfig.h" #include "irmp.h" +#include "irsndconfig.h" #include "irsnd.h" -/*--------------------------------------------------------------------------------------------------------------------------------------------------- - * 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 - *--------------------------------------------------------------------------------------------------------------------------------------------------- - */ -#define IRSND_SUPPORT_SIRCS_PROTOCOL 1 // flag: support SIRCS uses ~150 bytes -#define IRSND_SUPPORT_NEC_PROTOCOL 1 // flag: support NEC uses ~100 bytes -#define IRSND_SUPPORT_SAMSUNG_PROTOCOL 1 // flag: support Samsung + Samsung32 uses ~300 bytes -#define IRSND_SUPPORT_MATSUSHITA_PROTOCOL 1 // flag: support Matsushita uses ~150 bytes -#define IRSND_SUPPORT_KASEIKYO_PROTOCOL 0 // flag: support Kaseikyo NOT SUPPORTED YET! -#define IRSND_SUPPORT_RECS80_PROTOCOL 1 // flag: support RECS80 uses ~100 bytes -#define IRSND_SUPPORT_RC5_PROTOCOL 1 // flag: support RC5 uses ~250 bytes -#define IRSND_SUPPORT_DENON_PROTOCOL 1 // flag: support DENON uses ~200 bytes -#define IRSND_SUPPORT_RC6_PROTOCOL 0 // flag: support RC6 NOT SUPPORTED YET! -#define IRSND_SUPPORT_RECS80EXT_PROTOCOL 1 // flag: support RECS80EXT uses ~100 bytes -#define IRSND_SUPPORT_NUBERT_PROTOCOL 1 // flag: support NUBERT uses ~100 bytes -#define IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL 1 // flag: support Bang&Olufsen uses ~250 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... - - #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_REPETITION_LEN (uint16_t)(F_INTERRUPTS * SIRCS_REPETITION_TIME + 0.5) // use uint16_t! +#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 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_REPETITION_LEN (uint16_t)(F_INTERRUPTS * DENON_REPETITION_TIME + 0.5) // use uint16_t! +#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) @@ -143,7 +120,8 @@ typedef unsigned short uint16_t; #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_REPETITION_LEN (uint16_t)(F_INTERRUPTS * NUBERT_REPETITION_TIME + 0.5) // use uint16_t! +#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) @@ -156,6 +134,17 @@ typedef unsigned short uint16_t; #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) @@ -164,9 +153,17 @@ typedef unsigned short uint16_t; #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! + static volatile uint8_t irsnd_busy; static volatile uint8_t irsnd_protocol; -static volatile uint8_t irsnd_buffer[5]; +static volatile uint8_t irsnd_buffer[6]; +static volatile uint8_t irsnd_repeat; static volatile uint8_t irsnd_is_on = FALSE; /*--------------------------------------------------------------------------------------------------------------------------------------------------- @@ -184,7 +181,7 @@ irsnd_on (void) TCCR2 |= (1<protocol; + irsnd_repeat = irmp_data_p->flags; switch (irsnd_protocol) { @@ -307,7 +312,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) { command = bitsrevervse (irmp_data_p->command, SIRCS_MINIMUM_DATA_LEN); - irsnd_protocol = irmp_data_p->protocol; irsnd_buffer[0] = (command & 0x0FF0) >> 4; // CCCCCCCC irsnd_buffer[1] = (command & 0x000F) << 4; // CCCC0000 irsnd_busy = TRUE; @@ -316,15 +320,25 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) #endif #if IRSND_SUPPORT_NEC_PROTOCOL == 1 case IRMP_NEC_PROTOCOL: + case IRMP_APPLE_PROTOCOL: { address = bitsrevervse (irmp_data_p->address, NEC_ADDRESS_LEN); command = bitsrevervse (irmp_data_p->command, NEC_COMMAND_LEN); - irsnd_protocol = irmp_data_p->protocol; irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC - irsnd_buffer[3] = ~((command & 0xFF00) >> 8); // cccccccc + + if (irsnd_protocol == IRMP_APPLE_PROTOCOL) + { + irsnd_protocol = IRMP_NEC_PROTOCOL; // APPLE protocol is NEC with fix bitmask instead of inverted command + irsnd_buffer[3] = 0x8B; // 10001011 + } + else + { + irsnd_buffer[3] = ~((command & 0xFF00) >> 8); // cccccccc + } + irsnd_busy = TRUE; break; } @@ -335,7 +349,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN); command = bitsrevervse (irmp_data_p->command, SAMSUNG_COMMAND_LEN); - irsnd_protocol = irmp_data_p->protocol; irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA irsnd_buffer[2] = (command & 0x00F0) | ((command & 0xF000) >> 12); // IIIICCCC @@ -349,7 +362,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) address = bitsrevervse (irmp_data_p->address, SAMSUNG_ADDRESS_LEN); command = bitsrevervse (irmp_data_p->command, SAMSUNG32_COMMAND_LEN); - irsnd_protocol = irmp_data_p->protocol; irsnd_buffer[0] = (address & 0xFF00) >> 8; // AAAAAAAA irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA irsnd_buffer[2] = (command & 0xFF00) >> 8; // CCCCCCCC @@ -364,7 +376,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) address = bitsrevervse (irmp_data_p->address, MATSUSHITA_ADDRESS_LEN); command = bitsrevervse (irmp_data_p->command, MATSUSHITA_COMMAND_LEN); - irsnd_protocol = irmp_data_p->protocol; irsnd_buffer[0] = (command & 0x0FF0) >> 4; // CCCCCCCC irsnd_buffer[1] = ((command & 0x000F) << 4) | ((address & 0x0F00) >> 8); // CCCCAAAA irsnd_buffer[2] = (address & 0x00FF); // AAAAAAAA @@ -377,7 +388,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) { toggle_bit_recs80 = toggle_bit_recs80 ? 0x00 : 0x40; - irsnd_protocol = irmp_data_p->protocol; 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 @@ -390,7 +400,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) { toggle_bit_recs80ext = toggle_bit_recs80ext ? 0x00 : 0x40; - irsnd_protocol = irmp_data_p->protocol; 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 @@ -403,7 +412,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) { toggle_bit_rc5 = toggle_bit_rc5 ? 0x00 : 0x40; - irsnd_protocol = irmp_data_p->protocol; 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 @@ -414,11 +422,10 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) #if IRSND_SUPPORT_DENON_PROTOCOL == 1 case IRMP_DENON_PROTOCOL: { - irsnd_protocol = irmp_data_p->protocol; - irsnd_buffer[0] = ((irmp_data_p->address & 0x1F) << 3) | ((irmp_data_p->command & 0x0380) >> 7); // AAAAACCC - irsnd_buffer[1] = (irmp_data_p->command & 0x7F) << 1; // CCCCCCC0 - irsnd_buffer[2] = ((irmp_data_p->address & 0x1F) << 3) | (((~irmp_data_p->command) & 0x0380) >> 7); // AAAAACCC - irsnd_buffer[3] = (~(irmp_data_p->command) & 0x7F) << 1; // CCCCCCC0 + 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; } @@ -426,7 +433,6 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) #if IRSND_SUPPORT_NUBERT_PROTOCOL == 1 case IRMP_NUBERT_PROTOCOL: { - irsnd_protocol = irmp_data_p->protocol; irsnd_buffer[0] = irmp_data_p->command >> 2; // CCCCCCCC irsnd_buffer[1] = (irmp_data_p->command & 0x0003) << 6; // CC000000 irsnd_busy = TRUE; @@ -436,13 +442,68 @@ irsnd_send_data (IRMP_DATA * irmp_data_p) #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 case IRMP_BANG_OLUFSEN_PROTOCOL: { - irsnd_protocol = irmp_data_p->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); // CCCCC0 + 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 & 0xFF00) >> 8; // AAAAAAAA + irsnd_buffer[1] = (address & 0x00FF); // AAAAAAAA + irsnd_buffer[2] = 0; // 00000000 + irsnd_buffer[3] = (command & 0x0FE0) >> 5; // 0CCCCCCC + irsnd_buffer[4] = ((command & 0x001F) << 3) | 0x07; // CCCCC111 + irsnd_busy = TRUE; + break; + } #endif default: { @@ -473,10 +534,14 @@ irsnd_ISR (void) static uint8_t has_stop_bit; static uint8_t new_frame = TRUE; static uint8_t complete_data_len; - static uint8_t n_frames; // number of repetitions - static uint8_t frame_counter; // repetition counter - static uint16_t repetition_pause; // pause before repetition, uint16_t! - static uint16_t repetition_pause_counter; // pause before repetition, uint16_t! + 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 @@ -487,19 +552,37 @@ irsnd_ISR (void) { if (current_bit == 0xFF && new_frame) // start of transmission... { - if (frame_counter > 0) + if (auto_repetition_counter > 0) { - repetition_pause_counter++; + auto_repetition_pause_counter++; - if (repetition_pause_counter >= repetition_pause) + if (auto_repetition_pause_counter >= auto_repetition_pause_len) { - repetition_pause_counter = 0; + 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 { @@ -516,26 +599,45 @@ irsnd_ISR (void) 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 { - pulse_counter = 0; - pause_counter = 0; + 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_frames = SIRCS_REPETITION_CNT; - repetition_pause = SIRCS_REPETITION_LEN; // 45 ms pause + 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; } @@ -543,15 +645,27 @@ irsnd_ISR (void) #if IRSND_SUPPORT_NEC_PROTOCOL == 1 case IRMP_NEC_PROTOCOL: { - startbit_pulse_len = NEC_START_BIT_PULSE_LEN; - startbit_pause_len = NEC_START_BIT_PAUSE_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; - complete_data_len = NEC_COMPLETE_DATA_LEN; - n_frames = 1; + 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; } @@ -559,30 +673,34 @@ irsnd_ISR (void) #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_frames = 1; + 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_frames = 1; + 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; } @@ -590,15 +708,17 @@ irsnd_ISR (void) #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_frames = 1; + 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; } @@ -606,15 +726,17 @@ irsnd_ISR (void) #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_frames = 1; + 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; } @@ -622,15 +744,17 @@ irsnd_ISR (void) #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_frames = 1; + 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; } @@ -638,15 +762,15 @@ irsnd_ISR (void) #if IRSND_SUPPORT_RC5_PROTOCOL == 1 case IRMP_RC5_PROTOCOL: { - startbit_pulse_len = RC5_BIT_LEN; - startbit_pause_len = RC5_BIT_LEN; - pulse_1_len = RC5_BIT_LEN; - pause_1_len = RC5_BIT_LEN; - pulse_0_len = RC5_BIT_LEN; - pause_0_len = RC5_BIT_LEN; - has_stop_bit = RC5_STOP_BIT; - complete_data_len = RC5_COMPLETE_DATA_LEN; - n_frames = 1; + 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; } @@ -654,16 +778,17 @@ irsnd_ISR (void) #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_frames = 2; - repetition_pause = DENON_REPETITION_LEN; // 65 ms pause after 1st frame (15 bits) + 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; } @@ -671,16 +796,17 @@ irsnd_ISR (void) #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_frames = 2; - repetition_pause = NUBERT_REPETITION_LEN; // 35 ms pause + 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; } @@ -688,19 +814,88 @@ irsnd_ISR (void) #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_frames = 1; - last_bit_value = 0; + 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 default: { @@ -714,6 +909,7 @@ irsnd_ISR (void) if (irsnd_busy) { new_frame = FALSE; + switch (irsnd_protocol) { #if IRSND_SUPPORT_SIRCS_PROTOCOL == 1 @@ -744,6 +940,14 @@ irsnd_ISR (void) #if IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL == 1 case IRMP_BANG_OLUFSEN_PROTOCOL: #endif +#if IRSND_SUPPORT_NEC_PROTOCOL == 1 + case IRMP_FDC_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_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 { if (pulse_counter == 0) { @@ -836,7 +1040,7 @@ irsnd_ISR (void) { pulse_len = pulse_0_len; - if (frame_counter < n_frames) + if (auto_repetition_counter < n_auto_repetitions) { pause_len = pause_0_len; } @@ -870,12 +1074,12 @@ irsnd_ISR (void) if (current_bit >= complete_data_len + has_stop_bit) { current_bit = 0xFF; - frame_counter++; + auto_repetition_counter++; - if (frame_counter == n_frames) + if (auto_repetition_counter == n_auto_repetitions) { irsnd_busy = FALSE; - frame_counter = 0; + auto_repetition_counter = 0; } new_frame = TRUE; } @@ -885,86 +1089,149 @@ irsnd_ISR (void) } break; } +#endif + #if IRSND_SUPPORT_RC5_PROTOCOL == 1 case IRMP_RC5_PROTOCOL: - { - uint8_t first_pulse; - uint8_t next_bit = FALSE; +#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 (current_bit == 0xFF) // 1 start bit - { - first_pulse = FALSE; - } - else // send n'th bit +#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) { - first_pulse = (irsnd_buffer[current_bit / 8] & (1<<(7-(current_bit % 8)))) ? FALSE : TRUE; - } + current_bit++; - if (first_pulse) - { - if (pulse_counter < RC5_BIT_LEN) + if (current_bit >= complete_data_len) { - if (pulse_counter == 0) + 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) { - irsnd_on (); + 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; + } } - pulse_counter++; - } - else if (pause_counter < RC5_BIT_LEN) - { - if (pause_counter == 0) + else +#endif { - irsnd_off (); + irsnd_busy = FALSE; } - pause_counter++; - } - else - { - next_bit = TRUE; + + new_frame = TRUE; + irsnd_off (); } + + pulse_counter = 0; + pause_counter = 0; } - else + + if (! new_frame) { - if (pause_counter < RC5_BIT_LEN) + 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 (pause_counter == 0) + 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 { - irsnd_off (); + 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; } - pause_counter++; } - else if (pulse_counter < RC5_BIT_LEN) + else // if (irsnd_protocol == IRMP_RC5_PROTOCOL || irsnd_protocol == IRMP_SIEMENS_PROTOCOL) +#endif { - if (pulse_counter == 0) + 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) { - irsnd_on (); + first_pulse = first_pulse ? FALSE : TRUE; } - pulse_counter++; } - else + + if (first_pulse) { - next_bit = TRUE; + 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++; + } } - } - - if (next_bit) - { - current_bit++; - - if (current_bit >= RC5_COMPLETE_DATA_LEN) + else { - current_bit = 0xFF; - irsnd_busy = FALSE; - new_frame = TRUE; - irsnd_off (); + 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++; + } } - - pulse_counter = 0; - pause_counter = 0; } break; } -#endif // IRSND_SUPPORT_RC5_PROTOCOL +#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; @@ -972,6 +1239,20 @@ irsnd_ISR (void) } } } + + if (! irsnd_busy) + { + if (repeat_counter < n_repeat_frames) + { + repeat_counter++; + irsnd_busy = TRUE; + } + else + { + n_repeat_frames = 0; + repeat_counter = 0; + } + } } #ifdef DEBUG @@ -1001,16 +1282,14 @@ int main (int argc, char ** argv) { int idx; - int cnt; int protocol; int address; int command; - int repeat = 1; IRMP_DATA irmp_data; - if (argc != 4) + if (argc != 4 && argc != 5) { - fprintf (stderr, "usage: %s protocol hex-address hex-command > filename\n", argv[0]); + fprintf (stderr, "usage: %s protocol hex-address hex-command [repeat] > filename\n", argv[0]); return 1; } @@ -1022,16 +1301,26 @@ main (int argc, char ** argv) irmp_data.address = address; irmp_data.command = command; + if (argc == 5) + { + irmp_data.flags = atoi (argv[4]); + } + else + { + irmp_data.flags = 0; + } + irsnd_init (); - for (cnt = 0; cnt < repeat; cnt++) - { - (void) irsnd_send_data (&irmp_data); + (void) irsnd_send_data (&irmp_data, TRUE); - for (idx = 0; idx < 3000; idx++) - { - irsnd_ISR (); - } + while (irsnd_busy) + { + irsnd_ISR (); + } + for (idx = 0; idx < 20; idx++) + { + irsnd_ISR (); } putchar ('\n');