NeuronC y EEPROM I2C
En algunas ocasiones es interesante incorporar en un nodo Lonworks una memoria del tipo EEPROM I2C, fácil de conectar ya que solo precisa de dos hilos y que puede ser muy útil para registros, data-logger simple o como buffer temporal para un sistemas más complejo de adquisición de datos.
A continuación se incluye el código necesario para implementar operaciones simples de memoria, de la misma forma se pueden realizar registros de variables del tipo SNVT, en algunos programas lo he implementado. Este código es una pequeña introducción y quizás pueda servir de orientación a programadores de NeuronC / NodeBuilder.
- //--------------------------------------------------
- // Operaciones básicas memoria EEPROM I2C
- // Es necesario definir una UNVT del tipo struct
- // para las operaciones de memoria, tipo: op_memo
- // typedef struct // { unsigned int operacion;
- // unsigned long direccion;
- // unsigned long valor;
- // } op_memo;
- //
- //--------------------------------------------------
- #define eep_addr 0x50 // dirección I2C de la EEPROM 24C32 o 64
- #define ESIZE 8192 // Tamaño EEPROM ( 24C32->4096, 24C64->8192 )
- // Variables EEPROM - Ver tamaño real y procesos lógicos
- far unsigned int eepbuff[9];
- far unsigned int eepboff[9];
- //***********************************************************//
- // Operaciones EEPROM
- unsigned short lee_byte(unsigned long direcc);
- unsigned long lee_long(unsigned long direcc);
- void esc_byte(unsigned long direcc, unsigned short dat_s);
- void esc_long(unsigned long direcc, unsigned long dat_l); /
- /***********************************************************//
- // Errores I2C
- network output sd_string("Fallos Lect./Esc. I2C EEPROM") SNVT_count I2CFails;
- network input op_memo nviOpMemo;
- network output op_memo nvoOpMemo;
- //--------------------------------------------------------------------------
- // Memoria EEPROM IO_8 i2c io_i2c_bus;
- //--------------------------------------------------------------------------
- //*******************************************
- // Operaciones de Memoria de cara al Exterior
- //*******************************************
- // Operación (ui), direccion (ul), valor (ul)
- when(nv_update_occurs(nviOpMemo)){
- // Seleccionar por Operación
- switch (nviOpMemo.operacion) {
- case 0:
- // Leer byte
- nvoOpMemo.operacion=nviOpMemo.operacion;
- nvoOpMemo.direccion=nviOpMemo.direccion;
- nvoOpMemo.valor=lee_byte(nviOpMemo.direccion);
- break;
- case 1:
- // Leer long
- nvoOpMemo.operacion=nviOpMemo.operacion;
- nvoOpMemo.direccion=nviOpMemo.direccion;
- nvoOpMemo.valor=lee_long(nviOpMemo.direccion);
- break;
- case 128:
- // Escribir byte
- nvoOpMemo.operacion=nviOpMemo.operacion;
- nvoOpMemo.direccion=nviOpMemo.direccion;
- nvoOpMemo.valor=nviOpMemo.valor;
- esc_byte(nviOpMemo.direccion,(short)nviOpMemo.valor);
- break;
- case 129:
- // Escribir long
- nvoOpMemo.operacion=nviOpMemo.operacion;
- nvoOpMemo.direccion=nviOpMemo.direccion;
- nvoOpMemo.valor=nviOpMemo.valor;
- esc_long(nviOpMemo.direccion,nviOpMemo.valor);
- break; } }
- //*******************************************
- // **************************************************************************
- ///////////////////////////////// Funciones /////////////////////////////////
- // **************************************************************************
- //****************************************************************
- // Devuelve byte leido de EEPROM - pasar dirección (24C32 y 24C64)
- //****************************************************************
- unsigned short lee_byte(unsigned long direcc) {
- unsigned int i2c_add;
- unsigned long eep_cont;
- eep_cont=(direcc & (ESIZE-1));
- i2c_add=(short)((direcc/ESIZE)+eep_addr);
- // Calcular dirección base i2c memoria
- eepbuff[0]=high_byte(eep_cont);
- eepbuff[1]=low_byte(eep_cont);
- if (!io_out(io_i2c_bus,&eepbuff,i2c_add,2)) I2CFails++;
- if (!io_in(io_i2c_bus,eepboff,i2c_add,1)) I2CFails++;
- return eepboff[0];
- }
- // **************************************************************
- //*****************************************************************
- // Escribe byte en EEPROM - pasar dirección y valor (24C32 y 24C64)
- //*****************************************************************
- void esc_byte(unsigned long direcc,
- unsigned short dat_s) {
- unsigned int i2c_add;
- unsigned long eep_cont;
- eep_cont=(direcc & (ESIZE-1));
- i2c_add=(short)((direcc/ESIZE)+eep_addr);
- // Calcular dirección base i2c memoria
- eepbuff[0]=high_byte(eep_cont);
- eepbuff[1]=low_byte(eep_cont);
- eepbuff[2]=dat_s;
- if (!io_out(io_i2c_bus,&eepbuff,i2c_add,3)) I2CFails++;
- delay(500);
- }
- // ****************************************************************
- //*****************************************************************
- // Devuelve long leido de EEPROM - pasar dirección - (24C32 y 24C64)
- //******************************************************************
- unsigned long lee_long(unsigned long direcc) {
- unsigned int i2c_add;
- unsigned long eep_cont;
- eep_cont=(direcc & (ESIZE-1));
- i2c_add=(short)((direcc/ESIZE)+eep_addr);
- // Calcular dirección base i2c memoria
- eepbuff[0]=high_byte(eep_cont);
- eepbuff[1]=low_byte(eep_cont);
- if (!io_out(io_i2c_bus, &eepbuff, i2c_add, 2)) I2CFails++;
- if (!io_in(io_i2c_bus, eepboff, i2c_add,2)) I2CFails++;
- return ((eepboff[0]*256)+eepboff[1]);
- }
- // ************************************************
- //*************************************************
- // Escribe long en EEPROM - pasar dirección y valor
- //*************************************************
- void esc_long(unsigned long direcc, unsigned long dat_l) {
- unsigned int i2c_add;
- unsigned long eep_cont;
- eep_cont=(direcc & (ESIZE-1));
- i2c_add=(short)((direcc/ESIZE)+eep_addr);
- // Calcular dirección base i2c memoria
- eepbuff[0]=high_byte(eep_cont);
- eepbuff[1]=low_byte(eep_cont);
- eepbuff[2]=high_byte(dat_l);
- eepbuff[3]=low_byte(dat_l);
- // Prevenir roll-on de grabación en EEPROM I2C
- if((eep_cont & 0x001F)==31){
- if (!io_out(io_i2c_bus,&eepbuff,i2c_add,3)) I2CFails++;
- eep_cont++;
- eepbuff[0]=high_byte(eep_cont);
- eepbuff[1]=low_byte(eep_cont);
- eepbuff[2]=eepbuff[3];
- delay(400);
- if (!io_out(io_i2c_bus, &eepbuff, i2c_add, 3)) I2CFails++;
- }
- else if (!io_out(io_i2c_bus, &eepbuff, i2c_add, 4)) I2CFails++;
- delay(600);
- }
- // *************************************************************