feat: wdt and demos

This commit is contained in:
IOsetting 2022-01-10 11:14:35 +08:00
parent c9eec37a2b
commit 4f20ebc892
6 changed files with 187 additions and 129 deletions

View File

@ -0,0 +1,65 @@
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
//
// 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);
}

39
demo/wdt/watchdog_reset.c Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
//
// 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);
}
}

View File

@ -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"

View File

@ -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

49
include/fw_wdt.h Normal file
View File

@ -0,0 +1,49 @@
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
//
// 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

View File

@ -1,93 +0,0 @@
// Copyright 2021 IOsetting <iosetting(at)outlook.com>
//
// 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);
}