mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-24 22:13:52 +01:00
cpu/esp32/periph: add ESP32-H2 support
This commit is contained in:
parent
3019928ccc
commit
06f0c2cf09
99
cpu/esp32/periph/adc_arch_esp32h2.c
Normal file
99
cpu/esp32/periph/adc_arch_esp32h2.c
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_esp32
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Architecture-specific ADC/DAC definitions for ESP32-H2 variant (family)
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include "adc_arch_private.h"
|
||||
#include "esp_common.h"
|
||||
#include "soc/adc_channel.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief ADC hardware descriptor table (for internal use only)
|
||||
*
|
||||
* @note The index of entries in the table MUST correspond to the
|
||||
* RTCIO GPIO number.
|
||||
*/
|
||||
const _adc_hw_desc_t _adc_hw[] = {
|
||||
/* rtcio, gpio, adc_ctrl, adc_channel, pad_name */
|
||||
{ RTCIO_GPIO(0), ADC1_CHANNEL_0_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_0, "GPIO1" },
|
||||
{ RTCIO_GPIO(1), ADC1_CHANNEL_1_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_1, "MTMS" },
|
||||
{ RTCIO_GPIO(2), ADC1_CHANNEL_2_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_2, "MTDO" },
|
||||
{ RTCIO_GPIO(3), ADC1_CHANNEL_3_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_3, "MTCK" },
|
||||
{ RTCIO_GPIO(4), ADC1_CHANNEL_4_GPIO_NUM, ADC_UNIT_1, ADC_CHANNEL_4, "MTDI" },
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief GPIO to RTC IO map (for internal use only)
|
||||
*/
|
||||
const gpio_t _gpio_rtcio_map[] = {
|
||||
RTCIO_NA, /* GPIO0 */
|
||||
RTCIO_GPIO(0), /* GPIO1 */
|
||||
RTCIO_GPIO(1), /* GPIO2 */
|
||||
RTCIO_GPIO(2), /* GPIO3 */
|
||||
RTCIO_GPIO(3), /* GPIO4 */
|
||||
RTCIO_GPIO(4), /* GPIO5 */
|
||||
RTCIO_NA, /* GPIO6 */
|
||||
RTCIO_NA, /* GPIO7 */
|
||||
RTCIO_NA, /* GPIO8 */
|
||||
RTCIO_NA, /* GPIO9 */
|
||||
RTCIO_NA, /* GPIO10 */
|
||||
RTCIO_NA, /* GPIO11 */
|
||||
RTCIO_NA, /* GPIO12 */
|
||||
RTCIO_NA, /* GPIO13 */
|
||||
RTCIO_NA, /* GPIO14 */
|
||||
RTCIO_NA, /* GPIO15 */
|
||||
RTCIO_NA, /* GPIO16 */
|
||||
RTCIO_NA, /* GPIO17 */
|
||||
RTCIO_NA, /* GPIO18 */
|
||||
RTCIO_NA, /* GPIO19 */
|
||||
RTCIO_NA, /* GPIO20 */
|
||||
RTCIO_NA, /* GPIO21 */
|
||||
RTCIO_NA, /* GPIO22 */
|
||||
RTCIO_NA, /* GPIO23 */
|
||||
RTCIO_NA, /* GPIO24 */
|
||||
RTCIO_NA, /* GPIO25 */
|
||||
RTCIO_NA, /* GPIO26 */
|
||||
RTCIO_NA, /* GPIO27 */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Default voltage range of ADC results for different attenuations
|
||||
*
|
||||
* These values are used by function adc_get_vrange_min_max if software
|
||||
* calibration doesn't work for any reason and the voltage range can't be
|
||||
* determined by software.
|
||||
*
|
||||
* Table 5-5 in [ESP32-H2 Datasheet]
|
||||
* (https://www.espressif.com/sites/default/files/documentation/esp32-h2_datasheet_en.pdf).
|
||||
*/
|
||||
const int _adc_vrange_min_max[] = {
|
||||
0, 1000, /* min, max @ ADC_ATTEN_DB_0 */
|
||||
0, 1300, /* min, max @ ADC_ATTEN_DB_2_5 */
|
||||
0, 1900, /* min, max @ ADC_ATTEN_DB_6 */
|
||||
0, 3300, /* min, max @ ADC_ATTEN_DB_12 */
|
||||
};
|
||||
|
||||
_Static_assert(ARRAY_SIZE(_gpio_rtcio_map) == SOC_GPIO_PIN_COUNT,
|
||||
"size of _gpio_rtcio_map does not match SOC_GPIO_PIN_COUNT");
|
||||
_Static_assert(ARRAY_SIZE(_adc_vrange_min_max) == (SOC_ADC_ATTEN_NUM * 2),
|
||||
"size of _adc_vrange_min_max does not match SOC_ADC_ATTEN_NUM");
|
||||
@ -40,6 +40,11 @@
|
||||
|
||||
#define CAN TWAI
|
||||
|
||||
#ifdef CPU_FAM_ESP32H2
|
||||
# define PERIPH_TWAI_MODULE PERIPH_TWAI0_MODULE
|
||||
# define ETS_TWAI_INTR_SOURCE ETS_TWAI0_INTR_SOURCE
|
||||
#endif
|
||||
|
||||
/** Common ESP CAN definitions */
|
||||
#define ESP_CAN_INTR_MASK (0xffU) /* interrupts handled by ESP CAN */
|
||||
#define ESP_CAN_CLOCK APB_CLK_FREQ /* controller main clock */
|
||||
|
||||
@ -39,7 +39,9 @@
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#ifndef CPU_FAM_ESP32H2
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#endif
|
||||
#include "soc/rtc_io_periph.h"
|
||||
|
||||
#if __xtensa__
|
||||
@ -58,7 +60,7 @@
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#if SOC_PM_SUPPORT_EXT_WAKEUP
|
||||
#if SOC_PM_SUPPORT_EXT1_WAKEUP
|
||||
#if CPU_FAM_ESP32
|
||||
#define ESP_PM_WUP_PINS_ANY_HIGH ESP_EXT1_WAKEUP_ANY_HIGH
|
||||
#define ESP_PM_WUP_PINS_ANY_LOW -1
|
||||
@ -88,7 +90,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef ESP_PM_WUP_LEVEL
|
||||
#define ESP_PM_WUP_LEVEL ESP_PM_WUP_PINS_ANY_HIGH
|
||||
#endif
|
||||
@ -259,7 +260,9 @@ int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||
_gpio_pin_pd[pin] = cfg.pull_down_en;
|
||||
#if SOC_RTCIO_HOLD_SUPPORTED
|
||||
/* disable the RTCIO hold function for the case we come from deep sleep */
|
||||
rtc_gpio_hold_dis(pin);
|
||||
if (rtc_gpio_is_valid_gpio(pin)) {
|
||||
rtc_gpio_hold_dis(pin);
|
||||
}
|
||||
#endif /* SOC_RTCIO_HOLD_SUPPORTED */
|
||||
#endif /* ESP_PM_WUP_PINS */
|
||||
|
||||
@ -510,6 +513,14 @@ void gpio_pm_sleep_enter(unsigned mode)
|
||||
/* isolating GPIO12 from external circuits is especially recommended for
|
||||
* ESP32-WROVER that have an external pullup on GPIO12 */
|
||||
rtc_gpio_isolate(GPIO_NUM_12);
|
||||
#elif CPU_FAM_ESP32H2
|
||||
/* On ESP32H2 rtc_gpio_force_hold_en_all doesn't enable the hold
|
||||
* function for all RTC GPIOs, so we have to do it for each pin. */
|
||||
for (unsigned i = 0; i < SOC_GPIO_PIN_COUNT; i++) {
|
||||
if (rtc_gpio_is_valid_gpio(i)) {
|
||||
rtc_gpio_hold_en(i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
# error "ESP32x variant does not support hold feature in deep sleep";
|
||||
@ -589,6 +600,8 @@ void gpio_pm_sleep_enter(unsigned mode)
|
||||
gpio_pullup_dis(wup_pins[i]);
|
||||
gpio_pulldown_en(wup_pins[i]);
|
||||
}
|
||||
#elif SOC_GPIO_SUPPORT_HOLD_IO_IN_DSLP
|
||||
rtc_gpio_hold_en(wup_pins[i]);
|
||||
#endif
|
||||
}
|
||||
#if SOC_PM_SUPPORT_EXT1_WAKEUP
|
||||
|
||||
98
cpu/esp32/periph/gpio_arch_esp32h2.c
Normal file
98
cpu/esp32/periph/gpio_arch_esp32h2.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2025 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 details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_esp32
|
||||
* @ingroup drivers_periph_gpio
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Architecture-specific GPIO definitions for ESP32-H2 variant (family)
|
||||
*
|
||||
* @author Gunar Schorcht <gunar@schorcht.net>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "gpio_arch.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
|
||||
#if !IS_USED(MODULE_ESP_IDF_GPIO_HAL)
|
||||
|
||||
/* GPIO to IOMUX register mapping (see Technical Reference, Section 6.13 IO MUX Functions List)
|
||||
https://www.espressif.com/sites/default/files/documentation/esp32-h2_technical_reference_manual_en.pdf */
|
||||
|
||||
const uint32_t _gpio_to_iomux_reg[GPIO_PIN_NUMOF] =
|
||||
{
|
||||
PERIPHS_IO_MUX_GPIO0_U, /* GPIO0 */
|
||||
PERIPHS_IO_MUX_GPIO1_U, /* GPIO1 */
|
||||
PERIPHS_IO_MUX_MTMS_U, /* GPIO2 */
|
||||
PERIPHS_IO_MUX_MTDO_U, /* GPIO3 */
|
||||
PERIPHS_IO_MUX_MTCK_U, /* GPIO4 */
|
||||
PERIPHS_IO_MUX_MTDI_U, /* GPIO5 */
|
||||
0, /* GPIO6 is not available */
|
||||
0, /* GPIO7 is not available */
|
||||
PERIPHS_IO_MUX_GPIO8_U, /* GPIO8 */
|
||||
PERIPHS_IO_MUX_GPIO9_U, /* GPIO9 */
|
||||
PERIPHS_IO_MUX_GPIO10_U, /* GPIO10 */
|
||||
PERIPHS_IO_MUX_GPIO11_U, /* GPIO11 */
|
||||
PERIPHS_IO_MUX_GPIO12_U, /* GPIO12 */
|
||||
PERIPHS_IO_MUX_XTAL_32K_P_U, /* GPIO13 used for XTAL_32K_P */
|
||||
PERIPHS_IO_MUX_XTAL_32K_N_U, /* GPIO14 used for XTAL_32K_N*/
|
||||
0, /* GPIO15 is not available */
|
||||
0, /* GPIO16 is not available */
|
||||
0, /* GPIO17 is not available */
|
||||
0, /* GPIO18 is not available */
|
||||
0, /* GPIO19 is not available */
|
||||
0, /* GPIO20 is not available */
|
||||
0, /* GPIO21 is not available */
|
||||
PERIPHS_IO_MUX_GPIO22_U, /* GPIO22 */
|
||||
PERIPHS_IO_MUX_U0RXD_U, /* GPIO23 */
|
||||
PERIPHS_IO_MUX_U0TXD_U, /* GPIO24 */
|
||||
PERIPHS_IO_MUX_GPIO25_U, /* GPIO25 */
|
||||
PERIPHS_IO_MUX_GPIO26_U, /* GPIO26 */
|
||||
PERIPHS_IO_MUX_GPIO27_U, /* GPIO27 */
|
||||
};
|
||||
|
||||
#endif /* !IS_USED(MODULE_ESP_IDF_GPIO_HAL) */
|
||||
|
||||
/* Table of the usage type of each GPIO pin */
|
||||
gpio_pin_usage_t _gpio_pin_usage[GPIO_PIN_NUMOF] = {
|
||||
_GPIO, /* GPIO0 */
|
||||
_GPIO, /* GPIO1 */
|
||||
_GPIO, /* GPIO2 */
|
||||
_GPIO, /* GPIO3 */
|
||||
_GPIO, /* GPIO4 */
|
||||
_GPIO, /* GPIO5 */
|
||||
_NOT_EXIST, /* GPIO6 does not exist */
|
||||
_NOT_EXIST, /* GPIO7 does not exist */
|
||||
_GPIO, /* GPIO8 */
|
||||
_GPIO, /* GPIO9 */
|
||||
_GPIO, /* GPIO10 */
|
||||
_GPIO, /* GPIO11 */
|
||||
_GPIO, /* GPIO12 */
|
||||
#if MODULE_ESP_RTC_TIMER_32K
|
||||
_NOT_EXIST, /* GPIO13 is used for external 32K crystal */
|
||||
_NOT_EXIST, /* GPIO14 is used for external 32K crystal */
|
||||
#else
|
||||
_GPIO, /* GPIO13 */
|
||||
_GPIO, /* GPIO14 */
|
||||
#endif
|
||||
_NOT_EXIST, /* GPIO15 does not exist */
|
||||
_NOT_EXIST, /* GPIO16 does not exist */
|
||||
_NOT_EXIST, /* GPIO17 does not exist */
|
||||
_NOT_EXIST, /* GPIO18 does not exist */
|
||||
_NOT_EXIST, /* GPIO19 does not exist */
|
||||
_NOT_EXIST, /* GPIO20 does not exist */
|
||||
_NOT_EXIST, /* GPIO21 does not exist */
|
||||
_GPIO, /* GPIO22 */
|
||||
_UART, /* GPIO23 is used as direct I/O UART0 RxD */
|
||||
_UART, /* GPIO24 is used as direct I/O UART0 TxD */
|
||||
_GPIO, /* GPIO25 */
|
||||
_GPIO, /* GPIO26 could be used for builtin USB2JTAG bridge */
|
||||
_GPIO, /* GPIO27 could be used for builtin USB2JTAG bridge */
|
||||
};
|
||||
@ -36,7 +36,9 @@
|
||||
#include "rom/rtc.h"
|
||||
#include "rom/uart.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#ifndef CPU_FAM_ESP32H2
|
||||
# include "soc/rtc_cntl_reg.h"
|
||||
#endif
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
@ -192,6 +194,7 @@ void pm_set(unsigned mode)
|
||||
#endif
|
||||
|
||||
if (mode == ESP_PM_DEEP_SLEEP) {
|
||||
system_wdt_stop();
|
||||
esp_deep_sleep_start();
|
||||
/* waking up from deep-sleep leads to a DEEPSLEEP_RESET */
|
||||
UNREACHABLE();
|
||||
|
||||
@ -28,11 +28,13 @@
|
||||
#include "periph/pwm.h"
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#include "esp_clk_tree.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_common.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "hal/ledc_hal.h"
|
||||
#include "soc/ledc_periph.h"
|
||||
#include "soc/ledc_struct.h"
|
||||
#include "soc/rtc.h"
|
||||
|
||||
@ -126,9 +128,14 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||
hw_res_bit++;
|
||||
}
|
||||
|
||||
uint32_t clk_freq;
|
||||
esp_clk_tree_src_get_freq_hz((soc_module_clk_t)LEDC_SCLK,
|
||||
ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED,
|
||||
&clk_freq);
|
||||
|
||||
uint32_t hw_res = 1 << hw_res_bit;
|
||||
|
||||
uint32_t hw_ticks_max = rtc_clk_apb_freq_get();
|
||||
uint32_t hw_ticks_max = clk_freq;
|
||||
uint32_t hw_ticks_min = hw_ticks_max / (1 << SOC_LEDC_CLK_DIV_INT_BIT_NUM);
|
||||
uint32_t hw_freq_min = hw_ticks_min / (1 << SOC_LEDC_TIMER_BIT_WIDTH) + 1;
|
||||
|
||||
@ -139,11 +146,11 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||
}
|
||||
|
||||
/* number of hardware ticks required, at maximum it can be APB clock */
|
||||
uint32_t hw_ticks = MIN(freq * hw_res, rtc_clk_apb_freq_get());
|
||||
uint32_t hw_ticks = MIN(freq * hw_res, clk_freq);
|
||||
|
||||
/*
|
||||
* if the number of required ticks is less than minimum ticks supported by
|
||||
* the hardware supports, we have to increase the resolution.
|
||||
* if the number of required ticks is less than the minimum supported by
|
||||
* the hardware, we have to increase the resolution.
|
||||
*/
|
||||
while (hw_ticks < hw_ticks_min) {
|
||||
hw_res_bit++;
|
||||
@ -153,7 +160,7 @@ uint32_t pwm_init(pwm_t pwm, pwm_mode_t mode, uint32_t freq, uint16_t res)
|
||||
|
||||
/* LEDC_CLK_DIV is given in Q10.8 format */
|
||||
uint32_t hw_clk_div =
|
||||
((uint64_t)rtc_clk_apb_freq_get() << SOC_LEDC_CLK_DIV_FRAC_BIT_NUM) / hw_ticks;
|
||||
((uint64_t)clk_freq << SOC_LEDC_CLK_DIV_FRAC_BIT_NUM) / hw_ticks;
|
||||
|
||||
_DEV.freq = freq;
|
||||
_DEV.res = res;
|
||||
@ -255,9 +262,10 @@ void pwm_poweron(pwm_t pwm)
|
||||
/* enable and init the module and select the right clock source */
|
||||
periph_module_enable(_CFG.module);
|
||||
ledc_hal_init(&_DEV.hw, _CFG.group);
|
||||
ledc_hal_set_slow_clk_sel(&_DEV.hw, LEDC_SLOW_CLK_APB);
|
||||
ledc_ll_enable_clock(_DEV.hw.dev, true);
|
||||
ledc_hal_set_slow_clk_sel(&_DEV.hw, (ledc_slow_clk_sel_t)LEDC_SCLK);
|
||||
#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
|
||||
ledc_hal_set_clock_source(&_DEV.hw, _CFG.timer, LEDC_APB_CLK);
|
||||
ledc_hal_set_clock_source(&_DEV.hw, _CFG.timer, (ledc_clk_src_t)LEDC_SCLK);
|
||||
#endif
|
||||
|
||||
/* update the timer according to determined parameters */
|
||||
|
||||
@ -34,8 +34,6 @@
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define RTC_CLK_CAL_FRACT 19 /* fractional bits of calibration value */
|
||||
|
||||
/* contains the values as given at the interface */
|
||||
typedef struct {
|
||||
uint32_t alarm; /**< alarm value as set at the interface */
|
||||
|
||||
@ -19,24 +19,26 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
/* RIOT headers have to be included before ESP-IDF headers! */
|
||||
#include "cpu.h"
|
||||
#include "esp/common_macros.h"
|
||||
#include "esp_common.h"
|
||||
#include "irq_arch.h"
|
||||
#include "log.h"
|
||||
#include "periph/rtt.h"
|
||||
#include "rtt_arch.h"
|
||||
#include "syscalls.h"
|
||||
#include "timex.h"
|
||||
|
||||
/* ESP-IDF headers */
|
||||
#include "esp_attr.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if SOC_LP_TIMER_SUPPORTED
|
||||
# include "hal/lp_timer_ll.h"
|
||||
#else
|
||||
# include "soc/rtc_cntl_struct.h"
|
||||
#endif
|
||||
|
||||
#if __xtensa__
|
||||
#include "soc/dport_reg.h"
|
||||
@ -46,7 +48,11 @@
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define RTC_CLK_CAL_FRACT 19 /* fractional bits of calibration value */
|
||||
#if SOC_LP_TIMER_SUPPORTED
|
||||
# define RTC_TIMER_INTR_SOURCE ETS_LP_RTC_TIMER_INTR_SOURCE
|
||||
#else
|
||||
# define RTC_TIMER_INTR_SOURCE ETS_RTC_CORE_INTR_SOURCE
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t alarm_set; /**< alarm set at interface */
|
||||
@ -79,7 +85,7 @@ static void _rtc_init(void)
|
||||
static void _rtc_poweron(void)
|
||||
{
|
||||
/* route all interrupt sources to the same RTT level type interrupt */
|
||||
intr_matrix_set(PRO_CPU_NUM, ETS_RTC_CORE_INTR_SOURCE, CPU_INUM_RTT);
|
||||
intr_matrix_set(PRO_CPU_NUM, RTC_TIMER_INTR_SOURCE, CPU_INUM_RTT);
|
||||
|
||||
/* set interrupt handler and enable the CPU interrupt */
|
||||
esp_cpu_intr_set_handler(CPU_INUM_RTT, _rtc_isr, NULL);
|
||||
@ -93,6 +99,106 @@ static void _rtc_poweroff(void)
|
||||
esp_cpu_intr_set_handler(CPU_INUM_RTT, NULL, NULL);
|
||||
}
|
||||
|
||||
static void _rtc_save_counter(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void _rtc_restore_counter(bool in_init)
|
||||
{
|
||||
(void)in_init;
|
||||
}
|
||||
|
||||
#if SOC_LP_TIMER_SUPPORTED
|
||||
|
||||
uint64_t _rtc_get_counter(void)
|
||||
{
|
||||
/* trigger timer register update */
|
||||
LP_TIMER.update.update = 1;
|
||||
/* read the time from 48-bit counter and return */
|
||||
return ((uint64_t)LP_TIMER.counter[0].hi.counter_hi << 32) +
|
||||
LP_TIMER.counter[0].lo.counter_lo;
|
||||
}
|
||||
|
||||
static void _rtc_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
|
||||
{
|
||||
/* compute the time difference for 32.768 kHz as 32-bit value */
|
||||
uint64_t rtc_counter = _rtc_get_counter();
|
||||
uint32_t rtt_diff = alarm - rtc_counter;
|
||||
|
||||
/* use computed time difference directly to set the RTC counter alarm */
|
||||
uint64_t rtc_alarm = (rtc_counter + rtt_diff) & RTT_HW_COUNTER_MAX;
|
||||
|
||||
DEBUG("%s alarm=%" PRIu32 " rtt_diff=%" PRIu32
|
||||
" rtc_alarm=%" PRIu32 " @rtc=%" PRIu32 "\n",
|
||||
__func__, alarm, rtt_diff, (uint32_t)rtc_alarm, (uint32_t)rtc_counter);
|
||||
|
||||
/* save the alarm configuration for interrupt handling */
|
||||
_rtc_alarm.alarm_set = alarm;
|
||||
_rtc_alarm.alarm_cb = cb;
|
||||
_rtc_alarm.alarm_arg = arg;
|
||||
|
||||
/* set the timer value */
|
||||
LP_TIMER.target[0].lo.target_lo = rtc_alarm & UINT32_MAX;
|
||||
LP_TIMER.target[0].hi.target_hi = rtc_alarm >> 32;
|
||||
|
||||
DEBUG("%s %08x%08x \n", __func__,
|
||||
(unsigned)LP_TIMER.target[0].hi.target_hi,
|
||||
(unsigned)LP_TIMER.target[0].lo.target_lo);
|
||||
|
||||
/* clear and enable RTC timer interrupt */
|
||||
LP_TIMER.int_clr.alarm = 1;
|
||||
LP_TIMER.int_en.alarm = 1;
|
||||
|
||||
/* enable RTC timer alarm */
|
||||
LP_TIMER.target[0].hi.enable = 1;
|
||||
}
|
||||
|
||||
static void _rtc_clear_alarm(void)
|
||||
{
|
||||
/* disable alarms first */
|
||||
LP_TIMER.target[0].hi.enable = 0;
|
||||
|
||||
/* clear the bit in interrupt enable and status register */
|
||||
LP_TIMER.int_clr.alarm = 0;
|
||||
LP_TIMER.int_en.alarm = 0;
|
||||
|
||||
/* reset the alarm configuration for interrupt handling */
|
||||
_rtc_alarm.alarm_set = 0;
|
||||
_rtc_alarm.alarm_cb = NULL;
|
||||
_rtc_alarm.alarm_arg = NULL;
|
||||
}
|
||||
|
||||
static void IRAM _rtc_isr(void *arg)
|
||||
{
|
||||
/* disable alarms first */
|
||||
LP_TIMER.target[0].hi.enable = 0;
|
||||
|
||||
/* clear the bit in interrupt enable and status register */
|
||||
LP_TIMER.int_en.alarm = 0;
|
||||
LP_TIMER.int_clr.alarm = 1;
|
||||
|
||||
/* save the lower 32 bit of the current counter value */
|
||||
uint32_t counter = _rtc_get_counter();
|
||||
|
||||
DEBUG("%s %" PRIu32 "\n", __func__, counter);
|
||||
|
||||
if (_rtc_alarm.alarm_cb) {
|
||||
DEBUG("%s alarm %" PRIu32 "\n", __func__, counter);
|
||||
|
||||
rtt_cb_t alarm_cb = _rtc_alarm.alarm_cb;
|
||||
void *alarm_arg = _rtc_alarm.alarm_arg;
|
||||
|
||||
/* clear the alarm first */
|
||||
_rtc_alarm.alarm_cb = NULL;
|
||||
_rtc_alarm.alarm_arg = NULL;
|
||||
|
||||
/* call the alarm handler afterwards if callback was defined */
|
||||
alarm_cb(alarm_arg);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
uint64_t _rtc_get_counter(void)
|
||||
{
|
||||
/* trigger timer register update */
|
||||
@ -160,15 +266,6 @@ static void _rtc_clear_alarm(void)
|
||||
_rtc_alarm.alarm_arg = NULL;
|
||||
}
|
||||
|
||||
static void _rtc_save_counter(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void _rtc_restore_counter(bool in_init)
|
||||
{
|
||||
(void)in_init;
|
||||
}
|
||||
|
||||
static void IRAM _rtc_isr(void *arg)
|
||||
{
|
||||
/* disable alarms first */
|
||||
@ -198,6 +295,8 @@ static void IRAM _rtc_isr(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const rtt_hw_driver_t _rtt_hw_rtc_driver = {
|
||||
.init = _rtc_init,
|
||||
.get_counter = _rtc_get_counter,
|
||||
|
||||
@ -44,6 +44,7 @@
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "esp_cpu.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
@ -68,7 +69,7 @@ struct _spi_bus_t {
|
||||
spi_host_device_t hostid; /* SPI hostid as used by ESP-IDF */
|
||||
const spi_signal_conn_t *periph; /* SPI peripheral descriptor */
|
||||
spi_hal_timing_conf_t timing; /* calculated SPI timing parameters */
|
||||
spi_clk_t clk_last; /* SPI clock speed used last time in Hz */
|
||||
spi_clk_t clk_last; /* SPI clock speed used last time in Hz */
|
||||
uint8_t mode_last; /* SPI mode used last time */
|
||||
bool pins_initialized; /* SPI pins initialized */
|
||||
};
|
||||
@ -303,7 +304,7 @@ void IRAM_ATTR spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t cl
|
||||
cs = (cs == GPIO_UNDEF) ? spi_config[bus].cs : cs;
|
||||
|
||||
/* if the CS pin used is not yet initialized, we do it now */
|
||||
if (gpio_get_pin_usage(cs) != _SPI && spi_init_cs(bus, cs) != SPI_OK) {
|
||||
if ((gpio_get_pin_usage(cs) != _SPI) && (spi_init_cs(bus, cs) != SPI_OK)) {
|
||||
LOG_TAG_ERROR("spi",
|
||||
"SPI_DEV(%d) CS signal could not be initialized\n",
|
||||
bus);
|
||||
@ -313,6 +314,9 @@ void IRAM_ATTR spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t cl
|
||||
/* lock the bus */
|
||||
mutex_lock(&_spi[bus].lock);
|
||||
|
||||
/* enable peripheral output clock */
|
||||
spi_ll_enable_clock(_spi[bus].hostid, true);
|
||||
|
||||
/*
|
||||
* set SPI mode
|
||||
* see ESP32 Technical Reference, Section 7.4.1, Table 27
|
||||
@ -337,17 +341,22 @@ void IRAM_ATTR spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t cl
|
||||
|
||||
/* check whether timing has to be recalculated (time consuming) */
|
||||
if (clk != _spi[bus].clk_last) {
|
||||
uint32_t apb_clk = rtc_clk_apb_freq_get();
|
||||
uint32_t apb_clk = 0;
|
||||
uint32_t clk_reg;
|
||||
|
||||
if (apb_clk / 5 < clk) {
|
||||
spi_ll_set_clk_source(_spi[bus].periph->hw, SPI_CLK_SRC_DEFAULT);
|
||||
esp_clk_tree_src_get_freq_hz((soc_module_clk_t)SPI_CLK_SRC_DEFAULT,
|
||||
ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED,
|
||||
&apb_clk);
|
||||
|
||||
if ((apb_clk / 4) < clk) {
|
||||
LOG_TAG_ERROR("spi", "APB clock rate (%"PRIu32" Hz) has to be at "
|
||||
"least 5 times SPI clock rate (%d Hz)\n",
|
||||
"least 4 times SPI clock rate (%d Hz)\n",
|
||||
apb_clk, clk);
|
||||
assert(false);
|
||||
}
|
||||
|
||||
/* duty cycle is measured in is 1/256th, 50% = 128 */
|
||||
/* duty cycle is measured in 1/256th, 50% = 128 */
|
||||
int _clk = spi_ll_master_cal_clock(apb_clk, clk,
|
||||
128, &clk_reg);
|
||||
|
||||
@ -364,7 +373,7 @@ void IRAM_ATTR spi_acquire(spi_t bus, spi_cs_t cs, spi_mode_t mode, spi_clk_t cl
|
||||
&_spi[bus].timing.clock_reg);
|
||||
spi_ll_apply_config(_spi[bus].periph->hw);
|
||||
|
||||
#if defined(CPU_FAM_ESP32C3) || defined(CPU_FAM_ESP32S3)
|
||||
#if defined(CPU_FAM_ESP32C3) || defined(CPU_FAM_ESP32S3) || defined(CPU_FAM_ESP32H2)
|
||||
/*
|
||||
* If the SPI mode has been changed, the clock signal is only set to the
|
||||
* correct level at the beginning of the transfer on the ESP32x3. However,
|
||||
@ -402,6 +411,8 @@ void IRAM_ATTR spi_release(spi_t bus)
|
||||
static const char* _spi_names[] = { "CSPI/FSPI", "HSPI", "VSPI" };
|
||||
#elif defined(CPU_FAM_ESP32C3)
|
||||
static const char* _spi_names[] = { "SPI", "FSPI" };
|
||||
#elif defined(CPU_FAM_ESP32H2)
|
||||
static const char* _spi_names[] = { "SPI", "FSPI" };
|
||||
#elif defined(CPU_FAM_ESP32S2)
|
||||
static const char* _spi_names[] = { "SPI", "FSPI", "HSPI" };
|
||||
#elif defined(CPU_FAM_ESP32S3)
|
||||
|
||||
@ -64,8 +64,8 @@
|
||||
/* hardware timer modules used */
|
||||
|
||||
/**
|
||||
* ESP32 has four 64 bit hardware timers:
|
||||
* two timer groups TMG0 and TMG1 with 2 timers each
|
||||
* ESP32 and ESP32-S2 have four 64 bit hardware timers while ESP32-S3 has four
|
||||
* 54 bit hardware timers: two timer groups TMG0 and TMG1 with 2 timers each
|
||||
*
|
||||
* TMG0, timer 0 is used for system time in us and is therefore not
|
||||
* available as low level timer. Timers have only one channel. Timer devices
|
||||
@ -80,7 +80,7 @@
|
||||
* timer device is needed.
|
||||
*
|
||||
* ---
|
||||
* ESP32-C3 hast only two 54 bit hardware timers:
|
||||
* ESP32-C3, ESP32-H2 have only two 54 bit hardware timers:
|
||||
* two timer groups TMG0 and TMG1 with 1 timer each
|
||||
*
|
||||
* TMG0, timer 0 is used for system time in us and is therefore not
|
||||
@ -113,34 +113,29 @@ struct _hw_timer_desc_t {
|
||||
|
||||
static const struct _hw_timer_desc_t _timers_desc[] =
|
||||
{
|
||||
#if defined(CPU_FAM_ESP32) || defined(CPU_FAM_ESP32S2) || defined(CPU_FAM_ESP32S3)
|
||||
#if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1
|
||||
{
|
||||
.module = PERIPH_TIMG0_MODULE,
|
||||
.group = TIMER_GROUP_0,
|
||||
.index = TIMER_1,
|
||||
.int_src = ETS_TG0_T1_LEVEL_INTR_SOURCE,
|
||||
},
|
||||
#endif
|
||||
#if SOC_TIMER_GROUPS > 1
|
||||
{
|
||||
.module = PERIPH_TIMG1_MODULE,
|
||||
.group = TIMER_GROUP_1,
|
||||
.index = TIMER_0,
|
||||
.int_src = ETS_TG1_T0_LEVEL_INTR_SOURCE,
|
||||
},
|
||||
# if SOC_TIMER_GROUP_TIMERS_PER_GROUP > 1
|
||||
{
|
||||
.module = PERIPH_TIMG1_MODULE,
|
||||
.group = TIMER_GROUP_1,
|
||||
.index = TIMER_1,
|
||||
.int_src = ETS_TG1_T1_LEVEL_INTR_SOURCE,
|
||||
}
|
||||
#elif defined(CPU_FAM_ESP32C3)
|
||||
{
|
||||
.module = PERIPH_TIMG1_MODULE,
|
||||
.group = TIMER_GROUP_1,
|
||||
.index = TIMER_0,
|
||||
.int_src = ETS_TG1_T0_LEVEL_INTR_SOURCE
|
||||
},
|
||||
#else
|
||||
#error "MCU implementation needed"
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user