Skip to content
Snippets Groups Projects
Commit 48a578d5 authored by rahix's avatar rahix
Browse files

Merge 'Analog read for wristband GPIOs'

See merge request card10/firmware!229
parents 622d2145 490ffdc3
No related branches found
No related tags found
1 merge request!229feat(epicardium): gpios are configurable as ADC
Pipeline #3623 passed
...@@ -25,7 +25,10 @@ output in your scripts. ...@@ -25,7 +25,10 @@ output in your scripts.
:param int pin: ID of the pin to be configured. :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 :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`, 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) .. py:function:: get_mode(pin)
...@@ -47,6 +50,9 @@ output in your scripts. ...@@ -47,6 +50,9 @@ output in your scripts.
:param int pin: ID of the pin of to get the mode of. :param int pin: ID of the pin of to get the mode of.
:returns: Current value of the GPIO pin. :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 .. py:data:: WRISTBAND_1
......
...@@ -459,6 +459,7 @@ enum gpio_mode { ...@@ -459,6 +459,7 @@ enum gpio_mode {
EPIC_GPIO_MODE_IN = (1<<0), EPIC_GPIO_MODE_IN = (1<<0),
/** Configure the pin as output */ /** Configure the pin as output */
EPIC_GPIO_MODE_OUT = (1<<1), EPIC_GPIO_MODE_OUT = (1<<1),
EPIC_GPIO_MODE_ADC = (1<<2),
/** Enable the internal pull-up resistor */ /** Enable the internal pull-up resistor */
EPIC_GPIO_PULL_UP = (1<<6), EPIC_GPIO_PULL_UP = (1<<6),
......
#include "epicardium.h" #include "epicardium.h"
#include "gpio.h" #include "gpio.h"
#include "max32665.h" #include "max32665.h"
#include "mxc_sys.h"
#include "adc.h"
#include "mxc_errors.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 * Despite what the schematic (currently, 2019-08-18) says these are the correct
...@@ -26,6 +30,17 @@ static gpio_cfg_t gpio_configs[] = { ...@@ -26,6 +30,17 @@ static gpio_cfg_t gpio_configs[] = {
GPIO_PAD_NONE }, 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) int epic_gpio_set_pin_mode(uint8_t pin, uint8_t mode)
{ {
if (pin < EPIC_GPIO_WRISTBAND_1 || pin > EPIC_GPIO_WRISTBAND_4) 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) ...@@ -43,14 +58,27 @@ int epic_gpio_set_pin_mode(uint8_t pin, uint8_t mode)
if (mode & EPIC_GPIO_MODE_IN) { if (mode & EPIC_GPIO_MODE_IN) {
return -EINVAL; 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 { } else {
return -EINVAL; return -EINVAL;
} }
if (mode & EPIC_GPIO_PULL_UP) { if (!(mode & EPIC_GPIO_MODE_ADC)) {
cfg->pad = GPIO_PAD_PULL_UP; if (mode & EPIC_GPIO_PULL_UP) {
} else if (mode & EPIC_GPIO_PULL_DOWN) { cfg->pad = GPIO_PAD_PULL_UP;
cfg->pad = GPIO_PAD_PULL_DOWN; } else if (mode & EPIC_GPIO_PULL_DOWN) {
cfg->pad = GPIO_PAD_PULL_DOWN;
} else {
cfg->pad = GPIO_PAD_NONE;
}
} else { } else {
cfg->pad = GPIO_PAD_NONE; cfg->pad = GPIO_PAD_NONE;
} }
...@@ -71,6 +99,8 @@ int epic_gpio_get_pin_mode(uint8_t pin) ...@@ -71,6 +99,8 @@ int epic_gpio_get_pin_mode(uint8_t pin)
res |= EPIC_GPIO_MODE_IN; res |= EPIC_GPIO_MODE_IN;
else if (cfg->func == GPIO_FUNC_OUT) else if (cfg->func == GPIO_FUNC_OUT)
res |= EPIC_GPIO_MODE_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) if (cfg->pad == GPIO_PAD_PULL_UP)
res |= EPIC_GPIO_PULL_UP; res |= EPIC_GPIO_PULL_UP;
else if (cfg->pad == GPIO_PAD_PULL_DOWN) else if (cfg->pad == GPIO_PAD_PULL_DOWN)
...@@ -106,6 +136,19 @@ int epic_gpio_read_pin(uint8_t pin) ...@@ -106,6 +136,19 @@ int epic_gpio_read_pin(uint8_t pin)
return GPIO_OutGet(cfg) != 0; return GPIO_OutGet(cfg) != 0;
} else if (cfg->func == GPIO_FUNC_IN) { } else if (cfg->func == GPIO_FUNC_IN) {
return GPIO_InGet(cfg) != 0; 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 { } else {
return -EINVAL; return -EINVAL;
} }
......
...@@ -54,6 +54,7 @@ static const mp_rom_map_elem_t gpio_module_modes_table[] = { ...@@ -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_INPUT), MP_OBJ_NEW_SMALL_INT(EPIC_GPIO_MODE_IN) },
{ MP_ROM_QSTR(MP_QSTR_OUTPUT), { MP_ROM_QSTR(MP_QSTR_OUTPUT),
MP_OBJ_NEW_SMALL_INT(EPIC_GPIO_MODE_OUT) }, 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_ROM_QSTR(MP_QSTR_PULL_UP),
MP_OBJ_NEW_SMALL_INT(EPIC_GPIO_PULL_UP) }, MP_OBJ_NEW_SMALL_INT(EPIC_GPIO_PULL_UP) },
{ MP_ROM_QSTR(MP_QSTR_PULL_DOWN), { MP_ROM_QSTR(MP_QSTR_PULL_DOWN),
......
...@@ -151,6 +151,7 @@ Q(WRISTBAND_3) ...@@ -151,6 +151,7 @@ Q(WRISTBAND_3)
Q(WRISTBAND_4) Q(WRISTBAND_4)
Q(INPUT) Q(INPUT)
Q(OUTPUT) Q(OUTPUT)
Q(ADC)
Q(PULL_UP) Q(PULL_UP)
Q(PULL_DOWN) Q(PULL_DOWN)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment