Переглянути джерело

Merge branch 'bugfix/fix_cannot_lslp_again_after_ulp_wakeup' into 'master'

sleep: fix cannot lightsleep again after a wakeup from ULP

Closes IDFGH-4396

See merge request espressif/esp-idf!17970
Jing Li 3 роки тому
батько
коміт
ac0d16cdc8

+ 3 - 0
components/esp_hw_support/port/esp32/rtc_sleep.c

@@ -194,6 +194,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
     REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, cfg.rtc_dbias_wak);
     REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, cfg.dig_dbias_wak);
     REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_SLP, cfg.dig_dbias_slp);
+
+    REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
+    REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
 }
 
 void rtc_sleep_low_init(uint32_t slowclk_period)

+ 12 - 7
components/esp_hw_support/sleep_modes.c

@@ -366,6 +366,11 @@ inline static uint32_t call_rtc_sleep_start(uint32_t reject_triggers, uint32_t l
 //TODO: IDF-4813
 bool esp_no_sleep = false;
 
+inline static bool is_light_sleep(uint32_t pd_flags)
+{
+    return (pd_flags & RTC_SLEEP_PD_DIG) == 0;
+}
+
 static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
 {
 #if CONFIG_IDF_TARGET_ESP32S3
@@ -420,10 +425,14 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
     }
 #endif
 
-#ifdef CONFIG_IDF_TARGET_ESP32
+#if CONFIG_ULP_COPROC_ENABLED
     // Enable ULP wakeup
     if (s_config.wakeup_triggers & RTC_ULP_TRIG_EN) {
+#ifdef CONFIG_IDF_TARGET_ESP32
         rtc_hal_ulp_wakeup_enable();
+#else
+        rtc_hal_ulp_int_clear();
+#endif
     }
 #endif
 
@@ -453,15 +462,11 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
 #endif
 
     uint32_t reject_triggers = 0;
-    if ((pd_flags & RTC_SLEEP_PD_DIG) == 0 && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) {
+    if (is_light_sleep(pd_flags)) {
         /* Light sleep, enable sleep reject for faster return from this function,
          * in case the wakeup is already triggerred.
          */
-#if CONFIG_IDF_TARGET_ESP32
-        reject_triggers = RTC_CNTL_LIGHT_SLP_REJECT_EN_M | RTC_CNTL_GPIO_REJECT_EN_M;
-#else
-        reject_triggers = s_config.wakeup_triggers;
-#endif
+        reject_triggers = s_config.wakeup_triggers & RTC_SLEEP_REJECT_MASK;
     }
 
     // Enter sleep

+ 10 - 13
components/hal/esp32/include/hal/rtc_cntl_ll.h

@@ -1,16 +1,8 @@
-// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #pragma once
 
@@ -50,6 +42,11 @@ static inline void rtc_cntl_ll_ulp_wakeup_enable(void)
     SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_WAKEUP_FORCE_EN);
 }
 
+static inline void rtc_cntl_ll_ulp_int_clear(void)
+{
+    REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_SAR_INT_CLR);
+}
+
 #ifdef __cplusplus
 }
 #endif

+ 9 - 15
components/hal/esp32s2/include/hal/rtc_cntl_ll.h

@@ -1,16 +1,8 @@
-// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #pragma once
 
@@ -48,9 +40,11 @@ static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void)
     REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR);
 }
 
-static inline void rtc_cntl_ll_ulp_wakeup_enable(void)
+static inline void rtc_cntl_ll_ulp_int_clear(void)
 {
-    SET_PERI_REG_BITS(RTC_CNTL_STATE0_REG, RTC_CNTL_WAKEUP_ENA_V, 0x800, RTC_CNTL_WAKEUP_ENA_S);
+    REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_ULP_CP_INT_CLR);
+    REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR);
+    REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_TRAP_INT_CLR);
 }
 
 #ifdef __cplusplus

+ 12 - 18
components/hal/esp32s3/include/hal/rtc_cntl_ll.h

@@ -1,16 +1,8 @@
-// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+/*
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #pragma once
 
@@ -52,11 +44,6 @@ static inline void rtc_cntl_ll_ext1_clear_wakeup_pins(void)
     REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR);
 }
 
-static inline void rtc_cntl_ll_ulp_wakeup_enable(void)
-{
-    SET_PERI_REG_BITS(RTC_CNTL_STATE0_REG, RTC_CNTL_WAKEUP_ENA_V, 0x800, RTC_CNTL_WAKEUP_ENA_S);
-}
-
 static inline void rtc_cntl_ll_set_tagmem_retention_link_addr(uint32_t link_addr)
 {
     REG_SET_FIELD(APB_CTRL_RETENTION_CTRL1_REG, APB_CTRL_RETENTION_TAG_LINK_ADDR, link_addr);
@@ -133,6 +120,13 @@ static inline void rtc_cntl_ll_disable_cpu_retention(void)
     REG_CLR_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
 }
 
+static inline void rtc_cntl_ll_ulp_int_clear(void)
+{
+    REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_ULP_CP_INT_CLR);
+    REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR);
+    REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_TRAP_INT_CLR);
+}
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 0
components/hal/include/hal/rtc_hal.h

@@ -83,3 +83,5 @@ void rtc_cntl_hal_disable_tagmem_retention(void *addr);
  * Enable wakeup from ULP coprocessor.
  */
 #define rtc_hal_ulp_wakeup_enable()                       rtc_cntl_ll_ulp_wakeup_enable()
+
+#define rtc_hal_ulp_int_clear()                           rtc_cntl_ll_ulp_int_clear()

+ 11 - 1
components/soc/esp32/include/soc/rtc.h

@@ -520,6 +520,8 @@ typedef struct rtc_sleep_config_s {
     uint32_t lslp_meminf_pd : 1;        //!< remove all peripheral force power up flags
     uint32_t vddsdio_pd_en : 1;         //!< power down VDDSDIO regulator
     uint32_t xtal_fpu : 1;              //!< keep main XTAL powered up in sleep
+    uint32_t deep_slp_reject : 1;       //!< enable deep sleep reject
+    uint32_t light_slp_reject : 1;      //!< enable light sleep reject
 } rtc_sleep_config_t;
 
 /**
@@ -553,7 +555,9 @@ typedef struct rtc_sleep_config_s {
                    : RTC_CNTL_DBIAS_0V90, \
     .lslp_meminf_pd = 1, \
     .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \
-    .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1 \
+    .xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \
+    .deep_slp_reject = 1, \
+    .light_slp_reject = 1 \
 };
 
 #define RTC_SLEEP_PD_DIG                BIT(0)  //!< Deep sleep (power down digital domain)
@@ -620,6 +624,12 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
 #define RTC_ULP_TRIG_EN     BIT(9)  //!< ULP wakeup
 #define RTC_BT_TRIG_EN      BIT(10) //!< BT wakeup (light sleep only)
 
+/**
+ * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
+ * esp32 only supports GPIO and SDIO sleep reject sources
+ */
+#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN | RTC_SDIO_TRIG_EN)
+
 /**
  * @brief Enter deep or light sleep mode
  *

+ 15 - 2
components/soc/esp32c2/include/soc/rtc.h

@@ -561,8 +561,8 @@ typedef struct {
     uint32_t rtc_dbias_slp : 5;         //!< set bias for RTC domain, in sleep mode
     uint32_t vddsdio_pd_en : 1;         //!< power down VDDSDIO regulator
     uint32_t xtal_fpu : 1;              //!< keep main XTAL powered up in sleep
-    uint32_t deep_slp_reject : 1;
-    uint32_t light_slp_reject : 1;
+    uint32_t deep_slp_reject : 1;       //!< enable deep sleep reject
+    uint32_t light_slp_reject : 1;      //!< enable light sleep reject
 } rtc_sleep_config_t;
 
 /**
@@ -642,6 +642,19 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
 #define RTC_USB_TRIG_EN             BIT(14)
 #define RTC_BROWNOUT_DET_TRIG_EN    BIT(16)
 
+/**
+ * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
+ */
+#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN         | \
+                               RTC_TIMER_TRIG_EN        | \
+                               RTC_WIFI_TRIG_EN         | \
+                               RTC_UART0_TRIG_EN        | \
+                               RTC_UART1_TRIG_EN        | \
+                               RTC_BT_TRIG_EN           | \
+                               RTC_XTAL32K_DEAD_TRIG_EN | \
+                               RTC_USB_TRIG_EN          | \
+                               RTC_BROWNOUT_DET_TRIG_EN)
+
 /**
  * @brief Enter deep or light sleep mode
  *

+ 15 - 2
components/soc/esp32c3/include/soc/rtc.h

@@ -631,8 +631,8 @@ typedef struct {
     uint32_t rtc_dbias_slp : 5;         //!< set bias for RTC domain, in sleep mode
     uint32_t vddsdio_pd_en : 1;         //!< power down VDDSDIO regulator
     uint32_t xtal_fpu : 1;              //!< keep main XTAL powered up in sleep
-    uint32_t deep_slp_reject : 1;
-    uint32_t light_slp_reject : 1;
+    uint32_t deep_slp_reject : 1;       //!< enable deep sleep reject
+    uint32_t light_slp_reject : 1;      //!< enable light sleep reject
 } rtc_sleep_config_t;
 
 /**
@@ -728,6 +728,19 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
 #define RTC_USB_TRIG_EN             BIT(14)
 #define RTC_BROWNOUT_DET_TRIG_EN    BIT(16)
 
+/**
+ * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
+ */
+#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN         | \
+                               RTC_TIMER_TRIG_EN        | \
+                               RTC_WIFI_TRIG_EN         | \
+                               RTC_UART0_TRIG_EN        | \
+                               RTC_UART1_TRIG_EN        | \
+                               RTC_BT_TRIG_EN           | \
+                               RTC_XTAL32K_DEAD_TRIG_EN | \
+                               RTC_USB_TRIG_EN          | \
+                               RTC_BROWNOUT_DET_TRIG_EN)
+
 /**
  * @brief Enter deep or light sleep mode
  *

+ 15 - 2
components/soc/esp32h2/include/soc/rtc.h

@@ -647,8 +647,8 @@ typedef struct {
     uint32_t rtc_dbias_slp : 5;         //!< set bias for RTC domain, in sleep mode
     uint32_t vddsdio_pd_en : 1;         //!< power down VDDSDIO regulator
     uint32_t xtal_fpu : 1;              //!< keep main XTAL powered up in sleep
-    uint32_t deep_slp_reject : 1;
-    uint32_t light_slp_reject : 1;
+    uint32_t deep_slp_reject : 1;       //!< enable deep sleep reject
+    uint32_t light_slp_reject : 1;      //!< enable light sleep reject
 } rtc_sleep_config_t;
 
 /**
@@ -744,6 +744,19 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
 #define RTC_USB_TRIG_EN             BIT(14)
 #define RTC_BROWNOUT_DET_TRIG_EN    BIT(16)
 
+/**
+ * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
+ */
+#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN         | \
+                               RTC_TIMER_TRIG_EN        | \
+                               RTC_WIFI_TRIG_EN         | \
+                               RTC_UART0_TRIG_EN        | \
+                               RTC_UART1_TRIG_EN        | \
+                               RTC_BT_TRIG_EN           | \
+                               RTC_XTAL32K_DEAD_TRIG_EN | \
+                               RTC_USB_TRIG_EN          | \
+                               RTC_BROWNOUT_DET_TRIG_EN)
+
 /**
  * @brief Enter deep or light sleep mode
  *

+ 21 - 2
components/soc/esp32s2/include/soc/rtc.h

@@ -688,8 +688,8 @@ typedef struct {
     uint32_t rtc_dbias_slp : 3;         //!< set bias for RTC domain, in sleep mode
     uint32_t vddsdio_pd_en : 1;         //!< power down VDDSDIO regulator
     uint32_t xtal_fpu : 1;              //!< keep main XTAL powered up in sleep
-    uint32_t deep_slp_reject : 1;
-    uint32_t light_slp_reject : 1;
+    uint32_t deep_slp_reject : 1;       //!< enable deep sleep reject
+    uint32_t light_slp_reject : 1;      //!< enable light sleep reject
 } rtc_sleep_config_t;
 
 /**
@@ -780,6 +780,25 @@ void rtc_sleep_low_init(uint32_t slowclk_period);
 #define RTC_COCPU_TRAP_TRIG_EN      BIT(13)
 #define RTC_USB_TRIG_EN             BIT(14)
 
+/**
+ * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
+ */
+#define RTC_SLEEP_REJECT_MASK (RTC_EXT0_TRIG_EN         | \
+                               RTC_EXT1_TRIG_EN         | \
+                               RTC_GPIO_TRIG_EN         | \
+                               RTC_TIMER_TRIG_EN        | \
+                               RTC_SDIO_TRIG_EN         | \
+                               RTC_WIFI_TRIG_EN         | \
+                               RTC_UART0_TRIG_EN        | \
+                               RTC_UART1_TRIG_EN        | \
+                               RTC_TOUCH_TRIG_EN        | \
+                               RTC_ULP_TRIG_EN          | \
+                               RTC_BT_TRIG_EN           | \
+                               RTC_COCPU_TRIG_EN        | \
+                               RTC_XTAL32K_DEAD_TRIG_EN | \
+                               RTC_COCPU_TRAP_TRIG_EN   | \
+                               RTC_USB_TRIG_EN)
+
 /**
  * @brief Enter deep or light sleep mode
  *

+ 21 - 2
components/soc/esp32s3/include/soc/rtc.h

@@ -638,8 +638,8 @@ typedef struct {
     uint32_t rtc_dbias_slp : 5;         //!< set bias for RTC domain, in sleep mode
     uint32_t vddsdio_pd_en : 1;         //!< power down VDDSDIO regulator
     uint32_t xtal_fpu : 1;              //!< keep main XTAL powered up in sleep
-    uint32_t deep_slp_reject : 1;
-    uint32_t light_slp_reject : 1;
+    uint32_t deep_slp_reject : 1;       //!< enable deep sleep reject
+    uint32_t light_slp_reject : 1;      //!< enable light sleep reject
 } rtc_sleep_config_t;
 
 /**
@@ -742,6 +742,25 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
 #define RTC_COCPU_TRAP_TRIG_EN      BIT(13)
 #define RTC_USB_TRIG_EN             BIT(14)
 
+/**
+ * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
+ */
+#define RTC_SLEEP_REJECT_MASK (RTC_EXT0_TRIG_EN         | \
+                               RTC_EXT1_TRIG_EN         | \
+                               RTC_GPIO_TRIG_EN         | \
+                               RTC_TIMER_TRIG_EN        | \
+                               RTC_SDIO_TRIG_EN         | \
+                               RTC_WIFI_TRIG_EN         | \
+                               RTC_UART0_TRIG_EN        | \
+                               RTC_UART1_TRIG_EN        | \
+                               RTC_TOUCH_TRIG_EN        | \
+                               RTC_ULP_TRIG_EN          | \
+                               RTC_BT_TRIG_EN           | \
+                               RTC_COCPU_TRIG_EN        | \
+                               RTC_XTAL32K_DEAD_TRIG_EN | \
+                               RTC_COCPU_TRAP_TRIG_EN   | \
+                               RTC_USB_TRIG_EN)
+
 /**
  * @brief Enter deep or light sleep mode
  *

+ 18 - 1
components/ulp/test/ulp_riscv/test_ulp_riscv_main.c

@@ -113,7 +113,24 @@ TEST_CASE("ULP-RISC-V is able to wakeup main CPU from light sleep", "[ulp]")
     while (ulp_command_resp != RISCV_LIGHT_SLEEP_WAKEUP_TEST)
         ;
     gettimeofday(&end, NULL);
-    printf("Response time %jd ms\n", ((intmax_t)end.tv_sec - (intmax_t)start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000);
+    printf("Response time 1st: %jd ms\n", ((intmax_t)end.tv_sec - (intmax_t)start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000);
+
+    /* Verify test data */
+    TEST_ASSERT(ulp_command_resp == RISCV_LIGHT_SLEEP_WAKEUP_TEST);
+    TEST_ASSERT(ulp_main_cpu_reply == RISCV_COMMAND_OK);
+
+    /* Enter Light Sleep again */
+    TEST_ASSERT(esp_light_sleep_start() == ESP_OK);
+
+    /* Wait for wakeup from ULP RISC-V Coprocessor */
+    TEST_ASSERT(esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_ULP);
+
+    /* Wait till we receive the correct command response */
+    gettimeofday(&start, NULL);
+    while (ulp_command_resp != RISCV_LIGHT_SLEEP_WAKEUP_TEST)
+        ;
+    gettimeofday(&end, NULL);
+    printf("Response time 2nd: %jd ms\n", ((intmax_t)end.tv_sec - (intmax_t)start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000);
 
     /* Verify test data */
     TEST_ASSERT(ulp_command_resp == RISCV_LIGHT_SLEEP_WAKEUP_TEST);

+ 0 - 3
tools/ci/check_copyright_ignore.txt

@@ -792,7 +792,6 @@ components/hal/esp32/include/hal/dac_ll.h
 components/hal/esp32/include/hal/i2c_ll.h
 components/hal/esp32/include/hal/interrupt_controller_ll.h
 components/hal/esp32/include/hal/mpu_ll.h
-components/hal/esp32/include/hal/rtc_cntl_ll.h
 components/hal/esp32/include/hal/rtc_io_ll.h
 components/hal/esp32/include/hal/rwdt_ll.h
 components/hal/esp32/include/hal/sha_ll.h
@@ -849,7 +848,6 @@ components/hal/esp32s2/include/hal/interrupt_controller_ll.h
 components/hal/esp32s2/include/hal/memprot_ll.h
 components/hal/esp32s2/include/hal/memprot_peri_ll.h
 components/hal/esp32s2/include/hal/mpu_ll.h
-components/hal/esp32s2/include/hal/rtc_cntl_ll.h
 components/hal/esp32s2/include/hal/rtc_io_ll.h
 components/hal/esp32s2/include/hal/sha_ll.h
 components/hal/esp32s2/include/hal/sigmadelta_ll.h
@@ -867,7 +865,6 @@ components/hal/esp32s3/include/hal/i2c_ll.h
 components/hal/esp32s3/include/hal/interrupt_controller_ll.h
 components/hal/esp32s3/include/hal/memprot_ll.h
 components/hal/esp32s3/include/hal/mpu_ll.h
-components/hal/esp32s3/include/hal/rtc_cntl_ll.h
 components/hal/esp32s3/include/hal/rwdt_ll.h
 components/hal/esp32s3/include/hal/sha_ll.h
 components/hal/esp32s3/include/hal/sigmadelta_ll.h