1 // Copyright 2016-2018 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 #pragma once
15 
16 /* This file contains definitions that are common between esp32/ulp.h
17    and esp32s2/ulp.h
18 */
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 /**@{*/
25 #define ESP_ERR_ULP_BASE                0x1200                  /*!< Offset for ULP-related error codes */
26 #define ESP_ERR_ULP_SIZE_TOO_BIG        (ESP_ERR_ULP_BASE + 1)  /*!< Program doesn't fit into RTC memory reserved for the ULP */
27 #define ESP_ERR_ULP_INVALID_LOAD_ADDR   (ESP_ERR_ULP_BASE + 2)  /*!< Load address is outside of RTC memory reserved for the ULP */
28 #define ESP_ERR_ULP_DUPLICATE_LABEL     (ESP_ERR_ULP_BASE + 3)  /*!< More than one label with the same number was defined */
29 #define ESP_ERR_ULP_UNDEFINED_LABEL     (ESP_ERR_ULP_BASE + 4)  /*!< Branch instructions references an undefined label */
30 #define ESP_ERR_ULP_BRANCH_OUT_OF_RANGE (ESP_ERR_ULP_BASE + 5)  /*!< Branch target is out of range of B instruction (try replacing with BX) */
31 /**@}*/
32 
33 union ulp_insn;  // Declared in the chip-specific ulp.h header
34 
35 typedef union ulp_insn ulp_insn_t;
36 
37 /**
38  * @brief Resolve all macro references in a program and load it into RTC memory
39  * @param load_addr  address where the program should be loaded, expressed in 32-bit words
40  * @param program  ulp_insn_t array with the program
41  * @param psize  size of the program, expressed in 32-bit words
42  * @return
43  *      - ESP_OK on success
44  *      - ESP_ERR_NO_MEM if auxiliary temporary structure can not be allocated
45  *      - one of ESP_ERR_ULP_xxx if program is not valid or can not be loaded
46  */
47 esp_err_t ulp_process_macros_and_load(uint32_t load_addr, const ulp_insn_t* program, size_t* psize);
48 
49 /**
50  * @brief Load ULP program binary into RTC memory
51  *
52  * ULP program binary should have the following format (all values little-endian):
53  *
54  * 1. MAGIC, (value 0x00706c75, 4 bytes)
55  * 2. TEXT_OFFSET, offset of .text section from binary start (2 bytes)
56  * 3. TEXT_SIZE, size of .text section (2 bytes)
57  * 4. DATA_SIZE, size of .data section (2 bytes)
58  * 5. BSS_SIZE, size of .bss section (2 bytes)
59  * 6. (TEXT_OFFSET - 12) bytes of arbitrary data (will not be loaded into RTC memory)
60  * 7. .text section
61  * 8. .data section
62  *
63  * Linker script in components/ulp/ld/esp32.ulp.ld produces ELF files which
64  * correspond to this format. This linker script produces binaries with load_addr == 0.
65  *
66  * @param load_addr address where the program should be loaded, expressed in 32-bit words
67  * @param program_binary pointer to program binary
68  * @param program_size size of the program binary
69  * @return
70  *      - ESP_OK on success
71  *      - ESP_ERR_INVALID_ARG if load_addr is out of range
72  *      - ESP_ERR_INVALID_SIZE if program_size doesn't match (TEXT_OFFSET + TEXT_SIZE + DATA_SIZE)
73  *      - ESP_ERR_NOT_SUPPORTED if the magic number is incorrect
74  */
75 esp_err_t ulp_load_binary(uint32_t load_addr, const uint8_t* program_binary, size_t program_size);
76 
77 /**
78  * @brief Run the program loaded into RTC memory
79  * @param entry_point entry point, expressed in 32-bit words
80  * @return  ESP_OK on success
81  */
82 esp_err_t ulp_run(uint32_t entry_point);
83 
84 /**
85  * @brief Set one of ULP wakeup period values
86  *
87  * ULP coprocessor starts running the program when the wakeup timer counts up
88  * to a given value (called period). There are 5 period values which can be
89  * programmed into SENS_ULP_CP_SLEEP_CYCx_REG registers, x = 0..4 for ESP32, and
90  * one period value which can be programmed into RTC_CNTL_ULP_CP_TIMER_1_REG register for ESP32-S2.
91  * By default, for ESP32, wakeup timer will use the period set into SENS_ULP_CP_SLEEP_CYC0_REG,
92  * i.e. period number 0. ULP program code can use SLEEP instruction to select
93  * which of the SENS_ULP_CP_SLEEP_CYCx_REG should be used for subsequent wakeups.
94  *
95  * However, please note that SLEEP instruction issued (from ULP program) while the system
96  * is in deep sleep mode does not have effect, and sleep cycle count 0 is used.
97  *
98  * For ESP32-s2 the SLEEP instruction not exist. Instead a WAKE instruction will be used.
99  *
100  * @param period_index wakeup period setting number (0 - 4)
101  * @param period_us wakeup period, us
102  * @note  The ULP FSM requires two clock cycles to wakeup before being able to run the program.
103  *        Then additional 16 cycles are reserved after wakeup waiting until the 8M clock is stable.
104  *        The FSM also requires two more clock cycles to go to sleep after the program execution is halted.
105  *        The minimum wakeup period that may be set up for the ULP
106  *        is equal to the total number of cycles spent on the above internal tasks.
107  *        For a default configuration of the ULP running at 150kHz it makes about 133us.
108  * @return
109  *      - ESP_OK on success
110  *      - ESP_ERR_INVALID_ARG if period_index is out of range
111  */
112 esp_err_t ulp_set_wakeup_period(size_t period_index, uint32_t period_us);
113 
114 #ifdef __cplusplus
115 }
116 #endif
117