From 5da9e0740e070f63aa5fccb5727a153f40b5a9a4 Mon Sep 17 00:00:00 2001 From: Rahix <rahix@rahix.de> Date: Tue, 20 Aug 2019 17:39:17 +0200 Subject: [PATCH] feat(pmic): Implement AMUX reading Signed-off-by: Rahix <rahix@rahix.de> --- epicardium/modules/modules.h | 24 +++++++-- epicardium/modules/pmic.c | 96 +++++++++++++++++++++++++++++++++--- 2 files changed, 110 insertions(+), 10 deletions(-) diff --git a/epicardium/modules/modules.h b/epicardium/modules/modules.h index 3555ab52..57ebe425 100644 --- a/epicardium/modules/modules.h +++ b/epicardium/modules/modules.h @@ -32,11 +32,29 @@ void vLedTask(void *pvParameters); int personal_state_enabled(); /* ---------- PMIC --------------------------------------------------------- */ -/* In 1/10s */ -#define PMIC_PRESS_SLEEP 20 -#define PMIC_PRESS_POWEROFF 40 void vPmicTask(void *pvParameters); +enum pmic_amux_signal { + PMIC_AMUX_CHGIN_U = 0x1, + PMIC_AMUX_CHGIN_I = 0x2, + PMIC_AMUX_BATT_U = 0x3, + PMIC_AMUX_BATT_CHG_I = 0x4, + PMIC_AMUX_BATT_DIS_I = 0x5, + PMIC_AMUX_BATT_NULL_I = 0x6, + PMIC_AMUX_THM_U = 0x7, + PMIC_AMUX_TBIAS_U = 0x8, + PMIC_AMUX_AGND_U = 0x9, + PMIC_AMUX_SYS_U = 0xA, + _PMIC_AMUX_MAX, +}; + +/* + * Read a value from the PMIC's AMUX. The result is already converted into its + * proper unit. See the MAX77650 datasheet for details. + */ +int pmic_read_amux(enum pmic_amux_signal sig, float *result); + + /* ---------- BLE ---------------------------------------------------------- */ void vBleTask(void *pvParameters); bool ble_shall_start(void); diff --git a/epicardium/modules/pmic.c b/epicardium/modules/pmic.c index c02691dc..57b305c8 100644 --- a/epicardium/modules/pmic.c +++ b/epicardium/modules/pmic.c @@ -1,17 +1,20 @@ -#include <stdio.h> +#include "epicardium.h" +#include "modules/modules.h" +#include "modules/log.h" -#include "max32665.h" -#include "gcr_regs.h" +#include "card10.h" #include "pmic.h" #include "MAX77650-Arduino-Library.h" -#include "card10.h" + +#include "max32665.h" +#include "mxc_sys.h" +#include "mxc_pins.h" +#include "adc.h" #include "FreeRTOS.h" #include "task.h" -#include "epicardium.h" -#include "modules.h" -#include "modules/log.h" +#include <stdio.h> /* Task ID for the pmic handler */ static TaskHandle_t pmic_task_id = NULL; @@ -25,10 +28,89 @@ void pmic_interrupt_callback(void *_) } } +int pmic_read_amux(enum pmic_amux_signal sig, float *result) +{ + int ret = 0; + + if (sig > _PMIC_AMUX_MAX) { + return -EINVAL; + } + + ret = hwlock_acquire(HWLOCK_ADC, pdMS_TO_TICKS(100)); + if (ret < 0) { + return ret; + } + ret = hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(100)); + if (ret < 0) { + return ret; + } + + /* Select the correct channel for this measurement. */ + MAX77650_setMUX_SEL(sig); + + /* + * According to the datasheet, the voltage will stabilize within 0.3us. + * Just to be sure, we'll wait a little longer. In the meantime, + * release the I2C mutex. + */ + hwlock_release(HWLOCK_I2C); + vTaskDelay(pdMS_TO_TICKS(5)); + ret = hwlock_acquire(HWLOCK_I2C, pdMS_TO_TICKS(100)); + if (ret < 0) { + return ret; + } + + uint16_t adc_data; + ADC_StartConvert(ADC_CH_0, 0, 0); + ADC_GetData(&adc_data); + + /* Turn MUX back to neutral so it does not waste power. */ + MAX77650_setMUX_SEL(sig); + + /* Convert ADC measurement to SI Volts */ + float adc_voltage = (float)adc_data / 1023.0f * 1.22f; + + /* + * Convert value according to PMIC formulas (Table 7) + */ + switch (sig) { + case PMIC_AMUX_CHGIN_U: + *result = adc_voltage / 0.167f; + break; + case PMIC_AMUX_CHGIN_I: + *result = adc_voltage / 2.632f; + break; + case PMIC_AMUX_BATT_U: + *result = adc_voltage / 0.272f; + break; + case PMIC_AMUX_BATT_CHG_I: + *result = adc_voltage / 1.25f; + break; + case PMIC_AMUX_BATT_NULL_I: + case PMIC_AMUX_THM_U: + case PMIC_AMUX_TBIAS_U: + case PMIC_AMUX_AGND_U: + *result = adc_voltage; + break; + case PMIC_AMUX_SYS_U: + *result = adc_voltage / 0.26f; + break; + default: + ret = -EINVAL; + } + + hwlock_release(HWLOCK_I2C); + hwlock_release(HWLOCK_ADC); + return ret; +} + void vPmicTask(void *pvParameters) { pmic_task_id = xTaskGetCurrentTaskHandle(); + ADC_Init(0x9, NULL); + GPIO_Config(&gpio_cfg_adc0); + TickType_t button_start_tick = 0; while (1) { -- GitLab