initial commit of in progress firmware
nearly everything is "implemented" but how well it works, or if it works at all, is unknown.
This commit is contained in:
42
gat_stand_fw/user/ch32v20x_conf.h
Normal file
42
gat_stand_fw/user/ch32v20x_conf.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_conf.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : Library configuration file.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_CONF_H
|
||||
#define __CH32V20x_CONF_H
|
||||
|
||||
#include "ch32v20x_adc.h"
|
||||
#include "ch32v20x_bkp.h"
|
||||
#include "ch32v20x_can.h"
|
||||
#include "ch32v20x_crc.h"
|
||||
#include "ch32v20x_dbgmcu.h"
|
||||
#include "ch32v20x_dma.h"
|
||||
#include "ch32v20x_exti.h"
|
||||
#include "ch32v20x_flash.h"
|
||||
#include "ch32v20x_gpio.h"
|
||||
#include "ch32v20x_i2c.h"
|
||||
#include "ch32v20x_iwdg.h"
|
||||
#include "ch32v20x_pwr.h"
|
||||
#include "ch32v20x_rcc.h"
|
||||
#include "ch32v20x_rtc.h"
|
||||
#include "ch32v20x_spi.h"
|
||||
#include "ch32v20x_tim.h"
|
||||
#include "ch32v20x_usart.h"
|
||||
#include "ch32v20x_wwdg.h"
|
||||
#include "ch32v20x_it.h"
|
||||
#include "ch32v20x_misc.h"
|
||||
|
||||
|
||||
#endif /* __CH32V20x_CONF_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
45
gat_stand_fw/user/ch32v20x_it.c
Normal file
45
gat_stand_fw/user/ch32v20x_it.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2023/12/29
|
||||
* Description : Main Interrupt Service Routines.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x_it.h"
|
||||
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
|
||||
/*********************************************************************
|
||||
* @fn NMI_Handler
|
||||
*
|
||||
* @brief This function handles NMI exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn HardFault_Handler
|
||||
*
|
||||
* @brief This function handles Hard Fault exception.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
gat_stand_fw/user/ch32v20x_it.h
Normal file
20
gat_stand_fw/user/ch32v20x_it.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : ch32v20x_it.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains the headers of the interrupt handlers.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __CH32V20x_IT_H
|
||||
#define __CH32V20x_IT_H
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#endif /* __CH32V20x_IT_H */
|
||||
|
||||
|
||||
171
gat_stand_fw/user/main.c
Normal file
171
gat_stand_fw/user/main.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* The GAT Stand
|
||||
* GAT Host Firmware
|
||||
* by true
|
||||
*
|
||||
* version 0.0.1
|
||||
*
|
||||
* notes:
|
||||
*
|
||||
* - last 2K of flash memory is reserved for configuration storage
|
||||
*/
|
||||
|
||||
#include <ch32v20x.h>
|
||||
|
||||
#include "src/btn.h"
|
||||
#include "src/gat_gpio.h"
|
||||
#include "src/port_pwr.h"
|
||||
#include "src/rgbled.h"
|
||||
#include "src/rtc.h"
|
||||
|
||||
|
||||
|
||||
void btn_top_push_cb(uint8_t idx)
|
||||
{
|
||||
gat_toggle();
|
||||
}
|
||||
|
||||
void btn_bot_push_cb(uint8_t idx)
|
||||
{
|
||||
usb2_toggle();
|
||||
}
|
||||
|
||||
static inline void systick_init(void)
|
||||
{
|
||||
SysTick->CMP = (SystemCoreClock / 256 / 8) - 1; // we want a 256Hz interrupt
|
||||
SysTick->CNT = 0; // clear counter
|
||||
SysTick->CTLR = 0xB; // start counter in /8 mode, enable interrupts, auto-reset counter
|
||||
SysTick->SR = 0; // clear count comparison flag
|
||||
|
||||
NVIC_EnableIRQ(SysTicK_IRQn); // enable interrupt
|
||||
}
|
||||
|
||||
static void gpio_init()
|
||||
{
|
||||
GPIO_InitTypeDef gpio = {0};
|
||||
|
||||
gpio.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
|
||||
// unused pins
|
||||
gpio.GPIO_Mode = GPIO_Mode_IPD;
|
||||
gpio.GPIO_Pin = GPIO_Pin_13;
|
||||
GPIO_Init(GPIOC, &gpio);
|
||||
|
||||
gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
|
||||
GPIO_Init(GPIOD, &gpio);
|
||||
|
||||
gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
|
||||
gpio.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_5 | GPIO_Pin_15;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// OSC32K: don't need to configure these pins from defaults
|
||||
// enabling RTC does whatever is needed for these pins (assumed from example)
|
||||
|
||||
// RGBLED (PA0, PA1, PA2)
|
||||
RGBLED_PORT->BSHR = RGBLED_PIN_R | RGBLED_PIN_G | RGBLED_PIN_B;
|
||||
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
gpio.GPIO_Pin = RGBLED_PIN_R | RGBLED_PIN_G | RGBLED_PIN_B;
|
||||
GPIO_Init(RGBLED_PORT, &gpio);
|
||||
|
||||
// GAT power enable (PA3)
|
||||
GAT_EN_PORT->BCR = GAT_EN_PIN;
|
||||
gpio.GPIO_Pin = GAT_EN_PIN;
|
||||
GPIO_Init(GAT_EN_PORT, &gpio);
|
||||
|
||||
// GAT overcurrent detect (PA4)
|
||||
gpio.GPIO_Mode = GPIO_Mode_IPU;
|
||||
gpio.GPIO_Pin = GAT_OC_PIN;
|
||||
GPIO_Init(GAT_EN_PORT, &gpio);
|
||||
|
||||
// buttons (PB10, PB11) and DIP switches (PB12, PB13, PB14)
|
||||
gpio.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// GAT GPIO will be configured later
|
||||
|
||||
// USB PA11, PA12 will be configured later
|
||||
|
||||
// USB2 power enable (PB4)
|
||||
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
gpio.GPIO_Pin = USB2_EN_PIN;
|
||||
GPIO_Init(USB2_EN_PORT, &gpio);
|
||||
|
||||
// unused pins that are used for I2C passthrough
|
||||
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
gpio.GPIO_Pin = GPIO_Pin_15;
|
||||
GPIO_Init(GPIOA, &gpio);
|
||||
gpio.GPIO_Pin = GPIO_Pin_3;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
|
||||
// USB PB6, PB7 will be configured later
|
||||
|
||||
// I2C (PB8, PB9) - remapped
|
||||
GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
|
||||
gpio.GPIO_Speed = GPIO_Speed_10MHz;
|
||||
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
|
||||
gpio.GPIO_Mode = GPIO_Pin_8 | GPIO_Pin_9;
|
||||
GPIO_Init(GPIOB, &gpio);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// configure core
|
||||
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
// enable peripheral clocks
|
||||
RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR | RCC_APB1Periph_BKP |
|
||||
RCC_APB1Periph_I2C1, ENABLE);
|
||||
RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA |
|
||||
RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD |
|
||||
RCC_APB2Periph_ADC1, ENABLE);
|
||||
|
||||
// configure gpio pins
|
||||
gpio_init();
|
||||
|
||||
// configure RTC
|
||||
if (rtc_init()) {
|
||||
// rtc failed to initialize. let the end user know.
|
||||
// todo
|
||||
}
|
||||
|
||||
// initialize buttons
|
||||
btn_init();
|
||||
btn[0].cb_push = btn_top_push_cb;
|
||||
btn[1].cb_push = btn_bot_push_cb;
|
||||
|
||||
// set GAT GP pins weak pull to address the addon
|
||||
gat_gpio_init();
|
||||
|
||||
// set output ports to saved state, or on if no batt / first boot
|
||||
port_pwr_init();
|
||||
|
||||
// start up rgbled
|
||||
rgbled_init();
|
||||
|
||||
// finally, get the system tick interrupt going
|
||||
systick_init();
|
||||
|
||||
// let's do this
|
||||
while (1) {
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t st_tick;
|
||||
volatile uint32_t uptime;
|
||||
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
st_tick++;
|
||||
if (!st_tick) uptime++;
|
||||
|
||||
btn_poll();
|
||||
|
||||
if (!(st_tick & 0x3)) {
|
||||
rgbled_update();
|
||||
}
|
||||
}
|
||||
106
gat_stand_fw/user/src/btn.c
Normal file
106
gat_stand_fw/user/src/btn.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* btn.c
|
||||
*
|
||||
* handles buttons as well as the
|
||||
* DIP switches (in case action is desired by hot-switching)
|
||||
*/
|
||||
|
||||
|
||||
#include <ch32v20x.h>
|
||||
|
||||
#include "btn.h"
|
||||
|
||||
|
||||
|
||||
struct Btn btn[BTN_COUNT] = {0};
|
||||
|
||||
|
||||
|
||||
void btn_init()
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
// this function assumes GPIO has been configured already
|
||||
|
||||
// initialize default setup
|
||||
btn[0]._pintype = BTN1_PIN;
|
||||
btn[1]._pintype = BTN2_PIN;
|
||||
|
||||
btn[2]._pintype = DIP1_PIN;
|
||||
btn[3]._pintype = DIP2_PIN;
|
||||
btn[4]._pintype = DIP3_PIN;
|
||||
|
||||
for (i = 0; i < BTN_COUNT; i++) {
|
||||
btn[i]._mask = BTN_RELEASE;
|
||||
|
||||
// ignore any currently pressed buttons
|
||||
if (!(BTN_PORT->INDR & (1 << (btn[i]._pintype & BTN_PIN_MASK)))) {
|
||||
btn[0]._mask |= BTN_IGNORE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void btn_poll()
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t r;
|
||||
uint8_t ignore;
|
||||
|
||||
uint8_t pushed;
|
||||
|
||||
for (i = 0; i < BTN_COUNT; i++) {
|
||||
pushed = 0;
|
||||
|
||||
ignore = btn[i]._mask & BTN_IGNORE;
|
||||
r = BTN_PORT->INDR & (1 << (btn[i]._pintype & BTN_PIN_MASK));
|
||||
|
||||
// active low type buttons
|
||||
if (!r) pushed = 1;
|
||||
|
||||
if (pushed) {
|
||||
// hold counter
|
||||
if (btn[i]._count < 0xffff) btn[i]._count++;
|
||||
|
||||
// pushed long enough?
|
||||
if (btn[i]._count < BTN_DEBOUNCE) continue;
|
||||
|
||||
// first push?
|
||||
if (!(btn[i]._mask & BTN_PUSH)) {
|
||||
btn[i]._mask = BTN_PUSH | ignore;
|
||||
if (btn[i].cb_push && !ignore) {
|
||||
btn[i].cb_push(i);
|
||||
btn[i]._mask |= (BTN_PUSH << 4);
|
||||
}
|
||||
} else if (btn[i]._count >= btn[i].hold) {
|
||||
// held to count limit
|
||||
|
||||
// if button is not repeatable, do not retrigger
|
||||
if ((btn[i]._mask & BTN_HOLD) && !btn[i].repeat) continue;
|
||||
|
||||
btn[i]._mask |= BTN_HOLD;
|
||||
// call callback only if not in ignore state
|
||||
if (btn[i].cb_hold && !ignore) {
|
||||
btn[i].cb_hold(i);
|
||||
btn[i]._mask |= (BTN_HOLD << 4);
|
||||
}
|
||||
|
||||
// apply repeat rate to count
|
||||
if (btn[i].repeat > btn[i]._count) {
|
||||
btn[i]._count = 0;
|
||||
} else btn[i]._count -= btn[i].repeat;
|
||||
}
|
||||
} else {
|
||||
// is not pushed
|
||||
if (!(btn[i]._mask & BTN_RELEASE)) {
|
||||
// note: release will remove ignore status
|
||||
btn[i]._mask = BTN_RELEASE;
|
||||
btn[i]._count = 0;
|
||||
// call callback only if not in ignore state
|
||||
if (btn[i].cb_release && !ignore) {
|
||||
btn[i].cb_release(i);
|
||||
btn[i]._mask |= (BTN_RELEASE << 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
gat_stand_fw/user/src/btn.h
Normal file
58
gat_stand_fw/user/src/btn.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* btn.h
|
||||
*/
|
||||
|
||||
#ifndef USER_SRC_BTN_H_
|
||||
#define USER_SRC_BTN_H_
|
||||
|
||||
|
||||
|
||||
#include <ch32v20x.h>
|
||||
|
||||
|
||||
|
||||
#define BTN_COUNT 5
|
||||
#define BTN_DEBOUNCE (24 / 4) // debounce time in ~4ms increments
|
||||
|
||||
#define BTN_PORT GPIOB
|
||||
|
||||
#define BTN1_PIN 10
|
||||
#define BTN2_PIN 11
|
||||
|
||||
#define DIP1_PIN 12
|
||||
#define DIP2_PIN 13
|
||||
#define DIP3_PIN 14
|
||||
|
||||
#define BTN_PIN_MASK 0xf
|
||||
|
||||
|
||||
#define BTN_PUSH (1 << 0)
|
||||
#define BTN_HOLD (1 << 1)
|
||||
#define BTN_RELEASE (1 << 2)
|
||||
#define BTN_IGNORE (1 << 3)
|
||||
|
||||
|
||||
|
||||
typedef struct Btn {
|
||||
uint8_t _pintype;
|
||||
uint8_t _mask;
|
||||
uint16_t _count; // held counts
|
||||
uint16_t hold; // initial hold
|
||||
uint16_t repeat; // repeated hold
|
||||
void (*cb_push)(uint8_t);
|
||||
void (*cb_hold)(uint8_t);
|
||||
void (*cb_release)(uint8_t);
|
||||
} Btn;
|
||||
|
||||
|
||||
|
||||
extern struct Btn btn[BTN_COUNT];
|
||||
|
||||
|
||||
|
||||
void btn_init();
|
||||
void btn_poll();
|
||||
|
||||
|
||||
|
||||
#endif /* USER_SRC_BTN_H_ */
|
||||
24
gat_stand_fw/user/src/gat_gpio.c
Normal file
24
gat_stand_fw/user/src/gat_gpio.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* gat_gpio.c
|
||||
*
|
||||
* Created on: Oct 16, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
|
||||
#include "gat_gpio.h"
|
||||
|
||||
|
||||
|
||||
static GPIO_InitTypeDef gpio;
|
||||
|
||||
|
||||
|
||||
void gat_gpio_init()
|
||||
{
|
||||
// set the ID to 0 on GP pins.
|
||||
gpio.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
gpio.GPIO_Mode = GPIO_Mode_IPD;
|
||||
gpio.GPIO_Pin = (1 << GAT_GP1_PIN) | (1 << GAT_GP2_PIN);
|
||||
GPIO_Init(GAT_GPIO_PORT, &gpio);
|
||||
}
|
||||
28
gat_stand_fw/user/src/gat_gpio.h
Normal file
28
gat_stand_fw/user/src/gat_gpio.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* gat_gpio.h
|
||||
*
|
||||
* Created on: Oct 16, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#ifndef USER_SRC_GAT_GPIO_H_
|
||||
#define USER_SRC_GAT_GPIO_H_
|
||||
|
||||
|
||||
|
||||
#include <ch32v20x.h>
|
||||
|
||||
|
||||
|
||||
#define GAT_GPIO_PORT GPIOA
|
||||
|
||||
#define GAT_GP1_PIN 9
|
||||
#define GAT_GP2_PIN 10
|
||||
|
||||
|
||||
|
||||
void gat_gpio_init();
|
||||
|
||||
|
||||
|
||||
#endif /* USER_SRC_GAT_GPIO_H_ */
|
||||
103
gat_stand_fw/user/src/port_pwr.c
Normal file
103
gat_stand_fw/user/src/port_pwr.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* port_pwr.c
|
||||
*
|
||||
* Created Oct 16, 2024
|
||||
*
|
||||
* power control for GAT and USB ports.
|
||||
*/
|
||||
|
||||
|
||||
#include <ch32v20x.h>
|
||||
#include "port_pwr.h"
|
||||
|
||||
|
||||
|
||||
#define PORT_PWR_STATE_DR BKP_DR3
|
||||
|
||||
#define GAT_ON_FLAG (1 << 0)
|
||||
#define USB2_ON_FLAG (1 << 1)
|
||||
|
||||
#define INIT_FLAG (0xa0 << 8)
|
||||
|
||||
|
||||
|
||||
static uint8_t port_pwr_state;
|
||||
static uint8_t gat_oc_state_latch = 0;
|
||||
|
||||
|
||||
|
||||
void gat_on()
|
||||
{
|
||||
if (gat_oc_state_latch) return;
|
||||
|
||||
GAT_EN_PORT->BSHR = GAT_EN_PIN;
|
||||
|
||||
port_pwr_state |= GAT_ON_FLAG;
|
||||
BKP_WriteBackupRegister(PORT_PWR_STATE_DR, port_pwr_state);
|
||||
}
|
||||
|
||||
void gat_off()
|
||||
{
|
||||
GAT_EN_PORT->BCR = GAT_EN_PIN;
|
||||
|
||||
port_pwr_state &= ~GAT_ON_FLAG;
|
||||
BKP_WriteBackupRegister(PORT_PWR_STATE_DR, port_pwr_state);
|
||||
}
|
||||
|
||||
uint8_t gat_pwr_state()
|
||||
{
|
||||
return (GAT_EN_PORT->OUTDR & GAT_EN_PIN) ? 1 : 0;
|
||||
}
|
||||
|
||||
uint8_t gat_oc_state()
|
||||
{
|
||||
if (!(GAT_OC_PORT->INDR & GAT_OC_PIN)) {
|
||||
gat_oc_state_latch = 1;
|
||||
gat_off();
|
||||
}
|
||||
|
||||
return gat_oc_state_latch;
|
||||
}
|
||||
|
||||
void gat_toggle()
|
||||
{
|
||||
if (gat_pwr_state()) gat_off();
|
||||
else gat_on();
|
||||
}
|
||||
|
||||
void usb2_on()
|
||||
{
|
||||
port_pwr_state |= USB2_ON_FLAG;
|
||||
BKP_WriteBackupRegister(PORT_PWR_STATE_DR, port_pwr_state);
|
||||
}
|
||||
|
||||
void usb2_off()
|
||||
{
|
||||
port_pwr_state &= ~USB2_ON_FLAG;
|
||||
BKP_WriteBackupRegister(PORT_PWR_STATE_DR, port_pwr_state);
|
||||
}
|
||||
|
||||
uint8_t usb2_pwr_state()
|
||||
{
|
||||
return (USB2_EN_PORT->OUTDR & USB2_EN_PIN) ? 1 : 0;
|
||||
}
|
||||
|
||||
void usb2_toggle()
|
||||
{
|
||||
if (usb2_pwr_state()) gat_off();
|
||||
else gat_on();
|
||||
}
|
||||
|
||||
|
||||
void port_pwr_init()
|
||||
{
|
||||
port_pwr_state = BKP_ReadBackupRegister(PORT_PWR_STATE_DR);
|
||||
|
||||
if ((port_pwr_state & INIT_FLAG) != INIT_FLAG) {
|
||||
// no battery retention.
|
||||
// automatically turn on all outputs
|
||||
port_pwr_state |= INIT_FLAG;
|
||||
gat_on();
|
||||
usb2_on();
|
||||
}
|
||||
}
|
||||
46
gat_stand_fw/user/src/port_pwr.h
Normal file
46
gat_stand_fw/user/src/port_pwr.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* port_pwr.h
|
||||
*
|
||||
* Created on: Oct 16, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#ifndef USER_SRC_PORT_PWR_H_
|
||||
#define USER_SRC_PORT_PWR_H_
|
||||
|
||||
|
||||
|
||||
#include <ch32v20x.h>
|
||||
|
||||
|
||||
|
||||
// GAT port enable pin
|
||||
#define GAT_EN_PORT GPIOA
|
||||
#define GAT_EN_PIN GPIO_Pin_3
|
||||
|
||||
// overcurrent detect pin, active low
|
||||
#define GAT_OC_PORT GPIOA
|
||||
#define GAT_OC_PIN GPIO_Pin_4
|
||||
|
||||
#define USB2_EN_PORT GPIOB
|
||||
#define USB2_EN_PIN GPIO_Pin_4
|
||||
|
||||
|
||||
|
||||
void port_pwr_init();
|
||||
|
||||
uint8_t gat_oc_state();
|
||||
|
||||
void gat_on();
|
||||
void gat_off();
|
||||
void gat_toggle();
|
||||
uint8_t gat_pwr_state();
|
||||
|
||||
void usb2_on();
|
||||
void usb2_off();
|
||||
void usb2_toggle();
|
||||
uint8_t usb2_pwr_state();
|
||||
|
||||
|
||||
|
||||
#endif /* USER_SRC_PORT_PWR_H_ */
|
||||
119
gat_stand_fw/user/src/rgbled.c
Normal file
119
gat_stand_fw/user/src/rgbled.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* rgbled.c
|
||||
*
|
||||
* using TIM2 CH1-CH3
|
||||
*/
|
||||
|
||||
#include <ch32v20x.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rtc.h"
|
||||
|
||||
#include "port_pwr.h"
|
||||
|
||||
|
||||
|
||||
#define RED 0
|
||||
#define GRN 1
|
||||
#define BLU 2
|
||||
|
||||
#define BRT_RED 200
|
||||
#define BRT_GRN 100
|
||||
#define BRT_BLU 200
|
||||
|
||||
#define RGBLED_TIM TIM2
|
||||
|
||||
|
||||
|
||||
static uint8_t flash_timeout[3];
|
||||
static uint8_t flash[3] = {0};
|
||||
static uint8_t state[3] = {0};
|
||||
|
||||
|
||||
|
||||
void rgbled_set()
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
// flash counters
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!flash[i]) {
|
||||
flash[i] = flash_timeout[i];
|
||||
} else flash[i]--;
|
||||
|
||||
switch (flash_timeout[i]) {
|
||||
// always on
|
||||
case 0x00: {
|
||||
state[i] = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// always off
|
||||
case 0xff: {
|
||||
state[i] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// standard
|
||||
default: {
|
||||
if (flash[i] == flash_timeout[i]) {
|
||||
state[i] ^= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RGBLED_TIM->CH1CVR = state[RED] ? BRT_RED : 0;
|
||||
RGBLED_TIM->CH2CVR = state[GRN] ? BRT_GRN : 0;
|
||||
RGBLED_TIM->CH3CVR = state[BLU] ? BRT_BLU : 0;
|
||||
}
|
||||
|
||||
void rgbled_update()
|
||||
{
|
||||
uint16_t w;
|
||||
|
||||
// VCR flash if clock isn't set
|
||||
w = BKP_ReadBackupRegister(RTC_STATE_DR);
|
||||
switch (w) {
|
||||
case RTC_STATE_UNINITIALIZED: {
|
||||
flash_timeout[BLU] = 254;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
flash_timeout[BLU] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
flash_timeout[GRN] = gat_pwr_state() ? 0 : 0xff;
|
||||
flash_timeout[RED] = gat_oc_state() ? 50 : 0xff;
|
||||
}
|
||||
|
||||
void rgbled_init()
|
||||
{
|
||||
TIM_TimeBaseInitTypeDef timer ={0};
|
||||
TIM_OCInitTypeDef pwm = {0};
|
||||
|
||||
timer.TIM_Period = (1 << 10) - 1; // 10-bit
|
||||
timer.TIM_Prescaler = 0;
|
||||
timer.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||
timer.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
TIM_TimeBaseInit(RGBLED_TIM, &timer);
|
||||
|
||||
pwm.TIM_OCMode = TIM_OCMode_PWM1;
|
||||
pwm.TIM_OutputState = TIM_OutputState_Enable;
|
||||
pwm.TIM_Pulse = 0;
|
||||
pwm.TIM_OCPolarity = TIM_OCPolarity_High;
|
||||
TIM_OC1Init(RGBLED_TIM, &pwm);
|
||||
TIM_OC2Init(RGBLED_TIM, &pwm);
|
||||
TIM_OC3Init(RGBLED_TIM, &pwm);
|
||||
|
||||
TIM_CtrlPWMOutputs(RGBLED_TIM, ENABLE);
|
||||
TIM_OC1PreloadConfig(RGBLED_TIM, TIM_OCPreload_Disable);
|
||||
TIM_ARRPreloadConfig(RGBLED_TIM, ENABLE);
|
||||
TIM_Cmd(RGBLED_TIM, ENABLE);
|
||||
|
||||
RGBLED_TIM->CH1CVR = 0;
|
||||
RGBLED_TIM->CH2CVR = 0;
|
||||
RGBLED_TIM->CH3CVR = 0;
|
||||
}
|
||||
24
gat_stand_fw/user/src/rgbled.h
Normal file
24
gat_stand_fw/user/src/rgbled.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* rgbled.h
|
||||
*
|
||||
* Created on: Oct 16, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#ifndef USER_SRC_RGBLED_H_
|
||||
#define USER_SRC_RGBLED_H_
|
||||
|
||||
|
||||
|
||||
#define RGBLED_PORT GPIOA
|
||||
#define RGBLED_PIN_R GPIO_Pin_0
|
||||
#define RGBLED_PIN_G GPIO_Pin_1
|
||||
#define RGBLED_PIN_B GPIO_Pin_2
|
||||
|
||||
|
||||
|
||||
void rgbled_update();
|
||||
|
||||
|
||||
|
||||
#endif /* USER_SRC_RGBLED_H_ */
|
||||
160
gat_stand_fw/user/src/rtc.c
Normal file
160
gat_stand_fw/user/src/rtc.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* rtc.c
|
||||
*
|
||||
* Created on: Oct 16, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
|
||||
#include <ch32v20x.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "rtc.h"
|
||||
|
||||
|
||||
|
||||
#define RTC_INIT_PATTERN 0x1337
|
||||
|
||||
|
||||
|
||||
static const uint8_t days_per_mon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
||||
|
||||
|
||||
|
||||
uint8_t rtc_state;
|
||||
|
||||
|
||||
|
||||
void rtc_set_state(uint16_t state)
|
||||
{
|
||||
rtc_state = state;
|
||||
}
|
||||
|
||||
/*
|
||||
* @fn rtc_is_leapyear
|
||||
* @brief Returns true if year is a leap year.
|
||||
*
|
||||
* @param year
|
||||
*
|
||||
* @return 1 - Yes
|
||||
* 0 - No
|
||||
*/
|
||||
uint8_t rtc_is_leapyear(u16 year)
|
||||
{
|
||||
if (year % 4 == 0) {
|
||||
if (year % 100 == 0) {
|
||||
if (year % 400 == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else return 1;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @fn rtc_set_clock
|
||||
* @brief Set Time.
|
||||
*
|
||||
* @param Struct of RTClock
|
||||
*
|
||||
* @return 1 - error
|
||||
* 0 - success
|
||||
*/
|
||||
int8_t rtc_set_clock(struct RTClock *c)
|
||||
{
|
||||
uint16_t x;
|
||||
uint8_t m;
|
||||
uint32_t count = 0;
|
||||
|
||||
if(c->year < 1970 || c->year > 2099)
|
||||
return -1;
|
||||
|
||||
for(x = 1970; x < c->year; x++) {
|
||||
if (rtc_is_leapyear(x))
|
||||
count += 31622400;
|
||||
else
|
||||
count += 31536000;
|
||||
}
|
||||
|
||||
m = c->mon - 1;
|
||||
for(x = 0; x < m; x++){
|
||||
count += (u32)days_per_mon[x] * 86400;
|
||||
if(rtc_is_leapyear(c->year) && x == 1)
|
||||
count += 86400;
|
||||
}
|
||||
|
||||
count += (u32)(c->day - 1) * 86400;
|
||||
count += (u32)c->h * 3600;
|
||||
count += (u32)c->m * 60;
|
||||
count += c->s;
|
||||
|
||||
PWR_BackupAccessCmd(ENABLE);
|
||||
RTC_SetCounter(count);
|
||||
RTC_WaitForLastTask();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t rtc_init()
|
||||
{
|
||||
uint32_t timeout;
|
||||
static const struct RTClock clock = {
|
||||
.year = 2024,
|
||||
.mon = 11,
|
||||
.day = 1,
|
||||
.h = 8,
|
||||
.m = 0,
|
||||
.s = 0
|
||||
};
|
||||
|
||||
// enable access to RTC registers
|
||||
PWR_BackupAccessCmd(ENABLE);
|
||||
|
||||
// get RTC state
|
||||
// if things aren't configured it'll be initialized in a moment
|
||||
rtc_state = BKP_ReadBackupRegister(RTC_STATE_DR);
|
||||
|
||||
// is RTC already configured?
|
||||
if (BKP_ReadBackupRegister(RTC_INIT_DR) != RTC_INIT_PATTERN) {
|
||||
// must not be. initialize rtc
|
||||
BKP_DeInit();
|
||||
|
||||
RCC_LSEConfig(RCC_LSE_ON);
|
||||
|
||||
timeout = SystemCoreClock / 2;
|
||||
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET && timeout--);
|
||||
|
||||
// if crystal didn't start in time, let the application know
|
||||
if (!timeout) return -1;
|
||||
|
||||
// use crystal for RTC and enable it
|
||||
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
|
||||
RCC_RTCCLKCmd(ENABLE);
|
||||
RTC_WaitForLastTask();
|
||||
RTC_WaitForSynchro();
|
||||
// RTC_ITConfig(RTC_IT_ALR, ENABLE);
|
||||
// RTC_ITConfig(RTC_IT_SEC, ENABLE);
|
||||
// RTC_WaitForLastTask();
|
||||
|
||||
RTC_EnterConfigMode();
|
||||
RTC_SetPrescaler(32767);
|
||||
RTC_WaitForLastTask();
|
||||
|
||||
// set an initial time
|
||||
|
||||
rtc_set_clock((struct RTClock *)&clock);
|
||||
RTC_ExitConfigMode();
|
||||
|
||||
rtc_state = RTC_STATE_CLOCK_NOT_SET;
|
||||
BKP_WriteBackupRegister(RTC_STATE_DR, rtc_state);
|
||||
BKP_WriteBackupRegister(RTC_INIT_DR, RTC_INIT_PATTERN);
|
||||
|
||||
// RTC_NVIC_Config();
|
||||
// RTC_Get();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
44
gat_stand_fw/user/src/rtc.h
Normal file
44
gat_stand_fw/user/src/rtc.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* rtc.h
|
||||
*
|
||||
* Created on: Oct 16, 2024
|
||||
* Author: true
|
||||
*/
|
||||
|
||||
#ifndef USER_SRC_RTC_H_
|
||||
#define USER_SRC_RTC_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
#define RTC_INIT_DR BKP_DR1
|
||||
#define RTC_STATE_DR BKP_DR2
|
||||
|
||||
|
||||
|
||||
enum RTCState {
|
||||
RTC_STATE_UNINITIALIZED = 0,
|
||||
RTC_STATE_CLOCK_NOT_SET,
|
||||
RTC_STATE_OK = 0x7f
|
||||
};
|
||||
|
||||
typedef struct RTClock {
|
||||
uint16_t year;
|
||||
uint8_t mon;
|
||||
uint8_t day;
|
||||
uint8_t h;
|
||||
uint8_t m;
|
||||
uint8_t s;
|
||||
} RTClock;
|
||||
|
||||
|
||||
|
||||
int8_t rtc_init();
|
||||
|
||||
int8_t rtc_set_clock(struct RTClock *c);
|
||||
|
||||
|
||||
|
||||
#endif /* USER_SRC_RTC_H_ */
|
||||
987
gat_stand_fw/user/system_ch32v20x.c
Normal file
987
gat_stand_fw/user/system_ch32v20x.c
Normal file
@@ -0,0 +1,987 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.c
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Source File.
|
||||
* For HSE = 32Mhz (CH32V208x/CH32V203RBT6)
|
||||
* For HSE = 8Mhz (other CH32V203x)
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#include "ch32v20x.h"
|
||||
|
||||
/*
|
||||
* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after
|
||||
* reset the HSI is used as SYSCLK source).
|
||||
* If none of the define below is enabled, the HSI is used as System clock source.
|
||||
*/
|
||||
//#define SYSCLK_FREQ_HSE HSE_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSE 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSE 56000000
|
||||
//#define SYSCLK_FREQ_72MHz_HSE 72000000
|
||||
//#define SYSCLK_FREQ_96MHz_HSE 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSE 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSE 144000000
|
||||
//#define SYSCLK_FREQ_HSI HSI_VALUE
|
||||
//#define SYSCLK_FREQ_48MHz_HSI 48000000
|
||||
//#define SYSCLK_FREQ_56MHz_HSI 56000000
|
||||
#define SYSCLK_FREQ_72MHz_HSI 72000000
|
||||
//#define SYSCLK_FREQ_96MHz_HSI 96000000
|
||||
//#define SYSCLK_FREQ_120MHz_HSI 120000000
|
||||
//#define SYSCLK_FREQ_144MHz_HSI 144000000
|
||||
|
||||
/* Clock Definitions */
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */
|
||||
#else
|
||||
uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
#endif
|
||||
|
||||
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
|
||||
|
||||
/* system_private_function_proto_types */
|
||||
static void SetSysClock(void);
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
static void SetSysClockToHSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
static void SetSysClockTo48_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
static void SetSysClockTo56_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
static void SetSysClockTo72_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
static void SetSysClockTo96_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
static void SetSysClockTo120_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
static void SetSysClockTo144_HSE( void );
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
static void SetSysClockTo48_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
static void SetSysClockTo56_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
static void SetSysClockTo72_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
static void SetSysClockTo96_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
static void SetSysClockTo120_HSI( void );
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
static void SetSysClockTo144_HSI( void );
|
||||
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemInit
|
||||
*
|
||||
* @brief Setup the microcontroller system Initialize the Embedded Flash Interface,
|
||||
* the PLL and update the SystemCoreClock variable.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
RCC->CTLR |= (uint32_t)0x00000001;
|
||||
RCC->CFGR0 &= (uint32_t)0xF0FF0000;
|
||||
RCC->CTLR &= (uint32_t)0xFEF6FFFF;
|
||||
RCC->CTLR &= (uint32_t)0xFFFBFFFF;
|
||||
RCC->CFGR0 &= (uint32_t)0xFF00FFFF;
|
||||
RCC->INTR = 0x009F0000;
|
||||
SetSysClock();
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SystemCoreClockUpdate
|
||||
*
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0;
|
||||
|
||||
tmp = RCC->CFGR0 & RCC_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04:
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08:
|
||||
pllmull = RCC->CFGR0 & RCC_PLLMULL;
|
||||
pllsource = RCC->CFGR0 & RCC_PLLSRC;
|
||||
pllmull = ( pllmull >> 18) + 2;
|
||||
|
||||
if(pllmull == 17) pllmull = 18;
|
||||
|
||||
if (pllsource == 0x00)
|
||||
{
|
||||
if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){
|
||||
SystemCoreClock = HSI_VALUE * pllmull;
|
||||
}
|
||||
else{
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
if((RCC->CFGR0 & (3<<22)) == (3<<22))
|
||||
{
|
||||
SystemCoreClock = ((HSE_VALUE>>1)) * pllmull;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET)
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined (CH32V20x_D8) || defined (CH32V20x_D8W)
|
||||
SystemCoreClock = (HSE_VALUE>>2) * pllmull;
|
||||
#else
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2);
|
||||
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)];
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClock
|
||||
*
|
||||
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClock(void)
|
||||
{
|
||||
//GPIO_IPD_Unused();
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
SetSysClockToHSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
SetSysClockTo48_HSE();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
SetSysClockTo56_HSE();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
SetSysClockTo72_HSE();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
SetSysClockTo96_HSE();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
SetSysClockTo120_HSE();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
SetSysClockTo144_HSE();
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
SetSysClockTo48_HSI();
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
SetSysClockTo56_HSI();
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
SetSysClockTo72_HSI();
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
SetSysClockTo96_HSI();
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
SetSysClockTo120_HSI();
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
SetSysClockTo144_HSI();
|
||||
|
||||
#endif
|
||||
|
||||
/* If none of the define above is enabled, the HSI is used as System clock
|
||||
* source (default after reset)
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef SYSCLK_FREQ_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockToHSE
|
||||
*
|
||||
* @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockToHSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1;
|
||||
|
||||
/* Select HSE as system clock source
|
||||
* CH32V20x_D6 (HSE=8MHZ)
|
||||
* CH32V20x_D8 (HSE=32MHZ)
|
||||
* CH32V20x_D8W (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_HSE;
|
||||
|
||||
/* Wait till HSE is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if(HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
#if defined (CH32V20x_D8W)
|
||||
RCC->CFGR0 |= (uint32_t)(3<<22);
|
||||
/* HCLK = SYSCLK/2 */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2;
|
||||
#else
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
#endif
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSE
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSE
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSE(void)
|
||||
{
|
||||
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
|
||||
|
||||
RCC->CTLR |= ((uint32_t)RCC_HSEON);
|
||||
|
||||
/* Wait till HSE is ready and if Time out is reached exit */
|
||||
do
|
||||
{
|
||||
HSEStatus = RCC->CTLR & RCC_HSERDY;
|
||||
StartUpCounter++;
|
||||
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
|
||||
|
||||
if ((RCC->CTLR & RCC_HSERDY) != RESET)
|
||||
{
|
||||
HSEStatus = (uint32_t)0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
HSEStatus = (uint32_t)0x00;
|
||||
}
|
||||
|
||||
if (HSEStatus == (uint32_t)0x01)
|
||||
{
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ)
|
||||
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ)
|
||||
*/
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If HSE fails to start-up, the application will have wrong clock
|
||||
* configuration. User can add here some code to deal with this error
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_48MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo48_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo48_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_56MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo56_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo56_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined SYSCLK_FREQ_72MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo72_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo72_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_96MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo96_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo96_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#elif defined SYSCLK_FREQ_120MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo120_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo120_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE |
|
||||
RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
#elif defined SYSCLK_FREQ_144MHz_HSI
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SetSysClockTo144_HSI
|
||||
*
|
||||
* @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SetSysClockTo144_HSI(void)
|
||||
{
|
||||
EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE;
|
||||
|
||||
/* HCLK = SYSCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1;
|
||||
/* PCLK2 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1;
|
||||
/* PCLK1 = HCLK */
|
||||
RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2;
|
||||
|
||||
/* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL));
|
||||
|
||||
RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18);
|
||||
|
||||
/* Enable PLL */
|
||||
RCC->CTLR |= RCC_PLLON;
|
||||
/* Wait till PLL is ready */
|
||||
while((RCC->CTLR & RCC_PLLRDY) == 0)
|
||||
{
|
||||
}
|
||||
/* Select PLL as system clock source */
|
||||
RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW));
|
||||
RCC->CFGR0 |= (uint32_t)RCC_SW_PLL;
|
||||
/* Wait till PLL is used as system clock source */
|
||||
while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
32
gat_stand_fw/user/system_ch32v20x.h
Normal file
32
gat_stand_fw/user/system_ch32v20x.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : system_ch32v20x.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : CH32V20x Device Peripheral Access Layer System Header File.
|
||||
*********************************************************************************
|
||||
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
||||
* Attention: This software (modified or not) and binary are used for
|
||||
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
||||
*******************************************************************************/
|
||||
#ifndef __SYSTEM_ch32v20x_H
|
||||
#define __SYSTEM_ch32v20x_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */
|
||||
|
||||
/* System_Exported_Functions */
|
||||
extern void SystemInit(void);
|
||||
extern void SystemCoreClockUpdate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__CH32V20x_SYSTEM_H */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user