Просмотр исходного кода

ApiHal: initialize clock in parallel, switch LSE driving to high, enable EXTI line 18 to fix LSECSS, move some interrupts service routines to api-hal-interrupts. (#614)

あく 4 лет назад
Родитель
Сommit
e9e29e0e0c

+ 1 - 1
bootloader/targets/f6/target.c

@@ -88,7 +88,7 @@ void rtc_init() {
         // Start LSI1 needed for CSS
         LL_RCC_LSI1_Enable();
         // Try to start LSE normal way
-        LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_MEDIUMLOW);
+        LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);
         LL_RCC_LSE_Enable();
         uint32_t c = 0;
         while(!RTC_CLOCK_IS_READY() && c < 200) {

+ 0 - 8
firmware/targets/f6/Inc/stm32wbxx_it.h

@@ -47,15 +47,7 @@
 /* USER CODE END EM */
 
 /* Exported functions prototypes ---------------------------------------------*/
-void NMI_Handler(void);
-void HardFault_Handler(void);
-void MemManage_Handler(void);
-void BusFault_Handler(void);
-void UsageFault_Handler(void);
-void DebugMon_Handler(void);
 void SysTick_Handler(void);
-void TAMP_STAMP_LSECSS_IRQHandler(void);
-void RCC_IRQHandler(void);
 void ADC1_IRQHandler(void);
 void USB_LP_IRQHandler(void);
 void COMP_IRQHandler(void);

+ 0 - 47
firmware/targets/f6/Src/stm32wbxx_it.c

@@ -16,57 +16,10 @@ extern void HW_TS_RTC_Wakeup_Handler();
 extern void HW_IPCC_Tx_Handler();
 extern void HW_IPCC_Rx_Handler();
 
-void NMI_Handler(void) {
-    if (LL_RCC_IsActiveFlag_HSECSS()) {
-        LL_RCC_ClearFlag_HSECSS();
-        NVIC_SystemReset();
-    }
-}
-
-void HardFault_Handler(void) {
-    if ((*(volatile uint32_t *)CoreDebug_BASE) & (1 << 0)) {
-        __asm("bkpt 1");
-    }
-    while (1) {}
-}
-
-void MemManage_Handler(void) {
-    __asm("bkpt 1");
-    while (1) {}
-}
-
-void BusFault_Handler(void) {
-    __asm("bkpt 1");
-    while (1) {}
-}
-
-void UsageFault_Handler(void) {
-    __asm("bkpt 1");
-    while (1) {}
-}
-
-void DebugMon_Handler(void) {
-}
-
 void SysTick_Handler(void) {
     HAL_IncTick();
 }
 
-void TAMP_STAMP_LSECSS_IRQHandler(void) {
-    if (LL_RCC_IsActiveFlag_LSECSS()) {
-        LL_RCC_ClearFlag_LSECSS();
-        if (!LL_RCC_LSE_IsReady()) {
-            // TODO: notify user about issue with LSE
-            LL_RCC_ForceBackupDomainReset();
-            LL_RCC_ReleaseBackupDomainReset();
-            NVIC_SystemReset();
-        }
-    }
-}
-
-void RCC_IRQHandler(void) {
-}
-
 void ADC1_IRQHandler(void) {
     HAL_ADC_IRQHandler(&hadc1);
 }

+ 15 - 12
firmware/targets/f6/api-hal/api-hal-clock.c

@@ -5,26 +5,29 @@
 #include <stm32wbxx_ll_rcc.h>
 #include <stm32wbxx_ll_utils.h>
 
+#define HS_CLOCK_IS_READY() (LL_RCC_HSE_IsReady() && LL_RCC_HSI_IsReady())
+#define LS_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady())
+
 void api_hal_clock_init() {
+    /* Prepare Flash memory for 64mHz system clock */
     LL_FLASH_SetLatency(LL_FLASH_LATENCY_3);
     while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_3);
 
-    /* HSE configuration and activation */
+    /* HSE and HSI configuration and activation */
     LL_RCC_HSE_SetCapacitorTuning(0x26);
     LL_RCC_HSE_Enable();
-    while(LL_RCC_HSE_IsReady() != 1) ;
-
-    /* HSI configuration and activation */
     LL_RCC_HSI_Enable();
-    while(LL_RCC_HSI_IsReady() != 1) 
+    while(!HS_CLOCK_IS_READY());
+    LL_RCC_HSE_EnableCSS();
 
-    /* LSE configuration and activation */
+    /* LSE and LSI1 configuration and activation */
     LL_PWR_EnableBkUpAccess();
-    LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_MEDIUMLOW);
+    LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);
     LL_RCC_LSE_Enable();
-    while(LL_RCC_LSE_IsReady() != 1) ;
-
-    LL_RCC_HSE_EnableCSS();
+    LL_RCC_LSI1_Enable();
+    while(!LS_CLOCK_IS_READY());
+    LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_18); /* Why? Because that's why. See RM0434, Table 61. CPU1 vector table. */
+    LL_EXTI_EnableRisingTrig_0_31(LL_EXTI_LINE_18);
     LL_RCC_EnableIT_LSECSS();
     LL_RCC_LSE_EnableCSS();
 
@@ -68,8 +71,7 @@ void api_hal_clock_init() {
     LL_SetSystemCoreClock(64000000);
 
     /* Update the time base */
-    if (HAL_InitTick (TICK_INT_PRIORITY) != HAL_OK)
-    {
+    if (HAL_InitTick (TICK_INT_PRIORITY) != HAL_OK) {
         Error_Handler();
     }
 
@@ -104,6 +106,7 @@ void api_hal_clock_init() {
     LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH);
 
     // APB1
+    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
 
     // APB2

+ 59 - 1
firmware/targets/f6/api-hal/api-hal-interrupt.c

@@ -12,8 +12,15 @@ volatile ApiHalInterruptISR api_hal_tim_tim2_isr = NULL;
 volatile ApiHalInterruptISR api_hal_dma_channel_isr[API_HAL_INTERRUPT_DMA_COUNT][API_HAL_INTERRUPT_DMA_CHANNELS_COUNT] = {0};
 
 void api_hal_interrupt_init() {
+    NVIC_SetPriority(RCC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));
+    NVIC_EnableIRQ(RCC_IRQn);
+
+    NVIC_SetPriority(TAMP_STAMP_LSECSS_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));
+    NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn);
+
     NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
     NVIC_EnableIRQ(DMA1_Channel1_IRQn);
+
     FURI_LOG_I("FuriHalInterrupt", "Init OK");
 }
 
@@ -31,7 +38,7 @@ void api_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, ApiHalInterruptISR isr)
 }
 
 void api_hal_interrupt_set_dma_channel_isr(DMA_TypeDef* dma, uint32_t channel, ApiHalInterruptISR isr) {
-    --channel; // Pascal 
+    --channel; // Pascal
     furi_check(dma);
     furi_check(channel < API_HAL_INTERRUPT_DMA_CHANNELS_COUNT);
     if (dma == DMA1) {
@@ -131,3 +138,54 @@ void DMA2_Channel7_IRQHandler(void) {
 void DMA2_Channel8_IRQHandler(void) {
     if (api_hal_dma_channel_isr[1][7]) api_hal_dma_channel_isr[1][7]();
 }
+
+
+void TAMP_STAMP_LSECSS_IRQHandler(void) {
+    if (LL_RCC_IsActiveFlag_LSECSS()) {
+        LL_RCC_ClearFlag_LSECSS();
+        if (!LL_RCC_LSE_IsReady()) {
+            FURI_LOG_E("FuriHalInterrupt", "LSE CSS fired: resetting system");
+            NVIC_SystemReset();
+        } else {
+            FURI_LOG_E("FuriHalInterrupt", "LSE CSS fired: but LSE is alive");
+        }
+    }
+}
+
+void RCC_IRQHandler(void) {
+}
+
+
+void NMI_Handler(void) {
+    if (LL_RCC_IsActiveFlag_HSECSS()) {
+        LL_RCC_ClearFlag_HSECSS();
+        FURI_LOG_E("FuriHalInterrupt", "HSE CSS fired: resetting system");
+        NVIC_SystemReset();
+    }
+}
+
+void HardFault_Handler(void) {
+    if ((*(volatile uint32_t *)CoreDebug_BASE) & (1 << 0)) {
+        __asm("bkpt 1");
+    }
+    while (1) {}
+}
+
+void MemManage_Handler(void) {
+    __asm("bkpt 1");
+    while (1) {}
+}
+
+void BusFault_Handler(void) {
+    __asm("bkpt 1");
+    while (1) {}
+}
+
+void UsageFault_Handler(void) {
+    __asm("bkpt 1");
+    while (1) {}
+}
+
+void DebugMon_Handler(void) {
+
+}