diff --git a/components/esp32/dport_access.c b/components/esp32/dport_access.c index 834d046e6..ff4c8b79c 100644 --- a/components/esp32/dport_access.c +++ b/components/esp32/dport_access.c @@ -84,9 +84,9 @@ void IRAM_ATTR esp_dport_access_stall_other_cpu_start(void) dport_access_end[cpu_id] = 0; if (cpu_id == 0) { - WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_3_REG, DPORT_CPU_INTR_FROM_CPU_3); //interrupt on cpu1 + _DPORT_REG_WRITE(DPORT_CPU_INTR_FROM_CPU_3_REG, DPORT_CPU_INTR_FROM_CPU_3); //interrupt on cpu1 } else { - WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_2_REG, DPORT_CPU_INTR_FROM_CPU_2); //interrupt on cpu0 + _DPORT_REG_WRITE(DPORT_CPU_INTR_FROM_CPU_2_REG, DPORT_CPU_INTR_FROM_CPU_2); //interrupt on cpu0 } while (!dport_access_start[cpu_id]) {}; diff --git a/components/esp32/include/esp_assert.h b/components/esp32/include/esp_assert.h new file mode 100644 index 000000000..39d6a3284 --- /dev/null +++ b/components/esp32/include/esp_assert.h @@ -0,0 +1,37 @@ +// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef __ESP_ASSERT_H__ +#define __ESP_ASSERT_H__ + +#include "assert.h" + +/* Assert at compile time if possible, runtime otherwise */ +#ifndef __cplusplus +/* __builtin_choose_expr() is only in C, makes this a lot cleaner */ +#define TRY_STATIC_ASSERT(CONDITION, MSG) do { \ + _Static_assert(__builtin_choose_expr(__builtin_constant_p(CONDITION), (CONDITION), 1), #MSG); \ + assert(#MSG && (CONDITION)); \ + } while(0) +#else +/* for C++, use __attribute__((error)) - works almost as well as _Static_assert */ +#define TRY_STATIC_ASSERT(CONDITION, MSG) do { \ + if (__builtin_constant_p(CONDITION) && !(CONDITION)) { \ + extern __attribute__((error(#MSG))) void failed_compile_time_assert(void); \ + failed_compile_time_assert(); \ + } \ + assert(#MSG && (CONDITION)); \ + } while(0) +#endif /* __cplusplus */ + +#endif /* __ESP_ASSERT_H__ */ diff --git a/components/esp32/include/rom/cache.h b/components/esp32/include/rom/cache.h index fb84bca03..72aa33aaa 100644 --- a/components/esp32/include/rom/cache.h +++ b/components/esp32/include/rom/cache.h @@ -15,6 +15,8 @@ #ifndef _ROM_CACHE_H_ #define _ROM_CACHE_H_ +#include "soc/dport_access.h" + #ifdef __cplusplus extern "C" { #endif @@ -64,7 +66,18 @@ void mmu_init(int cpu_no); * 4 : mmu table to be written is out of range * 5 : vaddr is out of range */ -unsigned int cache_flash_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num); +static inline unsigned int IRAM_ATTR cache_flash_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num) +{ + extern unsigned int cache_flash_mmu_set_rom(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num); + + unsigned int ret; + + DPORT_STALL_OTHER_CPU_START(); + ret = cache_flash_mmu_set_rom(cpu_no, pid, vaddr, paddr, psize, num); + DPORT_STALL_OTHER_CPU_END(); + + return ret; +} /** * @brief Set Ext-SRAM-Cache mmu mapping. @@ -93,7 +106,18 @@ unsigned int cache_flash_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsign * 4 : mmu table to be written is out of range * 5 : vaddr is out of range */ -unsigned int cache_sram_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num); +static inline unsigned int IRAM_ATTR cache_sram_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num) +{ + extern unsigned int cache_sram_mmu_set_rom(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num); + + unsigned int ret; + + DPORT_STALL_OTHER_CPU_START(); + ret = cache_sram_mmu_set_rom(cpu_no, pid, vaddr, paddr, psize, num); + DPORT_STALL_OTHER_CPU_END(); + + return ret; +} /** * @brief Initialise cache access for the cpu. @@ -103,7 +127,13 @@ unsigned int cache_sram_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsigne * * @return None */ -void Cache_Read_Init(int cpu_no); +static inline void IRAM_ATTR Cache_Read_Init(int cpu_no) +{ + extern void Cache_Read_Init_rom(int cpu_no); + DPORT_STALL_OTHER_CPU_START(); + Cache_Read_Init_rom(cpu_no); + DPORT_STALL_OTHER_CPU_END(); +} /** * @brief Flush the cache value for the cpu. @@ -113,7 +143,13 @@ void Cache_Read_Init(int cpu_no); * * @return None */ -void Cache_Flush(int cpu_no); +static inline void IRAM_ATTR Cache_Flush(int cpu_no) +{ + extern void Cache_Flush_rom(int cpu_no); + DPORT_STALL_OTHER_CPU_START(); + Cache_Flush_rom(cpu_no); + DPORT_STALL_OTHER_CPU_END(); +} /** * @brief Disable Cache access for the cpu. @@ -123,7 +159,13 @@ void Cache_Flush(int cpu_no); * * @return None */ -void Cache_Read_Disable(int cpu_no); +static inline void IRAM_ATTR Cache_Read_Disable(int cpu_no) +{ + extern void Cache_Read_Disable_rom(int cpu_no); + DPORT_STALL_OTHER_CPU_START(); + Cache_Read_Disable_rom(cpu_no); + DPORT_STALL_OTHER_CPU_END(); +} /** * @brief Enable Cache access for the cpu. @@ -133,7 +175,13 @@ void Cache_Read_Disable(int cpu_no); * * @return None */ -void Cache_Read_Enable(int cpu_no); +static inline void IRAM_ATTR Cache_Read_Enable(int cpu_no) +{ + extern void Cache_Read_Enable_rom(int cpu_no); + DPORT_STALL_OTHER_CPU_START(); + Cache_Read_Enable_rom(cpu_no); + DPORT_STALL_OTHER_CPU_END(); +} /** * @} diff --git a/components/esp32/ld/esp32.rom.ld b/components/esp32/ld/esp32.rom.ld index 97588fb63..63a6927c5 100644 --- a/components/esp32/ld/esp32.rom.ld +++ b/components/esp32/ld/esp32.rom.ld @@ -50,12 +50,12 @@ PROVIDE ( btdm_r_modules_func_p_set = 0x40054270 ); PROVIDE ( btdm_r_plf_func_p_set = 0x40054288 ); PROVIDE ( bt_util_buf_env = 0x3ffb8bd4 ); PROVIDE ( bzero = 0x4000c1f4 ); -PROVIDE ( cache_flash_mmu_set = 0x400095e0 ); -PROVIDE ( Cache_Flush = 0x40009a14 ); -PROVIDE ( Cache_Read_Disable = 0x40009ab8 ); -PROVIDE ( Cache_Read_Enable = 0x40009a84 ); -PROVIDE ( Cache_Read_Init = 0x40009950 ); -PROVIDE ( cache_sram_mmu_set = 0x400097f4 ); +PROVIDE ( cache_flash_mmu_set_rom = 0x400095e0 ); +PROVIDE ( Cache_Flush_rom = 0x40009a14 ); +PROVIDE ( Cache_Read_Disable_rom = 0x40009ab8 ); +PROVIDE ( Cache_Read_Enable_rom = 0x40009a84 ); +PROVIDE ( Cache_Read_Init_rom = 0x40009950 ); +PROVIDE ( cache_sram_mmu_set_rom = 0x400097f4 ); /* This is static function, but can be used, not generated by script*/ PROVIDE ( calc_rtc_memory_crc = 0x40008170 ); PROVIDE ( calloc = 0x4000bee4 ); diff --git a/components/ethernet/emac_dev.c b/components/ethernet/emac_dev.c index cde9790d3..e4896af34 100644 --- a/components/ethernet/emac_dev.c +++ b/components/ethernet/emac_dev.c @@ -95,9 +95,9 @@ void emac_reset(void) void emac_enable_clk(bool enable) { if (enable == true) { - REG_SET_BIT(EMAC_CLK_EN_REG, EMAC_CLK_EN); + DPORT_REG_SET_BIT(EMAC_CLK_EN_REG, EMAC_CLK_EN); } else { - REG_CLR_BIT(EMAC_CLK_EN_REG, EMAC_CLK_EN); + DPORT_REG_CLR_BIT(EMAC_CLK_EN_REG, EMAC_CLK_EN); } } diff --git a/components/soc/esp32/include/soc/dport_access.h b/components/soc/esp32/include/soc/dport_access.h index f5c218248..3371b71eb 100644 --- a/components/soc/esp32/include/soc/dport_access.h +++ b/components/soc/esp32/include/soc/dport_access.h @@ -22,30 +22,29 @@ void esp_dport_access_stall_other_cpu_start(void); void esp_dport_access_stall_other_cpu_end(void); #if defined(BOOTLOADER_BUILD) || defined(CONFIG_FREERTOS_UNICORE) || !defined(ESP_PLATFORM) -#define DPORT_STAL_OTHER_CPU_START() -#define DPORT_STAL_OTHER_CPU_END() +#define DPORT_STALL_OTHER_CPU_START() +#define DPORT_STALL_OTHER_CPU_END() #else -#define DPORT_STAL_OTHER_CPU_START() esp_dport_access_stall_other_cpu_start() -#define DPORT_STAL_OTHER_CPU_END() esp_dport_access_stall_other_cpu_end() +#define DPORT_STALL_OTHER_CPU_START() esp_dport_access_stall_other_cpu_start() +#define DPORT_STALL_OTHER_CPU_END() esp_dport_access_stall_other_cpu_end() #endif -#define IS_DPORT_REG(_r) (((_r) >= DR_REG_DPORT_BASE) && (_r) <= DPORT_DATE_REG) - //Registers Operation {{ -#define _REG_READ(_r) (*(volatile uint32_t *)(_r)) -#define _REG_WRITE(_r, _v) (*(volatile uint32_t *)(_r)) = (_v) +//Origin access operation for the base and some special scene +#define _DPORT_REG_READ(_r) (*(volatile uint32_t *)(_r)) +#define _DPORT_REG_WRITE(_r, _v) (*(volatile uint32_t *)(_r)) = (_v) //write value to register -#define DPORT_REG_WRITE(_r, _v) _REG_WRITE(_r, _v) +#define DPORT_REG_WRITE(_r, _v) _DPORT_REG_WRITE(_r, _v) //read value from register -inline uint32_t IRAM_ATTR DPORT_REG_READ(uint32_t reg) +static inline uint32_t IRAM_ATTR DPORT_REG_READ(uint32_t reg) { uint32_t val; - DPORT_STAL_OTHER_CPU_START(); - val = _REG_READ(reg); - DPORT_STAL_OTHER_CPU_END(); + DPORT_STALL_OTHER_CPU_START(); + val = _DPORT_REG_READ(reg); + DPORT_STALL_OTHER_CPU_END(); return val; } @@ -54,19 +53,19 @@ inline uint32_t IRAM_ATTR DPORT_REG_READ(uint32_t reg) #define DPORT_REG_GET_BIT(_r, _b) (DPORT_REG_READ(_r) & (_b)) //set bit or set bits to register -#define DPORT_REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b)) +#define DPORT_REG_SET_BIT(_r, _b) DPORT_REG_WRITE((_r), (DPORT_REG_READ(_r)|(_b))) //clear bit or clear bits of register -#define DPORT_REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b)) +#define DPORT_REG_CLR_BIT(_r, _b) DPORT_REG_WRITE((_r), (DPORT_REG_READ(_r) & (~(_b)))) //set bits of register controlled by mask -#define DPORT_REG_SET_BITS(_r, _b, _m) (*(volatile uint32_t*)(_r) = (DPORT_REG_READ(_r) & ~(_m)) | ((_b) & (_m))) +#define DPORT_REG_SET_BITS(_r, _b, _m) DPORT_REG_WRITE((_r), ((DPORT_REG_READ(_r) & (~(_m))) | ((_b) & (_m)))) //get field from register, uses field _S & _V to determine mask #define DPORT_REG_GET_FIELD(_r, _f) ((DPORT_REG_READ(_r) >> (_f##_S)) & (_f##_V)) //set field to register, used when _f is not left shifted by _f##_S -#define DPORT_REG_SET_FIELD(_r, _f, _v) (DPORT_REG_WRITE((_r),((DPORT_REG_READ(_r) & ~((_f) << (_f##_S)))|(((_v) & (_f))<<(_f##_S))))) +#define DPORT_REG_SET_FIELD(_r, _f, _v) DPORT_REG_WRITE((_r), ((DPORT_REG_READ(_r) & (~((_f) << (_f##_S))))|(((_v) & (_f))<<(_f##_S)))) //get field value from a variable, used when _f is not left shifted by _f##_S #define DPORT_VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f)) @@ -90,13 +89,13 @@ inline uint32_t IRAM_ATTR DPORT_REG_READ(uint32_t reg) #define _WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)(addr))) = (uint32_t)(val) //read value from register -inline uint32_t IRAM_ATTR DPORT_READ_PERI_REG(uint32_t addr) +static inline uint32_t IRAM_ATTR DPORT_READ_PERI_REG(uint32_t addr) { uint32_t val; - DPORT_STAL_OTHER_CPU_START(); + DPORT_STALL_OTHER_CPU_START(); val = _READ_PERI_REG(addr); - DPORT_STAL_OTHER_CPU_END(); + DPORT_STALL_OTHER_CPU_END(); return val; } diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index fa99d9131..218cdf96d 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -17,6 +17,7 @@ #ifndef __ASSEMBLER__ #include +#include "esp_assert.h" #endif //Register Bits{{ @@ -57,98 +58,6 @@ #define PRO_CPU_NUM (0) #define APP_CPU_NUM (1) -//Registers Operation {{ -#define ETS_UNCACHED_ADDR(addr) (addr) -#define ETS_CACHED_ADDR(addr) (addr) - -#ifndef __ASSEMBLER__ -#define BIT(nr) (1UL << (nr)) -#else -#define BIT(nr) (1 << (nr)) -#endif - -#ifndef __ASSEMBLER__ -//write value to register -#define REG_WRITE(_r, _v) (*(volatile uint32_t *)(_r)) = (_v) - -//read value from register -#define REG_READ(_r) (*(volatile uint32_t *)(_r)) - -//get bit or get bits from register -#define REG_GET_BIT(_r, _b) (*(volatile uint32_t*)(_r) & (_b)) - -//set bit or set bits to register -#define REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b)) - -//clear bit or clear bits of register -#define REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b)) - -//set bits of register controlled by mask -#define REG_SET_BITS(_r, _b, _m) (*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r) & ~(_m)) | ((_b) & (_m))) - -//get field from register, uses field _S & _V to determine mask -#define REG_GET_FIELD(_r, _f) ((REG_READ(_r) >> (_f##_S)) & (_f##_V)) - -//set field of a register from variable, uses field _S & _V to determine mask -#define REG_SET_FIELD(_r, _f, _v) (REG_WRITE((_r),((REG_READ(_r) & ~((_f##_V) << (_f##_S)))|(((_v) & (_f##_V))<<(_f##_S))))) - -//get field value from a variable, used when _f is not left shifted by _f##_S -#define VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f)) - -//get field value from a variable, used when _f is left shifted by _f##_S -#define VALUE_GET_FIELD2(_r, _f) (((_r) & (_f))>> (_f##_S)) - -//set field value to a variable, used when _f is not left shifted by _f##_S -#define VALUE_SET_FIELD(_r, _f, _v) ((_r)=(((_r) & ~((_f) << (_f##_S)))|((_v)<<(_f##_S)))) - -//set field value to a variable, used when _f is left shifted by _f##_S -#define VALUE_SET_FIELD2(_r, _f, _v) ((_r)=(((_r) & ~(_f))|((_v)<<(_f##_S)))) - -//generate a value from a field value, used when _f is not left shifted by _f##_S -#define FIELD_TO_VALUE(_f, _v) (((_v)&(_f))<<_f##_S) - -//generate a value from a field value, used when _f is left shifted by _f##_S -#define FIELD_TO_VALUE2(_f, _v) (((_v)<<_f##_S) & (_f)) - -//read value from register -#define READ_PERI_REG(addr) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) - -//write value to register -#define WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val) - -//clear bits of register controlled by mask -#define CLEAR_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg)&(~(mask)))) - -//set bits of register controlled by mask -#define SET_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg)|(mask))) - -//get bits of register controlled by mask -#define GET_PERI_REG_MASK(reg, mask) (READ_PERI_REG(reg) & (mask)) - -//get bits of register controlled by highest bit and lowest bit -#define GET_PERI_REG_BITS(reg, hipos,lowpos) ((READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1)) - -//set bits of register controlled by mask and shift -#define SET_PERI_REG_BITS(reg,bit_map,value,shift) (WRITE_PERI_REG((reg),(READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|(((value) & bit_map)<<(shift)) )) - -//get field of register -#define GET_PERI_REG_BITS2(reg, mask,shift) ((READ_PERI_REG(reg)>>(shift))&(mask)) -//}} - -#endif /* !__ASSEMBLER__ */ - -//Periheral Clock {{ -#define APB_CLK_FREQ_ROM ( 26*1000000 ) -#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM -#define CPU_CLK_FREQ APB_CLK_FREQ -#define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz -#define UART_CLK_FREQ APB_CLK_FREQ -#define WDT_CLK_FREQ APB_CLK_FREQ -#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16 -#define SPI_CLK_DIV 4 -#define TICKS_PER_US_ROM 26 // CPU is 80MHz -//}} - /* Overall memory map */ #define SOC_IROM_LOW 0x400D0000 #define SOC_IROM_HIGH 0x40400000 @@ -160,6 +69,7 @@ #define SOC_RTC_DATA_HIGH 0x50002000 #define DR_REG_DPORT_BASE 0x3ff00000 +#define DR_REG_DPORT_END 0x3ff00FFC #define DR_REG_RSA_BASE 0x3ff02000 #define DR_REG_SHA_BASE 0x3ff03000 #define DR_REG_UART_BASE 0x3ff40000 @@ -210,6 +120,155 @@ #define DR_REG_PWM3_BASE 0x3ff70000 #define PERIPHS_SPI_ENCRYPT_BASEADDR DR_REG_SPI_ENCRYPT_BASE +//Registers Operation {{ +#define ETS_UNCACHED_ADDR(addr) (addr) +#define ETS_CACHED_ADDR(addr) (addr) + +#ifndef __ASSEMBLER__ +#define BIT(nr) (1UL << (nr)) +#else +#define BIT(nr) (1 << (nr)) +#endif + +#ifndef __ASSEMBLER__ + +#define IS_DPORT_REG(_r) (((_r) >= DR_REG_DPORT_BASE) && (_r) <= DR_REG_DPORT_END) + +#if !defined( BOOTLOADER_BUILD ) && !defined( CONFIG_FREERTOS_UNICORE ) && defined( ESP_PLATFORM ) +#define ASSERT_IF_DPORT_REG(_r, OP) TRY_STATIC_ASSERT(!IS_DPORT_REG(_r), (Cannot use OP for DPORT registers use DPORT_##OP)); +#else +#define ASSERT_IF_DPORT_REG(_r, OP) +#endif + +//write value to register +#define REG_WRITE(_r, _v) ({ \ + ASSERT_IF_DPORT_REG(_r, REG_WRITE); \ + (*(volatile uint32_t *)(_r)) = (_v); \ + }) + +//read value from register +#define REG_READ(_r) ({ \ + ASSERT_IF_DPORT_REG((_r), REG_READ); \ + (*(volatile uint32_t *)_r); \ + }) + +//get bit or get bits from register +#define REG_GET_BIT(_r, _b) ({ \ + ASSERT_IF_DPORT_REG((_r), REG_GET_BIT); \ + (*(volatile uint32_t*)(_r) & (_b)); \ + }) + +//set bit or set bits to register +#define REG_SET_BIT(_r, _b) ({ \ + ASSERT_IF_DPORT_REG((_r), REG_SET_BIT); \ + (*(volatile uint32_t*)(_r) |= (_b)); \ + }) + +//clear bit or clear bits of register +#define REG_CLR_BIT(_r, _b) ({ \ + ASSERT_IF_DPORT_REG((_r), REG_CLR_BIT); \ + (*(volatile uint32_t*)(_r) &= ~(_b)); \ + }) + +//set bits of register controlled by mask +#define REG_SET_BITS(_r, _b, _m) ({ \ + ASSERT_IF_DPORT_REG((_r), REG_SET_BITS); \ + (*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r) & ~(_m)) | ((_b) & (_m))); \ + }) + +//get field from register, uses field _S & _V to determine mask +#define REG_GET_FIELD(_r, _f) ({ \ + ASSERT_IF_DPORT_REG((_r), REG_GET_FIELD); \ + ((REG_READ(_r) >> (_f##_S)) & (_f##_V)); \ + }) + +//set field of a register from variable, uses field _S & _V to determine mask +#define REG_SET_FIELD(_r, _f, _v) ({ \ + ASSERT_IF_DPORT_REG((_r), REG_SET_FIELD); \ + (REG_WRITE((_r),((REG_READ(_r) & ~((_f##_V) << (_f##_S)))|(((_v) & (_f##_V))<<(_f##_S))))); \ + }) + +//get field value from a variable, used when _f is not left shifted by _f##_S +#define VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f)) + +//get field value from a variable, used when _f is left shifted by _f##_S +#define VALUE_GET_FIELD2(_r, _f) (((_r) & (_f))>> (_f##_S)) + +//set field value to a variable, used when _f is not left shifted by _f##_S +#define VALUE_SET_FIELD(_r, _f, _v) ((_r)=(((_r) & ~((_f) << (_f##_S)))|((_v)<<(_f##_S)))) + +//set field value to a variable, used when _f is left shifted by _f##_S +#define VALUE_SET_FIELD2(_r, _f, _v) ((_r)=(((_r) & ~(_f))|((_v)<<(_f##_S)))) + +//generate a value from a field value, used when _f is not left shifted by _f##_S +#define FIELD_TO_VALUE(_f, _v) (((_v)&(_f))<<_f##_S) + +//generate a value from a field value, used when _f is left shifted by _f##_S +#define FIELD_TO_VALUE2(_f, _v) (((_v)<<_f##_S) & (_f)) + +//read value from register +#define READ_PERI_REG(addr) ({ \ + ASSERT_IF_DPORT_REG((addr), READ_PERI_REG); \ + (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))); \ + }) + +//write value to register +#define WRITE_PERI_REG(addr, val) ({ \ + ASSERT_IF_DPORT_REG((addr), WRITE_PERI_REG); \ + (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val); \ + }) + +//clear bits of register controlled by mask +#define CLEAR_PERI_REG_MASK(reg, mask) ({ \ + ASSERT_IF_DPORT_REG((reg), CLEAR_PERI_REG_MASK); \ + WRITE_PERI_REG((reg), (READ_PERI_REG(reg)&(~(mask)))); \ + }) + +//set bits of register controlled by mask +#define SET_PERI_REG_MASK(reg, mask) ({ \ + ASSERT_IF_DPORT_REG((reg), SET_PERI_REG_MASK); \ + WRITE_PERI_REG((reg), (READ_PERI_REG(reg)|(mask))); \ + }) + +//get bits of register controlled by mask +#define GET_PERI_REG_MASK(reg, mask) ({ \ + ASSERT_IF_DPORT_REG((reg), GET_PERI_REG_MASK); \ + (READ_PERI_REG(reg) & (mask)); \ + }) + +//get bits of register controlled by highest bit and lowest bit +#define GET_PERI_REG_BITS(reg, hipos,lowpos) ({ \ + ASSERT_IF_DPORT_REG((reg), GET_PERI_REG_BITS); \ + ((READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1)); \ + }) + +//set bits of register controlled by mask and shift +#define SET_PERI_REG_BITS(reg,bit_map,value,shift) ({ \ + ASSERT_IF_DPORT_REG((reg), SET_PERI_REG_BITS); \ + (WRITE_PERI_REG((reg),(READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|(((value) & bit_map)<<(shift)) )); \ + }) + +//get field of register +#define GET_PERI_REG_BITS2(reg, mask,shift) ({ \ + ASSERT_IF_DPORT_REG((reg), GET_PERI_REG_BITS2); \ + ((READ_PERI_REG(reg)>>(shift))&(mask)); \ + }) + +#endif /* !__ASSEMBLER__ */ +//}} + +//Periheral Clock {{ +#define APB_CLK_FREQ_ROM ( 26*1000000 ) +#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM +#define CPU_CLK_FREQ APB_CLK_FREQ +#define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz +#define UART_CLK_FREQ APB_CLK_FREQ +#define WDT_CLK_FREQ APB_CLK_FREQ +#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16 +#define SPI_CLK_DIV 4 +#define TICKS_PER_US_ROM 26 // CPU is 80MHz +//}} + //Interrupt hardware source table //This table is decided by hardware, don't touch this. #define ETS_WIFI_MAC_INTR_SOURCE 0/**< interrupt of WiFi MAC, level*/