forked from karawin/Ka-Radio32
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheeprom.c
269 lines (237 loc) · 8.3 KB
/
eeprom.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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/******************************************************************************
*
* Copyright 2017 karawin (http://www.karawin.fr)
*
*******************************************************************************/
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_spi_flash.h"
#include "esp_partition.h"
#include "esp_task_wdt.h"
#include "freertos/FreeRTOS.h"
#include "esp_log.h"
//#include "driver/uart.h"
#include "eeprom.h"
#include "stdio.h"
#include "stdlib.h"
#include <assert.h>
//#include "spi_flash.h"
//#include <esp_libc.h>
#include "interface.h"
/*
#define ICACHE_STORE_TYPEDEF_ATTR
#define ICACHE_STORE_ATTR
#define ICACHE_RAM_ATTR
#define EEPROM_START 0x3E0000 // Last 128k of flash (32Mbits or 4 MBytes)
#define EEPROM_START1 0x3D0000 // Last 128k of flash (32Mbits or 4 MBytes)
#define EEPROM_SIZE 0xFFFF // until xffff ,
#define NBOLDSTATIONS 192
*/
#define NBSTATIONS 255
const static char *TAG = "eeprom";
static xSemaphoreHandle muxDevice;
//const char streMSG[] = {"Warning %s malloc low memory\n"};
//const char saveStationPos[] = {"saveStation fails pos=%d\n"};
//const char getStationPos[] = {"getStation fails pos=%d\n"};
//const char streERASE[] = {"erase setting1 (only one time) \n"};
//const char streGETDEVICE[] = {"getDeviceSetting%d fails\n"};
//const char streSETDEVICE[] = {"saveDeviceSetting%d: null\n"};
const esp_partition_t * DEVICE;
const esp_partition_t * DEVICE1;
const esp_partition_t * STATIONS;
void partitions_init(void)
{
DEVICE = esp_partition_find_first(64,0,NULL);
if (DEVICE == NULL) ESP_LOGE(TAG, "DEVICE Partition not found");
DEVICE1 = esp_partition_find_first(66,0,NULL);
if (DEVICE1 == NULL) ESP_LOGE(TAG, "DEVICE1 Partition not found");
STATIONS = esp_partition_find_first(65,0,NULL);
if (STATIONS == NULL) ESP_LOGE(TAG, "STATIONS Partition not found");
muxDevice=xSemaphoreCreateMutex();
}
bool eeSetData(int address, void* buffer, int size) { // address, size in BYTES !!!!
uint8_t* inbuf = buffer;
uint32_t* eebuf= malloc(4096);
uint16_t i = 0;
if (eebuf != NULL)
{
while(1) {
uint32_t sector = address & 0xFFF000;
uint8_t* eebuf8 = (uint8_t*)eebuf;
uint16_t startaddr = address & 0xFFF;
uint16_t maxsize = 4096 - startaddr;
//printf("set1 startaddr: %x, size:%x, maxsize: %x, sector: %x, eebuf: %x\n",startaddr,size,maxsize,(int)sector,(int)eebuf);
//spi_flash_read(sector, (uint32_t *)eebuf, 4096);
ESP_ERROR_CHECK(esp_partition_read(STATIONS, sector,eebuf, 4096));
vTaskDelay(1);
ESP_ERROR_CHECK(esp_partition_erase_range(STATIONS,sector,4096));
//spi_flash_erase_sector(sector >> 12);
//printf("set2 startaddr: %x, size:%x, maxsize: %x, sector: %x, eebuf: %x\n",startaddr,size,maxsize,(int)sector,(int)eebuf);
for(i=0; (i<size && i<maxsize); i++) eebuf8[i+startaddr] = inbuf[i];
ESP_ERROR_CHECK(esp_partition_write(STATIONS,sector,eebuf,4096));
//spi_flash_write(sector, (uint32_t *)eebuf, 4096);
//printf("set3 startaddr: %x, size:%x, maxsize: %x, result:%x, sector: %x, eebuf: %x\n",startaddr,size,maxsize,result,sector,eebuf);
if(maxsize >= size) break;
address += i;
inbuf += i;
size -= i;
//printf("set2 startaddr: %x, size:%x, maxsize: %x, sector: %x, eebuf: %x\n",startaddr,size,maxsize,sector,eebuf);
}
free (eebuf);
} else
{
ESP_LOGE(TAG,"Warning %s malloc low memory","eebuf");
return false;
}
return true;
}
void eeEraseAll() { // clear (0) stations and device
uint8_t* buffer= malloc(4096);
int i = 0;
// printf("erase All\n");
while (buffer == NULL)
{
if (++i > 4) break;
vTaskDelay(100);
buffer= malloc(4096); // last chance
}
if (buffer != NULL)
{
for(i=0; i<4096; i++) buffer[i] = 0;
ESP_ERROR_CHECK(esp_partition_write(DEVICE,0,buffer,4096)); //clear device
ESP_ERROR_CHECK(esp_partition_write(DEVICE1,0,buffer,4096)); //clear device1
for (i=0;i<16;i++)
{
// printf("erase from %x \n",4096*i);
ESP_ERROR_CHECK(esp_partition_write(STATIONS,4096*i,buffer,4096)); //clear stations
// eeSetClear(4096*i,buffer);
vTaskDelay(1); // avoid watchdog
}
// printf("erase All done\n");
free(buffer);
} else
printf("erase All fails\n");
}
void eeErasesettings(void){
int i = 0;
uint8_t* buffer= malloc(4096);
for(i=0; i<4096; i++) buffer[i] = 0;
ESP_ERROR_CHECK(esp_partition_write(DEVICE,0,buffer,4096)); //clear device
free(buffer);
}
void eeEraseStations() {
uint8_t* buffer = malloc(4096);
int i=0;
while (buffer == NULL)
{
if (++i > 10) break;
vTaskDelay(10);
buffer= malloc(4096); // last chance
}
if (buffer != NULL)
{
for(i=0; i<4096; i++) buffer[i] = 0;
for (i=0;i<16;i++)
{
// printf("erase from %x \n",4096*i);
ESP_ERROR_CHECK(esp_partition_write(STATIONS,4096*i,buffer,4096)); //clear stations
// eeSetClear(4096*i,buffer);
vTaskDelay(1); // avoid watchdog
}
free(buffer);
} else ESP_LOGE(TAG,"Warning %s malloc low memory","eeEraseStations");
}
void saveStation(struct shoutcast_info *station, uint16_t position) {
uint32_t i = 0;
if (position > NBSTATIONS-1) {ESP_LOGE(TAG,"saveStation fails pos=%d",position);return;}
while (!eeSetData((position+1)*256, station, 256))
{
kprintf("Retrying %d on saveStation\n",i+1);
vTaskDelay ((i+1)*20+200) ;
i++;
// if (i == 2) {clientDisconnect("saveStation low Memory"); vTaskDelay (300) ;} // stop the player
if (i == 10) return;
}
}
void saveMultiStation(struct shoutcast_info *station, uint16_t position, uint8_t number) {
uint32_t i = 0;
while ((position +number-1) > NBSTATIONS-1) {ESP_LOGE(TAG,"saveStation fails pos=%d",position+number-1); number--; }
if (number <= 0) return;
while (!eeSetData((position)*256, station, number*256))
{
kprintf("Retrying %d on SaveMultiStation for %d stations\n",i+1,number);
vTaskDelay ((i+1)*20+300) ;
i++;
// if (i == 3) {clientDisconnect("saveMultiStation low Memory"); vTaskDelay (300) ;}
if (i == 10) return;
}
}
struct shoutcast_info* getStation(uint8_t position) {
if (position > NBSTATIONS-1) {kprintf("getStation fails pos=%d\n",position); return NULL;}
uint8_t* buffer = malloc(256);
uint8_t i = 0;
while (buffer == NULL)
{
// ESP_LOGE(TAG,"getStation fails pos=%d",256);
if (++i > 2) break;
vTaskDelay(400);
buffer= malloc(256); // last chance
}
ESP_ERROR_CHECK(esp_partition_read(STATIONS, (position)*256, buffer, 256));
//eeGetData((position+1)*256, buffer, 256);
return (struct shoutcast_info*)buffer;
}
void copyDeviceSettings()
{
uint8_t* buffer= malloc(4096);
if(buffer) {
ESP_ERROR_CHECK(esp_partition_read(DEVICE, 0, buffer, sizeof(struct device_settings)));
ESP_ERROR_CHECK(esp_partition_erase_range(DEVICE1,0,DEVICE1->size));
ESP_ERROR_CHECK(esp_partition_write(DEVICE1,0,buffer,DEVICE1->size));
}
free (buffer);
}
void restoreDeviceSettings()
{
uint8_t* buffer= malloc(4096);
if(buffer) {
ESP_ERROR_CHECK(esp_partition_read(DEVICE1, 0, buffer, sizeof(struct device_settings)));
ESP_ERROR_CHECK(esp_partition_erase_range(DEVICE,0,DEVICE->size));
ESP_ERROR_CHECK(esp_partition_write(DEVICE,0,buffer,DEVICE->size));
}
free (buffer);
}
void saveDeviceSettings(struct device_settings *settings) {
if (settings == NULL) { ESP_LOGE(TAG,"saveDeviceSetting fails");return;}
ESP_LOGD(TAG,"saveDeviceSettings");
xSemaphoreTake(muxDevice, portMAX_DELAY);
ESP_ERROR_CHECK(esp_partition_erase_range(DEVICE,0,DEVICE->size));
vTaskDelay(1);
ESP_ERROR_CHECK(esp_partition_write(DEVICE,0,settings,DEVICE->size));
xSemaphoreGive(muxDevice);
}
void saveDeviceSettingsVolume(struct device_settings *settings) {
if (settings == NULL) { ESP_LOGE(TAG,"saveDeviceSetting fails");return;}
ESP_LOGD(TAG,"saveDeviceSettingsVolume");
if (xSemaphoreTake(muxDevice, 0) == pdFALSE) return; // not important. An other one in progress
ESP_ERROR_CHECK(esp_partition_erase_range(DEVICE,0,DEVICE->size));
ESP_ERROR_CHECK(esp_partition_write(DEVICE,0,settings,DEVICE->size));
xSemaphoreGive(muxDevice);
}
struct device_settings* getDeviceSettingsSilent() {
uint16_t size = sizeof(struct device_settings);
uint8_t* buffer = malloc(size);
if(buffer) {
ESP_ERROR_CHECK(esp_partition_read(DEVICE, 0, buffer, size));
return (struct device_settings*)buffer;
}
return NULL;
}
struct device_settings* getDeviceSettings() {
struct device_settings* buffer ;
if ((buffer = getDeviceSettingsSilent())==NULL)
ESP_LOGE(TAG,"getDeviceSetting fails");
// printf(streGETDEVICE,0);
return buffer;
}