-
Notifications
You must be signed in to change notification settings - Fork 11
/
nv.c
167 lines (131 loc) · 3.59 KB
/
nv.c
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/****************************************************************************
** nv.c
**
** Non-volatile parameter management
**
** Parameters are stored as TLV
** T identifies the parameter block
** L specifies the number of bytes that follow in
** V the value
*/
#include <avr/eeprom.h>
#include <avr/eeprom.h>
#include "cc1101_const.h"
#include "nv.h"
/***********************************************************************************
* eeprom access
*/
static uint8_t EEMEM eeprom[E2END+1];
#define EE_END &( eeprom[E2END+1] )
static uint8_t *ee_find_param( uint8_t id, uint8_t *len ) {
uint8_t *ee = eeprom;
uint8_t t,l=0;
while( ee<EE_END-1 ) {
t = eeprom_read_byte( ee );
l = eeprom_read_byte( ee+1 );
if( t==id ) { // Found it
if( ee+2+l > EE_END )
l = EE_END-ee-2;
break;
}
if( t==0xFF ) { // no more data
l = 0;
ee = EE_END;
break;
}
// Try next
ee += 2 + l;
}
if( ee>EE_END-2 )
ee = EE_END;
if( len ) (*len) = l;
return ee;
}
static uint8_t *ee_find_free( uint8_t *len ) {
uint8_t *ee = ee_find_param( 0xFF, len );
return ee;
};
static uint8_t ee_read_param( uint8_t id, uint8_t offset, uint8_t *buff, uint8_t buffLen ) {
uint8_t len=0;
uint8_t *ee = ee_find_param( id, &len );
if( ee<EE_END ) {
if( offset>len )
len = 0;
else if( offset+buffLen > len )
len = len - offset;
else
len = buffLen;
if( len > 0 )
eeprom_read_block( buff, ee+2+offset, len );
}
return len;
}
static uint8_t ee_write_param( uint8_t id, uint8_t paramLen, uint8_t offset, uint8_t *buff, uint8_t buffLen ) {
uint8_t len;
uint8_t *ee = ee_find_param( id, &len );
if( ee==EE_END && paramLen==buffLen ) { // Doesn't exist yet
ee = ee_find_free( &len );
if( len>paramLen ) {
eeprom_write_byte( ee, id );
eeprom_write_byte( ee+1, paramLen );
len = paramLen;
} else {
len = 0;
}
}
if( ee<EE_END ) {
if( offset>len )
len = 0;
else if( offset+buffLen > len )
len = len - offset;
else
len = buffLen;
if( len > 0 )
eeprom_update_block( buff, ee+2+offset, len );
}
return len;
}
void nv_reset(void) {
uint8_t buff[16] = { 0xFF,0xFF,0xFF,0xFF , 0xFF,0xFF,0xFF,0xFF , 0xFF,0xFF,0xFF,0xFF , 0xFF,0xFF,0xFF,0xFF };
uint8_t *ee;
for( ee=eeprom; ee<EE_END ; ee+=sizeof(buff) )
eeprom_update_block( buff, ee, sizeof(buff) );
}
/***********************************************************************************
* NV Parameter API
*/
struct nv_param {
uint8_t id;
uint8_t len;
// char * desc;
};
static struct nv_param const *nv_param_lookup( uint8_t param ) {
#define _NV_PARAM( _e,_i,_l,_t ) ,{ _i, _l }
static struct nv_param const nv_param_list[NV_MAX] = { { '\0', 0 } _NV_PARAM_LIST };
#undef _NV_PARAM
struct nv_param const *pParam = NULL;
if( param < NV_MAX )
pParam = nv_param_list + param;
return pParam;
}
uint8_t nv_param_len( uint8_t param ) {
uint8_t len = 0;
struct nv_param const *pParam = nv_param_lookup( param );
if( pParam )
len = pParam->len;
return len;
}
uint8_t nv_param_read( uint8_t param, uint8_t offset, uint8_t *buff, uint8_t buffLen ) {
uint8_t nRead = 0;
struct nv_param const *pParam = nv_param_lookup( param );
if( pParam )
nRead = ee_read_param( pParam->id, offset, buff, buffLen );
return nRead;
}
uint8_t nv_param_write( uint8_t param, uint8_t offset, uint8_t *buff, uint8_t buffLen ) {
uint8_t nWrite=0;
struct nv_param const *pParam = nv_param_lookup( param );
if( pParam )
nWrite = ee_write_param( pParam->id, pParam->len, offset,buff,buffLen );
return nWrite;
}