1#include <furi_hal_bus.h>
4#include <stm32wbxx_ll_bus.h>
7#define FURI_HAL_BUS_IGNORE (0x0U)
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)
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)
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)
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)
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)
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)
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)
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)
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))
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)))
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)))
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__))
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__))
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)
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)
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)
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)
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)
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,
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,
106 [FuriHalBusAES1] = LL_AHB2_GRP1_PERIPH_AES1,
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,
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,
127 [FuriHalBusAPB1_GRP2] = FURI_HAL_BUS_APB1_GRP2,
128 [FuriHalBusLPUART1] = LL_APB1_GRP2_PERIPH_LPUART1,
129 [FuriHalBusLPTIM2] = LL_APB1_GRP2_PERIPH_LPTIM2,
131 [FuriHalBusAPB2_GRP1] = FURI_HAL_BUS_APB2_GRP1,
132#if defined(ADC_SUPPORT_2_5_MSPS)
133 [FuriHalBusADC] = LL_APB2_GRP1_PERIPH_ADC,
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,
142 [FuriHalBusAPB3_GRP1] = FURI_HAL_BUS_IGNORE,
143 [FuriHalBusRF] = LL_APB3_GRP1_PERIPH_RF,
146void furi_hal_bus_init_early(
void) {
147 FURI_CRITICAL_ENTER();
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);
156 FURI_HAL_BUS_RESET_ASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
158 FURI_CRITICAL_EXIT();
161void furi_hal_bus_deinit_early(
void) {
162 FURI_CRITICAL_ENTER();
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);
171 FURI_HAL_BUS_RESET_DEASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
173 FURI_CRITICAL_EXIT();
176void furi_hal_bus_enable(FuriHalBus bus) {
178 const uint32_t value = furi_hal_bus[bus];
183 FURI_CRITICAL_ENTER();
184 if(bus < FuriHalBusAHB2_GRP1) {
186 FURI_HAL_BUS_PERIPH_ENABLE(AHB1, value, 1);
187 }
else if(bus < FuriHalBusAHB3_GRP1) {
189 FURI_HAL_BUS_PERIPH_ENABLE(AHB2, value, 1);
190 }
else if(bus < FuriHalBusAPB1_GRP1) {
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);
203 furi_check(FURI_HAL_BUS_IS_RESET_ASSERTED(APB3, value));
204 FURI_HAL_BUS_RESET_DEASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
206 FURI_CRITICAL_EXIT();
209void furi_hal_bus_reset(FuriHalBus bus) {
211 const uint32_t value = furi_hal_bus[bus];
216 FURI_CRITICAL_ENTER();
217 if(bus < FuriHalBusAHB2_GRP1) {
219 FURI_HAL_BUS_PERIPH_RESET(AHB1, value, 1);
220 }
else if(bus < FuriHalBusAHB3_GRP1) {
222 FURI_HAL_BUS_PERIPH_RESET(AHB2, value, 1);
223 }
else if(bus < FuriHalBusAPB1_GRP1) {
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);
236 furi_check(FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value));
237 FURI_HAL_BUS_PERIPH_RESET(APB3, value, 1);
239 FURI_CRITICAL_EXIT();
242void furi_hal_bus_disable(FuriHalBus bus) {
244 const uint32_t value = furi_hal_bus[bus];
249 FURI_CRITICAL_ENTER();
250 if(bus < FuriHalBusAHB2_GRP1) {
252 FURI_HAL_BUS_PERIPH_DISABLE(AHB1, value, 1);
253 }
else if(bus < FuriHalBusAHB3_GRP1) {
255 FURI_HAL_BUS_PERIPH_DISABLE(AHB2, value, 1);
256 }
else if(bus < FuriHalBusAPB1_GRP1) {
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);
269 furi_check(FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value));
270 FURI_HAL_BUS_RESET_ASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
272 FURI_CRITICAL_EXIT();
275bool furi_hal_bus_is_enabled(FuriHalBus bus) {
277 const uint32_t value = furi_hal_bus[bus];
278 if(value == FURI_HAL_BUS_IGNORE) {
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);
297 ret = FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value);
299 FURI_CRITICAL_EXIT();
#define furi_check(...)
Check condition and crash if failed.
Definition check.h:73