Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit c0a343c

Browse files
author
iwahdan88
committed
Merge branch 'master' of https://github.com/psychogenic/pycom-micropython-sigfox into psychogenic-master #226 @psychogenic
# Conflicts: # esp32/frozen/Custom/README.md # esp32/mods/modpycom.c
2 parents b70ddb1 + b636bd7 commit c0a343c

File tree

1 file changed

+76
-4
lines changed

1 file changed

+76
-4
lines changed

esp32/mods/modpycom.c

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "py/mpconfig.h"
1111
#include "py/obj.h"
12+
#include "py/objstr.h"
1213
#include "py/runtime.h"
1314
#include "mperror.h"
1415
#include "updater.h"
@@ -233,8 +234,41 @@ STATIC mp_obj_t mod_pycom_pulses_get (mp_obj_t gpio, mp_obj_t timeout) {
233234
}
234235
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_pycom_pulses_get_obj, mod_pycom_pulses_get);
235236

237+
238+
239+
/*
240+
* nvs_setstring/nvs_getstring: support for NVS string storage and,
241+
* thanks to JSON/other serializers, pretty much any datastructure.
242+
*/
243+
STATIC mp_obj_t mod_pycom_nvs_setstring (mp_obj_t _key, mp_obj_t _value) {
244+
const char *key = mp_obj_str_get_str(_key);
245+
const char *value = mp_obj_str_get_str(_value);
246+
if (strlen(value) >= 1984) {
247+
// orwell error: maximum length (including null character) is 1984 bytes
248+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "value too long (max: 1984)"));
249+
return mp_const_none;
250+
}
251+
esp_err_t esp_err = nvs_set_str(pycom_nvs_handle, key, value);
252+
if (ESP_OK == esp_err) {
253+
nvs_commit(pycom_nvs_handle);
254+
} else if (ESP_ERR_NVS_NOT_ENOUGH_SPACE == esp_err || ESP_ERR_NVS_PAGE_FULL == esp_err || ESP_ERR_NVS_NO_FREE_PAGES == esp_err) {
255+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no space available"));
256+
} else if (ESP_ERR_NVS_INVALID_NAME == esp_err || ESP_ERR_NVS_KEY_TOO_LONG == esp_err) {
257+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid key (or too long)"));
258+
} else {
259+
// not ESP_OK, but not reporting? TODO:check this...
260+
}
261+
return mp_const_none;
262+
}
263+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_pycom_nvs_setstring_obj, mod_pycom_nvs_setstring);
264+
265+
236266
STATIC mp_obj_t mod_pycom_nvs_set (mp_obj_t _key, mp_obj_t _value) {
237267
const char *key = mp_obj_str_get_str(_key);
268+
if (MP_OBJ_IS_STR_OR_BYTES(_value)) {
269+
// not certain how to differentiate between string and bytes, here... TODO
270+
return mod_pycom_nvs_setstring(_key, _value);
271+
}
238272
uint32_t value = mp_obj_get_int_truncated(_value);
239273

240274
esp_err_t esp_err = nvs_set_u32(pycom_nvs_handle, key, value);
@@ -249,17 +283,53 @@ STATIC mp_obj_t mod_pycom_nvs_set (mp_obj_t _key, mp_obj_t _value) {
249283
}
250284
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_pycom_nvs_set_obj, mod_pycom_nvs_set);
251285

286+
287+
288+
STATIC mp_obj_t mod_pycom_nvs_getstring (mp_obj_t _key) {
289+
vstr_t vstr;
290+
const char *key = mp_obj_str_get_str(_key);
291+
size_t required_size = 0;
292+
if (ESP_ERR_NVS_NOT_FOUND == nvs_get_str(pycom_nvs_handle, key, NULL, &required_size)) {
293+
return mp_const_none;
294+
}
295+
vstr_init_len(&vstr, required_size);
296+
if (ESP_OK != nvs_get_str(pycom_nvs_handle, key, vstr.buf, &required_size)) {
297+
vstr_clear(&vstr);
298+
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't get string"));
299+
return mp_const_none;
300+
}
301+
if (vstr.len && vstr.buf[vstr.len - 1] == '\0') {
302+
/* bit of a hack to get rid of trailing null terminator required by the
303+
* nvs backend to figure out string length... must be a better way, TODO.
304+
*/
305+
vstr.len = vstr.len - 1;
306+
}
307+
return mp_obj_new_str_from_vstr(&mp_type_str, &vstr);
308+
309+
}
310+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_pycom_nvs_getstring_obj, mod_pycom_nvs_getstring);
311+
312+
252313
STATIC mp_obj_t mod_pycom_nvs_get (mp_obj_t _key) {
253314
const char *key = mp_obj_str_get_str(_key);
254315
uint32_t value;
255-
256-
if (ESP_ERR_NVS_NOT_FOUND == nvs_get_u32(pycom_nvs_handle, key, &value)) {
257-
return mp_const_none;
316+
esp_err_t esp_err = nvs_get_u32(pycom_nvs_handle, key, &value);
317+
if (ESP_OK == esp_err) {
318+
return mp_obj_new_int(value);
258319
}
259-
return mp_obj_new_int(value);
320+
if (ESP_ERR_NVS_NOT_FOUND == esp_err || ESP_ERR_NVS_TYPE_MISMATCH == esp_err) {
321+
/* you would expect it to return TYPE_MISMATCH if it's been
322+
stored as a string, but it's actually returning NOT_FOUND...
323+
so: try string */
324+
return mod_pycom_nvs_getstring(_key);
325+
}
326+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Error doing nvs_get: %d", esp_err));
327+
return mp_const_none;
260328
}
261329
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_pycom_nvs_get_obj, mod_pycom_nvs_get);
262330

331+
332+
263333
STATIC mp_obj_t mod_pycom_nvs_erase (mp_obj_t _key) {
264334
const char *key = mp_obj_str_get_str(_key);
265335

@@ -478,7 +548,9 @@ STATIC const mp_map_elem_t pycom_module_globals_table[] = {
478548
{ MP_OBJ_NEW_QSTR(MP_QSTR_ota_slot), (mp_obj_t)&mod_pycom_ota_slot_obj },
479549
{ MP_OBJ_NEW_QSTR(MP_QSTR_pulses_get), (mp_obj_t)&mod_pycom_pulses_get_obj },
480550
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_set), (mp_obj_t)&mod_pycom_nvs_set_obj },
551+
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_setstring), (mp_obj_t)&mod_pycom_nvs_setstring_obj },
481552
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_get), (mp_obj_t)&mod_pycom_nvs_get_obj },
553+
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_getstring), (mp_obj_t)&mod_pycom_nvs_getstring_obj },
482554
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_erase), (mp_obj_t)&mod_pycom_nvs_erase_obj },
483555
{ MP_OBJ_NEW_QSTR(MP_QSTR_nvs_erase_all), (mp_obj_t)&mod_pycom_nvs_erase_all_obj },
484556
{ MP_OBJ_NEW_QSTR(MP_QSTR_wifi_on_boot), (mp_obj_t)&mod_pycom_wifi_on_boot_obj },

0 commit comments

Comments
 (0)