ulp_riscv.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #include <stdint.h>
  8. #include <stddef.h>
  9. #include <stdlib.h>
  10. #include "esp_err.h"
  11. #include "ulp_common.h"
  12. #include "esp_intr_alloc.h"
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. typedef enum {
  17. ULP_RISCV_WAKEUP_SOURCE_TIMER,
  18. ULP_RISCV_WAKEUP_SOURCE_GPIO,
  19. } ulp_riscv_wakeup_source_t;
  20. /**
  21. * @brief ULP riscv init parameters
  22. *
  23. */
  24. typedef struct {
  25. ulp_riscv_wakeup_source_t wakeup_source; /*!< ULP wakeup source */
  26. } ulp_riscv_cfg_t;
  27. #define ULP_RISCV_DEFAULT_CONFIG() \
  28. { \
  29. .wakeup_source = ULP_RISCV_WAKEUP_SOURCE_TIMER, \
  30. }
  31. /* ULP RISC-V interrupt signals for the main CPU */
  32. #if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
  33. #define ULP_RISCV_SW_INT (BIT(13)) // Corresponds to RTC_CNTL_COCPU_INT_ST_M interrupt status bit
  34. #define ULP_RISCV_TRAP_INT (BIT(17)) // Corresponds to RTC_CNTL_COCPU_TRAP_INT_ST_M interrupt status bit
  35. #else
  36. #error "ULP_RISCV_SW_INT and ULP_RISCV_TRAP_INT are undefined. Please check soc/rtc_cntl_reg.h for the correct bitmap on your target SoC."
  37. #endif /* (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3) */
  38. /**
  39. * @brief Register ULP signal ISR
  40. *
  41. * @note The ISR routine will only be active if the main CPU is not in deepsleep
  42. *
  43. * @param fn ISR callback function
  44. * @param arg ISR callback function arguments
  45. * @param mask Bit mask to enable the required ULP RISC-V interrupt signals
  46. * @return
  47. * - ESP_OK on success
  48. * - ESP_ERR_INVALID_ARG if callback function is NULL or if the interrupt bits are invalid
  49. * - ESP_ERR_NO_MEM if heap memory cannot be allocated for the interrupt
  50. * - other errors returned by esp_intr_alloc
  51. */
  52. esp_err_t ulp_riscv_isr_register(intr_handler_t fn, void *arg, uint32_t mask);
  53. /**
  54. * @brief Deregister ULP signal ISR
  55. *
  56. * @param fn ISR callback function
  57. * @param arg ISR callback function arguments
  58. * @param mask Bit mask to enable the required ULP RISC-V interrupt signals
  59. * @return
  60. * - ESP_OK on success
  61. * - ESP_ERR_INVALID_ARG if callback function is NULL or if the interrupt bits are invalid
  62. * - ESP_ERR_INVALID_STATE if a handler matching both callback function and its arguments isn't registered
  63. */
  64. esp_err_t ulp_riscv_isr_deregister(intr_handler_t fn, void *arg, uint32_t mask);
  65. /**
  66. * @brief Configure the ULP and run the program loaded into RTC memory
  67. *
  68. * @param cfg pointer to the config struct
  69. * @return ESP_OK on success
  70. */
  71. esp_err_t ulp_riscv_config_and_run(ulp_riscv_cfg_t* cfg);
  72. /**
  73. * @brief Configure the ULP with default settings
  74. * and run the program loaded into RTC memory
  75. *
  76. * @return ESP_OK on success
  77. */
  78. esp_err_t ulp_riscv_run(void);
  79. /**
  80. * @brief Load ULP-RISC-V program binary into RTC memory
  81. *
  82. * Different than ULP FSM, the binary program has no special format, it is the ELF
  83. * file generated by RISC-V toolchain converted to binary format using objcopy.
  84. *
  85. * Linker script in components/ulp/ld/ulp_riscv.ld produces ELF files which
  86. * correspond to this format. This linker script produces binaries with load_addr == 0.
  87. *
  88. * @param program_binary pointer to program binary
  89. * @param program_size_bytes size of the program binary
  90. * @return
  91. * - ESP_OK on success
  92. * - ESP_ERR_INVALID_SIZE if program_size_bytes is more than 8KiB
  93. */
  94. esp_err_t ulp_riscv_load_binary(const uint8_t* program_binary, size_t program_size_bytes);
  95. /**
  96. * @brief Stop the ULP timer
  97. *
  98. * @note This will stop the ULP from waking up if halted, but will not abort any program
  99. * currently executing on the ULP.
  100. */
  101. void ulp_riscv_timer_stop(void);
  102. /**
  103. * @brief Resumes the ULP timer
  104. *
  105. * @note This will resume an already configured timer, but does no other configuration
  106. *
  107. */
  108. void ulp_riscv_timer_resume(void);
  109. /**
  110. * @brief Halts the program currently running on the ULP-RISC-V
  111. *
  112. * @note Program will restart at the next ULP timer trigger if timer is still running.
  113. * If you want to stop the ULP from waking up then call ulp_riscv_timer_stop() first.
  114. */
  115. void ulp_riscv_halt(void);
  116. /**
  117. * @brief Resets the ULP-RISC-V core from the main CPU
  118. *
  119. * @note This will reset the ULP core from the main CPU. It is intended to be used when the
  120. * ULP is in a bad state and cannot run as intended due to a corrupt firmware or any other reason.
  121. * The main core can reset the ULP core with this API and then re-initilialize the ULP.
  122. */
  123. void ulp_riscv_reset(void);
  124. #ifdef __cplusplus
  125. }
  126. #endif