hal: Move dedicated GPIO LL and HAL

This commit moves the dedicated GPIO LL and HAL functions from
cpu_ll.h to dedic_gpio_cpu_ll.h.

- cpu_ll_enable_cycle_count() has also been removed due to lack of feasible usage scenarios
This commit is contained in:
Darian Leung 2022-06-07 14:47:05 +08:00
parent 61eb7baa6b
commit 149872131a
16 changed files with 269 additions and 165 deletions

View File

@ -19,7 +19,7 @@
#include "soc/gpio_periph.h"
#include "soc/io_mux_reg.h"
#include "hal/cpu_hal.h"
#include "hal/cpu_ll.h"
#include "hal/dedic_gpio_cpu_ll.h"
#include "hal/gpio_hal.h"
#include "esp_private/periph_ctrl.h"
#include "esp_rom_gpio.h"
@ -271,7 +271,7 @@ esp_err_t dedic_gpio_new_bundle(const dedic_gpio_bundle_config_t *config, dedic_
esp_rom_gpio_connect_out_signal(config->gpio_array[i], dedic_gpio_periph_signals.cores[core_id].out_sig_per_channel[out_offset + i], config->flags.out_invert, false);
}
#if !SOC_DEDIC_GPIO_OUT_AUTO_ENABLE
cpu_ll_enable_dedic_gpio_output(s_platform[core_id]->out_occupied_mask);
dedic_gpio_cpu_ll_enable_output(s_platform[core_id]->out_occupied_mask);
#endif // !SOC_DEDIC_GPIO_OUT_AUTO_ENABLE
}
@ -353,14 +353,14 @@ void dedic_gpio_bundle_write(dedic_gpio_bundle_handle_t bundle, uint32_t mask, u
{
// For performance reasons, we don't want to check the validation of parameters here
// Even didn't check if we're working on the correct CPU core (i.e. bundle->core_id == current core_id)
cpu_ll_write_dedic_gpio_mask(bundle->out_mask & (mask << bundle->out_offset), value << bundle->out_offset);
dedic_gpio_cpu_ll_write_mask(bundle->out_mask & (mask << bundle->out_offset), value << bundle->out_offset);
}
uint32_t dedic_gpio_bundle_read_out(dedic_gpio_bundle_handle_t bundle)
{
// For performance reasons, we don't want to check the validation of parameters here
// Even didn't check if we're working on the correct CPU core (i.e. bundle->core_id == current core_id)
uint32_t value = cpu_ll_read_dedic_gpio_out();
uint32_t value = dedic_gpio_cpu_ll_read_out();
return (value & bundle->out_mask) >> (bundle->out_offset);
}
@ -368,7 +368,7 @@ uint32_t dedic_gpio_bundle_read_in(dedic_gpio_bundle_handle_t bundle)
{
// For performance reasons, we don't want to check the validation of parameters here
// Even didn't check if we're working on the correct CPU core (i.e. bundle->core_id == current core_id)
uint32_t value = cpu_ll_read_dedic_gpio_in();
uint32_t value = dedic_gpio_cpu_ll_read_in();
return (value & bundle->in_mask) >> (bundle->in_offset);
}

View File

@ -74,7 +74,7 @@ esp_err_t dedic_gpio_del_bundle(dedic_gpio_bundle_handle_t bundle);
* - ESP_FAIL: Get channel mask failed because of other error
*
* @note Each bundle should have at least one mask (in or/and out), based on bundle configuration.
* @note With the returned mask, user can directly invoke LL function like "cpu_ll_write_dedic_gpio_mask"
* @note With the returned mask, user can directly invoke LL function like "dedic_gpio_cpu_ll_write_mask"
* or write assembly code with dedicated GPIO instructions, to get better performance on GPIO manipulation.
*/
esp_err_t dedic_gpio_get_out_mask(dedic_gpio_bundle_handle_t bundle, uint32_t *mask);

View File

@ -11,7 +11,7 @@
#include "unity_test_utils.h"
#include "esp_rom_sys.h"
#include "soc/soc_caps.h"
#include "hal/cpu_ll.h"
#include "hal/dedic_gpio_cpu_ll.h"
#include "driver/gpio.h"
#include "driver/dedic_gpio.h"
@ -67,7 +67,7 @@ static void test_dedic_gpio_on_specific_core(void *args)
{
test_dedic_task_context_t *ctx = (test_dedic_task_context_t *)args;
uint32_t value = 0;
cpu_ll_write_dedic_gpio_all(0x0); // clear all out channels
dedic_gpio_cpu_ll_write_all(0x0); // clear all out channels
// configure a group of GPIOs, output only
const int bundleA_gpios[] = {ctx->gpios[0], ctx->gpios[1]};
@ -112,21 +112,21 @@ static void test_dedic_gpio_on_specific_core(void *args)
dedic_gpio_bundle_write(bundleA, 0x01, 0x01);
dedic_gpio_bundle_write(bundleB, 0x03, 0x03);
value = cpu_ll_read_dedic_gpio_out();
value = dedic_gpio_cpu_ll_read_out();
TEST_ASSERT_EQUAL(0x0D, value); // 1101
value = cpu_ll_read_dedic_gpio_in();
value = dedic_gpio_cpu_ll_read_in();
TEST_ASSERT_EQUAL(0x03, value); // 11
dedic_gpio_bundle_write(bundleB, 0x02, 0x0);
value = cpu_ll_read_dedic_gpio_out();
value = dedic_gpio_cpu_ll_read_out();
TEST_ASSERT_EQUAL(0x05, value); // 0101
value = cpu_ll_read_dedic_gpio_in();
value = dedic_gpio_cpu_ll_read_in();
TEST_ASSERT_EQUAL(0x01, value); // 01
cpu_ll_write_dedic_gpio_all(0x0F); // Set all out channels
value = cpu_ll_read_dedic_gpio_out();
dedic_gpio_cpu_ll_write_all(0x0F); // Set all out channels
value = dedic_gpio_cpu_ll_read_out();
TEST_ASSERT_EQUAL(0x0F, value);
value = cpu_ll_read_dedic_gpio_in();
value = dedic_gpio_cpu_ll_read_in();
TEST_ASSERT_EQUAL(0x03, value); // 11
TEST_ASSERT_EQUAL(0x03, dedic_gpio_bundle_read_out(bundleA)); // 11
TEST_ASSERT_EQUAL(0x00, dedic_gpio_bundle_read_in(bundleA)); // input is not enabled for bundleA

View File

@ -21,11 +21,6 @@
#define CSR_PCMR_MACHINE 0x7e1
#define CSR_PCCR_MACHINE 0x7e2
/*fast gpio*/
#define CSR_GPIO_OEN_USER 0x803
#define CSR_GPIO_IN_USER 0x804
#define CSR_GPIO_OUT_USER 0x805
#ifdef __cplusplus
extern "C" {
#endif
@ -204,34 +199,6 @@ static inline void cpu_ll_waiti(void)
asm volatile ("wfi\n");
}
static inline void cpu_ll_enable_dedic_gpio_output(uint32_t mask)
{
RV_WRITE_CSR(CSR_GPIO_OEN_USER, mask);
}
static inline void cpu_ll_write_dedic_gpio_all(uint32_t value)
{
RV_WRITE_CSR(CSR_GPIO_OUT_USER, value);
}
static inline uint32_t cpu_ll_read_dedic_gpio_in(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_IN_USER);
return value;
}
static inline uint32_t cpu_ll_read_dedic_gpio_out(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_OUT_USER);
return value;
}
static inline void cpu_ll_write_dedic_gpio_mask(uint32_t mask, uint32_t value)
{
RV_SET_CSR(CSR_GPIO_OUT_USER, mask & value);
RV_CLEAR_CSR(CSR_GPIO_OUT_USER, mask & ~(value));
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
uint32_t old_value;

View File

@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "riscv/csr.h"
/*fast gpio*/
#define CSR_GPIO_OEN_USER 0x803
#define CSR_GPIO_IN_USER 0x804
#define CSR_GPIO_OUT_USER 0x805
#ifdef __cplusplus
extern "C" {
#endif
static inline void dedic_gpio_cpu_ll_enable_output(uint32_t mask)
{
RV_WRITE_CSR(CSR_GPIO_OEN_USER, mask);
}
static inline void dedic_gpio_cpu_ll_write_all(uint32_t value)
{
RV_WRITE_CSR(CSR_GPIO_OUT_USER, value);
}
static inline uint32_t dedic_gpio_cpu_ll_read_in(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_IN_USER);
return value;
}
static inline uint32_t dedic_gpio_cpu_ll_read_out(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_OUT_USER);
return value;
}
static inline void dedic_gpio_cpu_ll_write_mask(uint32_t mask, uint32_t value)
{
RV_SET_CSR(CSR_GPIO_OUT_USER, mask & value);
RV_CLEAR_CSR(CSR_GPIO_OUT_USER, mask & ~(value));
}
#ifdef __cplusplus
}
#endif

View File

@ -21,11 +21,6 @@
#define CSR_PCMR_MACHINE 0x7e1
#define CSR_PCCR_MACHINE 0x7e2
/*fast gpio*/
#define CSR_GPIO_OEN_USER 0x803
#define CSR_GPIO_IN_USER 0x804
#define CSR_GPIO_OUT_USER 0x805
#ifdef __cplusplus
extern "C" {
#endif
@ -204,34 +199,6 @@ static inline void cpu_ll_waiti(void)
asm volatile ("wfi\n");
}
static inline void cpu_ll_enable_dedic_gpio_output(uint32_t mask)
{
RV_WRITE_CSR(CSR_GPIO_OEN_USER, mask);
}
static inline void cpu_ll_write_dedic_gpio_all(uint32_t value)
{
RV_WRITE_CSR(CSR_GPIO_OUT_USER, value);
}
static inline uint32_t cpu_ll_read_dedic_gpio_in(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_IN_USER);
return value;
}
static inline uint32_t cpu_ll_read_dedic_gpio_out(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_OUT_USER);
return value;
}
static inline void cpu_ll_write_dedic_gpio_mask(uint32_t mask, uint32_t value)
{
RV_SET_CSR(CSR_GPIO_OUT_USER, mask & value);
RV_CLEAR_CSR(CSR_GPIO_OUT_USER, mask & ~(value));
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
uint32_t old_value;

View File

@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "riscv/csr.h"
/*fast gpio*/
#define CSR_GPIO_OEN_USER 0x803
#define CSR_GPIO_IN_USER 0x804
#define CSR_GPIO_OUT_USER 0x805
#ifdef __cplusplus
extern "C" {
#endif
static inline void dedic_gpio_cpu_ll_enable_output(uint32_t mask)
{
RV_WRITE_CSR(CSR_GPIO_OEN_USER, mask);
}
static inline void dedic_gpio_cpu_ll_write_all(uint32_t value)
{
RV_WRITE_CSR(CSR_GPIO_OUT_USER, value);
}
static inline uint32_t dedic_gpio_cpu_ll_read_in(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_IN_USER);
return value;
}
static inline uint32_t dedic_gpio_cpu_ll_read_out(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_OUT_USER);
return value;
}
static inline void dedic_gpio_cpu_ll_write_mask(uint32_t mask, uint32_t value)
{
RV_SET_CSR(CSR_GPIO_OUT_USER, mask & value);
RV_CLEAR_CSR(CSR_GPIO_OUT_USER, mask & ~(value));
}
#ifdef __cplusplus
}
#endif

View File

@ -19,11 +19,6 @@
#define CSR_PCMR_MACHINE 0x7e1
#define CSR_PCCR_MACHINE 0x7e2
/*fast gpio*/
#define CSR_GPIO_OEN_USER 0x803
#define CSR_GPIO_IN_USER 0x804
#define CSR_GPIO_OUT_USER 0x805
#ifdef __cplusplus
extern "C" {
#endif
@ -197,34 +192,6 @@ static inline void cpu_ll_waiti(void)
asm volatile ("wfi\n");
}
static inline void cpu_ll_enable_dedic_gpio_output(uint32_t mask)
{
RV_WRITE_CSR(CSR_GPIO_OEN_USER, mask);
}
static inline void cpu_ll_write_dedic_gpio_all(uint32_t value)
{
RV_WRITE_CSR(CSR_GPIO_OUT_USER, value);
}
static inline uint32_t cpu_ll_read_dedic_gpio_in(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_IN_USER);
return value;
}
static inline uint32_t cpu_ll_read_dedic_gpio_out(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_OUT_USER);
return value;
}
static inline void cpu_ll_write_dedic_gpio_mask(uint32_t mask, uint32_t value)
{
RV_SET_CSR(CSR_GPIO_OUT_USER, mask & value);
RV_CLEAR_CSR(CSR_GPIO_OUT_USER, mask & ~(value));
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
uint32_t old_value;

View File

@ -0,0 +1,51 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "riscv/csr.h"
/*fast gpio*/
#define CSR_GPIO_OEN_USER 0x803
#define CSR_GPIO_IN_USER 0x804
#define CSR_GPIO_OUT_USER 0x805
#ifdef __cplusplus
extern "C" {
#endif
static inline void dedic_gpio_cpu_ll_enable_output(uint32_t mask)
{
RV_WRITE_CSR(CSR_GPIO_OEN_USER, mask);
}
static inline void dedic_gpio_cpu_ll_write_all(uint32_t value)
{
RV_WRITE_CSR(CSR_GPIO_OUT_USER, value);
}
static inline uint32_t dedic_gpio_cpu_ll_read_in(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_IN_USER);
return value;
}
static inline uint32_t dedic_gpio_cpu_ll_read_out(void)
{
uint32_t value = RV_READ_CSR(CSR_GPIO_OUT_USER);
return value;
}
static inline void dedic_gpio_cpu_ll_write_mask(uint32_t mask, uint32_t value)
{
RV_SET_CSR(CSR_GPIO_OUT_USER, mask & value);
RV_CLEAR_CSR(CSR_GPIO_OUT_USER, mask & ~(value));
}
#ifdef __cplusplus
}
#endif

View File

@ -166,30 +166,6 @@ static inline void cpu_ll_set_vecbase(const void* vecbase)
asm volatile ("wsr %0, vecbase" :: "r" (vecbase));
}
static inline uint32_t cpu_ll_read_dedic_gpio_in(void)
{
uint32_t value = 0;
asm volatile("get_gpio_in %0" : "=r"(value) : :);
return value;
}
static inline uint32_t cpu_ll_read_dedic_gpio_out(void)
{
uint32_t value = 0;
asm volatile("rur.gpio_out %0" : "=r"(value) : :);
return value;
}
static inline void cpu_ll_write_dedic_gpio_all(uint32_t value)
{
asm volatile("wur.gpio_out %0"::"r"(value):);
}
static inline void cpu_ll_write_dedic_gpio_mask(uint32_t mask, uint32_t value)
{
asm volatile("wr_mask_gpio_out %0, %1" : : "r"(value), "r"(mask):);
}
static inline void cpu_ll_waiti(void)
{
asm volatile ("waiti 0\n");

View File

@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t dedic_gpio_cpu_ll_read_in(void)
{
uint32_t value = 0;
asm volatile("get_gpio_in %0" : "=r"(value) : :);
return value;
}
static inline uint32_t dedic_gpio_cpu_ll_read_out(void)
{
uint32_t value = 0;
asm volatile("rur.gpio_out %0" : "=r"(value) : :);
return value;
}
static inline void dedic_gpio_cpu_ll_write_all(uint32_t value)
{
asm volatile("wur.gpio_out %0"::"r"(value):);
}
static inline void dedic_gpio_cpu_ll_write_mask(uint32_t mask, uint32_t value)
{
asm volatile("wr_mask_gpio_out %0, %1" : : "r"(value), "r"(mask):);
}
#ifdef __cplusplus
}
#endif

View File

@ -174,30 +174,6 @@ static inline void cpu_ll_waiti(void)
asm volatile ("waiti 0\n");
}
static inline uint32_t cpu_ll_read_dedic_gpio_in(void)
{
uint32_t value = 0;
asm volatile("ee.get_gpio_in %0" : "=r"(value) : :);
return value;
}
static inline uint32_t cpu_ll_read_dedic_gpio_out(void)
{
uint32_t value = 0;
asm volatile("rur.gpio_out %0" : "=r"(value) : :);
return value;
}
static inline void cpu_ll_write_dedic_gpio_all(uint32_t value)
{
asm volatile("wur.gpio_out %0"::"r"(value):);
}
static inline void cpu_ll_write_dedic_gpio_mask(uint32_t mask, uint32_t value)
{
asm volatile("ee.wr_mask_gpio_out %0, %1" : : "r"(value), "r"(mask):);
}
static inline void cpu_ll_compare_and_set_native(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
{
__asm__ __volatile__ (

View File

@ -0,0 +1,50 @@
/*
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "xt_instr_macros.h"
#include "xtensa/config/specreg.h"
#include "xtensa/config/extreg.h"
#include "esp_bit_defs.h"
#include "esp_attr.h"
#include "xtensa/config/core.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t dedic_gpio_cpu_ll_read_in(void)
{
uint32_t value = 0;
asm volatile("ee.get_gpio_in %0" : "=r"(value) : :);
return value;
}
static inline uint32_t dedic_gpio_cpu_ll_read_out(void)
{
uint32_t value = 0;
asm volatile("rur.gpio_out %0" : "=r"(value) : :);
return value;
}
static inline void dedic_gpio_cpu_ll_write_all(uint32_t value)
{
asm volatile("wur.gpio_out %0"::"r"(value):);
}
static inline void dedic_gpio_cpu_ll_write_mask(uint32_t mask, uint32_t value)
{
asm volatile("ee.wr_mask_gpio_out %0, %1" : : "r"(value), "r"(mask):);
}
#ifdef __cplusplus
}
#endif

View File

@ -86,7 +86,7 @@ For advanced users, they can always manipulate the GPIOs by writing assembly cod
1. Allocate a GPIO bundle: :cpp:func:`dedic_gpio_new_bundle`
2. Query the mask occupied by that bundle: :cpp:func:`dedic_gpio_get_out_mask` or/and :cpp:func:`dedic_gpio_get_in_mask`
3. Call CPU LL apis (e.g. `cpu_ll_write_dedic_gpio_mask`) or write assembly code with that mask
3. Call CPU LL apis (e.g. `dedic_gpio_cpu_ll_write_mask`) or write assembly code with that mask
4. The fasted way of toggling IO is to use the dedicated "set/clear" instructions:
.. only:: esp32s2 or esp32s3
@ -113,7 +113,7 @@ For advanced users, they can always manipulate the GPIOs by writing assembly cod
For details of supported dedicated GPIO instructions, please refer to *{IDF_TARGET_NAME} Technical Reference Manual* > *ESP-RISC-V CPU* [`PDF <{IDF_TARGET_TRM_EN_URL}#riscvcpu>`__].
Some of the dedicated CPU instructions are also wrapped inside `hal/dedic_gpio_ll.h` as helper inline functions.
Some of the dedicated CPU instructions are also wrapped inside ``hal/dedic_gpio_cpu_ll.h`` as helper inline functions.
.. note::
Writing assembly code in application could make your code hard to port between targets, because those customized instructions are not guaranteed to remain the same format on different targets.

View File

@ -248,3 +248,10 @@ LCD
- ``mcpwm_sync_enable`` is removed. To configure synchronization, please use :cpp:func:`mcpwm_sync_configure`.
- ``mcpwm_isr_register`` is removed. You can register event callbacks, for capture channels. e.g. :cpp:member:`mcpwm_capture_config_t::capture_cb`.
- ``mcpwm_carrier_oneshot_mode_disable`` is removed. Disable the first pulse (a.k.a the one-shot pulse) in the carrier is not supported by hardware.
.. only:: SOC_DEDICATED_GPIO_SUPPORTED
Dedicated GPIO Driver
---------------------
- All of the dedicated GPIO related LL functionsn in ``cpu_ll.h`` have been moved to ``dedic_gpio_cpu_ll.h`` and renamed.

View File

@ -113,7 +113,7 @@ GPIO 捆绑包操作
有关支持的专用 GPIO 指令的详细信息,请参考 *{IDF_TARGET_NAME} 技术参考手册* > *ESP-RISC-V CPU* [`PDF <{IDF_TARGET_TRM_CN_URL}#riscvcpu>`__].
一些专用的 CPU 指令也包含在 `hal/dedic_gpio_ll.h` 中,作为辅助内联函数。
一些专用的 CPU 指令也包含在 `hal/dedic_gpio_cpu_ll.h` 中,作为辅助内联函数。
.. note::
由于自定义指令在不同目标上可能会有不同的格式,在应用程序中编写汇编代码可能会让代码难以在不同的芯片架构之间移植。