From 90a3107bfd3eb858062777ac0c5e3e863099dbb9 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 22 Mar 2024 18:06:29 +0800 Subject: [PATCH] fix(gpio): add workaround to ensure correct IO drive strength for C3 and S3 --- components/hal/esp32c3/include/hal/gpio_ll.h | 16 +++++++++++++--- components/hal/esp32s3/include/hal/gpio_ll.h | 16 +++++++++++++--- components/hal/esp32s3/include/hal/rtc_io_ll.h | 16 +++++++++++++--- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/components/hal/esp32c3/include/hal/gpio_ll.h b/components/hal/esp32c3/include/hal/gpio_ll.h index ce522286e83..e698799f699 100644 --- a/components/hal/esp32c3/include/hal/gpio_ll.h +++ b/components/hal/esp32c3/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -381,7 +381,12 @@ static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength) { - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, strength, FUN_DRV_S); + uint32_t drv_cap = (uint32_t)strength; + // DRV = 1 and DRV = 2 register bits are flipped for IO2, IO3, IO4, IO5, IO18, IO19 on the target + if (gpio_num == 2 || gpio_num == 3 || gpio_num == 4 || gpio_num == 5 || gpio_num == 18 || gpio_num == 19) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, drv_cap, FUN_DRV_S); } /** @@ -393,7 +398,12 @@ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu */ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength) { - *strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, FUN_DRV_S); + uint32_t drv_cap = GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S); + // DRV = 1 and DRV = 2 register bits are flipped for IO2, IO3, IO4, IO5, IO18, IO19 on the target + if (gpio_num == 2 || gpio_num == 3 || gpio_num == 4 || gpio_num == 5 || gpio_num == 18 || gpio_num == 19) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + *strength = (gpio_drive_cap_t)drv_cap; } /** diff --git a/components/hal/esp32s3/include/hal/gpio_ll.h b/components/hal/esp32s3/include/hal/gpio_ll.h index 13c81591bd2..d555f78c677 100644 --- a/components/hal/esp32s3/include/hal/gpio_ll.h +++ b/components/hal/esp32s3/include/hal/gpio_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -408,7 +408,12 @@ static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num) */ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength) { - SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, strength, FUN_DRV_S); + uint32_t drv_cap = (uint32_t)strength; + // DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target + if (gpio_num == 17 || gpio_num == 18) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, drv_cap, FUN_DRV_S); } /** @@ -420,7 +425,12 @@ static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_nu */ static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength) { - *strength = (gpio_drive_cap_t)GET_PERI_REG_BITS2(GPIO_PIN_MUX_REG[gpio_num], FUN_DRV_V, FUN_DRV_S); + uint32_t drv_cap = GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S); + // DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target + if (gpio_num == 17 || gpio_num == 18) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + *strength = (gpio_drive_cap_t)drv_cap; } /** diff --git a/components/hal/esp32s3/include/hal/rtc_io_ll.h b/components/hal/esp32s3/include/hal/rtc_io_ll.h index 572c89cfd96..1a988c000cb 100644 --- a/components/hal/esp32s3/include/hal/rtc_io_ll.h +++ b/components/hal/esp32s3/include/hal/rtc_io_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -155,7 +155,12 @@ static inline uint32_t rtcio_ll_get_level(int rtcio_num) static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength) { if (rtc_io_desc[rtcio_num].drv_v) { - SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, strength, rtc_io_desc[rtcio_num].drv_s); + uint32_t drv_cap = strength; + // DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target + if (rtcio_num == RTCIO_GPIO17_CHANNEL || rtcio_num == RTCIO_GPIO18_CHANNEL) { + drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1 + } + SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, drv_cap, rtc_io_desc[rtcio_num].drv_s); } } @@ -167,7 +172,12 @@ static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strengt */ static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num) { - return GET_PERI_REG_BITS2(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, rtc_io_desc[rtcio_num].drv_s); + uint32_t strength = GET_PERI_REG_BITS2(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, rtc_io_desc[rtcio_num].drv_s); + // DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target + if (rtcio_num == RTCIO_GPIO17_CHANNEL || rtcio_num == RTCIO_GPIO18_CHANNEL) { + strength = ((strength & 0x1) << 1) | ((strength & 0x2) >> 1); // swap bit0 and bit1 + } + return strength; } /**