Skip to content

Commit 6fd93ed

Browse files
added Preferences api spi commands
1 parent 3e69c6a commit 6fd93ed

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
@@ -1320,7 +1320,7 @@ int8_t WiFiDrv::fileOperation(uint8_t operation, const char *filename, uint8_t f
13201320
}
13211321

13221322
// pad to multiple of 4
1323-
int commandSize = 4 + numParams + sizeof(offset) + sizeof(len) + filename_len;
1323+
int commandSize = 6 + numParams + sizeof(offset) + sizeof(len) + filename_len;
13241324
while (commandSize % 4) {
13251325
SpiDrv::readChar();
13261326
commandSize++;
@@ -1352,4 +1352,286 @@ void WiFiDrv::applyOTA() {
13521352
}
13531353

13541354

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

3031
// Key index length
3132
#define KEY_IDX_LEN 1
@@ -324,6 +325,16 @@ class WiFiDrv
324325
return length >= 0;
325326
};
326327

328+
static bool prefBegin(const char * name, bool readOnly=false, const char* partition_label=NULL);
329+
static void prefEnd();
330+
static bool prefClear();
331+
static bool prefRemove(const char * key);
332+
static size_t prefLen(const char * key);
333+
static size_t prefStat();
334+
static size_t prefPut(const char * key, PreferenceType type, uint8_t value[], size_t len);
335+
static size_t prefGet(const char * key, PreferenceType type, uint8_t value[], size_t len);
336+
static PreferenceType prefGetType(const char * key);
337+
327338
static void applyOTA();
328339

329340
friend class WiFiUDP;

src/utility/wifi_spi.h

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

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

0 commit comments

Comments
 (0)