-
Notifications
You must be signed in to change notification settings - Fork 7.2k
/
soc.h
254 lines (203 loc) · 12.8 KB
/
soc.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/*
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifndef __ASSEMBLER__
#include <stdint.h>
#include "esp_assert.h"
#include "soc/soc_caps.h"
#include "soc/interrupts.h"
#endif
#include "esp_bit_defs.h"
#include "reg_base.h"
#define PRO_CPU_NUM (0)
#define APP_CPU_NUM (1)
#define SOC_MAX_CONTIGUOUS_RAM_SIZE 0x400000 ///< Largest span of contiguous memory (DRAM or IRAM) in the address space
//Registers Operation {{
#define ETS_UNCACHED_ADDR(addr) (addr)
#define ETS_CACHED_ADDR(addr) (addr)
#ifndef __ASSEMBLER__
#define IS_DPORT_REG(_r) (((_r) >= DR_REG_DPORT_BASE) && (_r) <= DR_REG_DPORT_END)
#if !defined( BOOTLOADER_BUILD ) && !defined( CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE ) && SOC_DPORT_WORKAROUND
#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) do { \
ASSERT_IF_DPORT_REG((_r), REG_WRITE); \
(*(volatile uint32_t *)(_r)) = (_v); \
} while(0)
//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) do { \
ASSERT_IF_DPORT_REG((_r), REG_SET_BIT); \
*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r)) | (_b); \
} while(0)
//clear bit or clear bits of register
#define REG_CLR_BIT(_r, _b) do { \
ASSERT_IF_DPORT_REG((_r), REG_CLR_BIT); \
*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r)) & (~(_b)); \
} while(0)
//set bits of register controlled by mask
#define REG_SET_BITS(_r, _b, _m) do { \
ASSERT_IF_DPORT_REG((_r), REG_SET_BITS); \
*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r) & ~(_m)) | ((_b) & (_m)); \
} while(0)
//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) do { \
ASSERT_IF_DPORT_REG((_r), REG_SET_FIELD); \
REG_WRITE((_r),((REG_READ(_r) & ~((_f##_V) << (_f##_S)))|(((_v) & (_f##_V))<<(_f##_S)))); \
} while(0)
//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) do { \
ASSERT_IF_DPORT_REG((addr), WRITE_PERI_REG); \
(*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val); \
} while(0)
//clear bits of register controlled by mask
#define CLEAR_PERI_REG_MASK(reg, mask) do { \
ASSERT_IF_DPORT_REG((reg), CLEAR_PERI_REG_MASK); \
WRITE_PERI_REG((reg), (READ_PERI_REG(reg)&(~(mask)))); \
} while(0)
//set bits of register controlled by mask
#define SET_PERI_REG_MASK(reg, mask) do { \
ASSERT_IF_DPORT_REG((reg), SET_PERI_REG_MASK); \
WRITE_PERI_REG((reg), (READ_PERI_REG(reg)|(mask))); \
} while(0)
//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) do { \
ASSERT_IF_DPORT_REG((reg), SET_PERI_REG_BITS); \
WRITE_PERI_REG((reg),(READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|(((value) & (bit_map))<<(shift)) ); \
} while(0)
//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_MHZ_BTLD (80) // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
#define APB_CLK_FREQ ( 80*1000000 ) //unit: Hz
#define MODEM_REQUIRED_MIN_APB_CLK_FREQ ( 80*1000000 )
#define REF_CLK_FREQ ( 1000000 )
#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_DROM_LOW 0x3F400000
#define SOC_DROM_HIGH 0x3F800000
#define SOC_DRAM_LOW 0x3FFAE000
#define SOC_DRAM_HIGH 0x40000000
#define SOC_IROM_LOW 0x400D0000
#define SOC_IROM_HIGH 0x40400000
#define SOC_IROM_MASK_LOW 0x40000000
#define SOC_IROM_MASK_HIGH 0x40070000
#define SOC_CACHE_PRO_LOW 0x40070000
#define SOC_CACHE_PRO_HIGH 0x40078000
#define SOC_CACHE_APP_LOW 0x40078000
#define SOC_CACHE_APP_HIGH 0x40080000
#define SOC_IRAM_LOW 0x40080000
#define SOC_IRAM_HIGH 0x400AA000
#define SOC_RTC_IRAM_LOW 0x400C0000
#define SOC_RTC_IRAM_HIGH 0x400C2000
#define SOC_RTC_DRAM_LOW 0x3FF80000
#define SOC_RTC_DRAM_HIGH 0x3FF82000
#define SOC_RTC_DATA_LOW 0x50000000
#define SOC_RTC_DATA_HIGH 0x50002000
#define SOC_EXTRAM_DATA_LOW 0x3F800000
#define SOC_EXTRAM_DATA_HIGH 0x3FC00000
#define SOC_EXTRAM_DATA_SIZE (SOC_EXTRAM_DATA_HIGH - SOC_EXTRAM_DATA_LOW)
//First and last words of the D/IRAM region, for both the DRAM address as well as the IRAM alias.
#define SOC_DIRAM_IRAM_LOW 0x400A0000
#define SOC_DIRAM_IRAM_HIGH 0x400C0000
#define SOC_DIRAM_DRAM_LOW 0x3FFE0000
#define SOC_DIRAM_DRAM_HIGH 0x40000000
// Byte order of D/IRAM regions is reversed between accessing as DRAM or IRAM
#define SOC_DIRAM_INVERTED 1
// Region of memory accessible via DMA. See esp_ptr_dma_capable().
#define SOC_DMA_LOW 0x3FFAE000
#define SOC_DMA_HIGH 0x40000000
// Region of memory that is byte-accessible. See esp_ptr_byte_accessible().
#define SOC_BYTE_ACCESSIBLE_LOW 0x3FF90000
#define SOC_BYTE_ACCESSIBLE_HIGH 0x40000000
//Region of memory that is internal, as in on the same silicon die as the ESP32 CPUs
//(excluding RTC data region, that's checked separately.) See esp_ptr_internal().
#define SOC_MEM_INTERNAL_LOW 0x3FF90000
#define SOC_MEM_INTERNAL_HIGH 0x400C2000
// Start (highest address) of ROM boot stack, only relevant during early boot
#define SOC_ROM_STACK_START 0x3ffe3f20
#define ETS_WMAC_INUM 0
#define ETS_BT_HOST_INUM 1
#define ETS_WBB_INUM 4
#if CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5
#define ETS_T1_WDT_CACHEERR_INUM 26
#define ETS_T1_WDT_INUM ETS_T1_WDT_CACHEERR_INUM
#define ETS_MEMACCESS_ERR_INUM ETS_T1_WDT_CACHEERR_INUM
/* backwards compatibility only, use ETS_MEMACCESS_ERR_INUM instead*/
#define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM
#define ETS_IPC_ISR_INUM 31
#elif CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4
#define ETS_T1_WDT_INUM 24
#define ETS_MEMACCESS_ERR_INUM 25
/* backwards compatibility only, use ETS_MEMACCESS_ERR_INUM instead*/
#define ETS_CACHEERR_INUM ETS_MEMACCESS_ERR_INUM
#define ETS_IPC_ISR_INUM 28
#endif /* CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 */
//CPU0 Interrupt number used in ROM, should be cancelled in SDK
#define ETS_SLC_INUM 1
#define ETS_UART0_INUM 5
#define ETS_UART1_INUM 5
//Other interrupt number should be managed by the user
//Invalid interrupt for number interrupt matrix
#define ETS_INVALID_INUM 6
// Interrupt number for the Interrupt watchdog
#define ETS_INT_WDT_INUM (ETS_T1_WDT_INUM)