diff --git a/Documentation/pycardium/power.rst b/Documentation/pycardium/power.rst new file mode 100644 index 0000000000000000000000000000000000000000..523529169e4ad21ee5396fe124936627d4891afb --- /dev/null +++ b/Documentation/pycardium/power.rst @@ -0,0 +1,47 @@ +.. py:module:: Power + +``power`` - PMIC power module handling +====================================== +The :py:mod:`power` module allows you to read the card10's power status +in your scripts. + +**Example**: + +.. code-block:: python + + import power + + print(power.read_battery_voltage()) + +.. py:function:: read_battery_voltage() + + Read the battery voltage in V. Please keep in mind that battery + voltage behaves exponentially when interpreting this value. + + .. warning:: + + Card10 will hard-shutdown once the voltage drops below 3.4 V + +.. py:function:: read_battery_current() + + Read the battery-side current flow in A. + +.. py:function:: read_chargin_voltage() + + Read the charge voltage in V. + +.. py:function:: read_chargin_current() + + Read the charge current in A. + +.. py:function:: read_system_voltage() + + Read the system-side voltate in V. + +.. py:function:: read_thermistor_voltage() + + Read the thermistor voltage in V. + + There is a resistor network from GND over a thermistor + (10K at room temperature) over 10K to the Thermistor Bias voltage. + This reads the voltage between thermistor and resistor. diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 2e7944b616287eeac7b51ddcd9e1ca6d9b99eeed..ebf66a9f4a93cb658c79223c059e38d27e998331 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -54,6 +54,13 @@ typedef _Bool bool; #define API_DISP_PIXEL 0x28 #define API_DISP_FRAMEBUFFER 0x29 +/* API_BATTERY_VOLTAGE 0x30 */ +#define API_BATTERY_CURRENT 0x31 +#define API_CHARGEIN_VOLTAGE 0x32 +#define API_CHARGEIN_CURRENT 0x33 +#define API_SYSTEM_VOLTAGE 0x34 +#define API_THERMISTOR_VOLTAGE 0x35 + #define API_FILE_OPEN 0x40 #define API_FILE_CLOSE 0x41 #define API_FILE_READ 0x42 @@ -227,15 +234,42 @@ API(API_SYSTEM_EXEC, int __epic_exec(char *name)); API(API_SYSTEM_RESET, void epic_system_reset(void)); /** - * Battery Voltage + * PMIC API * =============== */ + /** * Read the current battery voltage. */ API(API_BATTERY_VOLTAGE, int epic_read_battery_voltage(float *result)); +/** + * Read the current battery current. + */ +API(API_BATTERY_CURRENT, int epic_read_battery_current(float *result)); + +/** + * Read the current charge voltage. + */ +API(API_CHARGEIN_VOLTAGE, int epic_read_chargein_voltage(float *result)); + +/** + * Read the current charge current. + */ +API(API_CHARGEIN_CURRENT, int epic_read_chargein_current(float *result)); + +/** + * Read the current system voltage. + */ +API(API_SYSTEM_VOLTAGE, int epic_read_system_voltage(float *result)); + +/** + * Read the current thermistor voltage. + */ +API(API_THERMISTOR_VOLTAGE, int epic_read_thermistor_voltage(float *result)); + + /** * UART/Serial Interface * ===================== diff --git a/epicardium/modules/pmic.c b/epicardium/modules/pmic.c index b2105dc25ebd16676a6cffda007f59d579d6a03c..093e97ecdad2bd250636150c59ac18fcb16ad279 100644 --- a/epicardium/modules/pmic.c +++ b/epicardium/modules/pmic.c @@ -231,6 +231,50 @@ int epic_read_battery_voltage(float *result) return pmic_read_amux(PMIC_AMUX_BATT_U, result); } +/* + * API-call for battery current + */ +int epic_read_battery_current(float *result) +{ + return pmic_read_amux(PMIC_AMUX_BATT_CHG_I, result); +} + +/* + * API-call for charge voltage + */ +int epic_read_chargein_voltage(float *result) +{ + return pmic_read_amux(PMIC_AMUX_CHGIN_U, result); +} + +/* + * API-call for charge voltage + */ +int epic_read_chargein_current(float *result) +{ + return pmic_read_amux(PMIC_AMUX_BATT_CHG_I, result); +} + +/* + * API-call for system voltage + */ +int epic_read_system_voltage(float *result) +{ + return pmic_read_amux(PMIC_AMUX_SYS_U, result); +} + +/* + * API-call for thermistor voltage + * + * Thermistor is as 10k at room temperature, + * voltage divided with another 10k. + * (50% V_bias at room temperature) + */ +int epic_read_thermistor_voltage(float *result) +{ + return pmic_read_amux(PMIC_AMUX_THM_U, result); +} + static StaticTimer_t pmic_timer_data; static void vPmicTimerCb(TimerHandle_t xTimer) { diff --git a/pycardium/meson.build b/pycardium/meson.build index 2c43f62f35d0dfed88fab3dfbd6bfcecdcd0a70d..bb8d03b4fddca90a01be91b8de731abdfd7d3e74 100644 --- a/pycardium/meson.build +++ b/pycardium/meson.build @@ -11,6 +11,7 @@ modsrc = files( 'modules/light_sensor.c', 'modules/os.c', 'modules/personal_state.c', + 'modules/power.c', 'modules/sys_display.c', 'modules/utime.c', 'modules/vibra.c', diff --git a/pycardium/modules/os.c b/pycardium/modules/os.c index a693420b18979e8e1b835c85c71a943dd3c1ac9c..aa452a8dc5c573d50f144215a2d2da7bf775913a 100644 --- a/pycardium/modules/os.c +++ b/pycardium/modules/os.c @@ -141,7 +141,7 @@ static mp_obj_t mp_os_urandom(mp_obj_t size_in) vstr_t vstr; vstr_init_len(&vstr, size); - epic_trng_read((uint8_t*)vstr.buf, size); + epic_trng_read((uint8_t *)vstr.buf, size); return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); } diff --git a/pycardium/modules/power.c b/pycardium/modules/power.c new file mode 100644 index 0000000000000000000000000000000000000000..6a377aaf58d5090a31bc86d655bd9365d6c5d3e3 --- /dev/null +++ b/pycardium/modules/power.c @@ -0,0 +1,114 @@ +#include "epicardium.h" + +#include "py/builtin.h" +#include "py/obj.h" +#include "py/runtime.h" + +static mp_obj_t mp_power_read_battery_voltage() +{ + float result; + int status = epic_read_battery_voltage(&result); + if (status < 0) { + mp_raise_OSError(-status); + return mp_const_none; + } + return mp_obj_new_float(result); +} +static MP_DEFINE_CONST_FUN_OBJ_0( + power_read_battery_voltage_obj, mp_power_read_battery_voltage +); + +static mp_obj_t mp_power_read_battery_current() +{ + float result; + int status = epic_read_battery_current(&result); + if (status < 0) { + mp_raise_OSError(-status); + return mp_const_none; + } + return mp_obj_new_float(result); +} +static MP_DEFINE_CONST_FUN_OBJ_0( + power_read_battery_current_obj, mp_power_read_battery_current +); + +static mp_obj_t mp_power_read_chargein_voltage() +{ + float result; + int status = epic_read_chargein_voltage(&result); + if (status < 0) { + mp_raise_OSError(-status); + return mp_const_none; + } + return mp_obj_new_float(result); +} +static MP_DEFINE_CONST_FUN_OBJ_0( + power_read_chargein_voltage_obj, mp_power_read_chargein_voltage +); + +static mp_obj_t mp_power_read_chargein_current() +{ + float result; + int status = epic_read_chargein_current(&result); + if (status < 0) { + mp_raise_OSError(-status); + return mp_const_none; + } + return mp_obj_new_float(result); +} +static MP_DEFINE_CONST_FUN_OBJ_0( + power_read_chargein_current_obj, mp_power_read_chargein_current +); + +static mp_obj_t mp_power_read_system_voltage() +{ + float result; + int status = epic_read_system_voltage(&result); + if (status < 0) { + mp_raise_OSError(-status); + return mp_const_none; + } + return mp_obj_new_float(result); +} +static MP_DEFINE_CONST_FUN_OBJ_0( + power_read_system_voltage_obj, mp_power_read_system_voltage +); + +static mp_obj_t mp_power_read_thermistor_voltage() +{ + float result; + int status = epic_read_thermistor_voltage(&result); + if (status < 0) { + mp_raise_OSError(-status); + return mp_const_none; + } + return mp_obj_new_float(result); +} +static MP_DEFINE_CONST_FUN_OBJ_0( + power_read_thermistor_voltage_obj, mp_power_read_thermistor_voltage +); + +static const mp_rom_map_elem_t power_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_power) }, + { MP_ROM_QSTR(MP_QSTR_read_battery_voltage), + MP_ROM_PTR(&power_read_battery_voltage_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_battery_current), + MP_ROM_PTR(&power_read_battery_current_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_chargein_voltage), + MP_ROM_PTR(&power_read_chargein_voltage_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_chargein_current), + MP_ROM_PTR(&power_read_chargein_current_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_system_voltage), + MP_ROM_PTR(&power_read_system_voltage_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_thermistor_voltage), + MP_ROM_PTR(&power_read_thermistor_voltage_obj) }, +}; +static MP_DEFINE_CONST_DICT(power_module_globals, power_module_globals_table); + +const mp_obj_module_t power_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&power_module_globals, +}; + +/* clang-format off */ +MP_REGISTER_MODULE(MP_QSTR_power, power_module, MODULE_POWER_ENABLED); diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h index 82c1d12577ce06917fa8a94408f2961b2fbb5905..e418c24db58105796aa5b2cb34a1d80acd82af3b 100644 --- a/pycardium/modules/qstrdefs.h +++ b/pycardium/modules/qstrdefs.h @@ -71,6 +71,15 @@ Q(x) Q(y) Q(z) +/* power */ +Q(power) +Q(read_battery_voltage) +Q(read_battery_current) +Q(read_chargein_voltage) +Q(read_chargein_current) +Q(read_system_voltage) +Q(read_thermistor_voltage) + /* display */ Q(sys_display) Q(display) diff --git a/pycardium/mpconfigport.h b/pycardium/mpconfigport.h index b84867980a9858cdd6f9ec56398645ab4a9af8cd..43f878706cda83c9d7350f211a9b5ee3686dbea9 100644 --- a/pycardium/mpconfigport.h +++ b/pycardium/mpconfigport.h @@ -55,6 +55,7 @@ int mp_hal_trng_read_int(void); #define MODULE_LIGHT_SENSOR_ENABLED (1) #define MODULE_OS_ENABLED (1) #define MODULE_PERSONAL_STATE_ENABLED (1) +#define MODULE_POWER_ENABLED (1) #define MODULE_UTIME_ENABLED (1) #define MODULE_VIBRA_ENABLED (1)