Skip to content

Commit 8027775

Browse files
added Preferences api spi commands
1 parent 5e9e7cb commit 8027775

File tree

3 files changed

+295
-1
lines changed

3 files changed

+295
-1
lines changed

src/utility/wifi_drv.cpp

Lines changed: 283 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1287,7 +1287,7 @@ int8_t WiFiDrv::fileOperation(uint8_t operation, const char *filename, uint8_t f
12871287
}
12881288

12891289
// pad to multiple of 4
1290-
int commandSize = 4 + numParams + sizeof(offset) + sizeof(len) + filename_len;
1290+
int commandSize = 6 + numParams + sizeof(offset) + sizeof(len) + filename_len;
12911291
while (commandSize % 4) {
12921292
SpiDrv::readChar();
12931293
commandSize++;
@@ -1319,4 +1319,286 @@ void WiFiDrv::applyOTA() {
13191319
}
13201320

13211321

1322+
bool WiFiDrv::prefBegin(const char * name, bool readOnly, const char* partition_label) {
1323+
WAIT_FOR_SLAVE_SELECT();
1324+
1325+
// calculated by considering: 1 byte for start_cmd + 1byte CMD + 1 byte param + end command
1326+
int commandSize = 4;
1327+
bool result = false;
1328+
1329+
SpiDrv::sendCmd(PREFERENCES_BEGIN, partition_label!=NULL ? PARAM_NUMS_3 : PARAM_NUMS_2);
1330+
SpiDrv::sendParam((uint8_t*)name, strlen(name));
1331+
commandSize += strlen(name) + 1; // number of bytes in name + 1 byte for the length field
1332+
1333+
SpiDrv::sendParam((uint8_t*)&readOnly, 1, partition_label!=NULL ? NO_LAST_PARAM : LAST_PARAM);
1334+
commandSize += 2;
1335+
1336+
if(partition_label!=NULL) {
1337+
SpiDrv::sendParam((uint8_t*)partition_label, strlen(partition_label), LAST_PARAM);
1338+
commandSize += strlen(partition_label)+1; // number of bytes in partition_label + 1 byte for the length field
1339+
}
1340+
1341+
// pad to multiple of 4
1342+
while (commandSize % 4 != 0) {
1343+
SpiDrv::readChar();
1344+
commandSize++;
1345+
}
1346+
1347+
SpiDrv::spiSlaveDeselect();
1348+
//Wait the reply elaboration
1349+
SpiDrv::waitForSlaveReady();
1350+
SpiDrv::spiSlaveSelect();
1351+
1352+
// Wait for reply
1353+
uint8_t len = 1;
1354+
SpiDrv::waitResponseCmd(PREFERENCES_BEGIN, PARAM_NUMS_1, (uint8_t*)&result, &len);
1355+
1356+
SpiDrv::spiSlaveDeselect();
1357+
1358+
// if everything went ok the returned value is 0
1359+
return result == 0;
1360+
}
1361+
1362+
void WiFiDrv::prefEnd() {
1363+
WAIT_FOR_SLAVE_SELECT();
1364+
1365+
SpiDrv::sendCmd(PREFERENCES_END, PARAM_NUMS_0);
1366+
SpiDrv::spiSlaveDeselect();
1367+
//Wait the reply elaboration
1368+
SpiDrv::waitForSlaveReady();
1369+
SpiDrv::spiSlaveSelect();
1370+
1371+
uint8_t len = 1;
1372+
bool result = false;
1373+
SpiDrv::waitResponseCmd(PREFERENCES_END, PARAM_NUMS_1, (uint8_t*)&result, &len);
1374+
SpiDrv::spiSlaveDeselect();
1375+
}
1376+
1377+
bool WiFiDrv::prefClear() {
1378+
WAIT_FOR_SLAVE_SELECT();
1379+
1380+
SpiDrv::sendCmd(PREFERENCES_CLEAR, PARAM_NUMS_0);
1381+
1382+
SpiDrv::readChar();
1383+
SpiDrv::readChar();
1384+
SpiDrv::readChar();
1385+
1386+
SpiDrv::spiSlaveDeselect();
1387+
//Wait the reply elaboration
1388+
SpiDrv::waitForSlaveReady();
1389+
SpiDrv::spiSlaveSelect();
1390+
1391+
1392+
// Wait for reply
1393+
uint8_t len = 1;
1394+
bool result = false;
1395+
SpiDrv::waitResponseCmd(PREFERENCES_CLEAR, PARAM_NUMS_1, (uint8_t*)&result, &len);
1396+
SpiDrv::spiSlaveDeselect();
1397+
1398+
// if everything went ok the returned value is 0
1399+
return result == 0;
1400+
}
1401+
1402+
bool WiFiDrv::prefRemove(const char * key) {
1403+
WAIT_FOR_SLAVE_SELECT();
1404+
1405+
bool result = false;
1406+
int commandSize = 4;
1407+
SpiDrv::sendCmd(PREFERENCES_REMOVE, PARAM_NUMS_1);
1408+
1409+
SpiDrv::sendParam((uint8_t*)key, strlen(key), LAST_PARAM);
1410+
commandSize += strlen(key) + 1; // number of bytes in key + 1 byte for the length field
1411+
1412+
// pad to multiple of 4
1413+
while (commandSize % 4) {
1414+
SpiDrv::readChar();
1415+
commandSize++;
1416+
}
1417+
SpiDrv::spiSlaveDeselect();
1418+
//Wait the reply elaboration
1419+
SpiDrv::waitForSlaveReady();
1420+
SpiDrv::spiSlaveSelect();
1421+
1422+
// Wait for reply
1423+
uint8_t len = 1;
1424+
SpiDrv::waitResponseCmd(PREFERENCES_REMOVE, PARAM_NUMS_1, (uint8_t*)&result, &len);
1425+
1426+
SpiDrv::spiSlaveDeselect();
1427+
return result == 0;
1428+
}
1429+
1430+
size_t WiFiDrv::prefLen(const char * key) {
1431+
WAIT_FOR_SLAVE_SELECT();
1432+
1433+
uint32_t result = 0;
1434+
int commandSize = 4;
1435+
SpiDrv::sendCmd(PREFERENCES_LEN, PARAM_NUMS_1);
1436+
1437+
SpiDrv::sendParam((uint8_t*)key, strlen(key), LAST_PARAM);
1438+
commandSize += strlen(key) + 1; // number of bytes in key + 1 byte for the length field
1439+
1440+
// pad to multiple of 4
1441+
while (commandSize % 4 != 0) {
1442+
SpiDrv::readChar();
1443+
commandSize++;
1444+
}
1445+
SpiDrv::spiSlaveDeselect();
1446+
//Wait the reply elaboration
1447+
SpiDrv::waitForSlaveReady();
1448+
SpiDrv::spiSlaveSelect();
1449+
1450+
// Wait for reply
1451+
uint8_t len = 4;
1452+
SpiDrv::waitResponseCmd(PREFERENCES_LEN, PARAM_NUMS_1, (uint8_t*)&result, &len);
1453+
1454+
SpiDrv::spiSlaveDeselect();
1455+
1456+
// if len == 1 it means that the command retuned and error, in result the error code,
1457+
// as of now 255 may be returned if the number of parameters passed is wrong
1458+
return len == 1? 0 : result;
1459+
}
1460+
1461+
size_t WiFiDrv::prefStat() {
1462+
WAIT_FOR_SLAVE_SELECT();
1463+
1464+
SpiDrv::sendCmd(PREFERENCES_STAT, PARAM_NUMS_0);
1465+
1466+
SpiDrv::readChar();
1467+
SpiDrv::readChar();
1468+
SpiDrv::readChar();
1469+
1470+
SpiDrv::spiSlaveDeselect();
1471+
//Wait the reply elaboration
1472+
SpiDrv::waitForSlaveReady();
1473+
SpiDrv::spiSlaveSelect();
1474+
1475+
size_t result = 0;
1476+
uint8_t len = 4;
1477+
SpiDrv::waitResponseCmd(PREFERENCES_STAT, PARAM_NUMS_1, (uint8_t*)&result, &len);
1478+
SpiDrv::spiSlaveDeselect();
1479+
1480+
return result;
1481+
}
1482+
1483+
size_t WiFiDrv::prefPut(const char * key, PreferenceType type, uint8_t value[], size_t len) {
1484+
WAIT_FOR_SLAVE_SELECT();
1485+
1486+
int commandSize = 4;
1487+
SpiDrv::sendCmd(PREFERENCES_PUT, PARAM_NUMS_3);
1488+
1489+
SpiDrv::sendParam((uint8_t*)key, strlen(key));
1490+
commandSize += strlen(key) + 1; // number of bytes in key + 1 byte for the length field
1491+
1492+
SpiDrv::sendParam((uint8_t*)&type, 1);
1493+
commandSize += 2;
1494+
1495+
SpiDrv::sendBuffer((uint8_t*)value, len, LAST_PARAM);
1496+
commandSize += len + 1;
1497+
1498+
// pad to multiple of 4
1499+
while (commandSize % 4 != 0) {
1500+
SpiDrv::readChar();
1501+
commandSize++;
1502+
}
1503+
1504+
SpiDrv::spiSlaveDeselect();
1505+
//Wait the reply elaboration
1506+
SpiDrv::waitForSlaveReady();
1507+
SpiDrv::spiSlaveSelect();
1508+
1509+
uint8_t res_len = 1;
1510+
uint32_t res = 0;
1511+
SpiDrv::waitResponseCmd(PREFERENCES_PUT, PARAM_NUMS_1, (uint8_t*)&res, &res_len);
1512+
SpiDrv::spiSlaveDeselect();
1513+
1514+
// if len == 1 it means that the command retuned and error, in result the error code,
1515+
// as of now 255 may be returned if the number of parameters passed is wrong
1516+
// and 254 if the type passed as parameter is wrong
1517+
return res_len == 1? 0 : res;
1518+
}
1519+
1520+
size_t WiFiDrv::prefGet(const char * key, PreferenceType type, uint8_t value[], size_t len) {
1521+
WAIT_FOR_SLAVE_SELECT();
1522+
1523+
int commandSize = 4;
1524+
SpiDrv::sendCmd(PREFERENCES_GET, PARAM_NUMS_2);
1525+
1526+
SpiDrv::sendParam((uint8_t*)key, strlen(key));
1527+
commandSize += strlen(key) + 1; // number of bytes in key + 1 byte for the length field
1528+
1529+
SpiDrv::sendParam((uint8_t*)&type, 1, LAST_PARAM);
1530+
commandSize += 2;
1531+
1532+
// pad to multiple of 4
1533+
while (commandSize % 4 != 0) {
1534+
SpiDrv::readChar();
1535+
commandSize++;
1536+
}
1537+
1538+
SpiDrv::spiSlaveDeselect();
1539+
//Wait the reply elaboration
1540+
SpiDrv::waitForSlaveReady();
1541+
SpiDrv::spiSlaveSelect();
1542+
1543+
// we need to account for \0 if it is a string
1544+
size_t res_len = type == PT_STR? len-1 : len;
1545+
SpiDrv::waitResponseData16(PREFERENCES_GET, value, (uint16_t*)&res_len);
1546+
1547+
SpiDrv::spiSlaveDeselect();
1548+
1549+
// if res_len == 0 it means that the command retuned and error
1550+
if(res_len == 0) {
1551+
return 0;
1552+
}
1553+
1554+
// fix endianness
1555+
if(type != PT_STR && type != PT_BLOB) {
1556+
for(uint8_t i=0; i<res_len/2; i++) {
1557+
1558+
// XOR swap algorithm:
1559+
// a=a^b; b=a^b; a=b^a; with a != b
1560+
if(value[i] != value[res_len-i-1]) {
1561+
value[i] = value[i]^value[res_len-i-1];
1562+
value[res_len-i-1] = value[i]^value[res_len-i-1];
1563+
value[i] = value[res_len-i-1]^value[i];
1564+
}
1565+
}
1566+
}
1567+
1568+
if(type == PT_STR) {
1569+
value[res_len] = '\0';
1570+
}
1571+
1572+
return res_len;
1573+
}
1574+
1575+
PreferenceType WiFiDrv::prefGetType(const char * key) {
1576+
WAIT_FOR_SLAVE_SELECT();
1577+
1578+
PreferenceType type = PT_INVALID;
1579+
int commandSize = 4;
1580+
SpiDrv::sendCmd(PREFERENCES_GETTYPE, PARAM_NUMS_1);
1581+
1582+
SpiDrv::sendParam((uint8_t*)key, strlen(key), LAST_PARAM);
1583+
commandSize += strlen(key) + 1; // number of bytes in key + 1 byte for the length field
1584+
1585+
// pad to multiple of 4
1586+
while (commandSize % 4 != 0) {
1587+
SpiDrv::readChar();
1588+
commandSize++;
1589+
}
1590+
1591+
SpiDrv::spiSlaveDeselect();
1592+
//Wait the reply elaboration
1593+
SpiDrv::waitForSlaveReady();
1594+
SpiDrv::spiSlaveSelect();
1595+
1596+
uint8_t len = 1;
1597+
SpiDrv::waitResponseCmd(PREFERENCES_GETTYPE, PARAM_NUMS_1, (uint8_t*)&type, (uint8_t*)&len);
1598+
SpiDrv::spiSlaveDeselect();
1599+
1600+
return type;
1601+
}
1602+
1603+
13221604
WiFiDrv wiFiDrv;

src/utility/wifi_drv.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "IPAddress.h"
2727
#include "WiFiUdp.h"
2828
#include "WiFiClient.h"
29+
#include "Preferences.h"
2930

3031
// Key index length
3132
#define KEY_IDX_LEN 1
@@ -317,6 +318,16 @@ class WiFiDrv
317318
return length >= 0;
318319
};
319320

321+
static bool prefBegin(const char * name, bool readOnly=false, const char* partition_label=NULL);
322+
static void prefEnd();
323+
static bool prefClear();
324+
static bool prefRemove(const char * key);
325+
static size_t prefLen(const char * key);
326+
static size_t prefStat();
327+
static size_t prefPut(const char * key, PreferenceType type, uint8_t value[], size_t len);
328+
static size_t prefGet(const char * key, PreferenceType type, uint8_t value[], size_t len);
329+
static PreferenceType prefGetType(const char * key);
330+
320331
static void applyOTA();
321332

322333
friend class WiFiUDP;

src/utility/wifi_spi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ enum {
114114
PREFERENCES_STAT = 0x5A,
115115
PREFERENCES_PUT = 0x5B,
116116
PREFERENCES_GET = 0x5C,
117+
PREFERENCES_GETTYPE = 0x5D,
117118

118119
// regular format commands
119120
WRITE_FILE = 0x60,

0 commit comments

Comments
 (0)