Skip to content

Commit

Permalink
cpu/esp32: port periph/dac to ESP-IDF dac API
Browse files Browse the repository at this point in the history
  • Loading branch information
gschorcht committed Jul 17, 2022
1 parent 79ff1e5 commit 43d2340
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 67 deletions.
2 changes: 1 addition & 1 deletion cpu/esp32/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ typedef enum {
/**
* @brief Number of DAC channels that could be used at maximum.
*/
#define DAC_NUMOF_MAX 2
#define DAC_NUMOF_MAX (SOC_DAC_PERIPH_NUM)

/** @} */

Expand Down
97 changes: 31 additions & 66 deletions cpu/esp32/periph/dac.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019 Gunar Schorcht
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
Expand All @@ -22,108 +22,73 @@
#include "board.h"
#include "periph/dac.h"

#include "adc_arch.h"
#include "adc_ctrl.h"
#include "esp_common.h"
#include "gpio_arch.h"
#include "soc/rtc_io_struct.h"
#include "soc/rtc_cntl_struct.h"
#include "soc/sens_reg.h"
#include "soc/sens_struct.h"
#include "soc/dac_periph.h"
#include "esp_idf_api/dac.h"

#define ENABLE_DEBUG 0
#include "debug.h"

/* declaration of external functions */
extern void _adc2_ctrl_init(void);

/* forward declarations of internal functions */
static bool _dac_conf_check(void);
static bool _dac_module_initialized = false;

/* external variable declarations */
extern const gpio_t _gpio_rtcio_map[];
/* RIOT DAC line to ESP-IDF channel map, filled during initialization */
dac_channel_t _dac_channels[DAC_NUMOF] = { DAC_CHANNEL_MAX };

int8_t dac_init (dac_t line)
int8_t dac_init(dac_t line)
{
CHECK_PARAM_RET (line < DAC_NUMOF, DAC_NOLINE)

if (!_dac_module_initialized) {
/* do some configuration checks */
/* do some configuration checks and fill _dac_channel */
if (!_dac_conf_check()) {
return DAC_NOLINE;
}
_dac_module_initialized = true;
}

_adc2_ctrl_init();

uint8_t rtcio = _gpio_rtcio_map[dac_channels[line]];
uint8_t idx;

/* try to initialize the pin as DAC output */
if (gpio_get_pin_usage(_adc_hw[rtcio].gpio) != _GPIO) {
LOG_TAG_ERROR("dac", "GPIO%d is used for %s and cannot be used as "
"DAC output\n", _adc_hw[rtcio].gpio,
gpio_get_pin_usage_str(_adc_hw[rtcio].gpio));
if ((line >= DAC_NUMOF) || (_dac_channels[line] == DAC_CHANNEL_MAX)) {
LOG_TAG_ERROR("dac", "Line %u is an invalid DAC line\n", line);
return DAC_NOLINE;
}

/* disable the output of the pad */
RTCIO.enable_w1tc.val = BIT(_adc_hw[rtcio].rtc_gpio);

switch (rtcio) {
case RTCIO_DAC1: /* GPIO25, RTC6 */
case RTCIO_DAC2: /* GPIO26, RTC7 */
idx = rtcio - RTCIO_DAC1;
RTCIO.pad_dac[idx].mux_sel = 1; /* route to RTC */
RTCIO.pad_dac[idx].fun_sel = 0; /* function ADC2_CH8, ADC2_CH9 */
RTCIO.pad_dac[idx].fun_ie = 0; /* input disabled */
RTCIO.pad_dac[idx].rue = 0; /* pull-up disabled */
RTCIO.pad_dac[idx].rde = 0; /* pull-down disabled */

RTCIO.pad_dac[idx].dac_xpd_force = 1; /* use RTC pad not the FSM*/
RTCIO.pad_dac[idx].xpd_dac = 1; /* DAC powered on */
break;

default: return DAC_NOLINE;
}

/* set pin usage type */
gpio_set_pin_usage(_adc_hw[rtcio].gpio, _DAC);

/* don't use DMA */
SENS.sar_dac_ctrl1.dac_dig_force = 0;

/* disable CW generators and invert DAC signal */
SENS.sar_dac_ctrl1.sw_tone_en = 0;
SENS.sar_dac_ctrl2.dac_cw_en1 = 0;
SENS.sar_dac_ctrl2.dac_cw_en2 = 0;
dac_poweron(line);
dac_set(line, 0);

return DAC_OK;
}

void dac_set (dac_t line, uint16_t value)
void dac_set(dac_t line, uint16_t value)
{
CHECK_PARAM (line < DAC_NUMOF);
RTCIO.pad_dac[_gpio_rtcio_map[dac_channels[line]] - RTCIO_DAC1].dac = value >> 8;
assert(line < DAC_NUMOF);
assert(_dac_channels[line] != DAC_CHANNEL_MAX);
esp_idf_dac_output_voltage(_dac_channels[line],
value >> (16 - SOC_DAC_RESOLUTION));
}

void dac_poweroff (dac_t line)
void dac_poweroff(dac_t line)
{
CHECK_PARAM (line < DAC_NUMOF);
assert(line < DAC_NUMOF);
assert(_dac_channels[line] != DAC_CHANNEL_MAX);
esp_idf_dac_output_disable(_dac_channels[line]);
}

void dac_poweron (dac_t line)
void dac_poweron(dac_t line)
{
CHECK_PARAM (line < DAC_NUMOF);
assert(line < DAC_NUMOF);
assert(_dac_channels[line] != DAC_CHANNEL_MAX);
esp_idf_dac_output_enable(_dac_channels[line]);
}

static bool _dac_conf_check(void)
{
for (unsigned i = 0; i < DAC_NUMOF; i++) {
if (_gpio_rtcio_map[dac_channels[i]] != RTCIO_DAC1 &&
_gpio_rtcio_map[dac_channels[i]] != RTCIO_DAC2) {
for (unsigned j = 0; i < SOC_DAC_PERIPH_NUM; j++) {
if (dac_channels[i] == dac_periph_signal.dac_channel_io_num[j]) {
_dac_channels[i] = j;
break;
}
}
if (_dac_channels[i] == DAC_CHANNEL_MAX) {
LOG_TAG_ERROR("dac", "GPIO%d cannot be used as DAC line\n",
dac_channels[i]);
return false;
Expand Down

0 comments on commit 43d2340

Please sign in to comment.