README.rst 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. Programming ULP FSM coprocessor using C macros (legacy)
  2. =======================================================
  3. In addition to the existing binutils port for the {IDF_TARGET_NAME} ULP coprocessor, it is possible to generate programs for the ULP by embedding assembly-like macros into an {IDF_TARGET_NAME} application. Here is an example how this can be done::
  4. const ulp_insn_t program[] = {
  5. I_MOVI(R3, 16), // R3 <- 16
  6. I_LD(R0, R3, 0), // R0 <- RTC_SLOW_MEM[R3 + 0]
  7. I_LD(R1, R3, 1), // R1 <- RTC_SLOW_MEM[R3 + 1]
  8. I_ADDR(R2, R0, R1), // R2 <- R0 + R1
  9. I_ST(R2, R3, 2), // R2 -> RTC_SLOW_MEM[R2 + 2]
  10. I_HALT()
  11. };
  12. size_t load_addr = 0;
  13. size_t size = sizeof(program)/sizeof(ulp_insn_t);
  14. ulp_process_macros_and_load(load_addr, program, &size);
  15. ulp_run(load_addr);
  16. The ``program`` array is an array of ``ulp_insn_t``, i.e. ULP coprocessor instructions. Each ``I_XXX`` preprocessor define translates into a single 32-bit instruction. Arguments of these preprocessor defines can be register numbers (``R0 — R3``) and literal constants. See `ULP coprocessor instruction defines`_ section for descriptions of instructions and arguments they take.
  17. .. note::
  18. Because some of the instruction macros expand to inline function calls, defining such array in global scope will cause the compiler to produce an "initializer element is not constant" error. To fix this error, move the definition of instructions array into local scope.
  19. Load and store instructions use addresses expressed in 32-bit words. Address 0 corresponds to the first word of ``RTC_SLOW_MEM`` (which is address 0x50000000 as seen by the main CPUs).
  20. To generate branch instructions, special ``M_`` preprocessor defines are used. ``M_LABEL`` define can be used to define a branch target. Label identifier is a 16-bit integer. ``M_Bxxx`` defines can be used to generate branch instructions with target set to a particular label.
  21. Implementation note: these ``M_`` preprocessor defines will be translated into two ``ulp_insn_t`` values: one is a token value which contains label number, and the other is the actual instruction. ``ulp_process_macros_and_load`` function resolves the label number to the address, modifies the branch instruction to use the correct address, and removes the the extra ``ulp_insn_t`` token which contains the label numer.
  22. Here is an example of using labels and branches::
  23. const ulp_insn_t program[] = {
  24. I_MOVI(R0, 34), // R0 <- 34
  25. M_LABEL(1), // label_1
  26. I_MOVI(R1, 32), // R1 <- 32
  27. I_LD(R1, R1, 0), // R1 <- RTC_SLOW_MEM[R1]
  28. I_MOVI(R2, 33), // R2 <- 33
  29. I_LD(R2, R2, 0), // R2 <- RTC_SLOW_MEM[R2]
  30. I_SUBR(R3, R1, R2), // R3 <- R1 - R2
  31. I_ST(R3, R0, 0), // R3 -> RTC_SLOW_MEM[R0 + 0]
  32. I_ADDI(R0, R0, 1), // R0++
  33. M_BL(1, 64), // if (R0 < 64) goto label_1
  34. I_HALT(),
  35. };
  36. RTC_SLOW_MEM[32] = 42;
  37. RTC_SLOW_MEM[33] = 18;
  38. size_t load_addr = 0;
  39. size_t size = sizeof(program)/sizeof(ulp_insn_t);
  40. ulp_process_macros_and_load(load_addr, program, &size);
  41. ulp_run(load_addr);
  42. Application Example
  43. -------------------
  44. Demonstration of entering into deep sleep mode and waking up using several wake up sources: :example:`system/deep_sleep`.
  45. API Reference
  46. -------------
  47. Header File
  48. ^^^^^^^^^^^
  49. .. list::
  50. :esp32: - :component_file:`ulp/ulp_fsm/include/esp32/ulp.h`
  51. :esp32s2: - :component_file:`ulp/ulp_fsm/include/esp32s2/ulp.h`
  52. :esp32s3: - :component_file:`ulp/ulp_fsm/include/esp32s3/ulp.h`
  53. Functions
  54. ^^^^^^^^^
  55. .. doxygenfunction:: ulp_process_macros_and_load
  56. .. doxygenfunction:: ulp_run
  57. Error codes
  58. ^^^^^^^^^^^
  59. .. doxygendefine:: ESP_ERR_ULP_BASE
  60. .. doxygendefine:: ESP_ERR_ULP_SIZE_TOO_BIG
  61. .. doxygendefine:: ESP_ERR_ULP_INVALID_LOAD_ADDR
  62. .. doxygendefine:: ESP_ERR_ULP_DUPLICATE_LABEL
  63. .. doxygendefine:: ESP_ERR_ULP_UNDEFINED_LABEL
  64. .. doxygendefine:: ESP_ERR_ULP_BRANCH_OUT_OF_RANGE
  65. ULP coprocessor registers
  66. ^^^^^^^^^^^^^^^^^^^^^^^^^
  67. ULP co-processor has 4 16-bit general purpose registers. All registers have same functionality, with one exception. R0 register is used by some of the compare-and-branch instructions as a source register.
  68. These definitions can be used for all instructions which require a register.
  69. .. doxygengroup:: ulp_registers
  70. :content-only:
  71. ULP coprocessor instruction defines
  72. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  73. .. doxygendefine:: I_DELAY
  74. .. doxygendefine:: I_HALT
  75. .. doxygendefine:: I_END
  76. .. doxygendefine:: I_ST
  77. .. only:: esp32s2 or esp32s3
  78. .. doxygendefine:: I_ST_MANUAL
  79. .. doxygendefine:: I_STL
  80. .. doxygendefine:: I_STH
  81. .. doxygendefine:: I_ST32
  82. .. doxygendefine:: I_STL_LABEL
  83. .. doxygendefine:: I_STH_LABEL
  84. .. doxygendefine:: I_ST_AUTO
  85. .. doxygendefine:: I_STO
  86. .. doxygendefine:: I_STI
  87. .. doxygendefine:: I_STI_LABEL
  88. .. doxygendefine:: I_STI32
  89. .. doxygendefine:: I_LD
  90. .. only:: esp32s2 or esp32s3
  91. .. doxygendefine:: I_LD_MANUAL
  92. .. doxygendefine:: I_LDL
  93. .. doxygendefine:: I_LDH
  94. .. doxygendefine:: I_WR_REG
  95. .. doxygendefine:: I_RD_REG
  96. .. doxygendefine:: I_BL
  97. .. only:: esp32
  98. .. doxygendefine:: I_BGE
  99. .. only:: esp32s2 or esp32s3
  100. .. doxygendefine:: I_BG
  101. .. doxygendefine:: I_BE
  102. .. doxygendefine:: I_BXR
  103. .. doxygendefine:: I_BXI
  104. .. doxygendefine:: I_BXZR
  105. .. doxygendefine:: I_BXZI
  106. .. doxygendefine:: I_BXFR
  107. .. doxygendefine:: I_BXFI
  108. .. doxygendefine:: I_ADDR
  109. .. doxygendefine:: I_SUBR
  110. .. doxygendefine:: I_ANDR
  111. .. doxygendefine:: I_ORR
  112. .. doxygendefine:: I_MOVR
  113. .. doxygendefine:: I_LSHR
  114. .. doxygendefine:: I_RSHR
  115. .. doxygendefine:: I_ADDI
  116. .. doxygendefine:: I_SUBI
  117. .. doxygendefine:: I_ANDI
  118. .. doxygendefine:: I_ORI
  119. .. doxygendefine:: I_MOVI
  120. .. doxygendefine:: I_LSHI
  121. .. doxygendefine:: I_RSHI
  122. .. doxygendefine:: M_LABEL
  123. .. doxygendefine:: M_BL
  124. .. only:: esp32
  125. .. doxygendefine:: M_BGE
  126. .. only:: esp32s2 or esp32s3
  127. .. doxygendefine:: M_BG
  128. .. doxygendefine:: M_BE
  129. .. doxygendefine:: M_BX
  130. .. doxygendefine:: M_BXZ
  131. .. doxygendefine:: M_BXF
  132. Defines
  133. ^^^^^^^
  134. .. doxygendefine:: RTC_SLOW_MEM