1 /*
2  * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #ifndef __ASSEMBLER__
10 #include <stdint.h>
11 #include "esp_assert.h"
12 #endif
13 
14 #include "esp_bit_defs.h"
15 #include "reg_base.h"
16 
17 #define PRO_CPU_NUM (0)
18 
19 #define REG_UHCI_BASE(i)                        (DR_REG_UHCI0_BASE)                      // only one UHCI on C6
20 #define REG_UART_BASE(i)                        (DR_REG_UART_BASE + (i) * 0x1000)        // UART0 and UART1
21 #define REG_UART_AHB_BASE(i)                    (0x60000000 + (i) * 0x10000)
22 #define UART_FIFO_AHB_REG(i)                    (REG_UART_AHB_BASE(i) + 0x0)
23 #define REG_I2S_BASE(i)                         (DR_REG_I2S_BASE)                        // only one I2S on C6
24 #define REG_TIMG_BASE(i)                        (DR_REG_TIMERGROUP0_BASE + (i) * 0x1000) // TIMERG0 and TIMERG1
25 #define REG_SPI_MEM_BASE(i)                     (DR_REG_SPI0_BASE + (i) * 0x1000)        // SPIMEM0 and SPIMEM1
26 #define REG_SPI_BASE(i)                         (((i)==2) ? (DR_REG_SPI2_BASE) : (0))    // only one GPSPI on C6
27 #define REG_I2C_BASE(i)                         (DR_REG_I2C_EXT_BASE)                    // only one I2C on C6
28 #define REG_MCPWM_BASE(i)                       (DR_REG_MCPWM_BASE)                      // only one MCPWM on C6
29 #define REG_TWAI_BASE(i)                        (DR_REG_TWAI0_BASE + (i) * 0x2000)       // TWAI0 and TWAI1
30 
31 //Registers Operation {{
32 #define ETS_UNCACHED_ADDR(addr) (addr)
33 #define ETS_CACHED_ADDR(addr) (addr)
34 
35 #ifndef __ASSEMBLER__
36 
37 //write value to register
38 #define REG_WRITE(_r, _v)  do {                                                                                        \
39             (*(volatile uint32_t *)(_r)) = (_v);                                                                       \
40         } while(0)
41 
42 //read value from register
43 #define REG_READ(_r) ({                                                                                                \
44             (*(volatile uint32_t *)(_r));                                                                              \
45         })
46 
47 //get bit or get bits from register
48 #define REG_GET_BIT(_r, _b)  ({                                                                                        \
49             (*(volatile uint32_t*)(_r) & (_b));                                                                        \
50         })
51 
52 //set bit or set bits to register
53 #define REG_SET_BIT(_r, _b)  do {                                                                                      \
54             *(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r)) | (_b);                                            \
55         } while(0)
56 
57 //clear bit or clear bits of register
58 #define REG_CLR_BIT(_r, _b)  do {                                                                                      \
59             *(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r)) & (~(_b));                                         \
60         } while(0)
61 
62 //set bits of register controlled by mask
63 #define REG_SET_BITS(_r, _b, _m) do {                                                                                  \
64             *(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r) & ~(_m)) | ((_b) & (_m));                           \
65         } while(0)
66 
67 //get field from register, uses field _S & _V to determine mask
68 #define REG_GET_FIELD(_r, _f) ({                                                                                       \
69             ((REG_READ(_r) >> (_f##_S)) & (_f##_V));                                                                   \
70         })
71 
72 //set field of a register from variable, uses field _S & _V to determine mask
73 #define REG_SET_FIELD(_r, _f, _v) do {                                                                                 \
74             REG_WRITE((_r),((REG_READ(_r) & ~((_f##_V) << (_f##_S)))|(((_v) & (_f##_V))<<(_f##_S))));                  \
75         } while(0)
76 
77 //get field value from a variable, used when _f is not left shifted by _f##_S
78 #define VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f))
79 
80 //get field value from a variable, used when _f is left shifted by _f##_S
81 #define VALUE_GET_FIELD2(_r, _f) (((_r) & (_f))>> (_f##_S))
82 
83 //set field value to a variable, used when _f is not left shifted by _f##_S
84 #define VALUE_SET_FIELD(_r, _f, _v) ((_r)=(((_r) & ~((_f) << (_f##_S)))|((_v)<<(_f##_S))))
85 
86 //set field value to a variable, used when _f is left shifted by _f##_S
87 #define VALUE_SET_FIELD2(_r, _f, _v) ((_r)=(((_r) & ~(_f))|((_v)<<(_f##_S))))
88 
89 //generate a value from a field value, used when _f is not left shifted by _f##_S
90 #define FIELD_TO_VALUE(_f, _v) (((_v)&(_f))<<_f##_S)
91 
92 //generate a value from a field value, used when _f is left shifted by _f##_S
93 #define FIELD_TO_VALUE2(_f, _v) (((_v)<<_f##_S) & (_f))
94 
95 //read value from register
96 #define READ_PERI_REG(addr) ({                                                                                         \
97             (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr)));                                                         \
98         })
99 
100 //write value to register
101 #define WRITE_PERI_REG(addr, val) do {                                                                                 \
102             (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val);                                       \
103         } while(0)
104 
105 //clear bits of register controlled by mask
106 #define CLEAR_PERI_REG_MASK(reg, mask)  do {                                                                           \
107             WRITE_PERI_REG((reg), (READ_PERI_REG(reg)&(~(mask))));                                                     \
108         } while(0)
109 
110 //set bits of register controlled by mask
111 #define SET_PERI_REG_MASK(reg, mask) do {                                                                              \
112             WRITE_PERI_REG((reg), (READ_PERI_REG(reg)|(mask)));                                                        \
113         } while(0)
114 
115 //get bits of register controlled by mask
116 #define GET_PERI_REG_MASK(reg, mask) ({                                                                                \
117             (READ_PERI_REG(reg) & (mask));                                                                             \
118         })
119 
120 //get bits of register controlled by highest bit and lowest bit
121 #define GET_PERI_REG_BITS(reg, hipos,lowpos) ({                                                                        \
122             ((READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1));                                            \
123         })
124 
125 //set bits of register controlled by mask and shift
126 #define SET_PERI_REG_BITS(reg,bit_map,value,shift) do {                                                                \
127             WRITE_PERI_REG((reg),(READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|(((value) & (bit_map))<<(shift)) );      \
128         } while(0)
129 
130 //get field of register
131 #define GET_PERI_REG_BITS2(reg, mask,shift) ({                                                                         \
132             ((READ_PERI_REG(reg)>>(shift))&(mask));                                                                    \
133         })
134 
135 #endif /* !__ASSEMBLER__ */
136 //}}
137 
138 //Periheral Clock {{
139 #define  APB_CLK_FREQ_ROM                            ( 40*1000000 )
140 #define  CPU_CLK_FREQ_ROM                            APB_CLK_FREQ_ROM
141 #define  EFUSE_CLK_FREQ_ROM                          ( 20*1000000)
142 #define  CPU_CLK_FREQ_MHZ_BTLD                       (80)               // The cpu clock frequency (in MHz) to set at 2nd stage bootloader system clock configuration
143 #define  CPU_CLK_FREQ                                APB_CLK_FREQ
144 #define  APB_CLK_FREQ                                ( 40*1000000 )
145 #define  MODEM_APB_CLK_FREQ                          ( 80*1000000 )
146 #define  REF_CLK_FREQ                                ( 1000000 )
147 #define  XTAL_CLK_FREQ                               (40*1000000)
148 #define  GPIO_MATRIX_DELAY_NS                        0
149 //}}
150 
151 /* Overall memory map */
152 /* Note: We should not use MACROs similar in cache_memory.h
153  * those are defined during run-time. But the MACROs here
154  * should be defined statically!
155  */
156 
157 #define SOC_IROM_LOW    0x42000000
158 #define SOC_IROM_HIGH   (SOC_IROM_LOW + (CONFIG_MMU_PAGE_SIZE<<8))
159 #define SOC_DROM_LOW    SOC_IROM_LOW
160 #define SOC_DROM_HIGH   SOC_IROM_HIGH
161 #define SOC_IROM_MASK_LOW  0x40000000
162 #define SOC_IROM_MASK_HIGH 0x40050000
163 #define SOC_DROM_MASK_LOW  0x40000000
164 #define SOC_DROM_MASK_HIGH 0x40050000
165 #define SOC_IRAM_LOW    0x40800000
166 #define SOC_IRAM_HIGH   0x40880000
167 #define SOC_DRAM_LOW    0x40800000
168 #define SOC_DRAM_HIGH   0x40880000
169 #define SOC_RTC_IRAM_LOW  0x50000000 // ESP32-C6 only has 16k LP memory
170 #define SOC_RTC_IRAM_HIGH 0x50004000
171 #define SOC_RTC_DRAM_LOW  0x50000000
172 #define SOC_RTC_DRAM_HIGH 0x50004000
173 #define SOC_RTC_DATA_LOW  0x50000000
174 #define SOC_RTC_DATA_HIGH 0x50004000
175 
176 //First and last words of the D/IRAM region, for both the DRAM address as well as the IRAM alias.
177 #define SOC_DIRAM_IRAM_LOW    0x40800000
178 #define SOC_DIRAM_IRAM_HIGH   0x40880000
179 #define SOC_DIRAM_DRAM_LOW    0x40800000
180 #define SOC_DIRAM_DRAM_HIGH   0x40880000
181 
182 #define MAP_DRAM_TO_IRAM(addr) (addr)
183 #define MAP_IRAM_TO_DRAM(addr) (addr)
184 
185 // Region of memory accessible via DMA. See esp_ptr_dma_capable().
186 #define SOC_DMA_LOW  0x40800000
187 #define SOC_DMA_HIGH 0x40880000
188 
189 // Region of RAM that is byte-accessible. See esp_ptr_byte_accessible().
190 #define SOC_BYTE_ACCESSIBLE_LOW     0x40800000
191 #define SOC_BYTE_ACCESSIBLE_HIGH    0x40880000
192 
193 //Region of memory that is internal, as in on the same silicon die as the ESP32 CPUs
194 //(excluding RTC data region, that's checked separately.) See esp_ptr_internal().
195 #define SOC_MEM_INTERNAL_LOW        0x40800000
196 #define SOC_MEM_INTERNAL_HIGH       0x40880000
197 #define SOC_MEM_INTERNAL_LOW1       0x40800000
198 #define SOC_MEM_INTERNAL_HIGH1      0x40880000
199 
200 #define SOC_MAX_CONTIGUOUS_RAM_SIZE (SOC_IRAM_HIGH - SOC_IRAM_LOW) ///< Largest span of contiguous memory (DRAM or IRAM) in the address space
201 
202 // Region of address space that holds peripherals
203 #define SOC_PERIPHERAL_LOW 0x60000000
204 #define SOC_PERIPHERAL_HIGH 0x60100000
205 
206 // CPU sub-system region, contains interrupt config registers
207 #define SOC_CPU_SUBSYSTEM_LOW 0x20000000
208 #define SOC_CPU_SUBSYSTEM_HIGH 0x30000000
209 
210 // Start (highest address) of ROM boot stack, only relevant during early boot
211 #define SOC_ROM_STACK_START         0x4087e610
212 #define SOC_ROM_STACK_SIZE          0x2000
213 
214 //On RISC-V CPUs, the interrupt sources are all external interrupts, whose type, source and priority are configured by SW.
215 //There is no HW NMI conception. SW should controlled the masked levels through INT_THRESH_REG.
216 
217 //CPU0 Interrupt number reserved in riscv/vector.S, not touch this.
218 #define ETS_T1_WDT_INUM                         24
219 #define ETS_CACHEERR_INUM                       25
220 #define ETS_MEMPROT_ERR_INUM                    26
221 //CPU0 Max valid interrupt number
222 #define ETS_MAX_INUM                            31
223 
224 //CPU0 Interrupt number used in ROM, should be cancelled in SDK
225 #define ETS_SLC_INUM                            1
226 #define ETS_UART0_INUM                          5
227 #define ETS_UART1_INUM                          5
228 #define ETS_SPI2_INUM                           1
229 //CPU0 Interrupt number used in ROM code only when module init function called, should pay attention here.
230 #define ETS_GPIO_INUM       4
231 
232 //Other interrupt number should be managed by the user
233 
234 //Invalid interrupt for number interrupt matrix
235 #define ETS_INVALID_INUM                        0
236 
237 //Interrupt medium level, used for INT WDT for example
238 #define SOC_INTERRUPT_LEVEL_MEDIUM              4
239 
240 // Interrupt number for the Interrupt watchdog
241 #define ETS_INT_WDT_INUM                         (ETS_T1_WDT_INUM)
242