summaryrefslogtreecommitdiffstats
path: root/arduino/src/emem.cpp
blob: 50fa99d97ebc6dc7aaf4dff34bbff9fa647b1a09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <Arduino.h>
#include <EEPROM.h>

#include "config.h"

// from doorman.ino
extern unsigned char global_hash[];

/**
 * Function reads record with given address from EEPROM. 
 * @param adr Address of record to read, or NULL.
 * @param id Pointer to space reserved for id.
 * @param data Pointer to space reserved for hash.
 * @return Function returns true when data was red, false otherwise.
 */
boolean emem_get_record(unsigned int adr,unsigned int * id,unsigned char * data) {
  if (adr>EMEM_MAX_ADR || adr<ENEM_MIN_ADR) {
    //Address out of range.
    return false;  
  }
  (*id)=EEPROM.read(adr*EMEM_RECORD_SIZE);
  for (int ii=1;ii<EMEM_RECORD_SIZE;ii++){
    *(data+ii-1) = EEPROM.read(adr*EMEM_RECORD_SIZE+ii);    
  }
  for (int ii=EMEM_RECORD_SIZE-1;ii<EMEM_HASH_SIZE;ii++){
    *(data+ii) = 0;
  }  
  return true;  
}

/** 
 * Function deletes record with given address.
 * @param adr Record address.
 * @return True if record was deleted, false otherwise.
 */
boolean emem_del_record(unsigned int adr) {
  if (adr>EMEM_MAX_ADR || adr<ENEM_MIN_ADR) {
    //Address out of range.
    return false;  
  }
  for (int ii=0;ii<EMEM_RECORD_SIZE;ii++){
    EEPROM.write(adr*EMEM_RECORD_SIZE+ii,0);
  }
  return true;  
}

/**
 * Finds record with given ID. 
 * @param id Record id.
 * @return Address of found record or EMEM_INV_ADR.
 */
unsigned int emem_find_id(unsigned int id){
  if (id>EMEM_MAX_ADR || id<ENEM_MIN_ADR) {
    //Address out of range.
    return EMEM_INV_ADR;  
  }
  if (EEPROM.read(id*EMEM_RECORD_SIZE)==id) return id;
  return EMEM_INV_ADR;
}

/**
 * Finds record containing given data (hash).
 * @param data Data to be found.
 * @return Address of found record or EMEM_INV_ADR.
 */
unsigned int emem_find_data(unsigned char * data) {  
  for (int adr=ENEM_MIN_ADR;adr<=EMEM_MAX_ADR;adr++){    
    for (int ii=1;ii<EMEM_RECORD_SIZE;ii++){
      unsigned char edata=EEPROM.read(adr*EMEM_RECORD_SIZE+ii);
      if (edata!=*(data+ii-1)){        
        break;
      } else {
        if (ii==EMEM_RECORD_SIZE-1) {
          return adr;
        }
      }
    }    
  } 
  return EMEM_INV_ADR; 
}

/**
 * Finds first free record.
 * @return Record address or EMEM_INV_ADR if no space left.
 */
unsigned int emem_find_free() {
  for (int adr=ENEM_MIN_ADR;adr<=EMEM_MAX_ADR;adr++){    
    if (EEPROM.read(adr*EMEM_RECORD_SIZE)==0){
      return adr;
    }        
  } 
  return EMEM_INV_ADR;    
}

/**
 * Function sets data into EEPROM record.
 * @param data Data to be set.
 * @param adr Record address.
 * @return True if data was written, false otherwise (adress out of range or failed write).
 */
boolean emem_set_record(unsigned int adr,unsigned char * data) {
  if (adr>EMEM_MAX_ADR || adr<ENEM_MIN_ADR) return false;  
  EEPROM.write(adr*EMEM_RECORD_SIZE,(unsigned char)(adr&0x0ff));
  for (int ii=1;ii<EMEM_RECORD_SIZE;ii++) {
    EEPROM.write(adr*EMEM_RECORD_SIZE+ii,*(data+ii-1));  
  }
  //Ok, now try to read and compare.
  for (int ii=1;ii<EMEM_RECORD_SIZE;ii++) {
    if (EEPROM.read(adr*EMEM_RECORD_SIZE+ii) != *(data+ii-1)){
      return false;
    }
  }  
  return true;
}


/**
 * Prints all records in EEPROM memory.
 */
void emem_print() {  
  unsigned int id;  
  for (int ii=0;ii<EMEM_HASH_SIZE;ii++){
    global_hash[ii] = 0;
  }
  for (int ii=ENEM_MIN_ADR;ii<=EMEM_MAX_ADR;ii++){
    if (emem_get_record(ii,&id,global_hash)){
      Serial.print("REC,");
      Serial.print(ii,HEX);
      Serial.print(',');
      Serial.print(id,HEX);
      for (int jj=0;jj<EMEM_HASH_SIZE;jj++){
        Serial.print(',');
        Serial.print(*(global_hash+jj),HEX);   
      }
      Serial.println();
    } else {
      Serial.println("Error reading EEPROM"); 
    }    
  }
}