// ir_command.c by Redpic
// ANSONIC SDG-20H (TDT) supporting NEC-32 Protocol
// With recording Command send function
// and automode programing on reset
#include <18f4550.h>
#fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7)
#define PIN_FUNC1 PIN_E0
#define PIN_FUNC2 PIN_E1
#define PIN_FUNC3 PIN_E2
#define PIN_LED PIN_E0
// CONSTANTES -
const char Version[]="1.0.H\0";
const int total_bits = 32;
const int total_bytes = 4;
const char COMANDO232_MENU = '?'; const char COMANDO232_TXT_MENU[] = "Muestra menu de opciones RS232.";
const char COMANDO232_MODO_PROG = 'p'; const char COMANDO232_TXT_MODO_PROG[] = "Entrar en modo Programación.";
const char COMANDO232_FUNC_ON = 'o'; const char COMANDO232_TXT_FUNC_ON[] = " * 1 Activa/Desactiva procesar Comandos IR.";
const char COMANDO232_FUNC_1 = '1'; const char COMANDO232_TXT_FUNC_1[] = " * 2 Ejecutar Función 1";
const char COMANDO232_FUNC_2 = '2'; const char COMANDO232_TXT_FUNC_2[] = " * 3 Ejecutar Función 2";
const char COMANDO232_FUNC_3 = '3'; const char COMANDO232_TXT_FUNC_3[] = " * 4 Ejecutar Función 3";
const char COMANDO232_FUNC_VEX = 'f'; const char COMANDO232_TXT_FUNC_VEX[] = " * 5 Ver Estado actual de funciones.";
const char COMANDO232_FUNC_VER = 'm'; const char COMANDO232_TXT_FUNC_VER[] = " * 6 Ver Comandos almacenados por función.";
const char COMANDO232_FUNC_RESET= 'r'; const char COMANDO232_TXT_FUNC_RESET[]= " * 7 Reset Hardware.";
const char COMANDO232_FUNC_PLUS = '+'; const char COMANDO232_TXT_FUNC_PLUS[] = " * 8 Incrementa valor Ref.";
const char COMANDO232_FUNC_Minus= '-'; const char COMANDO232_TXT_FUNC_MINUS[]= " * 9 Decrementa valor Ref.";
const int MODO_INACTIVO = 0; const char MODO_TXT_INACTIVO[] = "INACTIVO";
const int MODO_ACTIVO = 1; const char MODO_TXT_ACTIVO[] = "ACTIVO";
const int MODO_PROGRAMACION = 2; const char MODO_TXT_PROGRAMACION[] = "PROGRAMACIÓN";
const int RTCCS_AUTOPROG = 3;
// VARIABLES EN RAM -
// De recepción IR y generales --
int1 first_ext=0;
int1 start_recived=0;
int1 hay_dato=0;
int1 autoprog_enabled=0;
int1 flag_flash_led=0;
char sbits[total_bits];
int i,j,k;
long tt,tti,t;
int ntbits=0;
char sbit1;
int bits[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int bytes[total_bytes]={0x00,0x00,0x00,0x00};
int nrtcc=0;
// De Comandos y Funciones --
char rec232=0x00;
char opcion=0x00;
int Modo=MODO_INACTIVO;
int nextPROG=0;
int1 FUNC1=0;
int1 FUNC2=0;
int1 FUNC3=0;
int VALREF;
int ADDRESSDEV;
int COMANDODEV_FUNC_ON;
int COMANDODEV_FUNC_1;
int COMANDODEV_FUNC_2;
int COMANDODEV_FUNC_3;
int COMANDODEV_FUNC_VEX;
int COMANDODEV_FUNC_VER;
int COMANDODEV_FUNC_RESET;
int COMANDODEV_FUNC_PLUS;
int COMANDODEV_FUNC_MINUS;
// Prototipos de funciones --
void flash_led(int n);
void limpia_bits(void);
void convierte_bits_a_bytes(void);
void muestra_bits(void);
void lee_config_desde_EEPROM(void);
void programar_comandos(int funcion, int device_address, int device_command);
void presenta_menu(void);
void on_reset(void);
// INTERRUPCION por RECEPCION SERIE -
#int_rda
void serial_isr() {
rec232=0x00;
if(kbhit()){
if( rec232==COMANDO232_MENU ||
rec232==COMANDO232_MODO_PROG ||
rec232==COMANDO232_FUNC_ON ||
rec232==COMANDO232_FUNC_1 ||
rec232==COMANDO232_FUNC_2 ||
rec232==COMANDO232_FUNC_3 ||
rec232==COMANDO232_FUNC_PLUS ||
rec232==COMANDO232_FUNC_MINUS ||
rec232==COMANDO232_FUNC_RESET ||
rec232==COMANDO232_FUNC_VEX ||
rec232==COMANDO232_FUNC_VER){
opcion=rec232;
}
}
}
// INTERRUPCION EXT por RB0 --
#int_ext
void ext_isr() {
// Obtengo datos de Timer0
tt = get_timer0();
t = tt-tti;
tti= tt;
// Si he recibido el Start Bit puedo guardar
if(start_recived==1){
// Bit "0"
if(t>40 && t<50){ sbits[ntbits]='0'; }
// Bit "1"
if(t>85 && t<90){ sbits[ntbits]='1'; }
// Si he recibido 32 bits entonces hay dato
if(++ntbits==total_bits){
hay_dato=1;
}
}
// Detecto Start Bit
if(t>525 && t<530){
start_recived=1;
limpia_bits();
}
}
// INTERRUPCION RTCC por TIMER0 -
#int_rtcc
void rtcc_isr() {
if(autoprog_enabled){
++nrtcc;
flag_flash_led=1;
if(nrtcc==RTCCS_AUTOPROG){
autoprog_enabled=0;
printf("\r\nAutoprog disabled.\r\n"); }
}
}
//-
void flash_led(int n){
for(i=0;i<n-1;i++){
output_high(PIN_LED);
delay_ms(75);
output_low(PIN_LED);
delay_ms(75);
}
}
void limpia_bits(void){
for(i=0;i<total_bits;++i){
sbits[i]='\0';
}
ntbits=0;
}
void convierte_bits_a_bytes(void){
for(i=0;i<4;++i){
Bytes[i]=0x00;
for(j=0;j<8;++j){
if(sbits[(i*8)+j]=='1'){
bytes[i]=bytes[i]|Bits[j];
}
}
}
}
void muestra_bits(void){
printf("[COMANDO] %u\\%u\r\n",Bytes
[0],Bytes
[2]); }
void lee_config_desde_EEPROM(void){
ADDRESSDEV = read_eeprom( 0); if(ADDRESSDEV ==0xFF){ADDRESSDEV=64;}
VALREF = read_eeprom( 1); if(VALREF ==0xFF){VALREF=127;}
COMANDODEV_FUNC_ON = read_eeprom( 2); if(COMANDODEV_FUNC_ON ==0xFF){COMANDODEV_FUNC_ON = 24;} // Btn ON/OFF
COMANDODEV_FUNC_1 = read_eeprom( 3); if(COMANDODEV_FUNC_1 ==0xFF){COMANDODEV_FUNC_1 = 26;} // Btn 1
COMANDODEV_FUNC_2 = read_eeprom( 4); if(COMANDODEV_FUNC_2 ==0xFF){COMANDODEV_FUNC_2 = 17;} // Btn 2
COMANDODEV_FUNC_3 = read_eeprom( 5); if(COMANDODEV_FUNC_3 ==0xFF){COMANDODEV_FUNC_3 = 9;} // Btn 3
COMANDODEV_FUNC_VEX = read_eeprom( 6); if(COMANDODEV_FUNC_VEX ==0xFF){COMANDODEV_FUNC_VEX = 7;} // Btn Ok
COMANDODEV_FUNC_VER = read_eeprom( 7); if(COMANDODEV_FUNC_VER ==0xFF){COMANDODEV_FUNC_VER = 25;} // Btn Menu
COMANDODEV_FUNC_RESET = read_eeprom( 8); if(COMANDODEV_FUNC_RESET==0xFF){COMANDODEV_FUNC_RESET= 3;} // Btn Exit
COMANDODEV_FUNC_PLUS = read_eeprom( 9); if(COMANDODEV_FUNC_PLUS ==0xFF){COMANDODEV_FUNC_PLUS= 13;} // Btn CH+
COMANDODEV_FUNC_MINUS = read_eeprom(10); if(COMANDODEV_FUNC_MINUS==0xFF){COMANDODEV_FUNC_MINUS= 30;} // Btn CH-
}
void programar_comandos(int funcion, int device_address, int device_command){
switch(funcion){
case 0:
printf("Modo PROGRAMACIÓN activado ...\r\n"); printf("Pulse cualquier botón para obtener el ADDRESS "); flash_led(1);
break;
case 1:
printf("Address=%2u (0x%x)\r\n",device_address
,device_address
); write_eeprom(0,device_address);
delay_ms(10);
printf("Pulse para [Activar/Desactivar] "); flash_led(2);
break;
case 2:
printf("Command=%2u (0x%x)\r\n",device_command
,device_command
); write_eeprom(2,device_command);
delay_ms(10);
printf("Pulse para [Ejecutar Función 1] "); flash_led(3);
break;
case 3:
printf("Command=%2u (0x%x)\r\n",device_command
,device_command
); write_eeprom(3,device_command);
delay_ms(10);
printf("Pulse para [Ejecutar Función 2] "); flash_led(4);
break;
case 4:
printf("Command=%2u (0x%x)\r\n",device_command
,device_command
); write_eeprom(4,device_command);
delay_ms(10);
printf("Pulse para [Ejecutar Función 3] "); flash_led(5);
break;
case 5:
printf("Command=%2u (0x%x)\r\n",device_command
,device_command
); write_eeprom(5,device_command);
delay_ms(10);
printf("Pulse para [Ver estado de funciones] "); flash_led(6);
break;
case 6:
printf("Command=%2u (0x%x)\r\n",device_command
,device_command
); write_eeprom(6,device_command);
delay_ms(10);
printf("Pulse para [Ver comandos almacenados] "); flash_led(7);
break;
case 7:
printf("Command=%2u (0x%x)\r\n",device_command
,device_command
); write_eeprom(7,device_command);
delay_ms(10);
printf("Pulse para [Reset Hardware] "); flash_led(8);
break;
case 8:
printf("Command=%2u (0x%x)\r\n",device_command
,device_command
); write_eeprom(8,device_command);
delay_ms(10);
printf("Pulse para [Inc. Valor Ref.] "); flash_led(9);
break;
case 9:
printf("Command=%2u (0x%x)\r\n",device_command
,device_command
); write_eeprom(9,device_command);
delay_ms(10);
printf("Pulse para [Dec. Valor Ref.] "); flash_led(9);
break;
case 10:
printf("Command=%2u (0x%x)\r\n",device_command
,device_command
); write_eeprom(10,device_command);
delay_ms(11);
// fin programación
printf("Fin Modo PROGRAMACION.\r\n"); on_reset();
break;
}
}
//-
void presenta_menu(void){
printf("Opciones Menu RS232:\r\n\n"); printf(" [%c] %s\r\n", COMANDO232_MENU
, COMANDO232_TXT_MENU
); printf(" [%c] %s\r\n", COMANDO232_MODO_PROG
, COMANDO232_TXT_MODO_PROG
); printf(" [%c] %s\r\n", COMANDO232_FUNC_ON
, COMANDO232_TXT_FUNC_ON
); printf(" [%c] %s\r\n", COMANDO232_FUNC_1
, COMANDO232_TXT_FUNC_1
); printf(" [%c] %s\r\n", COMANDO232_FUNC_2
, COMANDO232_TXT_FUNC_2
); printf(" [%c] %s\r\n", COMANDO232_FUNC_3
, COMANDO232_TXT_FUNC_3
); printf(" [%c] %s\r\n", COMANDO232_FUNC_VEX
, COMANDO232_TXT_FUNC_VEX
); printf(" [%c] %s\r\n", COMANDO232_FUNC_VER
, COMANDO232_TXT_FUNC_VER
); printf(" [%c] %s\r\n", COMANDO232_FUNC_RESET
,COMANDO232_TXT_FUNC_RESET
); printf(" [%c] %s\r\n", COMANDO232_FUNC_PLUS
, COMANDO232_TXT_FUNC_PLUS
); printf(" [%c] %s\r\n", COMANDO232_FUNC_MINUS
,COMANDO232_TXT_FUNC_MINUS
); }
void on_reset(void){
disable_interrupts(global);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(FALSE);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128);
set_tris_b(0b00000001);
set_tris_c(0b10000000);
set_tris_e(0b00010000);
output_e(0x00);
delay_ms(500);
printf("[RRBOARD2] IR Command Receiver version %s\r\n",version
); printf("TSOP1738 Reader-Decoder over 18F4550\r\n"); printf("for ANSONIC SDG-20H with NEC-32 Protocol\r\n\n"); flash_led(3);
presenta_menu();
ext_int_edge(H_TO_L);
first_ext=0;
start_recived=0;
hay_dato=0;
limpia_bits();
rec232=0x00;
opcion=0x00;
Modo=MODO_INACTIVO;
FUNC1=0;
FUNC2=0;
FUNC3=0;
nextPROG=0;
nrtcc=0;
flag_flash_led=0;
autoprog_enabled=1;
lee_config_desde_EEPROM();
delay_ms(500);
enable_interrupts(int_rda);
enable_interrupts(int_ext);
enable_interrupts(int_rtcc);
enable_interrupts(global);
}
void main() {
on_reset();
do {
// Recibe y procesa IR Command para generar 232 Command -
if(hay_dato==1){
hay_dato=0;
// Extrae byte recibido y limpia -
convierte_bits_a_bytes();
limpia_bits();
// Detecta cualquier pulsacion IR durante Autoprog_enabled -
if(Autoprog_enabled){
Autoprog_enabled=0;
Opcion=COMANDO232_MODO_PROG;
}else{
// Si no estamos en modo PROGRAMACION -
if(Modo!=MODO_PROGRAMACION){
muestra_bits();
// Si el Address es correcto ... -
if(Bytes[0]==ADDRESSDEV){
// Comando COMANDO232_FUNC_ON -
if(Bytes[2]==COMANDODEV_FUNC_ON){
opcion=COMANDO232_FUNC_ON;
}
// Comando FUNC1 --
if(Bytes[2]==COMANDODEV_FUNC_1){
opcion=COMANDO232_FUNC_1;
}
// Comando FUNC2 --
if(Bytes[2]==COMANDODEV_FUNC_2){
opcion=COMANDO232_FUNC_2;
}
// Comando FUNC3 --
if(Bytes[2]==COMANDODEV_FUNC_3){
opcion=COMANDO232_FUNC_3;
}
// Comando FUNC_VEX -
if(Bytes[2]==COMANDODEV_FUNC_VEX){
opcion=COMANDO232_FUNC_VEX;
}
// Comando FUNC_VER -
if(Bytes[2]==COMANDODEV_FUNC_VER){
opcion=COMANDO232_FUNC_VER;
}
// Comando FUNC_RESET -
if(Bytes[2]==COMANDODEV_FUNC_RESET){
opcion=COMANDO232_FUNC_RESET;
}
// Comando FUNC_PLUS --
if(Bytes[2]==COMANDODEV_FUNC_PLUS){
opcion=COMANDO232_FUNC_PLUS;
}
// Comando FUNC_MINUS --
if(Bytes[2]==COMANDODEV_FUNC_MINUS){
opcion=COMANDO232_FUNC_MINUS;
}
}
// Si estamos en Modo PROGRAMACION -
}else{
programar_comandos(++nextPROG,bytes[0],bytes[2]);
}
}
}
// Recibe y procesa RS232 Opcion
if(opcion!=0x00){
Switch(opcion){
// Muestra menu de opciones -
case COMANDO232_MENU:
presenta_menu();
break;
// Entrar en Modo PROGRAMACION --
case COMANDO232_MODO_PROG:
nextPROG=0;
Modo=MODO_PROGRAMACION;
programar_comandos(0,0,0);
break;
// Activa/Desactiva procesar Comandos FUNC --
case COMANDO232_FUNC_ON:
if(Modo==MODO_INACTIVO){
Modo=MODO_ACTIVO;
printf("Modo : Activada recepción de Comandos\r\n"); }else{
Modo=MODO_INACTIVO;
printf("Modo : Desactivada recepción de Comandos\r\n"); };
break;
// Reset de Hardware --
case COMANDO232_FUNC_RESET:
if(Modo==MODO_ACTIVO){
on_reset();
}else{
printf("**Error, Recibido RESET pero Modo=INACTIVO\r\n"); }
break;
// Ejecutar Función 1 -
case COMANDO232_FUNC_1:
if(Modo==MODO_ACTIVO){
FUNC1=!FUNC1;
if(FUNC1){
output_high(PIN_FUNC1);
printf("FUNC1 : Activada\r\n"); }else{
output_low(PIN_FUNC1);
printf("FUNC1 : Desactivada\r\n"); }
}else{
printf("**Error, Recibido F1 pero Modo=INACTIVO\r\n"); }
break;
// Ejecutar Función 2 -
case COMANDO232_FUNC_2:
if(Modo==MODO_ACTIVO){
FUNC2=!FUNC2;
if(FUNC2){
output_high(PIN_FUNC2);
printf("FUNC2 : Activada\r\n"); }else{
output_low(PIN_FUNC2);
printf("FUNC2 : Desactivada\r\n"); }
}else{
printf("**Error, Recibido F2 pero Modo=INACTIVO\r\n"); }
break;
// Ejecutar Función 3 -
case COMANDO232_FUNC_3:
if(Modo==MODO_ACTIVO){
FUNC3=!FUNC3;
if(FUNC3){
output_high(PIN_FUNC3);
printf("FUNC3 : Activada\r\n"); }else{
output_low(PIN_FUNC3);
printf("FUNC3 : Desactivada\r\n"); }
}else{
printf("**Error, Recibido F3 pero Modo=INACTIVO\r\n"); }
break;
// Ejecutar Plus --
case COMANDO232_FUNC_PLUS:
if(Modo==MODO_ACTIVO){
++VALREF;
write_eeprom(1,VALREF);
printf("V.Ref.=%u\r\n",VALREF
); }else{
printf("**Error, Recibido Inc. pero Modo=INACTIVO\r\n"); }
break;
// Ejecutar Minus -
case COMANDO232_FUNC_MINUS:
if(Modo==MODO_ACTIVO){
--VALREF;
write_eeprom(1,VALREF);
printf("V.Ref.=%u\r\n",VALREF
); }else{
printf("**Error, Recibido Dec. pero Modo=INACTIVO\r\n"); }
break;
// Ver Estado actual de funciones -
case COMANDO232_FUNC_VEX:
switch(Modo){
case MODO_PROGRAMACION:
printf("Estado = %s, ",MODO_TXT_PROGRAMACION
); break;
case MODO_INACTIVO:
printf("Estado = %s, ",MODO_TXT_INACTIVO
); break;
case MODO_ACTIVO:
printf("Estado = %s, ",MODO_TXT_ACTIVO
); break;
}
if(FUNC1
) printf("F3 = ON\r\n "); else printf("F3 = OFF\r\n"); break;
// Ver Comandos almacenados por función -
case COMANDO232_FUNC_VER:
printf("Address= %3u (0x%x)\r\n",ADDRESSDEV
,ADDRESSDEV
); printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_ON
, COMANDODEV_FUNC_ON
, COMANDO232_TXT_FUNC_ON
); printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_1
, COMANDODEV_FUNC_1
, COMANDO232_TXT_FUNC_1
); printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_2
, COMANDODEV_FUNC_2
, COMANDO232_TXT_FUNC_2
); printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_3
, COMANDODEV_FUNC_3
, COMANDO232_TXT_FUNC_3
); printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_VEX
, COMANDODEV_FUNC_VEX
, COMANDO232_TXT_FUNC_VEX
); printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_VER
, COMANDODEV_FUNC_VER
, COMANDO232_TXT_FUNC_VER
); printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_RESET
, COMANDODEV_FUNC_RESET
, COMANDO232_TXT_FUNC_RESET
); printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_PLUS
, COMANDODEV_FUNC_PLUS
, COMANDO232_TXT_FUNC_PLUS
); printf("Command= %3u (0x%x) %s\r\n",COMANDODEV_FUNC_MINUS
, COMANDODEV_FUNC_MINUS
, COMANDO232_TXT_FUNC_MINUS
); break;
//-
}
opcion=0x00;
}
// Detecto FLASH LED --
if(flag_flash_led){
flag_flash_led=0;
flash_led(2);
}
} while (TRUE);
}