diff --git a/Documentation/pycardium/gpio.rst b/Documentation/pycardium/gpio.rst index 51c7d5f90f270aedf583d0bd347c85323683626d..7d17b3fdf3597aba664ebc46feae7f7a41dc62ba 100644 --- a/Documentation/pycardium/gpio.rst +++ b/Documentation/pycardium/gpio.rst @@ -25,7 +25,10 @@ output in your scripts. :param int pin: ID of the pin to be configured. :param int mode: An integer with the bits for the wanted mode set. Create your integer by ORing :py:data:`gpio.mode.OUTPUT`, :py:data:`gpio.mode.INPUT`, - :py:data:`gpio.mode.PULL_UP`, :py:data:`gpio.mode.PULL_DOWN`. + :py:data:`gpio.mode.ADC`, :py:data:`gpio.mode.PULL_UP`, + :py:data:`gpio.mode.PULL_DOWN`. + + .. note:: On WRISTBAND_3, there is no ADC functionality available .. py:function:: get_mode(pin) @@ -47,6 +50,9 @@ output in your scripts. :param int pin: ID of the pin of to get the mode of. :returns: Current value of the GPIO pin. + If the pin is configured as ADC, the value returned + will be between 0 and 1000, representing voltages from + 0V to 3.3V .. py:data:: WRISTBAND_1 diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 29476b026c4b16740d82dff5f3aea04a1c1e85d9..9585690867f3c3e8a854641ce7006466b17143e5 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -459,6 +459,7 @@ enum gpio_mode { EPIC_GPIO_MODE_IN = (1<<0), /** Configure the pin as output */ EPIC_GPIO_MODE_OUT = (1<<1), + EPIC_GPIO_MODE_ADC = (1<<2), /** Enable the internal pull-up resistor */ EPIC_GPIO_PULL_UP = (1<<6), diff --git a/epicardium/modules/gpio.c b/epicardium/modules/gpio.c index 9577f094a166b6c52f25f11f7dd9acce8077c293..6b6977391f878fa58ad6618b98d08dcd9cf7f5a7 100644 --- a/epicardium/modules/gpio.c +++ b/epicardium/modules/gpio.c @@ -1,7 +1,11 @@ #include "epicardium.h" #include "gpio.h" #include "max32665.h" +#include "mxc_sys.h" +#include "adc.h" #include "mxc_errors.h" +#include "modules/log.h" +#include "modules/modules.h" /* * Despite what the schematic (currently, 2019-08-18) says these are the correct @@ -26,6 +30,17 @@ static gpio_cfg_t gpio_configs[] = { GPIO_PAD_NONE }, }; +static int s_adc_channels[] = { + [EPIC_GPIO_WRISTBAND_1] = ADC_CH_5, + [EPIC_GPIO_WRISTBAND_2] = ADC_CH_6, + /* on P0.29, there is no ADC available + * see GPIO matrix in MAX32665-MAX32668.pdf, + * pages 32,33 + */ + [EPIC_GPIO_WRISTBAND_3] = -1, + [EPIC_GPIO_WRISTBAND_4] = ADC_CH_4, +}; + int epic_gpio_set_pin_mode(uint8_t pin, uint8_t mode) { if (pin < EPIC_GPIO_WRISTBAND_1 || pin > EPIC_GPIO_WRISTBAND_4) @@ -43,14 +58,27 @@ int epic_gpio_set_pin_mode(uint8_t pin, uint8_t mode) if (mode & EPIC_GPIO_MODE_IN) { return -EINVAL; } + } else if (mode & EPIC_GPIO_MODE_ADC) { + if (s_adc_channels[pin] == -1) { + LOG_WARN("gpio", "ADC not available on pin %d", pin); + return -EINVAL; + } + cfg->func = GPIO_FUNC_ALT1; + if (mode & EPIC_GPIO_MODE_OUT) { + return -EINVAL; + } } else { return -EINVAL; } - if (mode & EPIC_GPIO_PULL_UP) { - cfg->pad = GPIO_PAD_PULL_UP; - } else if (mode & EPIC_GPIO_PULL_DOWN) { - cfg->pad = GPIO_PAD_PULL_DOWN; + if (!(mode & EPIC_GPIO_MODE_ADC)) { + if (mode & EPIC_GPIO_PULL_UP) { + cfg->pad = GPIO_PAD_PULL_UP; + } else if (mode & EPIC_GPIO_PULL_DOWN) { + cfg->pad = GPIO_PAD_PULL_DOWN; + } else { + cfg->pad = GPIO_PAD_NONE; + } } else { cfg->pad = GPIO_PAD_NONE; } @@ -71,6 +99,8 @@ int epic_gpio_get_pin_mode(uint8_t pin) res |= EPIC_GPIO_MODE_IN; else if (cfg->func == GPIO_FUNC_OUT) res |= EPIC_GPIO_MODE_OUT; + else if (cfg->func == GPIO_FUNC_ALT1) + res |= EPIC_GPIO_MODE_ADC; if (cfg->pad == GPIO_PAD_PULL_UP) res |= EPIC_GPIO_PULL_UP; else if (cfg->pad == GPIO_PAD_PULL_DOWN) @@ -106,6 +136,19 @@ int epic_gpio_read_pin(uint8_t pin) return GPIO_OutGet(cfg) != 0; } else if (cfg->func == GPIO_FUNC_IN) { return GPIO_InGet(cfg) != 0; + } else if (cfg->func == GPIO_FUNC_ALT1) { + int rc = hwlock_acquire(HWLOCK_ADC, pdMS_TO_TICKS(10)); + if (!rc) { + ADC_StartConvert(s_adc_channels[pin], 0, 0); + uint16_t value; + int rc = ADC_GetData(&value); + hwlock_release(HWLOCK_ADC); + if (rc < 0) { + return -EIO; + } + return (int)value; + } + return rc; } else { return -EINVAL; } diff --git a/pycardium/modules/gpio.c b/pycardium/modules/gpio.c index 49c3c37c4ea52ee1f207ddf5d78ecd65a957fdc9..08db00b536b02ade2544b74a3ef24a94ef84e386 100644 --- a/pycardium/modules/gpio.c +++ b/pycardium/modules/gpio.c @@ -54,6 +54,7 @@ static const mp_rom_map_elem_t gpio_module_modes_table[] = { { MP_ROM_QSTR(MP_QSTR_INPUT), MP_OBJ_NEW_SMALL_INT(EPIC_GPIO_MODE_IN) }, { MP_ROM_QSTR(MP_QSTR_OUTPUT), MP_OBJ_NEW_SMALL_INT(EPIC_GPIO_MODE_OUT) }, + { MP_ROM_QSTR(MP_QSTR_ADC), MP_OBJ_NEW_SMALL_INT(EPIC_GPIO_MODE_ADC) }, { MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(EPIC_GPIO_PULL_UP) }, { MP_ROM_QSTR(MP_QSTR_PULL_DOWN), diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h index 75c8876e3a1413f753c5d52114822fdc8ad4595d..3ccb0ca01b1d925d009ca48360e4c31f907168ae 100644 --- a/pycardium/modules/qstrdefs.h +++ b/pycardium/modules/qstrdefs.h @@ -151,6 +151,7 @@ Q(WRISTBAND_3) Q(WRISTBAND_4) Q(INPUT) Q(OUTPUT) +Q(ADC) Q(PULL_UP) Q(PULL_DOWN)