diff --git a/demo/wdt/watchdog_clear_n_reset.c b/demo/wdt/watchdog_clear_n_reset.c new file mode 100644 index 0000000..e348bea --- /dev/null +++ b/demo/wdt/watchdog_clear_n_reset.c @@ -0,0 +1,65 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*** + * Demo: Watchdog Clear And Reset + */ + +#include "fw_hal.h" + +static uint8_t c0 = 0, c1 = 0; + +INTERRUPT(Timer0_Routine, EXTI_VectTimer0) +{ + c0++; + if (c0 == 100) + { + c0 = 0; + c1++; + if (c1 < 5) + { + UART1_TxString("Round "); + UART1_TxHex(c1); + UART1_TxString(", reset watchdog counter\r\n"); + WDT_ResetCounter(); + } + else + { + UART1_TxString("Round "); + UART1_TxHex(c1); + UART1_TxString(", no operation\r\n"); + } + } +} + +int main(void) +{ + uint8_t count = 9; + SYS_SetClock(); + UART1_Config8bitUart(UART1_BaudSource_Timer2, HAL_State_ON, 115200); + UART1_TxString("Watchdog test restarted\r\n"); + // Timer0: 12T mode, frequency 100Hz + TIM_Timer0_Config(HAL_State_OFF, TIM_TimerMode_16BitAuto, 100); + EXTI_Timer0_SetIntState(HAL_State_ON); + EXTI_Timer0_SetIntPriority(EXTI_IntPriority_High); + EXTI_Global_SetIntState(HAL_State_ON); + TIM_Timer0_SetRunState(HAL_State_ON); + UART1_TxString("Timer 0 started\r\n"); + /** + * Set countdown time to around 3 seconds(FOSC = 36.864MHz) + */ + WDT_SetCounterPrescaler(0x07); + WDT_StartWatchDog(); + while(1); +} diff --git a/demo/wdt/watchdog_reset.c b/demo/wdt/watchdog_reset.c new file mode 100644 index 0000000..8ac1bc4 --- /dev/null +++ b/demo/wdt/watchdog_reset.c @@ -0,0 +1,39 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*** + * Demo: Watchdog Reset + */ + +#include "fw_hal.h" + +int main(void) +{ + uint8_t count = 9; + SYS_SetClock(); + UART1_Config8bitUart(UART1_BaudSource_Timer2, HAL_State_ON, 115200); + UART1_TxString("Watchdog test restarted\r\n"); + /** + * Set countdown time to around 3 seconds(FOSC = 36.864MHz) + */ + WDT_SetCounterPrescaler(0x07); + WDT_StartWatchDog(); + while(1) + { + UART1_TxString("Countdown: "); + UART1_TxHex(count--); + UART1_TxString("\r\n"); + SYS_Delay(1000); + } +} diff --git a/include/fw_hal.h b/include/fw_hal.h index 82ad4dc..fe02233 100644 --- a/include/fw_hal.h +++ b/include/fw_hal.h @@ -28,6 +28,7 @@ #include "fw_spi.h" #include "fw_iap.h" #include "fw_util.h" +#include "fw_wdt.h" #if (__CONF_MCU_TYPE == 2 ) #include "fw_pca.h" diff --git a/include/fw_rcc.h b/include/fw_rcc.h index 2399b94..18f6321 100644 --- a/include/fw_rcc.h +++ b/include/fw_rcc.h @@ -26,51 +26,48 @@ typedef enum RCC_SYSCLKSource_LSI = 0x03, /* Internal 32KHz RC osc */ } RCC_SYSCLKSource_t; -typedef enum -{ - RCC_IRCBand_20MHz = 0x00, /* 20MHz RC osc band */ - RCC_IRCBand_35MHz = 0x01, /* 35MHz RC osc band */ -} RCC_IRCBand_t; - -typedef enum -{ - RCC_LIRTrim_None = 0x00, /* none */ - RCC_LIRTrim_001 = 0x01, /* +0.01% */ - RCC_LIRTrim_004 = 0x02, /* +0.04% */ - RCC_LIRTrim_010 = 0x03, /* +0.10% */ -} RCC_LIRTrim_t; - -typedef enum -{ - RCC_SoftwareReset_Code = 0x00, /* restart from user code */ - RCC_SoftwareReset_ISP = 0x01, /* restart from ISP */ -} RCC_SoftwareReset_t; - typedef enum { RCC_LowVoltResetPinAF_IO = 0x00, /* P5.4 as GPIO */ RCC_LowVoltResetPinAF_Reset = 0x01, /* P5.4 as RESET */ } RCC_LowVoltResetPinAF_t; +/** + * Low voltage threshold + * + * | | STC8H8K64U | Other | + * | -- | ---------- | ---------- | + * | 00 | 1.9V | 2.0V | + * | 01 | 2.3V | 2.4V | + * | 10 | 2.8V | 2.7V | + * | 11 | 3.7V | 3.0V | +*/ typedef enum { - RCC_LowVoltDetectVolt_2V0 = 0x00, /* Detect at 2.0V */ - RCC_LowVoltDetectVolt_2V4 = 0x01, /* Detect at 2.4V */ - RCC_LowVoltDetectVolt_2V7 = 0x02, /* Detect at 2.7V */ - RCC_LowVoltDetectVolt_3V0 = 0x03, /* Detect at 3.0V */ -} RCC_LowVoltDetectVolt_t; + RCC_LowVoltThreshold_Lowest = 0x00, + RCC_LowVoltThreshold_Low = 0x01, + RCC_LowVoltThreshold_High = 0x02, + RCC_LowVoltThreshold_Highest = 0x03, +} RCC_LowVoltThreshold_t; -void RCC_SetSYSCLKSource(RCC_SYSCLKSource_t SYSCLKSource); -void RCC_SetCLKDivider(uint8_t divider); -void RCC_SetIRC(RCC_IRCBand_t IRCBand, uint8_t IRTrim, RCC_LIRTrim_t LIRTrim); -void RCC_SoftwareReset(RCC_SoftwareReset_t SoftwareReset); -void RCC_ConfigLowVoltReset( - HAL_State_t HAL_State, - RCC_LowVoltResetPinAF_t LowVoltResetPinAF, - RCC_LowVoltDetectVolt_t LowVoltDetectVolt); +#define RCC_SetSYSCLKSource(__SOURCE__) do { \ + SFRX_ON(); \ + (CKSEL) = (CKSEL) & ~(0x03) | (__SOURCE__); \ + SFRX_OFF(); \ + } while(0) + +#define RCC_SetCLKDivider(__DIV__) do {SFRX_ON(); CLKDIV = (__DIV__ & 0xFF); SFRX_OFF();} while(0) +#define RCC_SetPowerDownMode(__STATE__) SFR_ASSIGN(PCON, 1) +#define RCC_SetIdleMode(__STATE__) SFR_ASSIGN(PCON, 0) +#define RCC_SetPowerDownWakeupTimerState(__STATE__) SFR_ASSIGN(WKTCH, 7) +#define RCC_SetPowerDownWakeupTimerCountdown(__16BIT_COUNT__) do { \ + WKTCH = WKTCH & ~(0x7F) | (__16BIT_COUNT__ << 8); \ + WKTCL = (__16BIT_COUNT__ & 0xFF); \ + }while(0) + +#define RCC_SetLowVoltResetState(__STATE__) SFR_ASSIGN(RSTCFG, 6) +#define RCC_SetLowVoltResetPinAF(__PIN_AF__) SFR_ASSIGN(RSTCFG, 4) +#define RCC_SetLowVoltResetThreshold(__THRESHOLD__) (RSTCFG = RSTCFG & ~(0x03) | (__THRESHOLD__)) -void RCC_SetPowerDownWakeupTimer(HAL_State_t HAL_State, uint16_t countdown); -void RCC_SetPowerDownMode(HAL_State_t HAL_State); -void RCC_SetIdleMode(HAL_State_t HAL_State); #endif diff --git a/include/fw_wdt.h b/include/fw_wdt.h new file mode 100644 index 0000000..2843343 --- /dev/null +++ b/include/fw_wdt.h @@ -0,0 +1,49 @@ +// Copyright 2021 IOsetting +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ___FW_WDT_H___ +#define ___FW_WDT_H___ + +#include "fw_conf.h" +#include "fw_types.h" + +/******************************************************** + * STC8 watchdog reset behavior is different from STC15 + * + * STC8 watchdog will ALWAYS reset chip from ISP code region inspite of the + * setting of SWBS in IAP_CONTR + * +*/ + +/** + * Start watchdog. + * It cannot be stopped in code once it is started +*/ +#define WDT_StartWatchDog() SFR_SET(WDT_CONTR, 5) +/** + * Reset watchdog counter to avoid reset +*/ +#define WDT_ResetCounter() SFR_SET(WDT_CONTR, 4) +/** + * Enable or disable watchdog counter in idle mode +*/ +#define WDT_EnableCounterWhenIdle(__STATE__) SFR_ASSIGN(WDT_CONTR, 3, __STATE__) +/** + * Set counter prescaler. The higher this value is, the longer counter overflow will take place + * + * Toverflow (in seconds) = 12 * 32768 * 2^(__PRE_SCALER__ + 1) / SYSCLK +*/ +#define WDT_SetCounterPrescaler(__PRE_SCALER__) (WDT_CONTR = WDT_CONTR & ~0x07 | (__PRE_SCALER__ & 0x07)) + +#endif diff --git a/src/fw_rcc.c b/src/fw_rcc.c deleted file mode 100644 index def0f18..0000000 --- a/src/fw_rcc.c +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2021 IOsetting -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "fw_rcc.h" - -void RCC_SetSYSCLKSource(RCC_SYSCLKSource_t SYSCLKSource) -{ - P_SW2 = 0x80; - if (SYSCLKSource == RCC_SYSCLKSource_HSI) - { - // Enable internal high speed rc osc - HIRCCR |= B10000000; - while(!(HIRCCR & B00000001)); - } - else if (SYSCLKSource == RCC_SYSCLKSource_HSE) - { - // Enable external high speed osc - XOSCCR |= B10000000; - while(!(XOSCCR & B00000001)); - } - else if (SYSCLKSource == RCC_SYSCLKSource_LSE) - { - // Enable external 32khz osc - X32KCR |= B10000000; - while(!(X32KCR & B00000001)); - } - else if (SYSCLKSource == RCC_SYSCLKSource_LSI) - { - // Enable internal 32khz rc osc - IRC32KCR |= B10000000; - while(!(IRC32KCR & B00000001)); - } - CKSEL = CKSEL & ~(B00000011) | SYSCLKSource; - P_SW2 = 0x00; -} - -void RCC_SetCLKDivider(uint8_t divider) -{ - P_SW2 = 0x80; - CLKDIV = divider; - P_SW2 = 0x00; -} - -void RCC_SetIRC(RCC_IRCBand_t IRCBand, uint8_t IRTrim, RCC_LIRTrim_t LIRTrim) -{ - IRCBAND = IRCBAND & ~(B00000001) | IRCBand; - IRTRIM = IRTrim; - LIRTRIM = LIRTRIM & ~(B00000011) | LIRTrim; -} - -void RCC_SoftwareReset(RCC_SoftwareReset_t SoftwareReset) -{ - /* IAP_CONTR = IAP_CONTR & ~(B0011 << 5) | (((SoftwareReset << 1) | B0001) << 5);*/ - IAP_CONTR |= ((SoftwareReset << 1) | B00000001) << 5; -} - -void RCC_ConfigLowVoltReset( - HAL_State_t HAL_State, - RCC_LowVoltResetPinAF_t LowVoltResetPinAF, - RCC_LowVoltDetectVolt_t LowVoltDetectVolt) -{ - RSTCFG = RSTCFG - & ~(B01000000 | B00010000 | B00000011) - | ((HAL_State << 6)|(LowVoltResetPinAF << 4)|(LowVoltDetectVolt)); -} - -void RCC_SetPowerDownWakeupTimer(HAL_State_t HAL_State, uint16_t countdown) -{ - WKTCH = WKTCH & ~B10000000 | (HAL_State << 7); - WKTCH = WKTCH & ~B01111111 | ((countdown >> 8) & B01111111); - WKTCL = countdown & 0xFF; -} - -void RCC_SetPowerDownMode(HAL_State_t HAL_State) -{ - PCON |= (HAL_State << 1); -} - -void RCC_SetIdleMode(HAL_State_t HAL_State) -{ - PCON |= (HAL_State); -}