Home | History | Annotate | Download | only in stm32
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <plat/pwr.h>
     18 #include <plat/wdt.h>
     19 #include <plat/cmsis.h>
     20 
     21 struct StmDbgmcu {
     22     volatile uint32_t IDCODE;
     23     volatile uint32_t CR;
     24     volatile uint32_t APB1FZ;
     25     volatile uint32_t APB2FZ;
     26 };
     27 
     28 struct StmWwdg {
     29     volatile uint16_t CR;
     30     uint8_t unused0[2];
     31     volatile uint16_t CFR;
     32     uint8_t unused1[2];
     33     volatile uint16_t SR;
     34     uint8_t unused2[2];
     35 };
     36 
     37 #define DBGMCU              ((struct StmDbgmcu*)DBGMCU_BASE)
     38 #define WWDG                ((struct StmWwdg*)WWDG_BASE)
     39 
     40 /* DBGMCU bit definitions */
     41 #define DBG_WWDG_STOP       0x00000800U
     42 
     43 /* WWDG bit definitions */
     44 #define WWDG_CR_ENABLE      0x80
     45 
     46 #define WWDG_TCNT_HIGH      0x40
     47 #define WWDG_TCNT_MASK      0x3F
     48 
     49 #define WWDG_CFR_DIV2       0x0080
     50 #define WWDG_CFR_DIV4       0x0100
     51 #define WWDG_CFR_DIV8       0x0180
     52 #define WWDG_CFR_EWI        0x0200
     53 
     54 /* WWDG parameters */
     55 #define WWDG_WINDOW_SIZE    0x3F // 0 < x <= 0x3F
     56 
     57 void WWDG_IRQHandler(void);
     58 void __attribute__((naked)) WWDG_IRQHandler(void)
     59 {
     60     asm volatile(
     61         "mov    r0, #2                    \n"
     62         "b      cpuCommonFaultCode        \n"
     63     );
     64 }
     65 
     66 void wdtEnableClk()
     67 {
     68     pwrUnitClock(PERIPH_BUS_APB1, PERIPH_APB1_WWDG, true);
     69 }
     70 
     71 void wdtEnableIrq()
     72 {
     73     NVIC_EnableIRQ(WWDG_IRQn);
     74 }
     75 
     76 void wdtDisableClk()
     77 {
     78     pwrUnitClock(PERIPH_BUS_APB1, PERIPH_APB1_WWDG, false);
     79 }
     80 
     81 void wdtDisableIrq()
     82 {
     83     NVIC_DisableIRQ(WWDG_IRQn);
     84 }
     85 
     86 void wdtInit()
     87 {
     88 #if defined(DEBUG) && defined(DEBUG_SWD)
     89     // Disable WWDG if core is halted
     90     DBGMCU->APB1FZ |= DBG_WWDG_STOP;
     91 #endif
     92 
     93     wdtEnableClk();
     94     WWDG->CFR = WWDG_CFR_EWI | WWDG_CFR_DIV8 | WWDG_TCNT_HIGH | (WWDG_WINDOW_SIZE & WWDG_TCNT_MASK);
     95     WWDG->CR  = WWDG_CR_ENABLE | WWDG_TCNT_HIGH | (WWDG_WINDOW_SIZE & WWDG_TCNT_MASK);
     96     // with 16Mhz APB1 clock, this is 256*DIV = 2,048 uS per WWDG tick with DIV=8, max 131,072 uS WWDG window
     97     wdtEnableIrq();
     98 }
     99 
    100 void wdtPing()
    101 {
    102     WWDG->CR = (WWDG->CR & ~WWDG_TCNT_MASK) | WWDG_TCNT_HIGH | (WWDG_WINDOW_SIZE & WWDG_TCNT_MASK);
    103 }
    104