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