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