test_ulp.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <freertos/FreeRTOS.h>
  17. #include <freertos/task.h>
  18. #include <freertos/semphr.h>
  19. #include <unity.h>
  20. #include "esp_attr.h"
  21. #include "esp_err.h"
  22. #include "esp_log.h"
  23. #include "esp_deep_sleep.h"
  24. #include "esp32/ulp.h"
  25. #include "soc/soc.h"
  26. #include "soc/rtc_cntl_reg.h"
  27. #include "soc/sens_reg.h"
  28. #include "driver/rtc_io.h"
  29. #include "sdkconfig.h"
  30. static void hexdump(const uint32_t* src, size_t count) {
  31. for (size_t i = 0; i < count; ++i) {
  32. printf("%08x ", *src);
  33. ++src;
  34. if ((i + 1) % 4 == 0) {
  35. printf("\n");
  36. }
  37. }
  38. }
  39. TEST_CASE("ulp add test", "[ulp]")
  40. {
  41. memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM);
  42. const ulp_insn_t program[] = {
  43. I_MOVI(R3, 16),
  44. I_LD(R0, R3, 0),
  45. I_LD(R1, R3, 1),
  46. I_ADDR(R2, R0, R1),
  47. I_ST(R2, R3, 2),
  48. I_HALT()
  49. };
  50. RTC_SLOW_MEM[16] = 10;
  51. RTC_SLOW_MEM[17] = 11;
  52. size_t size = sizeof(program)/sizeof(ulp_insn_t);
  53. TEST_ASSERT_EQUAL(ESP_OK, ulp_process_macros_and_load(0, program, &size));
  54. TEST_ASSERT_EQUAL(ESP_OK, ulp_run(0));
  55. ets_delay_us(1000);
  56. hexdump(RTC_SLOW_MEM, CONFIG_ULP_COPROC_RESERVE_MEM / 4);
  57. TEST_ASSERT_EQUAL(10 + 11, RTC_SLOW_MEM[18] & 0xffff);
  58. }
  59. TEST_CASE("ulp branch test", "[ulp]")
  60. {
  61. assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig");
  62. memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM);
  63. const ulp_insn_t program[] = {
  64. I_MOVI(R0, 34), // r0 = dst
  65. M_LABEL(1),
  66. I_MOVI(R1, 32),
  67. I_LD(R1, R1, 0), // r1 = mem[33]
  68. I_MOVI(R2, 33),
  69. I_LD(R2, R2, 0), // r2 = mem[34]
  70. I_SUBR(R3, R1, R2), // r3 = r1 - r2
  71. I_ST(R3, R0, 0), // dst[0] = r3
  72. I_ADDI(R0, R0, 1),
  73. M_BL(1, 64),
  74. I_HALT(),
  75. };
  76. RTC_SLOW_MEM[32] = 42;
  77. RTC_SLOW_MEM[33] = 18;
  78. hexdump(RTC_SLOW_MEM, CONFIG_ULP_COPROC_RESERVE_MEM / 4);
  79. size_t size = sizeof(program)/sizeof(ulp_insn_t);
  80. ulp_process_macros_and_load(0, program, &size);
  81. ulp_run(0);
  82. printf("\n\n");
  83. hexdump(RTC_SLOW_MEM, CONFIG_ULP_COPROC_RESERVE_MEM / 4);
  84. for (int i = 34; i < 64; ++i) {
  85. TEST_ASSERT_EQUAL(42 - 18, RTC_SLOW_MEM[i] & 0xffff);
  86. }
  87. TEST_ASSERT_EQUAL(0, RTC_SLOW_MEM[64]);
  88. }
  89. TEST_CASE("ulp wakeup test", "[ulp]")
  90. {
  91. assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig");
  92. memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM);
  93. const ulp_insn_t program[] = {
  94. I_MOVI(R1, 1024),
  95. M_LABEL(1),
  96. I_DELAY(32000),
  97. I_SUBI(R1, R1, 1),
  98. M_BXZ(3),
  99. I_RSHI(R3, R1, 5), // R3 = R1 / 32
  100. I_ST(R1, R3, 16),
  101. M_BX(1),
  102. M_LABEL(3),
  103. I_MOVI(R2, 42),
  104. I_MOVI(R3, 15),
  105. I_ST(R2, R3, 0),
  106. I_END(1)
  107. };
  108. size_t size = sizeof(program)/sizeof(ulp_insn_t);
  109. ulp_process_macros_and_load(0, program, &size);
  110. ulp_run(0);
  111. esp_deep_sleep_enable_ulp_wakeup();
  112. esp_deep_sleep_start();
  113. }
  114. TEST_CASE("ulp controls RTC_IO", "[ulp]")
  115. {
  116. assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig");
  117. memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM);
  118. const ulp_insn_t program[] = {
  119. I_MOVI(R0, 0), // R0 is LED state
  120. I_MOVI(R2, 16), // loop R2 from 16 down to 0
  121. M_LABEL(4),
  122. I_SUBI(R2, R2, 1),
  123. M_BXZ(6),
  124. I_ADDI(R0, R0, 1), // R0 = (R0 + 1) % 2
  125. I_ANDI(R0, R0, 0x1),
  126. M_BL(0, 1), // if R0 < 1 goto 0
  127. M_LABEL(1),
  128. I_WR_REG(RTC_GPIO_OUT_REG, 26, 27, 1), // RTC_GPIO12 = 1
  129. M_BX(2), // goto 2
  130. M_LABEL(0), // 0:
  131. I_WR_REG(RTC_GPIO_OUT_REG, 26, 27, 0), // RTC_GPIO12 = 0
  132. M_LABEL(2), // 2:
  133. I_MOVI(R1, 100), // loop R1 from 100 down to 0
  134. M_LABEL(3),
  135. I_SUBI(R1, R1, 1),
  136. M_BXZ(5),
  137. I_DELAY(32000), // delay for a while
  138. M_BX(3),
  139. M_LABEL(5),
  140. M_BX(4),
  141. M_LABEL(6),
  142. I_END(1) // wake up the SoC
  143. };
  144. const gpio_num_t led_gpios[] = {
  145. GPIO_NUM_2,
  146. GPIO_NUM_0,
  147. GPIO_NUM_4
  148. };
  149. for (size_t i = 0; i < sizeof(led_gpios)/sizeof(led_gpios[0]); ++i) {
  150. rtc_gpio_init(led_gpios[i]);
  151. rtc_gpio_set_direction(led_gpios[i], RTC_GPIO_MODE_OUTPUT_ONLY);
  152. rtc_gpio_set_level(led_gpios[i], 0);
  153. }
  154. size_t size = sizeof(program)/sizeof(ulp_insn_t);
  155. ulp_process_macros_and_load(0, program, &size);
  156. ulp_run(0);
  157. esp_deep_sleep_enable_ulp_wakeup();
  158. esp_deep_sleep_start();
  159. }