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/inc/pwr.h> 18 #include <plat/inc/wdt.h> 19 #include <plat/inc/cmsis.h> 20 21 struct StmWwdg { 22 volatile uint16_t CR; 23 uint8_t unused0[2]; 24 volatile uint16_t CFR; 25 uint8_t unused1[2]; 26 volatile uint16_t SR; 27 uint8_t unused2[2]; 28 }; 29 30 #define WWDG ((struct StmWwdg*)WWDG_BASE) 31 32 /* WWDG bit definitions */ 33 #define WWDG_CR_ENABLE 0x80 34 35 #define WWDG_TCNT_HIGH 0x40 36 #define WWDG_TCNT_MASK 0x3F 37 38 #define WWDG_CFR_DIV2 0x0080 39 #define WWDG_CFR_DIV4 0x0100 40 #define WWDG_CFR_DIV8 0x0180 41 #define WWDG_CFR_EWI 0x0200 42 43 /* WWDG parameters */ 44 #define WWDG_WINDOW_SIZE 0x3F // 0 < x <= 0x3F 45 46 void WWDG_IRQHandler(void); 47 void __attribute__((naked)) WWDG_IRQHandler(void) 48 { 49 asm volatile( 50 "mov r0, #2 \n" 51 "b cpuCommonFaultCode \n" 52 ); 53 } 54 55 void wdtEnableClk() 56 { 57 pwrUnitClock(PERIPH_BUS_APB1, PERIPH_APB1_WWDG, true); 58 } 59 60 void wdtEnableIrq() 61 { 62 NVIC_EnableIRQ(WWDG_IRQn); 63 } 64 65 void wdtDisableClk() 66 { 67 pwrUnitClock(PERIPH_BUS_APB1, PERIPH_APB1_WWDG, false); 68 } 69 70 void wdtDisableIrq() 71 { 72 NVIC_DisableIRQ(WWDG_IRQn); 73 } 74 75 void wdtInit() 76 { 77 wdtEnableClk(); 78 WWDG->CFR = WWDG_CFR_EWI | WWDG_CFR_DIV8 | WWDG_TCNT_HIGH | (WWDG_WINDOW_SIZE & WWDG_TCNT_MASK); 79 WWDG->CR = WWDG_CR_ENABLE | WWDG_TCNT_HIGH | (WWDG_WINDOW_SIZE & WWDG_TCNT_MASK); 80 // with 16Mhz APB1 clock, this is 256*DIV = 2,048 uS per WWDG tick with DIV=8, max 131,072 uS WWDG window 81 wdtEnableIrq(); 82 } 83 84 void wdtPing() 85 { 86 WWDG->CR = (WWDG->CR & ~WWDG_TCNT_MASK) | WWDG_TCNT_HIGH | (WWDG_WINDOW_SIZE & WWDG_TCNT_MASK); 87 } 88