
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//   PROGRAMA  QUE  NO PUED0 COMPILAR  MAS ABAJO APARECEN LOS ARCHIVOS   esclavos_i2c.c   y external_eeprom.c                     //
//   dice  identificador indefinido  con relacin a las lineas que corresponden a lecturas de  esclavo y memoria externas         //
//   respectivamente:                                                                                                             //
//   int16 valor;                                                                                                                 //
//   valor=read_int16_ext_eeprom(0x100);   // Linea con problema                                                                  //
//   int8 esclavo1=0x1E;                                                                                                          //
//   int16 valor;                                                                                                                 //
//   valor=leer_int16_esclavo(esclavo1,0x20);   // NO RECONOCE ESTA  FUNCION ???                                                  // 
//   OTRA DUDA                                                                                                                    //
//   OBSERVE LOS EJEMPLOS  EX_EXTEE.C Y EX.INTEE.C  QUE TRAE  EL  COMPILADOR                                                      //
//   Y  no logro ver por donde se hace referencia algun archivo que contenga las rutinas de escritura o lectura de la eeprom      //
//   interna   o externa solo veo un input.c  pero nada ralacionado con dichas funciones                                          //
//   ALGO  CURIOSO  LUEGO QUE ESCRIBI EL DRIVER USANDO EL COMPILADOR C CCS LO GUARDE EN EL ARCHIVO DE DRIVERS PERO LUEGO           //
//   LO ABRI CON VISUAL C++  DESDE LA CARPETA DRIVERS DEL COMPILADOR C CCS  Y  SORPRESA NO ESTABAN LOS CAMBIOS QUE LE HABIA HECHO  //
//   A  ESCLAVOS_I2C.C  LUEGO LO ABRI CON CCS  Y SI ESTABAN LOS CAMBIOS    ?????????????????????????                               //
//   PQ EL COMPILADOR MOSTRABA LOS CAMBIOS Y EL C++  NO ??????    HICE UNA COPIA DEL ARCHIVO L PEGUE EN OTRO LUGAR Y LUEGO LA  MOVI//
//   A DRIVER DE CCS  ENTONCES LA ABRI CON C++  Y SI FIGURABAN LOS CAMBIOS  CREI QUE POR ALLI ALGO PODIA AFECTAR PERO  NO HUBO     //
//   MEJORAS                                                                                                                       //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/#define H1_CK_W1_SDA PIN_B0                   // NO LOS ACEPTA 
//#define H1_DT_W0_SCL PIN_B1
//#define SDA_CHANNEL  H1_CK_W1_SDA
//#define SCL_CHANNEL  H1_DT_W0_SCL




#INCLUDE <18f4550.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,VREGEN,PLL5,USBDIV,PUT                      // con cristal de 20 Mhz
#use delay(clock=20000000)
#use i2c(MASTER,SDA=pin_b0,SCL=pin_b1,fast=450000,FORCE_HW)                              //Configuracin I2C
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8, parity=N)                //Configuracion USART para tx_rc  mediante mdulo  Xbee
#use rtos(timer=0,minor_cycle=5ms)                     //Directiva del RTOS

//#define INTERNAL_EEPROM_UTILITIES
#define usb_con_sense_pin pin_b2                                              
#define ESCLAVOS_I2C_UTILITIES                 //  SI HABILITO O DESHABILITO ESTA LINEA 1 NO RECONOCE FUNCION A LA Q SE HACE REFERENCIA EN LINA
                                               //  109 Y EN LA 2 NO RECONOCE LAS  FUNCIONES Q ESTAN EN ESCLAVOS_I2C Q SON LLAMADAS POR LA FUNCION DE LA LINEA
                                               //  109
#define EXTERNAL_EEPROM_UTILITIES
#use standard_io(d)
#include <input.c>
#include <usb_cdc.h>  
#include <usb.c>  
// para escribir y leer cuando se envian o solicitan datos por i2c 
#include <esclavos_i2c.c>
#include <external_eeprom.c>   // si habilito o deshabilito esta linea  no  hay variacion en el error
#include <internal_eeprom.c> 
#include <24256.c>

char recepcion[];
char serie;
float dato;   //  para recuperar los datos ledos en los esclavos



#task(rate=10ms)                                               //Indica que la siguiente funcin es una Tarea.
void recepcion_usb ( );  
                                                                //que se ejecutar cada Xxsegundos.
#task(rate=10ms)                                               //Indica que la siguiente funcin es una Tarea.
void PuertaPrincipal ( ); 

#task(rate=500ms)
void lee_datos_modulo_IO();                                     //que se ejecutar cada Xxsegundos.


#task(rate=500ms)
void lee_datos_drv_teclado();

#task(rate=500ms)
void EepromExterna_();

#task (rate=500ms)
void calculos_pwm();



 

void main(){

init_ext_eeprom();
usb_cdc_init();
usb_init();
rtos_run ( ); 
                                                //Inicia la operacin de RTOS
}





void recepcion_usb ( )                                             //recepcin
{
 usb_task();
 if (usb_enumerated()){
 if(usb_cdc_kbhit()){recepcion=usb_cdc_getc();usb_cdc_putc(recepcion);}
                      }
 rtos_yield();
}

void PuertaPrincipal( ){
puts("estado");
delay_ms(2);
if(kbhit()){serie=getc();putc(serie);output_toggle(pin_d1);}
rtos_yield();
// informo  a HMI estado de puerta  via  usb

// informo a HMI local estado de puerta

}


void lee_datos_drv_teclado(){  // 0x1E  direccin del esclavo
int8 esclavo1=0x1E;
int8 temperatura=0x21;
int32 valor;
// leo variables ingresadas  en HMI local y las guardo en memoria local y las mantengo disponoble para otras tareas 

valor=leer_int32_esclavo(esclavo1,temperatura);   // NO RECONOCE ESTA  FUNCION ???
write_int32_eeprom(0x21,valor);
rtos_yield();
}

void lee_datos_modulo_IO(){      // 0x20   direccin del esclavo
int8 esclavo2=0x20;
// leo las conversiones AD y estado de entradas digitales  y almaceno sus valores 
rtos_yield();
}

void EepromExterna_(){           // 0xA0   direccin del esclavo
int16 valor;
int8 direccion=0x20;
valor=read_int16_ext_eeprom(direccion);  // NO RECONOCE ESTA  FUNCION   ????????????????????????????????
// guardo un registro de los ultimos estados de las varibles y de las claves de ecceso de activacin de puertas 

rtos_yield();
}
//  calculo los CD  de las salids pwm en funcion del valor de las entradas anlogas,
//  parametros PID  y envio valor a mdulo_IO
void calculos_pwm(){

rtos_yield();
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///                       ESCLAVOS_I2.C 
//////////////////////////////////////////////////////////////////////////////////
//                            esclavos_i2c.c
//  Rutinas  para  la  lectura  y escritura  sobre  un microcontrolador esclavo //
//  i2c con variables de distintos formatos                                     //
//  Como  parte del proyecto de titulacin en Ing. En Automatizacin y control  //
//  Industrial                                                                  //
//  Por:Rodrigo Alejandro Elgueda Elgueda                                       //
//  Estudiante Seminarista de la Universidad Tecnologica de Chile Sede Calama   //
//  Julio 2009                                                                  //
//                                                                              //  
//  Para escribir se debe usar:                                                 //
//                                                                              //
//                                                                              //  
//  void escribir_int1_esclavo(esclavo ,direccion ,int8 bitPosicion, int1 data) //
//     utilizar para escribir dato de 1 bit                                     //
//                                                                              //
//   int1 leer_int1_esclavo(esclavo,direccion, int8 bitPosicion)                //
//     utilizar para leer dato de 1 bit                                         //
//                                                                              //
//                                                                              //
//   void escribir_int16_esclavo(esclavo, direccion, int16 data)                //
//     utilizar para escribir dato de 16 bit  (integer)                         //
//                                                                              //
//   int16 leer_int16_esclavo(esclavo, direccion)                                //
//    utilizar para leer dato de 16 bit  (integer)                              //
//                                                                              //
//                                                                              //
//   void escribir_int32_esclavo(esclavo, direccin, int32 data)                //
//     utilizar para escribir dato de 32 bit  (integer)                         //
//                                                                              //
//   int32 leer_int32_esclavo(esclavo,direccion)                                //
//     utilizar para leer dato de 16 bit  (integer)                             //
//                                                                              //
//                                                                              //
//   void escribir_float_esclavo(esclavo, direccion, float data)                //
//     utilizar para escribir numero de punto flotante                          //
//                                                                              //
//   float leer_float_esclavo(esclavo,direccion)                                //
//      utilizar para escribir numero de punto flotante                         //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef ESCLAVOS_I2C_UTILITIES
#define ESCLAVOS_I2C_UTILITIES

 //Ajustar el rango del tamao de las  direcciones a usar
#ifndef direccion_esclavo
#define direccion_esclavo  int8
#endif
#ifndef posicion_memoria
#define posicion_memoria  int8
#endif
#define  i2c_reinicio() i2c_start()


// Propsito:   Escribir un bit en un microcontrolador esclavo 
//  Entradas:  1) direccion del  esclavo
//             2) direccion de la memoria del esclavo
//             3) La posicin del bit (LSB == 0)
//             4) el bit a escribir
// Salidas : No aplica
void escribir_int1_esclavo(direccion_esclavo esclavo,posicion_memoria direccion, int8 bitPosicion, int1 data)
{
   int8 stored_data;

   stored_data = leer_esclavo(esclavo,direccion);    //extrae el valor de la direccion de memoria del esclavo indicado

   if(data)
   {
      bit_set(stored_data, bitPosicion);                         //  stored data x7 x6 x5 x4 x3 x4 x3 x2 x1 x0 ;bitPosicion 0-7
   }
   else
   {
      bit_clear(stored_data, bitPosicion);
   }

   escribir_esclavo(esclavo,direccion, stored_data);
}


// Propsito:    Leer un bit de un microcontrolador esclavo
// Entradas :  1) direccion del  esclavo
//             2) direccion de la memoria del esclavo
//             3) La posicin del bit (LSB == 0)
// Salidas:    El bit ledo del microcontrolador
int1 leer_int1_esclavo(direccion_esclavo esclavo,posicion_memoria direccion, int8 bitPosicion)
{
  int8 registro;
  registro=leer_esclavo(esclavo,direccion);
  return bit_test(registro, bitPosicion);
}

//  Propsito:   Escribir un numero de 16 bit en un microcontrolador esclavo 
//  Entradas:  1) direccion del  esclavo
//             2) direccion de la memoria del esclavo
//             3) dato de 16 bit a escribir          
// Salidas : No aplica
void escribir_int16_esclavo(direccion_esclavo esclavo,posicion_memoria direccion, int16 data)
{
   int8 i;

   for(i = 0; i < 2; ++i)
   {
     escribir_esclavo(esclavo,direccion + i, *(&data + i));
   }
}


// Propsito:    Leer un numero de 16 bit de un microcontrolador esclavo
// Entradas :  1) direccion del  esclavo
//             2) direccion de la memoria del esclavo            
// Salidas:    Numero de 16 bit  ledo del microcontrolador
int16 leer_int16_esclavo(direccion_esclavo esclavo,posicion_memoria direccion)
{
   int8  i;
   int16 data;

   for(i = 0; i < 2; ++i)
   {
     *(&data + i) = leer_esclavo(esclavo,direccion + i);
   }

   return(data);
}


///  Propsito:   Escribir un numero de 32 bit en un microcontrolador esclavo 
//  Entradas:  1) direccion del  esclavo
//             2) direccion de la memoria del esclavo
//             3) dato de 32 bit a escribir          
// Salidas : No aplica
void escribir_int32_esclavo(direccion_esclavo esclavo,posicion_memoria direccion, int32 data)
{
   int8 i;

   for(i = 0; i < 4; ++i)
   {
     escribir_esclavo(esclavo,direccion + i, *(&data + i));
   }
}
// Propsito:    Leer un numero de 32 bit de un microcontrolador esclavo
// Entradas :  1) direccion del  esclavo
//             2) direccion de la memoria del esclavo         
// Salidas:    Numero de 32 bit  ledo del microcontrolador
int32 leer_int32_esclavo(direccion_esclavo esclavo,posicion_memoria direccion)
{
   int8  i;
   int32 data;

   for(i = 0; i < 4; ++i)
   {
     *(&data + i) = leer_esclavo(esclavo,direccion + i);
   }

   return data;
}


///  Propsito:   Escribir un numero de punto flotante en un microcontrolador esclavo 
//  Entradas:  1) direccion del  esclavo
//             2) direccion de la memoria del esclavo
//             3) dato de punto flotante  a escribir          
// Salidas : No aplica
void escribir_float_esclavo(direccion_esclavo esclavo,posicion_memoria direccion, float data)
{
   int8 i;

   for(i = 0; i < 4; ++i)
   {
     escribir_esclavo(esclavo,direccion + i, *(&data + i));
   }
}


// Propsito:    Leer un numero de punto flotante de un microcontrolador esclavo
// Entradas :  1) direccion del  esclavo
//             2) direccion de la memoria del esclavo
//             3) Dato de punto flotante
// Salidas:    Numero de punto  flotante  ledo del microcontrolador

float leer_float_esclavo(direccion_esclavo esclavo,posicion_memoria direccion)
{
   int8 i;
   float data;

   for(i = 0; i < 4; ++i)
   {
     *(&data + i) = leer_esclavo(esclavo,direccion + i);
   }

   return data;
}


void escribir_esclavo(direccion_esclavo esclavo_,posicion_memoria direccion_,int8 dato)
{
short int estado;
i2c_start();                            //  inicia  la  transmision
i2c_write(esclavo_);                    //  escribe direccin del esclavo +0 para escritura 
i2c_write(direccion_);                  //  indica la posicin de memoria donde se desea escribir el dato  
i2c_write(dato);                        //  dato a  escribir 
i2c_stop();                             //  bit de parada
i2c_reinicio();                         //  reinicia la comunicacin en espera de bit ACK enviado por el esclavo 
estado=i2c_write(esclavo_);             //  
while (estado==1)                       //  si es  1 espera a q responda  el esclavo
{ 
i2c_reinicio();
estado=i2c_write(esclavo_);
}
}


int8 leer_esclavo(int8 esclavo_,int8 direccion_)
{
int8 data; 
i2c_start();                        // inicia  la  transmision
i2c_write(esclavo_);                // direccion del esclavo a leer 
i2c_write(direccion_);              // direccion de memoria del esclavo a leer
i2c_reinicio();                     // reinicia para cambio a lectura 
i2c_write(esclavo_+1);
data=i2c_read(0);                   // recibe dato de la posicin de memoria del esclavo leda
i2c_stop();                         // detiene la transmision         
return(data);                       // retorna valor a la rutina que dio uso a esta funcin
}
#endif


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                            EXTERNAL_EEPROM.C

#ifndef EXTERNAL_EEPROM_UTILITIES
#define EXTERNAL_EEPROM_UTILITIES

// Used to adjust the address range
#ifndef EEPROM_ADDRESS
#define EEPROM_ADDRESS  int8
#endif

// Purpose:    Write one bit to external eeprom
// Inputs:     1) An eeprom address
//             2) The bit position (LSB == 0)
//             3) The bit to write
// Outputs:    None
void write_int1_ext_eeprom(EEPROM_ADDRESS address, int8 bitPosition, int1 data)
{
   int8 stored_data;

   stored_data = read_ext_eeprom(address);

   if(data)
   {
      bit_set(stored_data, bitPosition);
   }
   else
   {
      bit_clear(stored_data, bitPosition);
   }

   write_ext_eeprom(address, stored_data);
}


// Purpose:    Read one bit from external eeprom
// Inputs:     1) An eeprom address
//             2) The bit position (LSB == 0)
// Outputs:    The bit read from external eeprom
int1 read_int1_ext_eeprom(EEPROM_ADDRESS address, int8 bitPosition)
{
   return bit_test(read_ext_eeprom(address), bitPosition);
}


// Purpose:    Write a 16 bit number to external eeprom
// Inputs:     1) An eeprom address
//             2) The 16 bit number to write to external eeprom
// Outputs:    None
void write_int16_ext_eeprom(EEPROM_ADDRESS address, int16 data)
{
   int8 i;

   for(i = 0; i < 2; ++i)
   {
     write_ext_eeprom(address + i, *(&data + i));
   }
}


// Purpose:    Read a 16 bit number from external eeprom
// Inputs:     An eeprom address
// Outputs:    The 16 bit number read from external eeprom
int16 read_int16_ext_eeprom(EEPROM_ADDRESS address)
{
   int8  i;
   int16 data;

   for(i = 0; i < 2; ++i)
   {
     *(&data + i) = read_ext_eeprom(address + i);
   }

   return(data);
}


// Purpose:    Write a 32 bit integer to external eeprom
// Inputs:     1) An eeprom address
//             2) The 32 bit number to write to external eeprom
// Outputs:    None
void write_int32_ext_eeprom(EEPROM_ADDRESS address, int32 data)
{
   int8 i;

   for(i = 0; i < 4; ++i)
   {
     write_ext_eeprom(address + i, *(&data + i));
   }
}


// Purpose:    Read a 32 bit integer from external eeprom
// Inputs:     An eeprom address
// Outputs:    The 32 bit integer read from external eeprom
int32 read_int32_ext_eeprom(EEPROM_ADDRESS address)
{
   int8  i;
   int32 data;

   for(i = 0; i < 4; ++i)
   {
     *(&data + i) = read_ext_eeprom(address + i);
   }

   return data;
}


// Purpose:    Write a floating point number to external eeprom
// Inputs:     1) An eeprom address. Four eeprom locations will be used.
//             2) The floating point number to write to external eeprom
// Outputs:    None
void write_float_ext_eeprom(EEPROM_ADDRESS address, float data)
{
   int8 i;

   for(i = 0; i < 4; ++i)
   {
     write_ext_eeprom(address + i, *(&data + i));
   }
}


// Purpose:    Read a floating point number from external eeprom
// Inputs:     An eeprom address
// Outputs:    The floating point number read from the external eeprom
float read_float_ext_eeprom(EEPROM_ADDRESS address)
{
   int8 i;
   float data;

   for(i = 0; i < 4; ++i)
   {
     *(&data + i) = read_ext_eeprom(address + i);
   }

   return data;
}

#endif
