A switch between esp32 and esp32s2betta added to the ULP build process.
The new bin utils will have extension esp32s2ulp-elf, and they have to be placed to the bin directory.
This commit is contained in:
parent
f64ee5aba3
commit
1518c410bc
12 changed files with 552 additions and 26 deletions
|
@ -1,8 +1,13 @@
|
|||
ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
ULP_BINUTILS_PREFIX ?= esp32s2ulp-elf-
|
||||
else
|
||||
ULP_BINUTILS_PREFIX ?= esp32ulp-elf-
|
||||
endif
|
||||
#
|
||||
export ULP_AS := $(ULP_BINUTILS_PREFIX)as
|
||||
export ULP_LD := $(ULP_BINUTILS_PREFIX)ld
|
||||
export ULP_OBJCOPY := $(ULP_BINUTILS_PREFIX)objcopy
|
||||
export ULP_OBJDUMP := $(ULP_BINUTILS_PREFIX)objdump
|
||||
export ULP_NM := $(ULP_BINUTILS_PREFIX)nm
|
||||
export ULP_LD_TEMPLATE := $(IDF_PATH)/components/ulp/ld/esp32.ulp.ld
|
||||
export ULP_NM := $(ULP_BINUTILS_PREFIX)nm
|
||||
export ULP_MAP_GEN := $(IDF_PATH)/components/ulp/esp32ulp_mapgen.py
|
||||
|
|
15
components/ulp/cmake/toolchain-esp32s2beta-ulp.cmake
Normal file
15
components/ulp/cmake/toolchain-esp32s2beta-ulp.cmake
Normal file
|
@ -0,0 +1,15 @@
|
|||
# CMake toolchain file for ULP
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
|
||||
# Compiler is only used for preprocessing
|
||||
set(CMAKE_C_COMPILER "xtensa-esp32s2-elf-gcc")
|
||||
|
||||
set(CMAKE_ASM_COMPILER "esp32s2ulp-elf-as")
|
||||
set(CMAKE_LINKER "esp32s2ulp-elf-ld")
|
||||
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "${CMAKE_ASM${ASM_DIALECT}_COMPILER} \
|
||||
<DEFINES> <INCLUDES> -o <OBJECT> -c <SOURCE>")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-A elf32-esp32s2ulp -nostdlib" CACHE STRING "ULP Linker Base Flags")
|
||||
set(CMAKE_ASM_LINK_EXECUTABLE "${CMAKE_LINKER} <FLAGS> <CMAKE_ASM_LINK_FLAGS> \
|
||||
<LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
|
@ -16,6 +16,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc.h"
|
||||
#include "ulp_common.h"
|
||||
|
@ -76,15 +77,29 @@ extern "C" {
|
|||
#define ALU_SEL_MOV 4 /*!< Copy value (immediate to destination register or source register to destination register */
|
||||
#define ALU_SEL_LSH 5 /*!< Shift left by given number of bits */
|
||||
#define ALU_SEL_RSH 6 /*!< Shift right by given number of bits */
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define ALU_SEL_INC 0 /*!< Stage_cnt = Stage_cnt + Imm */
|
||||
#define ALU_SEL_DEC 1 /*!< Stage_cnt = Stage_cnt - Imm */
|
||||
#define ALU_SEL_RST 2 /*!< Stage_cnt = 0 */
|
||||
#endif
|
||||
|
||||
#define OPCODE_BRANCH 8 /*!< Branch instructions */
|
||||
#define SUB_OPCODE_BX 0 /*!< Branch to absolute PC (immediate or in register) */
|
||||
#define BX_JUMP_TYPE_DIRECT 0 /*!< Unconditional jump */
|
||||
#define BX_JUMP_TYPE_ZERO 1 /*!< Branch if last ALU result is zero */
|
||||
#define BX_JUMP_TYPE_OVF 2 /*!< Branch if last ALU operation caused and overflow */
|
||||
#define SUB_OPCODE_B 1 /*!< Branch to a relative offset */
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define B_CMP_L 0 /*!< Branch if R0 is less than an immediate */
|
||||
#define B_CMP_GE 1 /*!< Branch if R0 is greater than or equal to an immediate */
|
||||
#define SUB_OPCODE_BX 0 /*!< Branch to absolute PC (immediate or in register) */
|
||||
#define SUB_OPCODE_B 1 /*!< Branch to a relative offset */
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define B_CMP_L 1 /*!< Branch if R0 is less than an immediate */
|
||||
#define B_CMP_GE 2 /*!< Branch if R0 is greater than an immediate */
|
||||
#define B_CMP_EQ 4 /*!< Branch if R0 is equal to an immediate */
|
||||
#define SUB_OPCODE_BX 1 /*!< Branch to absolute PC (immediate or in register) */
|
||||
#define SUB_OPCODE_B 0 /*!< Branch to a relative offset base on R0 */
|
||||
#define SUB_OPCODE_B_STAGE 2 /*!< Branch to a relative offset base on stage reg */
|
||||
#endif
|
||||
|
||||
#define OPCODE_END 9 /*!< Stop executing the program */
|
||||
#define SUB_OPCODE_END 0 /*!< Stop executing the program and optionally wake up the chip */
|
||||
|
@ -99,6 +114,10 @@ extern "C" {
|
|||
#define OPCODE_MACRO 15 /*!< Not a real opcode. Used to identify labels and branches in the program */
|
||||
#define SUB_OPCODE_MACRO_LABEL 0 /*!< Label macro */
|
||||
#define SUB_OPCODE_MACRO_BRANCH 1 /*!< Branch macro */
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define OPCODE_SLEEP_WAIT 4
|
||||
#endif
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
|
@ -123,6 +142,7 @@ union ulp_insn {
|
|||
uint32_t opcode : 4; /*!< Opcode (OPCODE_DELAY) */
|
||||
} delay; /*!< Format of DELAY instruction */
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register which contains data to store */
|
||||
uint32_t sreg : 2; /*!< Register which contains address in RTC memory (expressed in words) */
|
||||
|
@ -132,7 +152,24 @@ union ulp_insn {
|
|||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ST) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ST) */
|
||||
} st; /*!< Format of ST instruction */
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Data address register number */
|
||||
uint32_t sreg : 2; /*!< Base address register number */
|
||||
uint32_t data_label : 2; /*!< Data label */
|
||||
uint32_t upper : 1; /*!< High and low half-word Select 1: Write high half-word; 0 : write low half-word; */
|
||||
uint32_t write_way : 2; /*!< Write number Mode 0 : full word write; 1: with data_label; 3: without label; */
|
||||
uint32_t unused1 : 1; /*!< Unused */
|
||||
uint32_t offset : 11; /*!< When you select automatic storage, you need to configure the base address offset*/
|
||||
uint32_t unused2 : 4; /*!< Unused */
|
||||
uint32_t wr_auto : 1; /*!< Automatic storage selection enabled (burst mode)*/
|
||||
uint32_t offset_set : 1; /*!< Configure OFFSET enable */
|
||||
uint32_t manul_en : 1; /*!< Manual storage selection enabled */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ST) */
|
||||
} st; /*!< Format of ST instruction */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register where the data should be loaded to */
|
||||
uint32_t sreg : 2; /*!< Register which contains address in RTC memory (expressed in words) */
|
||||
|
@ -141,12 +178,24 @@ union ulp_insn {
|
|||
uint32_t unused2 : 7; /*!< Unused */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_LD) */
|
||||
} ld; /*!< Format of LD instruction */
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register where the data should be loaded to */
|
||||
uint32_t sreg : 2; /*!< Register which contains address in RTC memory (expressed in words) */
|
||||
uint32_t unused1 : 6; /*!< Unused */
|
||||
uint32_t offset : 11; /*!< Offset to add to sreg */
|
||||
uint32_t unused2 : 6; /*!< Unused */
|
||||
uint32_t rd_upper: 1;
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_LD) */
|
||||
} ld; /*!< Format of LD instruction */
|
||||
#endif
|
||||
|
||||
struct {
|
||||
uint32_t unused : 28; /*!< Unused */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_HALT) */
|
||||
} halt; /*!< Format of HALT instruction */
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register which contains target PC, expressed in words (used if .reg == 1) */
|
||||
uint32_t addr : 11; /*!< Target PC, expressed in words (used if .reg == 0) */
|
||||
|
@ -165,7 +214,29 @@ union ulp_insn {
|
|||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_B) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_BRANCH) */
|
||||
} b; /*!< Format of BRANCH instruction (relative address) */
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register which contains target PC, expressed in words (used if .reg == 1) */
|
||||
uint32_t addr : 11; /*!< Target PC, expressed in words (used if .reg == 0) */
|
||||
uint32_t unused : 8; /*!< Unused */
|
||||
uint32_t reg : 1; /*!< Target PC in register (1) or immediate (0) */
|
||||
uint32_t type : 3; /*!< Jump condition (BX_JUMP_TYPE_xxx) */
|
||||
uint32_t unused1 : 1; /*!< Unused */
|
||||
uint32_t sub_opcode : 2; /*!< Sub opcode (SUB_OPCODE_BX) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_BRANCH) */
|
||||
} bx; /*!< Format of BRANCH instruction (absolute address) */
|
||||
|
||||
struct {
|
||||
uint32_t imm : 15; /*!< Immediate value to compare against */
|
||||
uint32_t cmp : 3; /*!< Comparison to perform: B_CMP_L or B_CMP_GE */
|
||||
uint32_t offset : 7; /*!< Absolute value of target PC offset w.r.t. current PC, expressed in words */
|
||||
uint32_t sign : 1; /*!< Sign of target PC offset: 0: positive, 1: negative */
|
||||
uint32_t sub_opcode : 2; /*!< Sub opcode (SUB_OPCODE_B) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_BRANCH) */
|
||||
} b;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Destination register */
|
||||
uint32_t sreg : 2; /*!< Register with operand A */
|
||||
|
@ -175,7 +246,20 @@ union ulp_insn {
|
|||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ALU_REG) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */
|
||||
} alu_reg; /*!< Format of ALU instruction (both sources are registers) */
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Destination register */
|
||||
uint32_t sreg : 2; /*!< Register with operand A */
|
||||
uint32_t treg : 2; /*!< Register with operand B */
|
||||
uint32_t unused : 15; /*!< Unused */
|
||||
uint32_t sel : 4; /*!< Operation to perform, one of ALU_SEL_xxx */
|
||||
uint32_t unused1 : 1; /*!< Unused */
|
||||
uint32_t sub_opcode : 2; /*!< Sub opcode (SUB_OPCODE_ALU_REG) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */
|
||||
} alu_reg; /*!< Format of ALU instruction (both sources are registers) */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Destination register */
|
||||
uint32_t sreg : 2; /*!< Register with operand A */
|
||||
|
@ -185,6 +269,27 @@ union ulp_insn {
|
|||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ALU_IMM) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */
|
||||
} alu_imm; /*!< Format of ALU instruction (one source is an immediate) */
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Destination register */
|
||||
uint32_t sreg : 2; /*!< Register with operand A */
|
||||
uint32_t imm : 16; /*!< Immediate value of operand B */
|
||||
uint32_t unused : 1; /*!< Unused */
|
||||
uint32_t sel : 4; /*!< Operation to perform, one of ALU_SEL_xxx */
|
||||
uint32_t unused1 : 1; /*!< Unused */
|
||||
uint32_t sub_opcode : 2; /*!< Sub opcode (SUB_OPCODE_ALU_IMM) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */
|
||||
} alu_imm; /*!< Format of ALU instruction (one source is an immediate) */
|
||||
struct {
|
||||
uint32_t unused : 4; /*!< Unused */
|
||||
uint32_t imm : 16; /*!< Immediate value of operand B */
|
||||
uint32_t unused1 : 1; /*!< Unused */
|
||||
uint32_t sel : 4; /*!< Operation to perform, one of ALU_SEL_xxx */
|
||||
uint32_t unused2 : 1; /*!< Unused */
|
||||
uint32_t sub_opcode : 2; /*!< Sub opcode (SUB_OPCODE_ALU_IMM) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */
|
||||
} alu_cnt; /*!< Format of ALU instruction (one source is an immediate) */
|
||||
#endif
|
||||
|
||||
struct {
|
||||
uint32_t addr : 8; /*!< Address within either RTC_CNTL, RTC_IO, or SARADC */
|
||||
|
@ -203,7 +308,7 @@ union ulp_insn {
|
|||
uint32_t high : 5; /*!< High bit */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_WR_REG) */
|
||||
} rd_reg; /*!< Format of RD_REG instruction */
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register where to store ADC result */
|
||||
uint32_t mux : 4; /*!< Select SARADC pad (mux + 1) */
|
||||
|
@ -213,7 +318,17 @@ union ulp_insn {
|
|||
uint32_t unused2 : 4; /*!< Unused */
|
||||
uint32_t opcode: 4; /*!< Opcode (OPCODE_ADC) */
|
||||
} adc; /*!< Format of ADC instruction */
|
||||
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register where to store ADC result */
|
||||
uint32_t mux : 4; /*!< Select SARADC pad (mux + 1) */
|
||||
uint32_t sar_sel : 1; /*!< Select SARADC0 (0) or SARADC1 (1) */
|
||||
uint32_t hall_phase : 1; /*!< Unused */
|
||||
uint32_t xpd_hall : 1; /*!< Unused */
|
||||
uint32_t unused1 : 19; /*!< Unused */
|
||||
uint32_t opcode: 4; /*!< Opcode (OPCODE_ADC) */
|
||||
} adc;
|
||||
#endif
|
||||
struct {
|
||||
uint32_t dreg : 2; /*!< Register where to store temperature measurement result */
|
||||
uint32_t wait_delay: 14; /*!< Cycles to wait after measurement is done */
|
||||
|
@ -231,7 +346,7 @@ union ulp_insn {
|
|||
uint32_t rw : 1; /*!< Write (1) or read (0) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_I2C) */
|
||||
} i2c; /*!< Format of I2C instruction */
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
struct {
|
||||
uint32_t wakeup : 1; /*!< Set to 1 to wake up chip */
|
||||
uint32_t unused : 24; /*!< Unused */
|
||||
|
@ -245,7 +360,20 @@ union ulp_insn {
|
|||
uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_SLEEP) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_END) */
|
||||
} sleep; /*!< Format of END instruction with sleep */
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
struct {
|
||||
uint32_t wakeup : 1; /*!< Set to 1 to wake up chip */
|
||||
uint32_t unused : 25; /*!< Unused */
|
||||
uint32_t sub_opcode : 2; /*!< Sub opcode (SUB_OPCODE_WAKEUP) */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_END) */
|
||||
} end;
|
||||
|
||||
struct {
|
||||
uint32_t cycle_sel : 16; /*!< Select which one of SARADC_ULP_CP_SLEEP_CYCx_REG to get the sleep duration from */
|
||||
uint32_t unused : 12; /*!< Unused */
|
||||
uint32_t opcode : 4; /*!< Opcode (OPCODE_END) */
|
||||
} sleep;
|
||||
#endif
|
||||
struct {
|
||||
uint32_t label : 16; /*!< Label number */
|
||||
uint32_t unused : 8; /*!< Unused */
|
||||
|
@ -373,8 +501,13 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
* ULP program will continue running after this instruction. To stop
|
||||
* the currently running program, use I_HALT().
|
||||
*/
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define I_END() \
|
||||
I_WR_REG_BIT(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN_S, 0)
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define I_END() \
|
||||
I_WR_REG_BIT(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN_S, 0)
|
||||
#endif
|
||||
/**
|
||||
* Select the time interval used to run ULP program.
|
||||
*
|
||||
|
@ -390,12 +523,18 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
* By default, SENS_SLEEP_CYCLES_S0 register is used by the ULP
|
||||
* program timer.
|
||||
*/
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define I_SLEEP_CYCLE_SEL(timer_idx) { .sleep = { \
|
||||
.cycle_sel = timer_idx, \
|
||||
.unused = 0, \
|
||||
.sub_opcode = SUB_OPCODE_SLEEP, \
|
||||
.opcode = OPCODE_END } }
|
||||
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define I_SLEEP_CYCLE_SEL(timer_idx) { .sleep = { \
|
||||
.cycle_sel = timer_idx, \
|
||||
.unused = 0, \
|
||||
.opcode = OPCODE_SLEEP_WAIT } }
|
||||
#endif
|
||||
/**
|
||||
* Perform temperature sensor measurement and store it into reg_dest.
|
||||
*
|
||||
|
@ -414,6 +553,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
* adc_idx selects ADC (0 or 1).
|
||||
* pad_idx selects ADC pad (0 - 7).
|
||||
*/
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define I_ADC(reg_dest, adc_idx, pad_idx) { .adc = {\
|
||||
.dreg = reg_dest, \
|
||||
.mux = pad_idx + 1, \
|
||||
|
@ -422,6 +562,16 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.cycles = 0, \
|
||||
.unused2 = 0, \
|
||||
.opcode = OPCODE_ADC } }
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define I_ADC(reg_dest, adc_idx, pad_idx) { .adc = {\
|
||||
.dreg = reg_dest, \
|
||||
.mux = pad_idx + 1, \
|
||||
.sar_sel = adc_idx, \
|
||||
.hall_phase = 0, \
|
||||
.xpd_hall = 0, \
|
||||
.unused1 = 0, \
|
||||
.opcode = OPCODE_ADC } }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Store value from register reg_val into RTC memory.
|
||||
|
@ -435,6 +585,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
*
|
||||
* RTC_SLOW_MEM[addr + offset_] = { 5'b0, insn_PC[10:0], val[15:0] }
|
||||
*/
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define I_ST(reg_val, reg_addr, offset_) { .st = { \
|
||||
.dreg = reg_val, \
|
||||
.sreg = reg_addr, \
|
||||
|
@ -443,7 +594,138 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.unused2 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ST, \
|
||||
.opcode = OPCODE_ST } }
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
/**
|
||||
* burst Mode: write to consecutive address spaces.
|
||||
* STW, STC instructions for the Class burst storage instructions for continuous address space write operation;
|
||||
* Need to be used with the SET_OFFSET instruction, you first need to set the start address offset by SET_OFFSET, SREG is the base address,
|
||||
* Where STW instruction WORD instruction, each execution time, address offset+1;STC for the half-word operation
|
||||
* (First write high 16bit current address, the Second Write low 16bit current address), each performed twice, the address offset+1.
|
||||
* Note: when using STC, you must write a word, that is, a burst operation instruction must be an even number.
|
||||
*/
|
||||
#define I_STO(offset_) { .st = { \
|
||||
.dreg = 0, \
|
||||
.sreg = 0, \
|
||||
.data_label = 0, \
|
||||
.upper = 0, \
|
||||
.write_way = 0, \
|
||||
.unused1 = 0, \
|
||||
.offset = offset_, \
|
||||
.unused2 = 0, \
|
||||
.wr_auto = 0, \
|
||||
.offset_set = 0, \
|
||||
.manul_en = 1, \
|
||||
.opcode = OPCODE_ST } }
|
||||
|
||||
#define I_STW(reg_val, reg_addr) { .st = { \
|
||||
.dreg = reg_val, \
|
||||
.sreg = reg_addr, \
|
||||
.data_label = 0, \
|
||||
.upper = 0, \
|
||||
.write_way = 0, \
|
||||
.unused1 = 0, \
|
||||
.offset = 0, \
|
||||
.unused2 = 0, \
|
||||
.wr_auto = 1, \
|
||||
.offset_set = 0, \
|
||||
.manul_en = 0, \
|
||||
.opcode = OPCODE_ST } }
|
||||
|
||||
#define I_STC(reg_val, reg_addr) { .st = { \
|
||||
.dreg = reg_val, \
|
||||
.sreg = reg_addr, \
|
||||
.data_label = 0, \
|
||||
.upper = 0, \
|
||||
.write_way = 3, \
|
||||
.unused1 = 0, \
|
||||
.offset = 0, \
|
||||
.unused2 = 0, \
|
||||
.wr_auto = 1, \
|
||||
.offset_set = 0, \
|
||||
.manul_en = 0, \
|
||||
.opcode = OPCODE_ST } }
|
||||
/**
|
||||
* Single mode of operation: write to a single address space.
|
||||
*
|
||||
* Loads 16 LSBs from RTC memory word given by the sum of value in reg_addr and
|
||||
* value of offset_.
|
||||
*/
|
||||
/* Mem [ Rsrc1 + offset ]{31:0} = {PC[10:0], 5<>d0,Rdst[15:0]} */
|
||||
#define I_ST(reg_val, reg_addr, offset_) { .st = { \
|
||||
.dreg = reg_val, \
|
||||
.sreg = reg_addr, \
|
||||
.data_label = 0, \
|
||||
.upper = 0, \
|
||||
.write_way = 0, \
|
||||
.unused1 = 0, \
|
||||
.offset = offset_, \
|
||||
.unused2 = 0, \
|
||||
.wr_auto = 0, \
|
||||
.offset_set = 0, \
|
||||
.manul_en = 1, \
|
||||
.opcode = OPCODE_ST } }
|
||||
|
||||
/* Mem [ Rsrc1 + offset ]{31:16} = {Rdst[15:0]} */
|
||||
#define I_STM32U(reg_val, reg_addr, offset_) { .st = { \
|
||||
.dreg = reg_val, \
|
||||
.sreg = reg_addr, \
|
||||
.data_label = 0, \
|
||||
.upper = 1, \
|
||||
.write_way = 3, \
|
||||
.unused1 = 0, \
|
||||
.offset = offset_, \
|
||||
.unused1 = 0, \
|
||||
.wr_auto = 0, \
|
||||
.offset_set = 0, \
|
||||
.manul_en = 1, \
|
||||
.opcode = OPCODE_ST } }
|
||||
|
||||
/* Mem [ Rsrc1 + offset ]{15:0} = {Rdst[15:0]} */
|
||||
#define I_STM32L(reg_val, reg_addr, offset_) { .st = { \
|
||||
.dreg = reg_val, \
|
||||
.sreg = reg_addr, \
|
||||
.data_label = 0, \
|
||||
.upper = 0, \
|
||||
.write_way = 3, \
|
||||
.unused1 = 0, \
|
||||
.offset = offset_, \
|
||||
.unused2 = 0, \
|
||||
.wr_auto = 0, \
|
||||
.offset_set = 0, \
|
||||
.manul_en = 1, \
|
||||
.opcode = OPCODE_ST } }
|
||||
|
||||
/* Mem [ Rsrc1 + offset ]{31:0} = {data_label[1:0],Rdst[13:0]} */
|
||||
#define I_STMLBU(reg_val, reg_addr, label, offset_) { .st = { \
|
||||
.dreg = reg_val, \
|
||||
.sreg = reg_addr, \
|
||||
.data_label = label, \
|
||||
.upper = 1, \
|
||||
.write_way = 1, \
|
||||
.unused1 = 0, \
|
||||
.offset = offset_, \
|
||||
.unused1 = 0, \
|
||||
.wr_auto = 0, \
|
||||
.offset_set = 0, \
|
||||
.manul_en = 1, \
|
||||
.opcode = OPCODE_ST } }
|
||||
|
||||
/* Mem [ Rsrc1 + offset ]{15:0} = {data_label[1:0],Rdst[13:0]} */
|
||||
#define I_STMLBL(reg_val, reg_addr, label, offset_) { .st = { \
|
||||
.dreg = reg_val, \
|
||||
.sreg = reg_addr, \
|
||||
.data_label = label, \
|
||||
.upper = 0, \
|
||||
.write_way = 1, \
|
||||
.unused1 = 0, \
|
||||
.offset = offset_, \
|
||||
.unused2 = 0, \
|
||||
.wr_auto = 0, \
|
||||
.offset_set = 0, \
|
||||
.manul_en = 1, \
|
||||
.opcode = OPCODE_ST } }
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Load value from RTC memory into reg_dest register.
|
||||
|
@ -451,6 +733,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
* Loads 16 LSBs from RTC memory word given by the sum of value in reg_addr and
|
||||
* value of offset_.
|
||||
*/
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define I_LD(reg_dest, reg_addr, offset_) { .ld = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_addr, \
|
||||
|
@ -458,7 +741,16 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.offset = offset_, \
|
||||
.unused2 = 0, \
|
||||
.opcode = OPCODE_LD } }
|
||||
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
#define I_LD(reg_dest, reg_addr, offset_) { .ld = { \
|
||||
.dreg = reg_dest, \
|
||||
.sreg = reg_addr, \
|
||||
.unused1 = 0, \
|
||||
.offset = offset_, \
|
||||
.unused2 = 0, \
|
||||
.rd_upper = 0, \
|
||||
.opcode = OPCODE_LD } }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Branch relative if R0 less than immediate value.
|
||||
|
@ -474,6 +766,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.sub_opcode = SUB_OPCODE_B, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
/**
|
||||
* Branch relative if R0 greater or equal than immediate value.
|
||||
*
|
||||
|
@ -487,7 +780,75 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.sign = (pc_offset >= 0) ? 0 : 1, \
|
||||
.sub_opcode = SUB_OPCODE_B, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
|
||||
/**
|
||||
* Branch relative if R0 greater than immediate value.
|
||||
*
|
||||
* pc_offset is expressed in words, and can be from -127 to 127
|
||||
* imm_value is a 16-bit value to compare R0 against
|
||||
*/
|
||||
#define I_BG(pc_offset, imm_value) { .b = { \
|
||||
.imm = imm_value, \
|
||||
.cmp = B_CMP_GE, \
|
||||
.offset = abs(pc_offset), \
|
||||
.sign = (pc_offset >= 0) ? 0 : 1, \
|
||||
.sub_opcode = SUB_OPCODE_B, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/**
|
||||
* Branch relative if R0 equal to immediate value.
|
||||
*
|
||||
* pc_offset is expressed in words, and can be from -127 to 127
|
||||
* imm_value is a 16-bit value to compare R0 against
|
||||
*/
|
||||
#define I_BE(pc_offset, imm_value) { .b = { \
|
||||
.imm = imm_value, \
|
||||
.cmp = B_CMP_EQ, \
|
||||
.offset = abs(pc_offset), \
|
||||
.sign = (pc_offset >= 0) ? 0 : 1, \
|
||||
.sub_opcode = SUB_OPCODE_B, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/*
|
||||
* Branch to a relative offset base on stage reg
|
||||
* If stage reg less imm_value, PC will jump pc_offset.
|
||||
*/
|
||||
#define I_BRLS(pc_offset, imm_value) { .b = { \
|
||||
.imm = imm_value, \
|
||||
.cmp = B_CMP_L, \
|
||||
.offset = abs(pc_offset), \
|
||||
.sign = (pc_offset >= 0) ? 0 : 1, \
|
||||
.sub_opcode = SUB_OPCODE_B_STAGE, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/*
|
||||
* Branch to a relative offset base on stage reg
|
||||
* If stage reg greater imm_value, PC will jump pc_offset.
|
||||
*/
|
||||
#define I_BRGS(pc_offset, imm_value) { .b = { \
|
||||
.imm = imm_value, \
|
||||
.cmp = B_CMP_GE, \
|
||||
.offset = abs(pc_offset), \
|
||||
.sign = (pc_offset >= 0) ? 0 : 1, \
|
||||
.sub_opcode = SUB_OPCODE_B_STAGE, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
/*
|
||||
* Branch to a relative offset base on stage reg
|
||||
* If stage reg equal to imm_value, PC will jump pc_offset.
|
||||
*/
|
||||
#define I_BRES(pc_offset, imm_value) { .b = { \
|
||||
.imm = imm_value, \
|
||||
.cmp = B_CMP_EQ, \
|
||||
.offset = abs(pc_offset), \
|
||||
.sign = (pc_offset >= 0) ? 0 : 1, \
|
||||
.sub_opcode = SUB_OPCODE_B_STAGE, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Unconditional branch to absolute PC, address in register.
|
||||
*
|
||||
|
@ -500,6 +861,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.unused = 0, \
|
||||
.reg = 1, \
|
||||
.type = BX_JUMP_TYPE_DIRECT, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
|
@ -514,6 +876,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.unused = 0, \
|
||||
.reg = 0, \
|
||||
.type = BX_JUMP_TYPE_DIRECT, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
|
@ -529,6 +892,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.unused = 0, \
|
||||
.reg = 1, \
|
||||
.type = BX_JUMP_TYPE_ZERO, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
|
@ -543,6 +907,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.unused = 0, \
|
||||
.reg = 0, \
|
||||
.type = BX_JUMP_TYPE_ZERO, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
|
@ -558,6 +923,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.unused = 0, \
|
||||
.reg = 1, \
|
||||
.type = BX_JUMP_TYPE_OVF, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
|
@ -572,6 +938,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.unused = 0, \
|
||||
.reg = 0, \
|
||||
.type = BX_JUMP_TYPE_OVF, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_BX, \
|
||||
.opcode = OPCODE_BRANCH } }
|
||||
|
||||
|
@ -585,6 +952,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.treg = reg_src2, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_ADD, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -597,6 +965,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.treg = reg_src2, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_SUB, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -609,6 +978,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.treg = reg_src2, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_AND, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -621,6 +991,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.treg = reg_src2, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_OR, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -633,6 +1004,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.treg = 0, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_MOV, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -645,6 +1017,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.treg = reg_shift, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_LSH, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -658,6 +1031,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.treg = reg_shift, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_RSH, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_REG, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -670,6 +1044,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_ADD, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -683,6 +1058,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_SUB, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -695,6 +1071,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_AND, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -707,6 +1084,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_OR, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -719,6 +1097,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_MOV, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -731,6 +1110,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_LSH, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
@ -744,9 +1124,49 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
|
|||
.imm = imm_, \
|
||||
.unused = 0, \
|
||||
.sel = ALU_SEL_RSH, \
|
||||
.unused1 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_IMM, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
/**
|
||||
* Increments the stage counter for the subscript of the cycle count, Stage_cnt = Stage_cnt + Imm
|
||||
*/
|
||||
#define I_SINC(imm_) { .alu_cnt = { \
|
||||
.unused = 0, \
|
||||
.imm = imm_, \
|
||||
.unused1 = 0, \
|
||||
.sel = ALU_SEL_INC, \
|
||||
.unused2 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_CNT, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Decrements the stage counter for the subscript of the cycle count, Stage_cnt = Stage_cnt - Imm
|
||||
*/
|
||||
#define I_SDEC(imm_) { .alu_cnt = { \
|
||||
.unused = 0, \
|
||||
.imm = imm_, \
|
||||
.unused1 = 0, \
|
||||
.sel = ALU_SEL_DEC, \
|
||||
.unused2 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_CNT, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
|
||||
/**
|
||||
* Phase counter is reset for the cycle count subscript, Stage_cnt = 0
|
||||
*/
|
||||
#define I_SRST() { .alu_cnt = { \
|
||||
.unused = 0, \
|
||||
.imm = 0, \
|
||||
.unused1 = 0, \
|
||||
.sel = ALU_SEL_RST, \
|
||||
.unused2 = 0, \
|
||||
.sub_opcode = SUB_OPCODE_ALU_CNT, \
|
||||
.opcode = OPCODE_ALU } }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Define a label with number label_num.
|
||||
*
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
#include "sdkconfig.h"
|
||||
|
||||
#if CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM
|
||||
#define LOCAL_ULP_COPROC_RESERVE_MEM CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM
|
||||
#else
|
||||
#define LOCAL_ULP_COPROC_RESERVE_MEM CONFIG_ESP32_ULP_COPROC_RESERVE_MEM
|
||||
#endif
|
||||
|
||||
#define ULP_BIN_MAGIC 0x00706c75
|
||||
#define HEADER_SIZE 12
|
||||
MEMORY
|
||||
{
|
||||
ram(RW) : ORIGIN = 0, LENGTH = CONFIG_ESP32_ULP_COPROC_RESERVE_MEM
|
||||
ram(RW) : ORIGIN = 0, LENGTH = LOCAL_ULP_COPROC_RESERVE_MEM
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
|
|
|
@ -34,12 +34,19 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs)
|
|||
idf_build_get_property(python PYTHON)
|
||||
idf_build_get_property(extra_cmake_args EXTRA_CMAKE_ARGS)
|
||||
|
||||
if(IDF_TARGET STREQUAL "esp32")
|
||||
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-esp32-ulp.cmake)
|
||||
endif()
|
||||
if(IDF_TARGET STREQUAL "esp32s2beta")
|
||||
set(TOOLCHAIN_FLAG ${idf_path}/components/ulp/cmake/toolchain-esp32s2beta-ulp.cmake)
|
||||
endif()
|
||||
|
||||
externalproject_add(${app_name}
|
||||
SOURCE_DIR ${idf_path}/components/ulp/cmake
|
||||
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${app_name}
|
||||
INSTALL_COMMAND ""
|
||||
CMAKE_ARGS -DCMAKE_GENERATOR=${CMAKE_GENERATOR}
|
||||
-DCMAKE_TOOLCHAIN_FILE=${idf_path}/components/ulp/cmake/toolchain-ulp.cmake
|
||||
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FLAG}
|
||||
-DULP_S_SOURCES=${sources} -DULP_APP_NAME=${app_name}
|
||||
-DCOMPONENT_DIR=${COMPONENT_DIR}
|
||||
# Even though this resolves to a ';' separated list, this is fine. This must be special behavior
|
||||
|
|
|
@ -1 +1 @@
|
|||
SUPPORTED_ULP_ASSEMBLER_VERSION = 2.28.51.20170517
|
||||
SUPPORTED_ULP_ASSEMBLER_VERSION = 2.28.51-esp-20190801
|
|
@ -65,6 +65,25 @@ esp_err_t ulp_run(uint32_t entry_point)
|
|||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_SLEEP_FOLW_8M);
|
||||
// enable ULP timer
|
||||
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
// disable ULP timer
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
|
||||
// wait for at least 1 RTC_SLOW_CLK cycle
|
||||
ets_delay_us(10);
|
||||
// set entry point
|
||||
REG_SET_FIELD(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_PC_INIT, entry_point);
|
||||
|
||||
SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SEL); // Select ULP_TIMER trigger target for ULP.
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_DONE_FORCE); // Select the value for ULP_TIMER sleep. 1: REG_COCPU_DONE;0: ULP END value.
|
||||
/* Set the number of cycles of ULP_TIMER sleep, the wait time required to start ULP */
|
||||
REG_SET_FIELD(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_TIMER_SLP_CYCLE, 100);
|
||||
/* Clear interrupt COCPU status */
|
||||
REG_WRITE(RTC_CNTL_INT_CLR_REG, RTC_CNTL_COCPU_INT_CLR | RTC_CNTL_COCPU_TRAP_INT_CLR | RTC_CNTL_ULP_CP_INT_CLR);
|
||||
// start ULP clock gate.
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ULP_CP_CTRL_REG ,RTC_CNTL_ULP_CP_CLK_FO);
|
||||
// 1: start with timer. wait ULP_TIMER cnt timer.
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_CTRL_REG, RTC_CNTL_ULP_CP_FORCE_START_TOP); // Select ULP_TIMER timer as COCPU trigger source
|
||||
SET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); // Software to turn on the ULP_TIMER timer
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -131,6 +150,13 @@ esp_err_t ulp_set_wakeup_period(size_t period_index, uint32_t period_us)
|
|||
}
|
||||
REG_SET_FIELD(SENS_ULP_CP_SLEEP_CYC0_REG + period_index * sizeof(uint32_t),
|
||||
SENS_SLEEP_CYCLES_S0, (uint32_t) period_cycles);
|
||||
#elif defined CONFIG_IDF_TARGET_ESP32S2BETA
|
||||
if (period_index > 4) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
uint64_t period_us_64 = period_us;
|
||||
uint64_t period_cycles = (period_us_64 * 1000) / 90; //COCPU sleep clock is 90KHZ.
|
||||
REG_SET_FIELD(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_TIMER_SLP_CYCLE, period_cycles);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ entry:
|
|||
* Check which IO this is.
|
||||
*/
|
||||
move r0, r3
|
||||
jumpr read_io_high, 16, ge
|
||||
jumps read_io_high, 16, ge
|
||||
|
||||
/* Read the value of lower 16 RTC IOs into R0 */
|
||||
READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S, 16)
|
||||
|
|
|
@ -80,7 +80,9 @@ static void init_ulp_program(void)
|
|||
*/
|
||||
rtc_gpio_isolate(GPIO_NUM_12);
|
||||
rtc_gpio_isolate(GPIO_NUM_15);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_deep_sleep_disable_rom_logging(); // suppress boot messages
|
||||
#endif
|
||||
}
|
||||
|
||||
static void start_ulp_program(void)
|
||||
|
|
|
@ -73,7 +73,7 @@ class TestUsage(unittest.TestCase):
|
|||
output = output_stream.getvalue()
|
||||
|
||||
xtensa_esp32_elf_version = 'esp-2019r2-8.2.0'
|
||||
esp32ulp_version = '2.28.51.20170517'
|
||||
esp32ulp_version = '2.28.51-esp-20190801'
|
||||
|
||||
self.assertIn('* xtensa-esp32-elf:', output)
|
||||
self.assertIn('- %s (recommended)' % xtensa_esp32_elf_version, output)
|
||||
|
|
|
@ -142,26 +142,71 @@
|
|||
"versions": [
|
||||
{
|
||||
"linux-amd64": {
|
||||
"sha256": "c1bbcd65e1e30c7312a50344c8dbc70c2941580a79aa8f8abbce8e0e90c79566",
|
||||
"size": 8246604,
|
||||
"url": "https://dl.espressif.com/dl/binutils-esp32ulp-linux64-2.28.51-esp32ulp-20180809.tar.gz"
|
||||
"sha256": "f036ef1907ee19c8705f7076ef8c2e3b6dd9ffff654d35c264e7036c14aa5230",
|
||||
"size": 8249059,
|
||||
"url": "https://github.com/espressif/binutils-esp32ulp/releases/download/v2.28.51-esp-20190801/binutils-esp32ulp-linux-amd64-2.28.51-esp-20190801.tar.gz"
|
||||
},
|
||||
"macos": {
|
||||
"sha256": "c92937d85cc9a90eb6c6099ce767ca021108c18c94e34bd7b1fa0cde168f94a0",
|
||||
"size": 5726662,
|
||||
"url": "https://dl.espressif.com/dl/binutils-esp32ulp-macos-2.28.51-esp32ulp-20180809.tar.gz"
|
||||
"sha256": "04f812bf410ae6bef438c53ff4f4a33f34884d9072ae5815814b208ab408a9a4",
|
||||
"size": 8871878,
|
||||
"url": "https://github.com/espressif/binutils-esp32ulp/releases/download/v2.28.51-esp-20190801/binutils-esp32ulp-macos-2.28.51-esp-20190801.tar.gz"
|
||||
},
|
||||
"name": "2.28.51.20170517",
|
||||
"name": "2.28.51-esp-20190801",
|
||||
"status": "recommended",
|
||||
"win32": {
|
||||
"sha256": "92dc83e69e534c9f73d7b939088f2e84f757d2478483415d17fe9dd1c236f2fd",
|
||||
"size": 12231559,
|
||||
"url": "https://dl.espressif.com/dl/binutils-esp32ulp-win32-2.28.51-esp32ulp-20180809.zip"
|
||||
"sha256": "44626cc2348686e9c57587142ca49cdab26fec742468942b8679f22b6661a7ec",
|
||||
"size": 12232098,
|
||||
"url": "https://github.com/espressif/binutils-esp32ulp/releases/download/v2.28.51-esp-20190801/binutils-esp32ulp-win32-2.28.51-esp-20190801.zip"
|
||||
},
|
||||
"win64": {
|
||||
"sha256": "92dc83e69e534c9f73d7b939088f2e84f757d2478483415d17fe9dd1c236f2fd",
|
||||
"size": 12231559,
|
||||
"url": "https://dl.espressif.com/dl/binutils-esp32ulp-win32-2.28.51-esp32ulp-20180809.zip"
|
||||
"sha256": "44626cc2348686e9c57587142ca49cdab26fec742468942b8679f22b6661a7ec",
|
||||
"size": 12232098,
|
||||
"url": "https://github.com/espressif/binutils-esp32ulp/releases/download/v2.28.51-esp-20190801/binutils-esp32ulp-win32-2.28.51-esp-20190801.zip"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Toolchain for ESP32-S2 ULP coprocessor",
|
||||
"export_paths": [
|
||||
[
|
||||
"esp32s2ulp-elf-binutils",
|
||||
"bin"
|
||||
]
|
||||
],
|
||||
"export_vars": {},
|
||||
"info_url": "https://github.com/espressif/binutils-esp32ulp",
|
||||
"install": "always",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"name": "esp32s2ulp-elf",
|
||||
"version_cmd": [
|
||||
"esp32s2ulp-elf-as",
|
||||
"--version"
|
||||
],
|
||||
"version_regex": "\\(GNU Binutils\\)\\s+([0-9a-z\\.\\-]+)",
|
||||
"versions": [
|
||||
{
|
||||
"linux-amd64": {
|
||||
"sha256": "0085852b0de25a2186c874a184385c1dde107414248ec6a726b48d6616da6274",
|
||||
"size": 8253802,
|
||||
"url": "https://github.com/espressif/binutils-esp32ulp/releases/download/v2.28.51-esp-20190801/binutils-esp32s2ulp-linux-amd64-2.28.51-esp-20190801.tar.gz"
|
||||
},
|
||||
"macos": {
|
||||
"sha256": "b180a5ed3b7b5aa4503f26e5bd562d8b0f4b55f24a2ca04942804fd88b4d91b5",
|
||||
"size": 8877256,
|
||||
"url": "https://github.com/espressif/binutils-esp32ulp/releases/download/v2.28.51-esp-20190801/binutils-esp32s2ulp-macos-2.28.51-esp-20190801.tar.gz"
|
||||
},
|
||||
"name": "2.28.51-esp-20190801",
|
||||
"status": "recommended",
|
||||
"win32": {
|
||||
"sha256": "dbd0f050273a95a82b3e506aba999c8e4d4b22c69e5f3f3efc712c8eb59355e2",
|
||||
"size": 12238724,
|
||||
"url": "https://github.com/espressif/binutils-esp32ulp/releases/download/v2.28.51-esp-20190801/binutils-esp32s2ulp-win32-2.28.51-esp-20190801.zip"
|
||||
},
|
||||
"win64": {
|
||||
"sha256": "dbd0f050273a95a82b3e506aba999c8e4d4b22c69e5f3f3efc712c8eb59355e2",
|
||||
"size": 12238724,
|
||||
"url": "https://github.com/espressif/binutils-esp32ulp/releases/download/v2.28.51-esp-20190801/binutils-esp32s2ulp-win32-2.28.51-esp-20190801.zip"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue