Flipper Zero Firmware
Loading...
Searching...
No Matches
furi_hal_bus.c
1#include <furi_hal_bus.h>
2#include <furi.h>
3
4#include <stm32wbxx_ll_bus.h>
5
6/* Bus bitmask definitions */
7#define FURI_HAL_BUS_IGNORE (0x0U)
8
9#define FURI_HAL_BUS_AHB1_GRP1 \
10 (LL_AHB1_GRP1_PERIPH_DMA1 | LL_AHB1_GRP1_PERIPH_DMA2 | LL_AHB1_GRP1_PERIPH_DMAMUX1 | \
11 LL_AHB1_GRP1_PERIPH_CRC | LL_AHB1_GRP1_PERIPH_TSC)
12
13#if defined(ADC_SUPPORT_5_MSPS)
14#define FURI_HAL_BUS_AHB2_GRP1 \
15 (LL_AHB2_GRP1_PERIPH_GPIOA | LL_AHB2_GRP1_PERIPH_GPIOB | LL_AHB2_GRP1_PERIPH_GPIOC | \
16 LL_AHB2_GRP1_PERIPH_GPIOD | LL_AHB2_GRP1_PERIPH_GPIOE | LL_AHB2_GRP1_PERIPH_GPIOH | \
17 LL_AHB2_GRP1_PERIPH_ADC | LL_AHB2_GRP1_PERIPH_AES1)
18
19#define FURI_HAL_BUS_APB2_GRP1 \
20 (LL_APB2_GRP1_PERIPH_TIM1 | LL_APB2_GRP1_PERIPH_SPI1 | LL_APB2_GRP1_PERIPH_USART1 | \
21 LL_APB2_GRP1_PERIPH_TIM16 | LL_APB2_GRP1_PERIPH_TIM17 | LL_APB2_GRP1_PERIPH_SAI1)
22#else
23#define FURI_HAL_BUS_AHB2_GRP1 \
24 (LL_AHB2_GRP1_PERIPH_GPIOA | LL_AHB2_GRP1_PERIPH_GPIOB | LL_AHB2_GRP1_PERIPH_GPIOC | \
25 LL_AHB2_GRP1_PERIPH_GPIOD | LL_AHB2_GRP1_PERIPH_GPIOE | LL_AHB2_GRP1_PERIPH_GPIOH | \
26 LL_AHB2_GRP1_PERIPH_AES1)
27
28#define FURI_HAL_BUS_APB2_GRP1 \
29 (LL_APB2_GRP1_PERIPH_ADC | LL_APB2_GRP1_PERIPH_TIM1 | LL_APB2_GRP1_PERIPH_SPI1 | \
30 LL_APB2_GRP1_PERIPH_USART1 | LL_APB2_GRP1_PERIPH_TIM16 | LL_APB2_GRP1_PERIPH_TIM17 | \
31 LL_APB2_GRP1_PERIPH_SAI1)
32#endif
33
34#define FURI_HAL_BUS_AHB3_GRP1 \
35 (LL_AHB3_GRP1_PERIPH_QUADSPI | LL_AHB3_GRP1_PERIPH_PKA | LL_AHB3_GRP1_PERIPH_AES2 | \
36 LL_AHB3_GRP1_PERIPH_RNG | LL_AHB3_GRP1_PERIPH_HSEM | LL_AHB3_GRP1_PERIPH_IPCC)
37// LL_AHB3_GRP1_PERIPH_FLASH enabled by default
38
39#define FURI_HAL_BUS_APB1_GRP1 \
40 (LL_APB1_GRP1_PERIPH_TIM2 | LL_APB1_GRP1_PERIPH_LCD | LL_APB1_GRP1_PERIPH_SPI2 | \
41 LL_APB1_GRP1_PERIPH_I2C1 | LL_APB1_GRP1_PERIPH_I2C3 | LL_APB1_GRP1_PERIPH_CRS | \
42 LL_APB1_GRP1_PERIPH_USB | LL_APB1_GRP1_PERIPH_LPTIM1)
43
44#define FURI_HAL_BUS_APB1_GRP2 (LL_APB1_GRP2_PERIPH_LPUART1 | LL_APB1_GRP2_PERIPH_LPTIM2)
45#define FURI_HAL_BUS_APB3_GRP1 (LL_APB3_GRP1_PERIPH_RF)
46
47/* Test macro definitions */
48#define FURI_HAL_BUS_IS_ALL_CLEAR(reg, value) (READ_BIT((reg), (value)) == 0UL)
49#define FURI_HAL_BUS_IS_ALL_SET(reg, value) (READ_BIT((reg), (value)) == (value))
50
51#define FURI_HAL_BUS_IS_CLOCK_ENABLED(bus, value, ...) \
52 (FURI_HAL_BUS_IS_ALL_SET(RCC->bus##ENR##__VA_ARGS__, (value)))
53#define FURI_HAL_BUS_IS_CLOCK_DISABLED(bus, value, ...) \
54 (FURI_HAL_BUS_IS_ALL_CLEAR(RCC->bus##ENR##__VA_ARGS__, (value)))
55
56#define FURI_HAL_BUS_IS_RESET_ASSERTED(bus, value, ...) \
57 (FURI_HAL_BUS_IS_ALL_SET(RCC->bus##RSTR##__VA_ARGS__, (value)))
58#define FURI_HAL_BUS_IS_RESET_DEASSERTED(bus, value, ...) \
59 (FURI_HAL_BUS_IS_ALL_CLEAR(RCC->bus##RSTR##__VA_ARGS__, (value)))
60
61#define FURI_HAL_BUS_IS_PERIPH_ENABLED(bus, value, ...) \
62 (FURI_HAL_BUS_IS_RESET_DEASSERTED(bus, (value), __VA_ARGS__) && \
63 FURI_HAL_BUS_IS_CLOCK_ENABLED(bus, (value), __VA_ARGS__))
64
65#define FURI_HAL_BUS_IS_PERIPH_DISABLED(bus, value, ...) \
66 (FURI_HAL_BUS_IS_CLOCK_DISABLED(bus, (value), __VA_ARGS__) && \
67 FURI_HAL_BUS_IS_RESET_ASSERTED(bus, (value), __VA_ARGS__))
68
69/* Control macro definitions */
70#define FURI_HAL_BUS_RESET_ASSERT(bus, value, grp) LL_##bus##_GRP##grp##_ForceReset(value)
71#define FURI_HAL_BUS_RESET_DEASSERT(bus, value, grp) LL_##bus##_GRP##grp##_ReleaseReset(value)
72
73#define FURI_HAL_BUS_CLOCK_ENABLE(bus, value, grp) LL_##bus##_GRP##grp##_EnableClock(value)
74#define FURI_HAL_BUS_CLOCK_DISABLE(bus, value, grp) LL_##bus##_GRP##grp##_DisableClock(value)
75
76#define FURI_HAL_BUS_PERIPH_ENABLE(bus, value, grp) \
77 FURI_HAL_BUS_CLOCK_ENABLE(bus, value, grp); \
78 FURI_HAL_BUS_RESET_DEASSERT(bus, value, grp)
79
80#define FURI_HAL_BUS_PERIPH_DISABLE(bus, value, grp) \
81 FURI_HAL_BUS_RESET_ASSERT(bus, value, grp); \
82 FURI_HAL_BUS_CLOCK_DISABLE(bus, value, grp)
83
84#define FURI_HAL_BUS_PERIPH_RESET(bus, value, grp) \
85 FURI_HAL_BUS_RESET_ASSERT(bus, value, grp); \
86 FURI_HAL_BUS_RESET_DEASSERT(bus, value, grp)
87
88static const uint32_t furi_hal_bus[] = {
89 [FuriHalBusAHB1_GRP1] = FURI_HAL_BUS_IGNORE,
90 [FuriHalBusDMA1] = LL_AHB1_GRP1_PERIPH_DMA1,
91 [FuriHalBusDMA2] = LL_AHB1_GRP1_PERIPH_DMA2,
92 [FuriHalBusDMAMUX1] = LL_AHB1_GRP1_PERIPH_DMAMUX1,
93 [FuriHalBusCRC] = LL_AHB1_GRP1_PERIPH_CRC,
94 [FuriHalBusTSC] = LL_AHB1_GRP1_PERIPH_TSC,
95
96 [FuriHalBusAHB2_GRP1] = FURI_HAL_BUS_IGNORE,
97 [FuriHalBusGPIOA] = LL_AHB2_GRP1_PERIPH_GPIOA,
98 [FuriHalBusGPIOB] = LL_AHB2_GRP1_PERIPH_GPIOB,
99 [FuriHalBusGPIOC] = LL_AHB2_GRP1_PERIPH_GPIOC,
100 [FuriHalBusGPIOD] = LL_AHB2_GRP1_PERIPH_GPIOD,
101 [FuriHalBusGPIOE] = LL_AHB2_GRP1_PERIPH_GPIOE,
102 [FuriHalBusGPIOH] = LL_AHB2_GRP1_PERIPH_GPIOH,
103#if defined(ADC_SUPPORT_5_MSPS)
104 [FuriHalBusADC] = LL_AHB2_GRP1_PERIPH_ADC,
105#endif
106 [FuriHalBusAES1] = LL_AHB2_GRP1_PERIPH_AES1,
107
108 [FuriHalBusAHB3_GRP1] = FURI_HAL_BUS_IGNORE,
109 [FuriHalBusQUADSPI] = LL_AHB3_GRP1_PERIPH_QUADSPI,
110 [FuriHalBusPKA] = LL_AHB3_GRP1_PERIPH_PKA,
111 [FuriHalBusAES2] = LL_AHB3_GRP1_PERIPH_AES2,
112 [FuriHalBusRNG] = LL_AHB3_GRP1_PERIPH_RNG,
113 [FuriHalBusHSEM] = LL_AHB3_GRP1_PERIPH_HSEM,
114 [FuriHalBusIPCC] = LL_AHB3_GRP1_PERIPH_IPCC,
115 [FuriHalBusFLASH] = LL_AHB3_GRP1_PERIPH_FLASH,
116
117 [FuriHalBusAPB1_GRP1] = FURI_HAL_BUS_APB1_GRP1,
118 [FuriHalBusTIM2] = LL_APB1_GRP1_PERIPH_TIM2,
119 [FuriHalBusLCD] = LL_APB1_GRP1_PERIPH_LCD,
120 [FuriHalBusSPI2] = LL_APB1_GRP1_PERIPH_SPI2,
121 [FuriHalBusI2C1] = LL_APB1_GRP1_PERIPH_I2C1,
122 [FuriHalBusI2C3] = LL_APB1_GRP1_PERIPH_I2C3,
123 [FuriHalBusCRS] = LL_APB1_GRP1_PERIPH_CRS,
124 [FuriHalBusUSB] = LL_APB1_GRP1_PERIPH_USB,
125 [FuriHalBusLPTIM1] = LL_APB1_GRP1_PERIPH_LPTIM1,
126
127 [FuriHalBusAPB1_GRP2] = FURI_HAL_BUS_APB1_GRP2,
128 [FuriHalBusLPUART1] = LL_APB1_GRP2_PERIPH_LPUART1,
129 [FuriHalBusLPTIM2] = LL_APB1_GRP2_PERIPH_LPTIM2,
130
131 [FuriHalBusAPB2_GRP1] = FURI_HAL_BUS_APB2_GRP1,
132#if defined(ADC_SUPPORT_2_5_MSPS)
133 [FuriHalBusADC] = LL_APB2_GRP1_PERIPH_ADC,
134#endif
135 [FuriHalBusTIM1] = LL_APB2_GRP1_PERIPH_TIM1,
136 [FuriHalBusSPI1] = LL_APB2_GRP1_PERIPH_SPI1,
137 [FuriHalBusUSART1] = LL_APB2_GRP1_PERIPH_USART1,
138 [FuriHalBusTIM16] = LL_APB2_GRP1_PERIPH_TIM16,
139 [FuriHalBusTIM17] = LL_APB2_GRP1_PERIPH_TIM17,
140 [FuriHalBusSAI1] = LL_APB2_GRP1_PERIPH_SAI1,
141
142 [FuriHalBusAPB3_GRP1] = FURI_HAL_BUS_IGNORE, // APB3_GRP1 clocking cannot be changed
143 [FuriHalBusRF] = LL_APB3_GRP1_PERIPH_RF,
144};
145
146void furi_hal_bus_init_early(void) {
147 FURI_CRITICAL_ENTER();
148
149 // FURI_HAL_BUS_PERIPH_DISABLE(AHB1, FURI_HAL_BUS_AHB1_GRP1, 1);
150 // FURI_HAL_BUS_PERIPH_DISABLE(AHB2, FURI_HAL_BUS_AHB2_GRP1, 1);
151 // FURI_HAL_BUS_PERIPH_DISABLE(AHB3, FURI_HAL_BUS_AHB3_GRP1, 1);
152 FURI_HAL_BUS_PERIPH_DISABLE(APB1, FURI_HAL_BUS_APB1_GRP1, 1);
153 FURI_HAL_BUS_PERIPH_DISABLE(APB1, FURI_HAL_BUS_APB1_GRP2, 2);
154 FURI_HAL_BUS_PERIPH_DISABLE(APB2, FURI_HAL_BUS_APB2_GRP1, 1);
155
156 FURI_HAL_BUS_RESET_ASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
157
158 FURI_CRITICAL_EXIT();
159}
160
161void furi_hal_bus_deinit_early(void) {
162 FURI_CRITICAL_ENTER();
163
164 // FURI_HAL_BUS_PERIPH_ENABLE(AHB1, FURI_HAL_BUS_AHB1_GRP1, 1);
165 // FURI_HAL_BUS_PERIPH_ENABLE(AHB2, FURI_HAL_BUS_AHB2_GRP1, 1);
166 // FURI_HAL_BUS_PERIPH_ENABLE(AHB3, FURI_HAL_BUS_AHB3_GRP1, 1);
167 FURI_HAL_BUS_PERIPH_ENABLE(APB1, FURI_HAL_BUS_APB1_GRP1, 1);
168 FURI_HAL_BUS_PERIPH_ENABLE(APB1, FURI_HAL_BUS_APB1_GRP2, 2);
169 FURI_HAL_BUS_PERIPH_ENABLE(APB2, FURI_HAL_BUS_APB2_GRP1, 1);
170
171 FURI_HAL_BUS_RESET_DEASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
172
173 FURI_CRITICAL_EXIT();
174}
175
176void furi_hal_bus_enable(FuriHalBus bus) {
177 furi_check(bus < FuriHalBusMAX);
178 const uint32_t value = furi_hal_bus[bus];
179 if(!value) {
180 return;
181 }
182
183 FURI_CRITICAL_ENTER();
184 if(bus < FuriHalBusAHB2_GRP1) {
185 // furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(AHB1, value));
186 FURI_HAL_BUS_PERIPH_ENABLE(AHB1, value, 1);
187 } else if(bus < FuriHalBusAHB3_GRP1) {
188 // furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(AHB2, value));
189 FURI_HAL_BUS_PERIPH_ENABLE(AHB2, value, 1);
190 } else if(bus < FuriHalBusAPB1_GRP1) {
191 // furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(AHB3, value));
192 FURI_HAL_BUS_PERIPH_ENABLE(AHB3, value, 1);
193 } else if(bus < FuriHalBusAPB1_GRP2) {
194 furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(APB1, value, 1));
195 FURI_HAL_BUS_PERIPH_ENABLE(APB1, value, 1);
196 } else if(bus < FuriHalBusAPB2_GRP1) {
197 furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(APB1, value, 2));
198 FURI_HAL_BUS_PERIPH_ENABLE(APB1, value, 2);
199 } else if(bus < FuriHalBusAPB3_GRP1) {
200 furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(APB2, value));
201 FURI_HAL_BUS_PERIPH_ENABLE(APB2, value, 1);
202 } else {
203 furi_check(FURI_HAL_BUS_IS_RESET_ASSERTED(APB3, value));
204 FURI_HAL_BUS_RESET_DEASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
205 }
206 FURI_CRITICAL_EXIT();
207}
208
209void furi_hal_bus_reset(FuriHalBus bus) {
210 furi_check(bus < FuriHalBusMAX);
211 const uint32_t value = furi_hal_bus[bus];
212 if(!value) {
213 return;
214 }
215
216 FURI_CRITICAL_ENTER();
217 if(bus < FuriHalBusAHB2_GRP1) {
218 // furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB1, value));
219 FURI_HAL_BUS_PERIPH_RESET(AHB1, value, 1);
220 } else if(bus < FuriHalBusAHB3_GRP1) {
221 // furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB2, value));
222 FURI_HAL_BUS_PERIPH_RESET(AHB2, value, 1);
223 } else if(bus < FuriHalBusAPB1_GRP1) {
224 // furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB3, value));
225 FURI_HAL_BUS_PERIPH_RESET(AHB3, value, 1);
226 } else if(bus < FuriHalBusAPB1_GRP2) {
227 furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 1));
228 FURI_HAL_BUS_PERIPH_RESET(APB1, value, 1);
229 } else if(bus < FuriHalBusAPB2_GRP1) {
230 furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 2));
231 FURI_HAL_BUS_PERIPH_RESET(APB1, value, 2);
232 } else if(bus < FuriHalBusAPB3_GRP1) {
233 furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB2, value));
234 FURI_HAL_BUS_PERIPH_RESET(APB2, value, 1);
235 } else {
236 furi_check(FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value));
237 FURI_HAL_BUS_PERIPH_RESET(APB3, value, 1);
238 }
239 FURI_CRITICAL_EXIT();
240}
241
242void furi_hal_bus_disable(FuriHalBus bus) {
243 furi_check(bus < FuriHalBusMAX);
244 const uint32_t value = furi_hal_bus[bus];
245 if(!value) {
246 return;
247 }
248
249 FURI_CRITICAL_ENTER();
250 if(bus < FuriHalBusAHB2_GRP1) {
251 // furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB1, value));
252 FURI_HAL_BUS_PERIPH_DISABLE(AHB1, value, 1);
253 } else if(bus < FuriHalBusAHB3_GRP1) {
254 // furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB2, value));
255 FURI_HAL_BUS_PERIPH_DISABLE(AHB2, value, 1);
256 } else if(bus < FuriHalBusAPB1_GRP1) {
257 // furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB3, value));
258 FURI_HAL_BUS_PERIPH_DISABLE(AHB3, value, 1);
259 } else if(bus < FuriHalBusAPB1_GRP2) {
260 furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 1));
261 FURI_HAL_BUS_PERIPH_DISABLE(APB1, value, 1);
262 } else if(bus < FuriHalBusAPB2_GRP1) {
263 furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 2));
264 FURI_HAL_BUS_PERIPH_DISABLE(APB1, value, 2);
265 } else if(bus < FuriHalBusAPB3_GRP1) {
266 furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB2, value));
267 FURI_HAL_BUS_PERIPH_DISABLE(APB2, value, 1);
268 } else {
269 furi_check(FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value));
270 FURI_HAL_BUS_RESET_ASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
271 }
272 FURI_CRITICAL_EXIT();
273}
274
275bool furi_hal_bus_is_enabled(FuriHalBus bus) {
276 furi_check(bus < FuriHalBusMAX);
277 const uint32_t value = furi_hal_bus[bus];
278 if(value == FURI_HAL_BUS_IGNORE) {
279 return true;
280 }
281
282 bool ret = false;
283 FURI_CRITICAL_ENTER();
284 if(bus < FuriHalBusAHB2_GRP1) {
285 ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB1, value);
286 } else if(bus < FuriHalBusAHB3_GRP1) {
287 ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB2, value);
288 } else if(bus < FuriHalBusAPB1_GRP1) {
289 ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB3, value);
290 } else if(bus < FuriHalBusAPB1_GRP2) {
291 ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 1);
292 } else if(bus < FuriHalBusAPB2_GRP1) {
293 ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 2);
294 } else if(bus < FuriHalBusAPB3_GRP1) {
295 ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(APB2, value);
296 } else {
297 ret = FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value);
298 }
299 FURI_CRITICAL_EXIT();
300
301 return ret;
302}
#define furi_check(...)
Check condition and crash if failed.
Definition check.h:73