kopia lustrzana https://github.com/espressif/esp-idf
refactor(pcnt): make pcnt driver as component
rodzic
c79dc27961
commit
98b5ea7bdf
|
@ -87,6 +87,7 @@
|
||||||
/components/esp_bootloader_format/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
|
/components/esp_bootloader_format/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
|
||||||
/components/esp_coex/ @esp-idf-codeowners/wifi @esp-idf-codeowners/bluetooth @esp-idf-codeowners/ieee802154
|
/components/esp_coex/ @esp-idf-codeowners/wifi @esp-idf-codeowners/bluetooth @esp-idf-codeowners/ieee802154
|
||||||
/components/esp_common/ @esp-idf-codeowners/system
|
/components/esp_common/ @esp-idf-codeowners/system
|
||||||
|
/components/esp_driver_*/ @esp-idf-codeowners/peripherals
|
||||||
/components/esp_eth/ @esp-idf-codeowners/network
|
/components/esp_eth/ @esp-idf-codeowners/network
|
||||||
/components/esp_event/ @esp-idf-codeowners/system
|
/components/esp_event/ @esp-idf-codeowners/system
|
||||||
/components/esp_gdbstub/ @esp-idf-codeowners/debugging
|
/components/esp_gdbstub/ @esp-idf-codeowners/debugging
|
||||||
|
|
|
@ -23,7 +23,6 @@ set(includes "include"
|
||||||
"ledc/include"
|
"ledc/include"
|
||||||
"mcpwm/include"
|
"mcpwm/include"
|
||||||
"parlio/include"
|
"parlio/include"
|
||||||
"pcnt/include"
|
|
||||||
"rmt/include"
|
"rmt/include"
|
||||||
"sdio_slave/include"
|
"sdio_slave/include"
|
||||||
"sdmmc/include"
|
"sdmmc/include"
|
||||||
|
@ -150,10 +149,9 @@ if(CONFIG_SOC_MCPWM_SUPPORTED)
|
||||||
list(APPEND ldfragments "mcpwm/linker.lf")
|
list(APPEND ldfragments "mcpwm/linker.lf")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# PCNT related source files
|
# PCNT legacy driver
|
||||||
if(CONFIG_SOC_PCNT_SUPPORTED)
|
if(CONFIG_SOC_PCNT_SUPPORTED)
|
||||||
list(APPEND srcs "pcnt/pulse_cnt.c"
|
list(APPEND srcs "deprecated/pcnt_legacy.c")
|
||||||
"deprecated/pcnt_legacy.c")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# RMT related source files
|
# RMT related source files
|
||||||
|
@ -245,6 +243,9 @@ else()
|
||||||
INCLUDE_DIRS ${includes}
|
INCLUDE_DIRS ${includes}
|
||||||
PRIV_REQUIRES efuse esp_timer esp_mm
|
PRIV_REQUIRES efuse esp_timer esp_mm
|
||||||
REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support
|
REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support
|
||||||
|
# for backward compatibility, the driver component needs to
|
||||||
|
# have a public dependency on other "esp_driver_foo" components
|
||||||
|
esp_driver_pcnt
|
||||||
LDFRAGMENTS ${ldfragments}
|
LDFRAGMENTS ${ldfragments}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -227,7 +227,7 @@ menu "Driver Configurations"
|
||||||
|
|
||||||
orsource "./gptimer/Kconfig.gptimer"
|
orsource "./gptimer/Kconfig.gptimer"
|
||||||
|
|
||||||
orsource "./pcnt/Kconfig.pcnt"
|
orsource "../esp_driver_pcnt/Kconfig.pcnt"
|
||||||
|
|
||||||
orsource "./rmt/Kconfig.rmt"
|
orsource "./rmt/Kconfig.rmt"
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
[mapping:driver]
|
[mapping:driver]
|
||||||
archive: libdriver.a
|
archive: libdriver.a
|
||||||
entries:
|
entries:
|
||||||
if PCNT_CTRL_FUNC_IN_IRAM = y:
|
|
||||||
pulse_cnt: pcnt_unit_start (noflash)
|
|
||||||
pulse_cnt: pcnt_unit_stop (noflash)
|
|
||||||
pulse_cnt: pcnt_unit_clear_count (noflash)
|
|
||||||
pulse_cnt: pcnt_unit_get_count (noflash)
|
|
||||||
if SDM_CTRL_FUNC_IN_IRAM = y:
|
if SDM_CTRL_FUNC_IN_IRAM = y:
|
||||||
sdm: sdm_channel_set_pulse_density (noflash)
|
sdm: sdm_channel_set_pulse_density (noflash)
|
||||||
if ANA_CMPR_CTRL_FUNC_IN_IRAM = y:
|
if ANA_CMPR_CTRL_FUNC_IN_IRAM = y:
|
||||||
|
|
|
@ -113,10 +113,6 @@ components/driver/test_apps/parlio:
|
||||||
temporary: true
|
temporary: true
|
||||||
reason: lack of runner
|
reason: lack of runner
|
||||||
|
|
||||||
components/driver/test_apps/pulse_cnt:
|
|
||||||
disable:
|
|
||||||
- if: SOC_PCNT_SUPPORTED != 1
|
|
||||||
|
|
||||||
components/driver/test_apps/rmt:
|
components/driver/test_apps/rmt:
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_RMT_SUPPORTED != 1
|
- if: SOC_RMT_SUPPORTED != 1
|
||||||
|
|
|
@ -8,5 +8,5 @@ endif()
|
||||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||||
# the component can be registered as WHOLE_ARCHIVE
|
# the component can be registered as WHOLE_ARCHIVE
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES unity driver esp_adc
|
PRIV_REQUIRES unity esp_driver_pcnt driver esp_adc
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
|
|
@ -3,5 +3,5 @@ set(srcs "test_app_main.c"
|
||||||
"test_i2s_iram.c")
|
"test_i2s_iram.c")
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES unity driver spi_flash
|
PRIV_REQUIRES unity esp_driver_pcnt driver spi_flash
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
|
|
@ -2,5 +2,5 @@ set(srcs "test_app_main.c"
|
||||||
"test_legacy_i2s.c")
|
"test_legacy_i2s.c")
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES unity driver
|
PRIV_REQUIRES unity esp_driver_pcnt driver
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
|
|
@ -4,5 +4,5 @@ set(srcs "test_app_main.c"
|
||||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||||
# the component can be registered as WHOLE_ARCHIVE
|
# the component can be registered as WHOLE_ARCHIVE
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES unity driver esp_timer esp_psram
|
PRIV_REQUIRES unity esp_driver_pcnt driver esp_timer esp_psram
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
|
|
@ -4,5 +4,5 @@ set(srcs "test_app_main.c"
|
||||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||||
# the component can be registered as WHOLE_ARCHIVE
|
# the component can be registered as WHOLE_ARCHIVE
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES unity driver
|
PRIV_REQUIRES unity esp_driver_pcnt driver
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
set(srcs)
|
||||||
|
set(public_include "include")
|
||||||
|
if(CONFIG_SOC_PCNT_SUPPORTED)
|
||||||
|
list(APPEND srcs "src/pulse_cnt.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(BOOTLOADER_BUILD)
|
||||||
|
# Bootloader shall NOT depend on the drivers
|
||||||
|
idf_component_register()
|
||||||
|
else()
|
||||||
|
idf_component_register(SRCS ${srcs}
|
||||||
|
INCLUDE_DIRS ${public_include}
|
||||||
|
PRIV_REQUIRES "esp_pm"
|
||||||
|
"driver" # will be replaced by esp_driver_gpio
|
||||||
|
LDFRAGMENTS "linker.lf"
|
||||||
|
)
|
||||||
|
endif()
|
|
@ -0,0 +1,8 @@
|
||||||
|
[mapping:pcnt_driver]
|
||||||
|
archive: libesp_driver_pcnt.a
|
||||||
|
entries:
|
||||||
|
if PCNT_CTRL_FUNC_IN_IRAM = y:
|
||||||
|
pulse_cnt: pcnt_unit_start (noflash)
|
||||||
|
pulse_cnt: pcnt_unit_stop (noflash)
|
||||||
|
pulse_cnt: pcnt_unit_clear_count (noflash)
|
||||||
|
pulse_cnt: pcnt_unit_get_count (noflash)
|
|
@ -192,7 +192,7 @@ esp_err_t pcnt_new_unit(const pcnt_unit_config_t *config, pcnt_unit_handle_t *re
|
||||||
"invalid limit range:[%d,%d]", config->low_limit, config->high_limit);
|
"invalid limit range:[%d,%d]", config->low_limit, config->high_limit);
|
||||||
if (config->intr_priority) {
|
if (config->intr_priority) {
|
||||||
ESP_GOTO_ON_FALSE(1 << (config->intr_priority) & PCNT_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, err,
|
ESP_GOTO_ON_FALSE(1 << (config->intr_priority) & PCNT_ALLOW_INTR_PRIORITY_MASK, ESP_ERR_INVALID_ARG, err,
|
||||||
TAG, "invalid interrupt priority:%d", config->intr_priority);
|
TAG, "invalid interrupt priority:%d", config->intr_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
unit = heap_caps_calloc(1, sizeof(pcnt_unit_t), PCNT_MEM_ALLOC_CAPS);
|
unit = heap_caps_calloc(1, sizeof(pcnt_unit_t), PCNT_MEM_ALLOC_CAPS);
|
||||||
|
@ -225,8 +225,8 @@ esp_err_t pcnt_new_unit(const pcnt_unit_config_t *config, pcnt_unit_handle_t *re
|
||||||
isr_flags |= PCNT_ALLOW_INTR_PRIORITY_MASK;
|
isr_flags |= PCNT_ALLOW_INTR_PRIORITY_MASK;
|
||||||
}
|
}
|
||||||
ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(pcnt_periph_signals.groups[group_id].irq, isr_flags,
|
ESP_GOTO_ON_ERROR(esp_intr_alloc_intrstatus(pcnt_periph_signals.groups[group_id].irq, isr_flags,
|
||||||
(uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id),
|
(uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id),
|
||||||
pcnt_default_isr, unit, &unit->intr), err,
|
pcnt_default_isr, unit, &unit->intr), err,
|
||||||
TAG, "install interrupt service failed");
|
TAG, "install interrupt service failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,8 +488,8 @@ esp_err_t pcnt_unit_register_event_callbacks(pcnt_unit_handle_t unit, const pcnt
|
||||||
isr_flags |= PCNT_ALLOW_INTR_PRIORITY_MASK;
|
isr_flags |= PCNT_ALLOW_INTR_PRIORITY_MASK;
|
||||||
}
|
}
|
||||||
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(pcnt_periph_signals.groups[group_id].irq, isr_flags,
|
ESP_RETURN_ON_ERROR(esp_intr_alloc_intrstatus(pcnt_periph_signals.groups[group_id].irq, isr_flags,
|
||||||
(uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id),
|
(uint32_t)pcnt_ll_get_intr_status_reg(group->hal.dev), PCNT_LL_UNIT_WATCH_EVENT(unit_id),
|
||||||
pcnt_default_isr, unit, &unit->intr),
|
pcnt_default_isr, unit, &unit->intr),
|
||||||
TAG, "install interrupt service failed");
|
TAG, "install interrupt service failed");
|
||||||
}
|
}
|
||||||
// enable/disable PCNT interrupt events
|
// enable/disable PCNT interrupt events
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||||
|
|
||||||
|
components/esp_driver_pcnt/test_apps/pulse_cnt:
|
||||||
|
disable:
|
||||||
|
- if: SOC_PCNT_SUPPORTED != 1
|
||||||
|
depends_components:
|
||||||
|
- esp_driver_pcnt
|
|
@ -10,7 +10,7 @@ project(pcnt_test)
|
||||||
if(CONFIG_COMPILER_DUMP_RTL_FILES)
|
if(CONFIG_COMPILER_DUMP_RTL_FILES)
|
||||||
add_custom_target(check_test_app_sections ALL
|
add_custom_target(check_test_app_sections ALL
|
||||||
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
|
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
|
||||||
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/
|
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_pcnt/,${CMAKE_BINARY_DIR}/esp-idf/hal/
|
||||||
--elf-file ${CMAKE_BINARY_DIR}/pcnt_test.elf
|
--elf-file ${CMAKE_BINARY_DIR}/pcnt_test.elf
|
||||||
find-refs
|
find-refs
|
||||||
--from-sections=.iram0.text
|
--from-sections=.iram0.text
|
|
@ -9,5 +9,6 @@ endif()
|
||||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||||
# the component can be registered as WHOLE_ARCHIVE
|
# the component can be registered as WHOLE_ARCHIVE
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES unity driver spi_flash
|
PRIV_REQUIRES unity esp_driver_pcnt spi_flash
|
||||||
|
driver # will be replaced by esp_driver_gpio
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
|
@ -1,28 +1,24 @@
|
||||||
idf_build_get_property(target IDF_TARGET)
|
idf_build_get_property(target IDF_TARGET)
|
||||||
|
|
||||||
if(${target} STREQUAL "linux")
|
if(${target} STREQUAL "linux")
|
||||||
idf_component_register(INCLUDE_DIRS include)
|
idf_component_register(INCLUDE_DIRS include)
|
||||||
else()
|
else()
|
||||||
|
set(srcs "src/esp_timer.c"
|
||||||
|
"src/ets_timer_legacy.c"
|
||||||
|
"src/system_time.c"
|
||||||
|
"src/esp_timer_impl_common.c")
|
||||||
|
|
||||||
set(srcs "src/esp_timer.c"
|
if(CONFIG_ESP_TIMER_IMPL_TG0_LAC)
|
||||||
"src/ets_timer_legacy.c"
|
list(APPEND srcs "src/esp_timer_impl_lac.c")
|
||||||
"src/system_time.c"
|
elseif(CONFIG_ESP_TIMER_IMPL_SYSTIMER)
|
||||||
"src/esp_timer_impl_common.c")
|
list(APPEND srcs "src/esp_timer_impl_systimer.c")
|
||||||
|
endif()
|
||||||
if(CONFIG_ESP_TIMER_IMPL_TG0_LAC)
|
|
||||||
list(APPEND srcs "src/esp_timer_impl_lac.c")
|
|
||||||
elseif(CONFIG_ESP_TIMER_IMPL_SYSTIMER)
|
|
||||||
list(APPEND srcs "src/esp_timer_impl_systimer.c")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CONFIG_SOC_SYSTIMER_SUPPORT_ETM)
|
|
||||||
list(APPEND srcs "src/esp_timer_etm.c")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
idf_component_register(SRCS "${srcs}"
|
|
||||||
INCLUDE_DIRS include
|
|
||||||
PRIV_INCLUDE_DIRS private_include
|
|
||||||
REQUIRES esp_common
|
|
||||||
PRIV_REQUIRES soc driver)
|
|
||||||
|
|
||||||
|
if(CONFIG_SOC_SYSTIMER_SUPPORT_ETM)
|
||||||
|
list(APPEND srcs "src/esp_timer_etm.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
idf_component_register(SRCS "${srcs}"
|
||||||
|
INCLUDE_DIRS include
|
||||||
|
PRIV_INCLUDE_DIRS private_include)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -106,7 +106,6 @@ INPUT = \
|
||||||
$(PROJECT_PATH)/components/driver/mcpwm/include/driver/mcpwm_types.h \
|
$(PROJECT_PATH)/components/driver/mcpwm/include/driver/mcpwm_types.h \
|
||||||
$(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_tx.h \
|
$(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_tx.h \
|
||||||
$(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_types.h \
|
$(PROJECT_PATH)/components/driver/parlio/include/driver/parlio_types.h \
|
||||||
$(PROJECT_PATH)/components/driver/pcnt/include/driver/pulse_cnt.h \
|
|
||||||
$(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_common.h \
|
$(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_common.h \
|
||||||
$(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_encoder.h \
|
$(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_encoder.h \
|
||||||
$(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_rx.h \
|
$(PROJECT_PATH)/components/driver/rmt/include/driver/rmt_rx.h \
|
||||||
|
@ -140,6 +139,7 @@ INPUT = \
|
||||||
$(PROJECT_PATH)/components/esp_common/include/esp_check.h \
|
$(PROJECT_PATH)/components/esp_common/include/esp_check.h \
|
||||||
$(PROJECT_PATH)/components/esp_common/include/esp_err.h \
|
$(PROJECT_PATH)/components/esp_common/include/esp_err.h \
|
||||||
$(PROJECT_PATH)/components/esp_common/include/esp_idf_version.h \
|
$(PROJECT_PATH)/components/esp_common/include/esp_idf_version.h \
|
||||||
|
$(PROJECT_PATH)/components/esp_driver_pcnt/include/driver/pulse_cnt.h \
|
||||||
$(PROJECT_PATH)/components/esp_eth/include/esp_eth_com.h \
|
$(PROJECT_PATH)/components/esp_eth/include/esp_eth_com.h \
|
||||||
$(PROJECT_PATH)/components/esp_eth/include/esp_eth_driver.h \
|
$(PROJECT_PATH)/components/esp_eth/include/esp_eth_driver.h \
|
||||||
$(PROJECT_PATH)/components/esp_eth/include/esp_eth_mac.h \
|
$(PROJECT_PATH)/components/esp_eth/include/esp_eth_mac.h \
|
||||||
|
|
|
@ -193,6 +193,8 @@ examples/peripherals/parlio/simple_rgb_led_matrix:
|
||||||
examples/peripherals/pcnt:
|
examples/peripherals/pcnt:
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_PCNT_SUPPORTED != 1
|
- if: SOC_PCNT_SUPPORTED != 1
|
||||||
|
depends_components:
|
||||||
|
- esp_driver_pcnt
|
||||||
|
|
||||||
examples/peripherals/rmt:
|
examples/peripherals/rmt:
|
||||||
disable:
|
disable:
|
||||||
|
|
|
@ -33,9 +33,9 @@ set(extra_components_which_shouldnt_be_included
|
||||||
bootloader_support
|
bootloader_support
|
||||||
# [refactor-todo]: should cxx be in G1? Can it exist without FreeRTOS?
|
# [refactor-todo]: should cxx be in G1? Can it exist without FreeRTOS?
|
||||||
cxx
|
cxx
|
||||||
# [refactor-todo]: driver is a dependency of esp_pm, esp_timer, spi_flash, vfs, esp_wifi, ${IDF_TARGET}
|
# [refactor-todo]: driver is a dependency of esp_pm, spi_flash, vfs, esp_wifi
|
||||||
# all of these should be removed from G1 except for spi_flash.
|
# all of these should be removed from G1 except for spi_flash.
|
||||||
driver
|
driver esp_driver_pcnt
|
||||||
# esp_app_format is dependency of bootloader_support, app_update
|
# esp_app_format is dependency of bootloader_support, app_update
|
||||||
esp_app_format
|
esp_app_format
|
||||||
# esp_bootloader_format is dependency of bootloader_support, app_update
|
# esp_bootloader_format is dependency of bootloader_support, app_update
|
||||||
|
|
|
@ -16,5 +16,5 @@ endif()
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
INCLUDE_DIRS include
|
INCLUDE_DIRS include
|
||||||
REQUIRES esp_partition idf_test cmock
|
REQUIRES esp_partition idf_test cmock
|
||||||
PRIV_REQUIRES perfmon driver esp_netif)
|
PRIV_REQUIRES perfmon esp_driver_pcnt driver esp_netif)
|
||||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||||
|
|
Ładowanie…
Reference in New Issue