Merge branch 'fix/spi_flash_legacy_on_esp32s2' into 'master'

spi_flash: fix the reading issue using the ROM functions on ESP32-S2

See merge request espressif/esp-idf!7767
This commit is contained in:
Michael (XIAO Xufeng) 2020-02-26 18:04:51 +08:00
commit 9d8e590d86
11 changed files with 178 additions and 826 deletions

View file

@ -21,16 +21,24 @@
#endif
#define WAKE_UP_IGNORE 1 // gpio_wakeup function development is not completed yet, set it deprecated.
#if CONFIG_IDF_TARGET_ESP32
#define GPIO_OUTPUT_IO 18 // default output GPIO
#define GPIO_INPUT_IO 19 // default input GPIO
#define GPIO_OUTPUT_MAX GPIO_NUM_34
#define TEST_GPIO_EXT_OUT_IO 18 // default output GPIO
#define TEST_GPIO_EXT_IN_IO 19 // default input GPIO
#define TEST_GPIO_OUTPUT_PIN 23
#define TEST_GPIO_INPUT_ONLY_PIN 34
#define TEST_GPIO_OUTPUT_MAX GPIO_NUM_34
#elif CONFIG_IDF_TARGET_ESP32S2
// ESP32_S2 DEVKIC uses IO19 and IO20 as USB functions, so it is necessary to avoid using IO19, otherwise GPIO io pull up/down function cannot pass
#define GPIO_OUTPUT_IO 18 // default output GPIO
#define GPIO_INPUT_IO 21 // default input GPIO
#define GPIO_OUTPUT_MAX GPIO_NUM_46
// Also the first version of ESP32-S2-Saola has pullup issue on GPIO18, which is tied to 3V3 on the
// runner. Also avoid using GPIO18.
#define TEST_GPIO_EXT_OUT_IO 17 // default output GPIO
#define TEST_GPIO_EXT_IN_IO 21 // default input GPIO
#define TEST_GPIO_OUTPUT_PIN 26
#define TEST_GPIO_INPUT_ONLY_PIN 46
#define TEST_GPIO_OUTPUT_MAX GPIO_NUM_46
#endif
static volatile int disable_intr_times = 0; // use this to calculate how many times it go into interrupt
static volatile int level_intr_times = 0; // use this to get how many times the level interrupt happened
static volatile int edge_intr_times = 0; // use this to get how many times the edge interrupt happened
@ -38,6 +46,7 @@ static volatile int edge_intr_times = 0; // use this to get how many times the
static bool wake_up_result = false; // use this to judge the wake up event happen or not
#endif
/**
* do some initialization operation in this function
* @param num: it is the destination GPIO wanted to be initialized
@ -45,7 +54,7 @@ static bool wake_up_result = false; // use this to judge the wake up event happ
*/
static gpio_config_t init_io(gpio_num_t num)
{
TEST_ASSERT(num < GPIO_OUTPUT_MAX);
TEST_ASSERT(num < TEST_GPIO_OUTPUT_MAX);
gpio_config_t io_conf;
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
@ -81,11 +90,11 @@ static void gpio_isr_level_handler2(void* arg)
level_intr_times++;
ets_printf("GPIO[%d] intr, val: %d\n", gpio_num, gpio_get_level(gpio_num));
if(gpio_get_level(gpio_num)) {
gpio_set_level(GPIO_OUTPUT_IO, 0);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
}else{
gpio_set_level(GPIO_OUTPUT_IO, 1);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
}
ets_printf("GPIO[%d] intr, val: %d, level_intr_times = %d\n", GPIO_OUTPUT_IO, gpio_get_level(GPIO_OUTPUT_IO), level_intr_times);
ets_printf("GPIO[%d] intr, val: %d, level_intr_times = %d\n", TEST_GPIO_EXT_OUT_IO, gpio_get_level(TEST_GPIO_EXT_OUT_IO), level_intr_times);
ets_printf("GPIO[%d] intr, val: %d, level_intr_times = %d\n", gpio_num, gpio_get_level(gpio_num), level_intr_times);
}
#endif
@ -94,10 +103,10 @@ static void gpio_isr_level_handler2(void* arg)
// get result of waking up or not
static void sleep_wake_up(void *arg)
{
gpio_config_t io_config = init_io(GPIO_INPUT_IO);
gpio_config_t io_config = init_io(TEST_GPIO_EXT_IN_IO);
io_config.mode = GPIO_MODE_INPUT;
gpio_config(&io_config);
TEST_ESP_OK(gpio_wakeup_enable(GPIO_INPUT_IO, GPIO_INTR_HIGH_LEVEL));
TEST_ESP_OK(gpio_wakeup_enable(TEST_GPIO_EXT_IN_IO, GPIO_INTR_HIGH_LEVEL));
esp_light_sleep_start();
wake_up_result = true;
}
@ -105,12 +114,12 @@ static void sleep_wake_up(void *arg)
// wake up light sleep event
static void trigger_wake_up(void *arg)
{
gpio_config_t io_config = init_io(GPIO_OUTPUT_IO);
gpio_config_t io_config = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config(&io_config);
gpio_set_level(GPIO_OUTPUT_IO, 0);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_OUTPUT_IO, gpio_isr_level_handler, (void*) GPIO_INPUT_IO);
gpio_set_level(GPIO_OUTPUT_IO, 1);
gpio_isr_handler_add(TEST_GPIO_EXT_OUT_IO, gpio_isr_level_handler, (void*) TEST_GPIO_EXT_IN_IO);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
vTaskDelay(100 / portTICK_RATE_MS);
}
#endif
@ -159,27 +168,15 @@ TEST_CASE("GPIO config parameters test", "[gpio]")
io_config.pin_bit_mask = ((uint64_t)1<<GPIO_NUM_MAX);
TEST_ASSERT(gpio_config(&io_config) == ESP_ERR_INVALID_ARG);
#if CONFIG_IDF_TARGET_ESP32
io_config.pin_bit_mask = (uint64_t)1<<23;
io_config.pin_bit_mask = ((uint64_t)1<<TEST_GPIO_OUTPUT_PIN);
TEST_ESP_OK(gpio_config(&io_config));
io_config.pin_bit_mask = ((uint64_t)1 << 34);
io_config.pin_bit_mask = ((uint64_t)1 << TEST_GPIO_INPUT_ONLY_PIN);
io_config.mode = GPIO_MODE_INPUT;
TEST_ESP_OK(gpio_config(&io_config));
io_config.mode = GPIO_MODE_OUTPUT;
// ESP32 34-39 input only, once set as output should log something
// The pin is input only, once set as output should log something
TEST_ASSERT(gpio_config(&io_config) == ESP_ERR_INVALID_ARG);
#elif CONFIG_IDF_TARGET_ESP32S2
io_config.pin_bit_mask = (uint64_t)1<<26;
TEST_ESP_OK(gpio_config(&io_config));
io_config.pin_bit_mask = ((uint64_t)1 << 46);
io_config.mode = GPIO_MODE_INPUT;
TEST_ESP_OK(gpio_config(&io_config));
io_config.mode = GPIO_MODE_OUTPUT;
// ESP32-S2 46 input only, once set as output should log something
TEST_ASSERT(gpio_config(&io_config) == ESP_ERR_INVALID_ARG);
#endif
}
@ -189,69 +186,69 @@ TEST_CASE("GPIO rising edge interrupt test", "[gpio][test_env=UT_T1_GPIO]")
{
edge_intr_times = 0; // set it as 0 prepare to test
//init input and output gpio
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
input_io.intr_type = GPIO_INTR_POSEDGE;
input_io.mode = GPIO_MODE_INPUT;
input_io.pull_up_en = 1;
TEST_ESP_OK(gpio_config(&output_io));
TEST_ESP_OK(gpio_config(&input_io));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 0));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
//rising edge intr
TEST_ESP_OK(gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_POSEDGE));
TEST_ESP_OK(gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_POSEDGE));
TEST_ESP_OK(gpio_install_isr_service(0));
gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_edge_handler, (void*)GPIO_INPUT_IO);
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 1));
gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_edge_handler, (void*)TEST_GPIO_EXT_IN_IO);
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
TEST_ASSERT_EQUAL_INT(edge_intr_times, 1);
vTaskDelay(100 / portTICK_RATE_MS);
gpio_isr_handler_remove(GPIO_INPUT_IO);
gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
gpio_uninstall_isr_service();
}
TEST_CASE("GPIO falling edge interrupt test", "[gpio][test_env=UT_T1_GPIO]")
{
edge_intr_times = 0;
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
input_io.intr_type = GPIO_INTR_POSEDGE;
input_io.mode = GPIO_MODE_INPUT;
input_io.pull_up_en = 1;
TEST_ESP_OK(gpio_config(&output_io));
TEST_ESP_OK(gpio_config(&input_io));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 1));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_NEGEDGE);
gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_NEGEDGE);
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_edge_handler, (void*) GPIO_INPUT_IO);
gpio_set_level(GPIO_OUTPUT_IO, 0);
gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_edge_handler, (void*) TEST_GPIO_EXT_IN_IO);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT(edge_intr_times, 1);
vTaskDelay(100 / portTICK_RATE_MS);
gpio_isr_handler_remove(GPIO_INPUT_IO);
gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
gpio_uninstall_isr_service();
}
TEST_CASE("GPIO both rising and falling edge interrupt test", "[gpio][test_env=UT_T1_GPIO]")
{
edge_intr_times = 0;
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
input_io.intr_type = GPIO_INTR_POSEDGE;
input_io.mode = GPIO_MODE_INPUT;
input_io.pull_up_en = 1;
TEST_ESP_OK(gpio_config(&output_io));
TEST_ESP_OK(gpio_config(&input_io));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 0));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
int level = 0;
gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_ANYEDGE);
gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_ANYEDGE);
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_edge_handler, (void*) GPIO_INPUT_IO);
gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_edge_handler, (void*) TEST_GPIO_EXT_IN_IO);
// for rising edge in GPIO_INTR_ANYEDGE
while(1) {
level = level + 1;
gpio_set_level(GPIO_OUTPUT_IO, level*0.2);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, level*0.2);
if(level > 10) {
break;
}
@ -261,7 +258,7 @@ TEST_CASE("GPIO both rising and falling edge interrupt test", "[gpio][test_env=U
// for falling rdge in GPIO_INTR_ANYEDGE
while(1) {
level = level - 1;
gpio_set_level(GPIO_OUTPUT_IO, level/5);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, level/5);
if(level < 0) {
break;
}
@ -270,29 +267,29 @@ TEST_CASE("GPIO both rising and falling edge interrupt test", "[gpio][test_env=U
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT(edge_intr_times, 2);
vTaskDelay(100 / portTICK_RATE_MS);
gpio_isr_handler_remove(GPIO_INPUT_IO);
gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
gpio_uninstall_isr_service();
}
TEST_CASE("GPIO input high level trigger, cut the interrupt source exit interrupt test", "[gpio][test_env=UT_T1_GPIO]")
{
level_intr_times=0;
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
input_io.intr_type = GPIO_INTR_POSEDGE;
input_io.mode = GPIO_MODE_INPUT;
input_io.pull_up_en = 1;
TEST_ESP_OK(gpio_config(&output_io));
TEST_ESP_OK(gpio_config(&input_io));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 0));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_HIGH_LEVEL);
gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_HIGH_LEVEL);
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_level_handler2, (void*) GPIO_INPUT_IO);
gpio_set_level(GPIO_OUTPUT_IO, 1);
gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler2, (void*) TEST_GPIO_EXT_IN_IO);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT_MESSAGE(level_intr_times, 1, "go into high-level interrupt more than once with cur interrupt source way");
gpio_isr_handler_remove(GPIO_INPUT_IO);
gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
gpio_uninstall_isr_service();
}
@ -300,80 +297,80 @@ TEST_CASE("GPIO input high level trigger, cut the interrupt source exit interrup
TEST_CASE("GPIO low level interrupt test", "[gpio][test_env=UT_T1_GPIO]")
{
disable_intr_times=0;
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
input_io.intr_type = GPIO_INTR_POSEDGE;
input_io.mode = GPIO_MODE_INPUT;
input_io.pull_up_en = 1;
TEST_ESP_OK(gpio_config(&output_io));
TEST_ESP_OK(gpio_config(&input_io));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 1));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_LOW_LEVEL);
gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_LOW_LEVEL);
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_level_handler, (void*) GPIO_INPUT_IO);
gpio_set_level(GPIO_OUTPUT_IO, 0);
printf("get level:%d\n",gpio_get_level(GPIO_INPUT_IO));
gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler, (void*) TEST_GPIO_EXT_IN_IO);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
printf("get level:%d\n",gpio_get_level(TEST_GPIO_EXT_IN_IO));
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT_MESSAGE(disable_intr_times, 1, "go into low-level interrupt more than once with disable way");
gpio_isr_handler_remove(GPIO_INPUT_IO);
gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
gpio_uninstall_isr_service();
}
TEST_CASE("GPIO multi-level interrupt test, to cut the interrupt source exit interrupt ", "[gpio][test_env=UT_T1_GPIO]")
{
level_intr_times=0;
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
input_io.intr_type = GPIO_INTR_POSEDGE;
input_io.mode = GPIO_MODE_INPUT;
input_io.pull_up_en = 1;
TEST_ESP_OK(gpio_config(&output_io));
TEST_ESP_OK(gpio_config(&input_io));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 0));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_HIGH_LEVEL);
gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_HIGH_LEVEL);
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_level_handler2, (void*) GPIO_INPUT_IO);
gpio_set_level(GPIO_OUTPUT_IO, 1);
gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler2, (void*) TEST_GPIO_EXT_IN_IO);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT_MESSAGE(level_intr_times, 1, "go into high-level interrupt more than once with cur interrupt source way");
gpio_set_level(GPIO_OUTPUT_IO, 1);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
vTaskDelay(200 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT_MESSAGE(level_intr_times, 2, "go into high-level interrupt more than once with cur interrupt source way");
gpio_isr_handler_remove(GPIO_INPUT_IO);
gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO);
gpio_uninstall_isr_service();
}
TEST_CASE("GPIO enable and disable interrupt test", "[gpio][test_env=UT_T1_GPIO]")
{
disable_intr_times = 0;
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
input_io.intr_type = GPIO_INTR_POSEDGE;
input_io.mode = GPIO_MODE_INPUT;
input_io.pull_up_en = 1;
TEST_ESP_OK(gpio_config(&output_io));
TEST_ESP_OK(gpio_config(&input_io));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 0)); // Because of GPIO_INTR_HIGH_LEVEL interrupt, 0 must be set first
TEST_ESP_OK(gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_HIGH_LEVEL));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0)); // Because of GPIO_INTR_HIGH_LEVEL interrupt, 0 must be set first
TEST_ESP_OK(gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_HIGH_LEVEL));
TEST_ESP_OK(gpio_install_isr_service(0));
TEST_ESP_OK(gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_level_handler, (void*) GPIO_INPUT_IO));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 1));
TEST_ESP_OK(gpio_isr_handler_remove(GPIO_INPUT_IO));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 0));
TEST_ESP_OK(gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler, (void*) TEST_GPIO_EXT_IN_IO));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
TEST_ESP_OK(gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
TEST_ASSERT_EQUAL_INT_MESSAGE(disable_intr_times, 1, "go into high-level interrupt more than once with disable way");
// not install service now
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ESP_OK(gpio_intr_disable(GPIO_INPUT_IO));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 1));
TEST_ESP_OK(gpio_intr_disable(TEST_GPIO_EXT_IN_IO));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1));
TEST_ASSERT_EQUAL_INT_MESSAGE(disable_intr_times, 1, "disable interrupt does not work, still go into interrupt!");
gpio_uninstall_isr_service(); //uninstall the service
TEST_ASSERT(gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_level_handler, (void*) GPIO_INPUT_IO) == ESP_ERR_INVALID_STATE);
TEST_ASSERT(gpio_isr_handler_remove(GPIO_INPUT_IO) == ESP_ERR_INVALID_STATE);
TEST_ASSERT(gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_level_handler, (void*) TEST_GPIO_EXT_IN_IO) == ESP_ERR_INVALID_STATE);
TEST_ASSERT(gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO) == ESP_ERR_INVALID_STATE);
}
#endif //DISABLED_FOR_TARGETS(ESP32S2)
@ -384,37 +381,28 @@ TEST_CASE("GPIO set gpio output level test", "[gpio][ignore]")
gpio_config_t io_conf;
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = (1<<GPIO_OUTPUT_IO);
io_conf.pin_bit_mask = (1<<TEST_GPIO_EXT_OUT_IO);
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0;
gpio_config(&io_conf);
io_conf.pin_bit_mask = (1<<GPIO_INPUT_IO);
io_conf.pin_bit_mask = (1<<TEST_GPIO_EXT_IN_IO);
io_conf.mode = GPIO_MODE_INPUT;
gpio_config(&io_conf);
gpio_set_level(GPIO_OUTPUT_IO, 0);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
// tested voltage is around 0v
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 0, "get level error! the level should be low!");
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "get level error! the level should be low!");
vTaskDelay(1000 / portTICK_RATE_MS);
gpio_set_level(GPIO_OUTPUT_IO, 1);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
// tested voltage is around 3.3v
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 1, "get level error! the level should be high!");
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 1, "get level error! the level should be high!");
#if CONFIG_IDF_TARGET_ESP32
//ESP32 IO34-39 are just used for input
io_conf.pin_bit_mask = ((uint64_t)1<<34);
//This IO is just used for input
io_conf.pin_bit_mask = ((uint64_t)1<<TEST_GPIO_INPUT_ONLY_PIN);
io_conf.mode = GPIO_MODE_OUTPUT;
gpio_config(&io_conf);
TEST_ASSERT(gpio_config(&io_conf) == ESP_ERR_INVALID_ARG);
#elif CONFIG_IDF_TARGET_ESP32S2
//ESP32-S2 IO46 are just used for input
io_conf.pin_bit_mask = ((uint64_t)1<<46);
io_conf.mode = GPIO_MODE_OUTPUT;
gpio_config(&io_conf);
TEST_ASSERT(gpio_config(&io_conf) == ESP_ERR_INVALID_ARG);
#endif
}
// gpio17 connects to 3.3v pin, gpio19 connects to the GND pin
@ -443,24 +431,24 @@ TEST_CASE("GPIO get input level test", "[gpio][ignore]")
TEST_CASE("GPIO io pull up/down function", "[gpio]")
{
// First, ensure that the output IO will not affect the level
gpio_config_t io_conf = init_io(GPIO_OUTPUT_IO);
gpio_config_t io_conf = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config(&io_conf);
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_INPUT);
io_conf = init_io(GPIO_INPUT_IO);
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT);
io_conf = init_io(TEST_GPIO_EXT_IN_IO);
gpio_config(&io_conf);
gpio_set_direction(GPIO_INPUT_IO, GPIO_MODE_INPUT);
TEST_ESP_OK(gpio_pullup_en(GPIO_INPUT_IO)); // pull up first
gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
TEST_ESP_OK(gpio_pullup_en(TEST_GPIO_EXT_IN_IO)); // pull up first
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 1, "gpio_pullup_en error, it can't pull up");
TEST_ESP_OK(gpio_pulldown_dis(GPIO_INPUT_IO)); //can't be pull down
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 1, "gpio_pullup_en error, it can't pull up");
TEST_ESP_OK(gpio_pulldown_dis(TEST_GPIO_EXT_IN_IO)); //can't be pull down
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 1, "gpio_pulldown_dis error, it can pull down");
TEST_ESP_OK(gpio_pulldown_en(GPIO_INPUT_IO)); // can be pull down now
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 1, "gpio_pulldown_dis error, it can pull down");
TEST_ESP_OK(gpio_pulldown_en(TEST_GPIO_EXT_IN_IO)); // can be pull down now
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 0, "gpio_pulldown_en error, it can't pull down");
TEST_ESP_OK(gpio_pullup_dis(GPIO_INPUT_IO)); // can't be pull up
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "gpio_pulldown_en error, it can't pull down");
TEST_ESP_OK(gpio_pullup_dis(TEST_GPIO_EXT_IN_IO)); // can't be pull up
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 0, "gpio_pullup_dis error, it can pull up");
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "gpio_pullup_dis error, it can pull up");
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
@ -468,71 +456,71 @@ TEST_CASE("GPIO io pull up/down function", "[gpio]")
TEST_CASE("GPIO output and input mode test", "[gpio][test_env=UT_T1_GPIO]")
{
//ESP32 connect io18 and io19, ESP32-S2 connect io18 and io21
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
gpio_config(&output_io);
gpio_config(&input_io);
int level = gpio_get_level(GPIO_INPUT_IO);
int level = gpio_get_level(TEST_GPIO_EXT_IN_IO);
//disable mode
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_DISABLE);
gpio_set_direction(GPIO_INPUT_IO, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_OUTPUT_IO, !level);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), level, "direction GPIO_MODE_DISABLE set error, it can output");
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_DISABLE);
gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_OUTPUT);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, !level);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), level, "direction GPIO_MODE_DISABLE set error, it can output");
//input mode and output mode
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_OUTPUT);
gpio_set_direction(GPIO_INPUT_IO, GPIO_MODE_INPUT);
gpio_set_level(GPIO_OUTPUT_IO, 1);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 1, "direction GPIO_MODE_OUTPUT set error, it can't output");
gpio_set_level(GPIO_OUTPUT_IO, 0);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT);
gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 1, "direction GPIO_MODE_OUTPUT set error, it can't output");
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
// open drain mode(output), can just output low level
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_OUTPUT_OD);
gpio_set_direction(GPIO_INPUT_IO, GPIO_MODE_INPUT);
gpio_set_level(GPIO_OUTPUT_IO, 1);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
gpio_set_level(GPIO_OUTPUT_IO, 0);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT_OD);
gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
// open drain mode(output and input), can just output low level
// output test
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_INPUT_OUTPUT_OD);
gpio_set_direction(GPIO_INPUT_IO, GPIO_MODE_INPUT);
gpio_set_level(GPIO_OUTPUT_IO, 1);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
gpio_set_level(GPIO_OUTPUT_IO, 0);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT_OD);
gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), 0, "direction GPIO_MODE_OUTPUT set error, it can't output");
// GPIO_MODE_INPUT_OUTPUT mode
// output test
level = gpio_get_level(GPIO_INPUT_IO);
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_INPUT_OUTPUT);
gpio_set_direction(GPIO_INPUT_IO, GPIO_MODE_INPUT);
gpio_set_level(GPIO_OUTPUT_IO, !level);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(GPIO_INPUT_IO), !level, "direction set error, it can't output");
level = gpio_get_level(TEST_GPIO_EXT_IN_IO);
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT);
gpio_set_direction(TEST_GPIO_EXT_IN_IO, GPIO_MODE_INPUT);
gpio_set_level(TEST_GPIO_EXT_OUT_IO, !level);
TEST_ASSERT_EQUAL_INT_MESSAGE(gpio_get_level(TEST_GPIO_EXT_IN_IO), !level, "direction set error, it can't output");
}
TEST_CASE("GPIO repeate call service and isr has no memory leak test","[gpio][test_env=UT_T1_GPIO][timeout=90]")
{
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
input_io.intr_type = GPIO_INTR_POSEDGE;
input_io.mode = GPIO_MODE_INPUT;
input_io.pull_up_en = 1;
TEST_ESP_OK(gpio_config(&output_io));
TEST_ESP_OK(gpio_config(&input_io));
TEST_ESP_OK(gpio_set_level(GPIO_OUTPUT_IO, 0));
TEST_ESP_OK(gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0));
//rising edge
uint32_t size = esp_get_free_heap_size();
for(int i=0;i<1000;i++) {
TEST_ESP_OK(gpio_set_intr_type(GPIO_INPUT_IO, GPIO_INTR_POSEDGE));
TEST_ESP_OK(gpio_set_intr_type(TEST_GPIO_EXT_IN_IO, GPIO_INTR_POSEDGE));
TEST_ESP_OK(gpio_install_isr_service(0));
TEST_ESP_OK(gpio_isr_handler_add(GPIO_INPUT_IO, gpio_isr_edge_handler, (void*)GPIO_INPUT_IO));
gpio_set_level(GPIO_OUTPUT_IO, 1);
TEST_ESP_OK(gpio_isr_handler_remove(GPIO_INPUT_IO));
gpio_set_level(GPIO_OUTPUT_IO, 0);
TEST_ESP_OK(gpio_isr_handler_add(TEST_GPIO_EXT_IN_IO, gpio_isr_edge_handler, (void*)TEST_GPIO_EXT_IN_IO));
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
TEST_ESP_OK(gpio_isr_handler_remove(TEST_GPIO_EXT_IN_IO));
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 0);
gpio_uninstall_isr_service();
}
TEST_ASSERT_INT32_WITHIN(size, esp_get_free_heap_size(), 100);
@ -549,8 +537,8 @@ TEST_CASE("GPIO wake up enable and disenable test", "[gpio][ignore]")
TEST_ASSERT_TRUE(wake_up_result);
wake_up_result = false;
TEST_ESP_OK(gpio_wakeup_disable(GPIO_INPUT_IO));
gpio_set_level(GPIO_OUTPUT_IO, 1);
TEST_ESP_OK(gpio_wakeup_disable(TEST_GPIO_EXT_IN_IO));
gpio_set_level(TEST_GPIO_EXT_OUT_IO, 1);
vTaskDelay(100 / portTICK_RATE_MS);
TEST_ASSERT_FALSE(wake_up_result);
}
@ -560,56 +548,56 @@ TEST_CASE("GPIO wake up enable and disenable test", "[gpio][ignore]")
// ignored because the voltage needs to be tested with multimeter
TEST_CASE("GPIO verify only the gpio with input ability can be set pull/down", "[gpio][ignore]")
{
gpio_config_t output_io = init_io(GPIO_OUTPUT_IO);
gpio_config_t input_io = init_io(GPIO_INPUT_IO);
gpio_config_t output_io = init_io(TEST_GPIO_EXT_OUT_IO);
gpio_config_t input_io = init_io(TEST_GPIO_EXT_IN_IO);
gpio_config(&output_io);
input_io.mode = GPIO_MODE_INPUT;
gpio_config(&input_io);
printf("pull up test!\n");
// pull up test
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_OUTPUT);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLUP_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
prompt_to_continue("mode: GPIO_MODE_OUTPUT");
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_OUTPUT_OD);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLUP_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT_OD);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
// open drain just can output low level
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_INPUT_OUTPUT_OD);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLUP_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT_OD);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
prompt_to_continue("mode: GPIO_MODE_OUTPUT_OD");
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_INPUT_OUTPUT);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLUP_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
prompt_to_continue("mode: GPIO_MODE_INPUT_OUTPUT");
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_INPUT);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLUP_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLUP_ONLY));
prompt_to_continue("mode: GPIO_MODE_INPUT");
// after pull up the level is high now
// pull down test
printf("pull down test!\n");
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_OUTPUT);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLDOWN_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
prompt_to_continue("mode: GPIO_MODE_OUTPUT");
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_OUTPUT_OD);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLDOWN_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_OUTPUT_OD);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
prompt_to_continue("mode: GPIO_MODE_OUTPUT_OD");
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_INPUT_OUTPUT_OD);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLDOWN_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT_OD);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
prompt_to_continue("mode: GPIO_MODE_INPUT_OUTPUT_OD");
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_INPUT_OUTPUT);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLDOWN_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT_OUTPUT);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
prompt_to_continue("mode: GPIO_MODE_INPUT_OUTPUT");
gpio_set_direction(GPIO_OUTPUT_IO, GPIO_MODE_INPUT);
TEST_ESP_OK(gpio_set_pull_mode(GPIO_OUTPUT_IO, GPIO_PULLDOWN_ONLY));
gpio_set_direction(TEST_GPIO_EXT_OUT_IO, GPIO_MODE_INPUT);
TEST_ESP_OK(gpio_set_pull_mode(TEST_GPIO_EXT_OUT_IO, GPIO_PULLDOWN_ONLY));
prompt_to_continue("mode: GPIO_MODE_INPUT");
}
@ -642,23 +630,23 @@ TEST_CASE("GPIO verify only the gpio with input ability can be set pull/down", "
TEST_CASE("GPIO drive capability test", "[gpio][ignore]")
{
printf("weak capability test! please view the current change!\n");
drive_capability_set_get(GPIO_OUTPUT_IO, GPIO_DRIVE_CAP_0);
drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_0);
prompt_to_continue("If this test finishes");
printf("stronger capability test! please view the current change!\n");
drive_capability_set_get(GPIO_OUTPUT_IO, GPIO_DRIVE_CAP_1);
drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_1);
prompt_to_continue("If this test finishes");
printf("default capability test! please view the current change!\n");
drive_capability_set_get(GPIO_OUTPUT_IO, GPIO_DRIVE_CAP_2);
drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_2);
prompt_to_continue("If this test finishes");
printf("default capability2 test! please view the current change!\n");
drive_capability_set_get(GPIO_OUTPUT_IO, GPIO_DRIVE_CAP_DEFAULT);
drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_DEFAULT);
prompt_to_continue("If this test finishes");
printf("strongest capability test! please view the current change!\n");
drive_capability_set_get(GPIO_OUTPUT_IO, GPIO_DRIVE_CAP_3);
drive_capability_set_get(TEST_GPIO_EXT_OUT_IO, GPIO_DRIVE_CAP_3);
prompt_to_continue("If this test finishes");
}

View file

@ -7,6 +7,8 @@ PROVIDE ( g_ticks_per_us_pro = g_ticks_per_us );
PROVIDE ( g_rom_flashchip = SPI_flashchip_data );
PROVIDE ( g_rom_spiflash_chip = SPI_flashchip_data );
PROVIDE ( esp_rom_spiflash_config_param = SPIParamCfg );
PROVIDE ( esp_rom_spiflash_read = SPIRead );
PROVIDE ( esp_rom_spiflash_read_status = SPI_read_status );
PROVIDE ( esp_rom_spiflash_read_statushigh = SPI_read_status_high );
PROVIDE ( esp_rom_spiflash_read_user_cmd = SPI_user_command_read );
PROVIDE ( esp_rom_spiflash_write = SPIWrite );

View file

@ -5,8 +5,6 @@ if(BOOTLOADER_BUILD)
# ESP32 Bootloader needs SPIUnlock from this file, but doesn't
# need other parts of this component
set(srcs "esp32/spi_flash_rom_patch.c")
elseif (CONFIG_IDF_TARGET_ESP32S2)
set(srcs "esp32s2/spi_flash_rom_patch.c")
else()
# but on other platforms no source files are needed for bootloader
set(srcs)
@ -24,9 +22,6 @@ else()
if (CONFIG_IDF_TARGET_ESP32)
list(APPEND srcs
"esp32/spi_flash_rom_patch.c")
elseif (CONFIG_IDF_TARGET_ESP32S2)
list(APPEND srcs
"esp32s2/spi_flash_rom_patch.c")
endif()
# New implementation after IDF v4.0

View file

@ -1,621 +0,0 @@
// Copyright 2015-2016 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.
#include "sdkconfig.h"
#include "esp32s2/rom/ets_sys.h"
#include "esp32s2/rom/gpio.h"
#include "esp32s2/rom/spi_flash.h"
#include "soc/spi_periph.h"
#define SPI_IDX 1
#define OTH_IDX 0
extern esp_rom_spiflash_chip_t g_rom_spiflash_chip;
esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi)
{
uint32_t status;
while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) {
}
while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) {
}
//wait for flash status ready
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_status(spi, &status)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
/* Modified version of esp_rom_spiflash_unlock() that replaces version in ROM.
This works around a bug where esp_rom_spiflash_unlock sometimes reads the wrong
high status byte (RDSR2 result) and then copies it back to the
flash status, which can cause the CMP bit or Status Register
Protect bit to become set.
Like other ROM SPI functions, this function is not designed to be
called directly from an RTOS environment without taking precautions
about interrupts, CPU coordination, flash mapping. However some of
the functions in esp_spi_flash.c call it.
*/
esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void)
{
uint32_t status;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
if (esp_rom_spiflash_read_statushigh(&g_rom_spiflash_chip, &status) != ESP_ROM_SPIFLASH_RESULT_OK) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
/* Clear all bits except QIE, if it is set.
(This is different from ROM esp_rom_spiflash_unlock, which keeps all bits as-is.)
*/
status &= ESP_ROM_SPIFLASH_QE;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
REG_WRITE(SPI_MEM_CMD_REG(SPI_IDX), SPI_MEM_FLASH_WREN);
while (REG_READ(SPI_MEM_CMD_REG(SPI_IDX)) != 0) {
}
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(SPI_IDX), SPI_MEM_WRSR_2B);
if (esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status) != ESP_ROM_SPIFLASH_RESULT_OK) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
#if CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
extern uint8_t g_rom_spiflash_dummy_len_plus[];
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi);
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip_internal(esp_rom_spiflash_chip_t *spi)
{
esp_rom_spiflash_wait_idle(spi);
// Chip erase.
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_CE);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
// check erase is finished.
esp_rom_spiflash_wait_idle(spi);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector_internal(esp_rom_spiflash_chip_t *spi, uint32_t addr)
{
//check if addr is 4k alignment
if (0 != (addr & 0xfff)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
esp_rom_spiflash_wait_idle(spi);
// sector erase 4Kbytes erase is sector erase.
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff);
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_SE);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
esp_rom_spiflash_wait_idle(spi);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_erase_block_internal(esp_rom_spiflash_chip_t *spi, uint32_t addr)
{
esp_rom_spiflash_wait_idle(spi);
// sector erase 4Kbytes erase is sector erase.
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr & 0xffffff);
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_BE);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
esp_rom_spiflash_wait_idle(spi);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_program_page_internal(esp_rom_spiflash_chip_t *spi, uint32_t spi_addr,
uint32_t *addr_source, int32_t byte_length)
{
uint32_t temp_addr;
int32_t temp_bl;
uint8_t i;
uint8_t remain_word_num;
//check 4byte alignment
if (0 != (byte_length & 0x3)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//check if write in one page
if ((spi->page_size) < ((spi_addr % (spi->page_size)) + byte_length)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
esp_rom_spiflash_wait_idle(spi);
temp_addr = spi_addr;
temp_bl = byte_length;
while (temp_bl > 0 ) {
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(spi)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if ( temp_bl >= ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM ) {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, (temp_addr & 0xffffff) | ( ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM << ESP_ROM_SPIFLASH_BYTES_LEN )); // 32 byte a block
for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM >> 2); i++) {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4, *addr_source++);
}
temp_bl = temp_bl - 32;
temp_addr = temp_addr + 32;
} else {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, (temp_addr & 0xffffff) | (temp_bl << ESP_ROM_SPIFLASH_BYTES_LEN ));
remain_word_num = (0 == (temp_bl & 0x3)) ? (temp_bl >> 2) : (temp_bl >> 2) + 1;
for (i = 0; i < remain_word_num; i++) {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4, *addr_source++);
temp_bl = temp_bl - 4;
}
temp_bl = 0;
}
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_PP);
while ( READ_PERI_REG(PERIPHS_SPI_FLASH_CMD ) != 0 );
esp_rom_spiflash_wait_idle(spi);
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t *spi, uint32_t *status)
{
uint32_t status_value = ESP_ROM_SPIFLASH_BUSY_FLAG;
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) {
WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, 0); // clear regisrter
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_RDSR);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
status_value = READ_PERI_REG(PERIPHS_SPI_FLASH_STATUS) & (spi->status_mask);
}
} else {
while (ESP_ROM_SPIFLASH_BUSY_FLAG == (status_value & ESP_ROM_SPIFLASH_BUSY_FLAG)) {
esp_rom_spiflash_read_user_cmd(&status_value, 0x05);
}
}
*status = status_value;
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_read_statushigh(esp_rom_spiflash_chip_t *spi, uint32_t *status)
{
esp_rom_spiflash_result_t ret;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
ret = esp_rom_spiflash_read_user_cmd(status, 0x35);
*status = *status << 8;
return ret;
}
esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t *spi, uint32_t status_value)
{
esp_rom_spiflash_wait_idle(spi);
// update status value by status_value
WRITE_PERI_REG(PERIPHS_SPI_FLASH_STATUS, status_value); // write status regisrter
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WRSR);
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
esp_rom_spiflash_wait_idle(spi);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
//only support spi1
static esp_rom_spiflash_result_t esp_rom_spiflash_read_data(esp_rom_spiflash_chip_t *spi, uint32_t flash_addr,
uint32_t *addr_dest, int32_t byte_length)
{
uint32_t temp_addr;
int32_t temp_length;
uint8_t i;
uint8_t remain_word_num;
//address range check
if ((flash_addr + byte_length) > (spi->chip_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
temp_addr = flash_addr;
temp_length = byte_length;
while (temp_length > 0) {
if (temp_length >= ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM) {
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << ESP_ROM_SPIFLASH_BYTES_LEN));
REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S);
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR);
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
for (i = 0; i < (ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM >> 2); i++) {
*addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4);
}
temp_length = temp_length - ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
temp_addr = temp_addr + ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM;
} else {
//WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr |(temp_length << ESP_ROM_SPIFLASH_BYTES_LEN ));
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, temp_addr);
REG_WRITE(SPI_MEM_MISO_DLEN_REG(1), ((ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM << 3) - 1) << SPI_MEM_USR_MISO_DBITLEN_S);
REG_WRITE(PERIPHS_SPI_FLASH_CMD, SPI_MEM_USR);
while (REG_READ(PERIPHS_SPI_FLASH_CMD) != 0);
remain_word_num = (0 == (temp_length & 0x3)) ? (temp_length >> 2) : (temp_length >> 2) + 1;
for (i = 0; i < remain_word_num; i++) {
*addr_dest++ = READ_PERI_REG(PERIPHS_SPI_FLASH_C0 + i * 4);
}
temp_length = 0;
}
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
static esp_rom_spiflash_result_t esp_rom_spiflash_enable_write(esp_rom_spiflash_chip_t *spi)
{
uint32_t flash_status = 0;
esp_rom_spiflash_wait_idle(spi);
//enable write
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_MEM_FLASH_WREN); // enable write operation
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0);
// make sure the flash is ready for writing
while (ESP_ROM_SPIFLASH_WRENABLE_FLAG != (flash_status & ESP_ROM_SPIFLASH_WRENABLE_FLAG)) {
esp_rom_spiflash_read_status(spi, &flash_status);
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
static void spi_cache_mode_switch(uint32_t modebit)
{
if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_QIO_ADDR_BITSLEN);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xEB);
} else if (modebit & SPI_MEM_FASTRD_MODE) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_FAST_ADDR_BITSLEN);
if ((modebit & SPI_MEM_FREAD_QUAD)) {
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x6B);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
} else if ((modebit & SPI_MEM_FREAD_DIO)) {
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_DIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0xBB);
} else if ((modebit & SPI_MEM_FREAD_DUAL)) {
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x3B);
} else {
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, SPI0_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[0]);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x0B);
}
} else {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MOSI);
if (g_rom_spiflash_dummy_len_plus[0] == 0) {
REG_CLR_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
} else {
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_DUMMY);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[0] - 1);
}
REG_SET_BIT(SPI_MEM_USER_REG(0), SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
REG_SET_FIELD(SPI_MEM_USER1_REG(0), SPI_MEM_USR_ADDR_BITLEN, SPI0_R_SIO_ADDR_BITSLEN);
REG_SET_FIELD(SPI_MEM_USER2_REG(0), SPI_MEM_USR_COMMAND_VALUE, 0x03);
}
}
esp_rom_spiflash_result_t esp_rom_spiflash_lock(void)
{
uint32_t status;
//read QE bit, not write if not QE
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_statushigh(&g_rom_spiflash_chip, &status)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//enable 2 byte status writing
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN);
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_write_status(&g_rom_spiflash_chip, status | ESP_ROM_SPIFLASH_WR_PROTECT)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode)
{
uint32_t modebit;
while ((REG_READ(SPI_MEM_FSM_REG(1)) & SPI_MEM_ST)) {
}
while ((REG_READ(SPI_MEM_FSM_REG(0)) & SPI_MEM_ST)) {
}
//clear old mode bit
CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE);
CLEAR_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE);
//configure read mode
switch (mode) {
case ESP_ROM_SPIFLASH_QIO_MODE : modebit = SPI_MEM_FREAD_QIO | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_QOUT_MODE : modebit = SPI_MEM_FREAD_QUAD | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_DIO_MODE : modebit = SPI_MEM_FREAD_DIO | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_DOUT_MODE : modebit = SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_FASTRD_MODE: modebit = SPI_MEM_FASTRD_MODE; break;
case ESP_ROM_SPIFLASH_SLOWRD_MODE: modebit = 0; break;
default : modebit = 0;
}
SET_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, modebit);
SET_PERI_REG_MASK(SPI_MEM_CTRL_REG(0), modebit);
spi_cache_mode_switch(modebit);
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void)
{
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_chip_internal(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num)
{
// flash write is always 1 line currently
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
//check program size
if (block_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.block_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_block_internal(&g_rom_spiflash_chip, block_num * (g_rom_spiflash_chip.block_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num)
{
// flash write is always 1 line currently
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
//check program size
if (sector_num >= ((g_rom_spiflash_chip.chip_size) / (g_rom_spiflash_chip.sector_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_enable_write(&g_rom_spiflash_chip)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector_internal(&g_rom_spiflash_chip, sector_num * (g_rom_spiflash_chip.sector_size))) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t target, const uint32_t *src_addr, int32_t len)
{
uint32_t page_size;
uint32_t pgm_len, pgm_num;
uint8_t i;
// flash write is always 1 line currently
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
//check program size
if ( (target + len) > (g_rom_spiflash_chip.chip_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
page_size = g_rom_spiflash_chip.page_size;
pgm_len = page_size - (target % page_size);
if (len < pgm_len) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip,
target, (uint32_t *)src_addr, len)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
} else {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip,
target, (uint32_t *)src_addr, pgm_len)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//whole page program
pgm_num = (len - pgm_len) / page_size;
for (i = 0; i < pgm_num; i++) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip,
target + pgm_len, (uint32_t *)src_addr + (pgm_len >> 2), page_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
pgm_len += page_size;
}
//remain parts to program
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_program_page_internal(&g_rom_spiflash_chip,
target + pgm_len, (uint32_t *)src_addr + (pgm_len >> 2), len - pgm_len)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t target, uint32_t *dest_addr, int32_t len)
{
// QIO or SIO, non-QIO regard as SIO
uint32_t modebit;
esp_rom_spiflash_wait_idle(&g_rom_spiflash_chip);
modebit = READ_PERI_REG(PERIPHS_SPI_FLASH_CTRL);
if ((modebit & SPI_MEM_FREAD_QIO) && (modebit & SPI_MEM_FASTRD_MODE)) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_DUMMY | SPI_MEM_USR_ADDR);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_QIO_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_QIO_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
//REG_SET_FIELD(PERIPHS_SPI_SPI_MEM_H_USRREG2, SPI_USR_COMMAND_VALUE, 0xEB);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xEB);
} else if (modebit & SPI_MEM_FASTRD_MODE) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
if (modebit & SPI_MEM_FREAD_DIO) {
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0xBB);
} else {
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_DIO_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG2, SPI_MEM_USR_COMMAND_VALUE, 0xBB);
}
} else {
if ((modebit & SPI_MEM_FREAD_QUAD)) {
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x6B);
} else if ((modebit & SPI_MEM_FREAD_DUAL)) {
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x3B);
} else {
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x0B);
}
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_FAST_ADDR_BITSLEN);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, SPI1_R_FAST_DUMMY_CYCLELEN + g_rom_spiflash_dummy_len_plus[1]);
}
} else {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MOSI);
if (g_rom_spiflash_dummy_len_plus[1] == 0) {
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
} else {
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_DUMMY);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_DUMMY_CYCLELEN, g_rom_spiflash_dummy_len_plus[1] - 1);
}
REG_SET_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_MEM_USR_MISO | SPI_MEM_USR_ADDR);
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_MEM_USR_ADDR_BITLEN, SPI1_R_SIO_ADDR_BITSLEN);
REG_WRITE(PERIPHS_SPI_FLASH_USRREG2, (0x7 << SPI_MEM_USR_COMMAND_BITLEN_S) | 0x03);
}
if ( ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_read_data(&g_rom_spiflash_chip, target, dest_addr, len)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
esp_rom_spiflash_result_t esp_rom_spiflash_erase_area(uint32_t start_addr, uint32_t area_len)
{
int32_t total_sector_num;
int32_t head_sector_num;
uint32_t sector_no;
uint32_t sector_num_per_block;
//set read mode to Fastmode ,not QDIO mode for erase
//
// TODO: this is probably a bug as it doesn't re-enable QIO mode, not serious as this
// function is not used in IDF.
esp_rom_spiflash_config_readmode(ESP_ROM_SPIFLASH_SLOWRD_MODE);
//check if area is oversize of flash
if ((start_addr + area_len) > g_rom_spiflash_chip.chip_size) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//start_addr is aligned as sector boundary
if (0 != (start_addr % g_rom_spiflash_chip.sector_size)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
//Unlock flash to enable erase
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_unlock(/*&g_rom_spiflash_chip*/)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
sector_no = start_addr / g_rom_spiflash_chip.sector_size;
sector_num_per_block = g_rom_spiflash_chip.block_size / g_rom_spiflash_chip.sector_size;
total_sector_num = (0 == (area_len % g_rom_spiflash_chip.sector_size)) ? area_len / g_rom_spiflash_chip.sector_size :
1 + (area_len / g_rom_spiflash_chip.sector_size);
//check if erase area reach over block boundary
head_sector_num = sector_num_per_block - (sector_no % sector_num_per_block);
head_sector_num = (head_sector_num >= total_sector_num) ? total_sector_num : head_sector_num;
//JJJ, BUG of 6.0 erase
//middle part of area is aligned by blocks
total_sector_num -= head_sector_num;
//head part of area is erased
while (0 != head_sector_num) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector(sector_no)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
sector_no++;
head_sector_num--;
}
while (total_sector_num > sector_num_per_block) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_block(sector_no / sector_num_per_block)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
sector_no += sector_num_per_block;
total_sector_num -= sector_num_per_block;
}
//tail part of area burn
while (0 < total_sector_num) {
if (ESP_ROM_SPIFLASH_RESULT_OK != esp_rom_spiflash_erase_sector(sector_no)) {
return ESP_ROM_SPIFLASH_RESULT_ERR;
}
sector_no++;
total_sector_num--;
}
return ESP_ROM_SPIFLASH_RESULT_OK;
}
#endif

View file

@ -77,6 +77,7 @@ typedef void (*flash_test_func_t)(esp_flash_t* chip);
// These tests needs external flash, right on the place of psram
#define FLASH_TEST_CASE_3(STR, FUNCT_TO_RUN)
#else
// Disabled for ESP32-S2 due to lack of runners
#define FLASH_TEST_CASE_3(STR, FUNC_TO_RUN) \
TEST_CASE(STR", 3 chips", "[esp_flash][test_env=UT_T1_ESP_FLASH]") {flash_test_func(FUNC_TO_RUN, ALL_TEST_NUM);}
#endif
@ -610,6 +611,7 @@ TEST_CASE("SPI flash test reading with all speed/mode permutations", "[esp_flash
#ifndef CONFIG_SPIRAM_SUPPORT
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
// No runners
TEST_CASE("SPI flash test reading with all speed/mode permutations, 3 chips", "[esp_flash][test_env=UT_T1_ESP_FLASH]")
{
for (int i = 0; i < ALL_TEST_NUM; i++) {

View file

@ -29,7 +29,6 @@
#include "../cache_utils.h"
#include "soc/timer_periph.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
static const uint8_t large_const_buffer[16400] = {
203, // first byte
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
@ -94,4 +93,3 @@ static void test_write_large_buffer(const uint8_t *source, size_t length)
TEST_ASSERT_EQUAL_HEX8(0xFF, ends[2]);
TEST_ASSERT_EQUAL_HEX8(0xFF, ends[3]);
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)

View file

@ -349,7 +349,6 @@ TEST_CASE("flash_mmap can mmap after get enough free MMU pages", "[spi_flash][mm
TEST_ASSERT_EQUAL_PTR(NULL, spi_flash_phys2cache(start, SPI_FLASH_MMAP_DATA));
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]")
{
uint8_t buf[64];
@ -382,7 +381,6 @@ TEST_CASE("phys2cache/cache2phys basic checks", "[spi_flash][mmap]")
spi_flash_read_maybe_encrypted(phys, buf, sizeof(constant_data));
TEST_ASSERT_EQUAL_HEX8_ARRAY(constant_data, buf, sizeof(constant_data));
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
TEST_CASE("mmap consistent with phys2cache/cache2phys", "[spi_flash][mmap]")
{

View file

@ -2,7 +2,6 @@
#include "esp_partition.h"
#include "unity.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
TEST_CASE("Basic handling of a partition in external flash", "[partition]")
{
esp_flash_t flash = {
@ -44,5 +43,4 @@ TEST_CASE("Basic handling of a partition in external flash", "[partition]")
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_partition_register_external(&flash, SPI_FLASH_SEC_SIZE, 2 * SPI_FLASH_SEC_SIZE,
"p2", t, st, NULL));
TEST_ESP_OK(esp_partition_deregister_external(ext_partition));
}
#endif
}

View file

@ -27,7 +27,6 @@
#include <esp_partition.h>
#include <esp_attr.h>
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
TEST_CASE("Test erase partition", "[spi_flash][esp_flash]")
{
const esp_partition_t *part = get_test_data_partition();
@ -69,7 +68,6 @@ TEST_CASE("Test erase partition", "[spi_flash][esp_flash]")
}
}
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
static bool s_test_nonzero_sha_of_partition(const esp_partition_t *part, bool allow_invalid_image)
{
@ -104,7 +102,6 @@ TEST_CASE("Test esp_partition_get_sha256() with data", "[spi_flash]")
s_test_nonzero_sha_of_partition(part, false);
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
TEST_CASE("Test esp_partition_get_sha256() with app", "[spi_flash]")
{
bool found_valid_app = false;
@ -124,5 +121,4 @@ TEST_CASE("Test esp_partition_get_sha256() with app", "[spi_flash]")
TEST_ASSERT_MESSAGE(found_valid_app, "At least one app partition should be a valid app partition");
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)

View file

@ -31,7 +31,6 @@
#define MIN_BLOCK_SIZE 12
/* Base offset in flash for tests. */
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
static size_t start;
static void setup_tests(void)
@ -140,9 +139,7 @@ TEST_CASE("Test spi_flash_read", "[spi_flash][esp_flash]")
}
#endif
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
static void IRAM_ATTR test_write(int dst_off, int src_off, int len)
{
char src_buf[64], dst_gold[64];
@ -243,7 +240,6 @@ TEST_CASE("Test spi_flash_write", "[spi_flash][esp_flash]")
ESP_ERROR_CHECK(spi_flash_write(start, (char *) 0x40080000, 16));
#endif
}
#endif
#ifdef CONFIG_SPIRAM

View file

@ -509,7 +509,7 @@ UT_034:
UT_035:
extends: .unit_test_s2_template
parallel: 26
parallel: 27
tags:
- ESP32S2_IDF
- UT_T1_1