未验证 提交 c802fcdc 编写于 作者: E emuzit 提交者: GitHub

WCH CH569W-R0-1v0 evt board bsp port, first version (#6167)

WCH CH569W-R0-1v0 evt board bsp port, first version

dev/test under Ubuntu 20.04
toolchain from MounRiver_Studio_Community_Linux_x64_V120

tested drivers : SysTick, gpio, gpio interrupt, uart1 (RX interrupt, TX polling)

libcpu/risc-v/SConscript :
group includes rtconfig.CPU only if folder exists

libcpu/risc-v/common/cpuport.c/rt_hw_context_switch_interrupt() :
make it RT_WEAK for customization
上级 226b3e19
......@@ -5,4 +5,11 @@ config SOC_RISCV_SERIES_CH32V103
bool
select ARCH_RISCV
select SOC_RISCV_FAMILY_CH32
\ No newline at end of file
config SOC_FAMILY_CH56X
bool
select ARCH_RISCV
config SOC_SERIES_CH569
bool
select SOC_FAMILY_CH56X
from building import *
cwd = GetCurrentDir()
src = Split("""
ch56x_sys.c
swi_gcc.S
""")
if GetDepend('SOC_SERIES_CH569'):
src += ['ch56x_pfic.c']
if GetDepend('RT_USING_WDT'):
src += ['ch56x_wdt.c']
if GetDepend('RT_USING_HWTIMER'):
src += ['ch56x_timer.c']
if GetDepend('RT_USING_PIN'):
src += ['ch56x_gpio.c']
if GetDepend(['RT_USING_SERIAL', 'BSP_USING_UART']):
src += ['ch56x_uart.c']
path = [cwd]
group = DefineGroup('Drivers', src, depend=[''], CPPPATH=path)
Return('group')
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#include <rthw.h>
#include <rtdebug.h>
#include <drivers/pin.h>
#include "ch56x_gpio.h"
#include "isr_sp.h"
struct port_info
{
uint32_t pin_mark;
struct gpio_px_regs *regbase;
};
static const struct port_info pin_ports[GPIO_PORTS] =
{
{GPIO_PA_PIN_MARK, (struct gpio_px_regs *)GPIO_REG_BASE_PA},
{GPIO_PB_PIN_MARK, (struct gpio_px_regs *)GPIO_REG_BASE_PB},
};
static struct rt_pin_irq_hdr pin_irq_hdr_table[8] =
{
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
{-1, 0, RT_NULL, RT_NULL},
};
#if defined(SOC_SERIES_CH569)
static int _gpio_pin_to_ibit(rt_base_t pin)
{
/* gpio ext interrupt 7-0 : {PB15,PB12,PB11,PB4,PB3,PA4,PA3,PA2}
* not time critical, use linear search
*/
switch (pin)
{
case GET_PIN(A, 2): return 0;
case GET_PIN(A, 3): return 1;
case GET_PIN(A, 4): return 2;
case GET_PIN(B, 3): return 3;
case GET_PIN(B, 4): return 4;
case GET_PIN(B, 11): return 5;
case GET_PIN(B, 12): return 6;
case GET_PIN(B, 15): return 7;
}
return -1;
}
#else
static int _gpio_pin_to_ibit(rt_base_t pin)
{
/* gpio ext interrupt 7-0 : {PB10,PB4,PA12,PA11,PA10,PA6,PA4,PA3}
* not time critical, use linear search
*/
switch (pin)
{
case GET_PIN(A, 3): return 0;
case GET_PIN(A, 4): return 1;
case GET_PIN(A, 6): return 2;
case GET_PIN(A, 10): return 3;
case GET_PIN(A, 11): return 4;
case GET_PIN(A, 12): return 5;
case GET_PIN(B, 4): return 6;
case GET_PIN(B, 10): return 7;
}
return -1;
}
#endif
static struct gpio_px_regs *_gpio_px_regbase(rt_base_t pin)
{
/* fixed linear mapping : 32 pins per port, for ports A,B,C,D...
*/
uint32_t port = (uint32_t)pin >> 5;
uint32_t bitpos = 1 << (pin & 0x1f);
if (port < GPIO_PORTS && (pin_ports[port].pin_mark & bitpos))
return pin_ports[port].regbase;
else
return RT_NULL;
}
static void gpio_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode)
{
volatile struct gpio_px_regs *px;
uint32_t port = (uint32_t)pin >> 5;
uint32_t bitpos = 1 << (pin & 0x1f);
if (port < GPIO_PORTS && (pin_ports[port].pin_mark & bitpos))
px = pin_ports[port].regbase;
else
return;
switch (mode)
{
case PIN_MODE_OUTPUT:
BITS_CLR(px->PD, bitpos);
BITS_SET(px->DIR, bitpos);
break;
case PIN_MODE_INPUT:
BITS_CLR(px->PU, bitpos);
BITS_CLR(px->PD, bitpos);
BITS_CLR(px->DIR, bitpos);
break;
case PIN_MODE_INPUT_PULLUP:
BITS_SET(px->PU, bitpos);
BITS_CLR(px->PD, bitpos);
BITS_CLR(px->DIR, bitpos);
break;
case PIN_MODE_INPUT_PULLDOWN:
BITS_CLR(px->PU, bitpos);
BITS_SET(px->PD, bitpos);
BITS_CLR(px->DIR, bitpos);
break;
case PIN_MODE_OUTPUT_OD:
BITS_SET(px->PD, bitpos);
BITS_SET(px->OUT, bitpos);
}
}
static void gpio_pin_write(struct rt_device *device, rt_base_t pin, rt_base_t value)
{
volatile struct gpio_px_regs *px;
uint32_t port = (uint32_t)pin >> 5;
uint32_t bitpos = 1 << (pin & 0x1f);
if (port < GPIO_PORTS && (pin_ports[port].pin_mark & bitpos))
px = pin_ports[port].regbase;
else
return;
if (value == 0)
BITS_CLR(px->OUT, bitpos);
else
BITS_SET(px->OUT, bitpos);
}
static int gpio_pin_read(struct rt_device *device, rt_base_t pin)
{
volatile struct gpio_px_regs *px;
uint32_t port = (uint32_t)pin >> 5;
uint32_t bitpos = 1 << (pin & 0x1f);
if (port < GPIO_PORTS && (pin_ports[port].pin_mark & bitpos))
px = pin_ports[port].regbase;
else
return PIN_LOW;
return (px->PIN & bitpos) ? PIN_HIGH : PIN_LOW;
}
static rt_base_t gpio_pin_get(const char *name)
{
int port, pin, sz, n;
/* pin name is in the form "PX.nn" (X: A,B,C,D...; nn: 0~31)
* fixed linear mapping : 32 pins per port, for ports A,B,C,D...
*/
sz = rt_strlen(name);
if ((sz == 4 || sz == 5) && name[0] == 'P' && name[2] == '.')
{
port = name[1] - 'A';
pin = name[3] - '0';
if (0 <= port && port < GPIO_PORTS && 0 <= pin && pin <= 9)
{
if (sz == 5)
{
n = name[4] - '0';
pin = (0 <= n && n <= 9) ? (pin * 10 + n) : 32;
}
if (pin < 32 && (pin_ports[port].pin_mark & (1 << pin)))
{
return port * 32 + pin;
}
}
}
return -1;
}
static rt_err_t gpio_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
rt_base_t level;
int ibit;
switch (mode)
{
case PIN_IRQ_MODE_RISING:
case PIN_IRQ_MODE_FALLING:
case PIN_IRQ_MODE_HIGH_LEVEL:
case PIN_IRQ_MODE_LOW_LEVEL:
break;
case PIN_IRQ_MODE_RISING_FALLING:
/* hardware not supported */
default:
return -RT_EINVAL;
}
ibit = _gpio_pin_to_ibit(pin);
if (ibit < 0)
return -RT_EINVAL;
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_table[ibit].pin == pin &&
pin_irq_hdr_table[ibit].mode == mode &&
pin_irq_hdr_table[ibit].hdr == hdr &&
pin_irq_hdr_table[ibit].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
if (pin_irq_hdr_table[ibit].pin >= 0)
{
rt_hw_interrupt_enable(level);
return -RT_EFULL;
}
pin_irq_hdr_table[ibit].pin = pin;
pin_irq_hdr_table[ibit].mode = mode;
pin_irq_hdr_table[ibit].hdr = hdr;
pin_irq_hdr_table[ibit].args = args;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t gpio_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_base_t level;
int ibit;
ibit = _gpio_pin_to_ibit(pin);
if (ibit < 0)
return -RT_EINVAL;
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_table[ibit].pin < 0)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
pin_irq_hdr_table[ibit].pin = -1;
pin_irq_hdr_table[ibit].mode = 0;
pin_irq_hdr_table[ibit].hdr = RT_NULL;
pin_irq_hdr_table[ibit].args = RT_NULL;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t gpio_pin_irq_enable(struct rt_device *device, rt_base_t pin,
rt_uint32_t enabled)
{
volatile struct gpio_registers *gpio;
rt_base_t level, int_enable;
int ibit, bitpos;
ibit = _gpio_pin_to_ibit(pin);
if (ibit < 0)
return -RT_EINVAL;
bitpos = (1 << ibit);
gpio = (struct gpio_registers *)GPIO_REG_BASE;
if (enabled == PIN_IRQ_ENABLE)
{
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_table[ibit].pin != pin)
{
rt_hw_interrupt_enable(level);
return -RT_EINVAL;
}
switch (pin_irq_hdr_table[ibit].mode)
{
case PIN_IRQ_MODE_RISING:
BITS_SET(gpio->INT_MODE.reg, bitpos);
BITS_SET(gpio->INT_POLAR.reg, bitpos);
break;
case PIN_IRQ_MODE_FALLING:
BITS_SET(gpio->INT_MODE.reg, bitpos);
BITS_CLR(gpio->INT_POLAR.reg, bitpos);
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
BITS_CLR(gpio->INT_MODE.reg, bitpos);
BITS_SET(gpio->INT_POLAR.reg, bitpos);
break;
case PIN_IRQ_MODE_LOW_LEVEL:
BITS_CLR(gpio->INT_MODE.reg, bitpos);
BITS_CLR(gpio->INT_POLAR.reg, bitpos);
break;
case PIN_IRQ_MODE_RISING_FALLING:
default:
rt_hw_interrupt_enable(level);
return -RT_EINVAL;
}
/* clear possible pending intr, then enable pin intr */
int_enable = gpio->INT_ENABLE.reg;
gpio->INT_FLAG.reg = bitpos;
gpio->INT_ENABLE.reg = int_enable | bitpos;
/* enable GPIO_IRQn if this is the first enabled EXTIx */
if (int_enable == 0)
{
rt_hw_interrupt_umask(GPIO_IRQn);
}
rt_hw_interrupt_enable(level);
}
else if (enabled == PIN_IRQ_DISABLE)
{
level = rt_hw_interrupt_disable();
int_enable = gpio->INT_ENABLE.reg;
BITS_CLR(int_enable, bitpos);
gpio->INT_ENABLE.reg = int_enable;
/* disable GPIO_IRQn if no EXTIx enabled */
if (int_enable == 0)
{
rt_hw_interrupt_mask(GPIO_IRQn);
}
rt_hw_interrupt_enable(level);
}
else
{
return -RT_EINVAL;
}
return RT_EOK;
}
static const struct rt_pin_ops pin_ops =
{
.pin_mode = gpio_pin_mode,
.pin_write = gpio_pin_write,
.pin_read = gpio_pin_read,
.pin_attach_irq = gpio_pin_attach_irq,
.pin_detach_irq = gpio_pin_detach_irq,
.pin_irq_enable = gpio_pin_irq_enable,
.pin_get = gpio_pin_get,
};
static int rt_hw_pin_init(void)
{
return rt_device_pin_register("pin", &pin_ops, RT_NULL);
}
INIT_BOARD_EXPORT(rt_hw_pin_init);
void gpio_irq_handler(void) __attribute__((interrupt()));
void gpio_irq_handler(void)
{
volatile struct gpio_registers *gpio;
uint8_t iflags;
int ibit, bitpos;
isr_sp_enter();
rt_interrupt_enter();
gpio = (struct gpio_registers *)GPIO_REG_BASE;
iflags = gpio->INT_FLAG.reg;
/* prioritized as pb15 -> pa2 (CH569), or pb10 -> pa3 */
for (ibit = 7; ibit >= 0; ibit--)
{
bitpos = (1 << ibit);
if (iflags & bitpos)
{
if (pin_irq_hdr_table[ibit].hdr)
{
pin_irq_hdr_table[ibit].hdr(pin_irq_hdr_table[ibit].args);
}
/* clear interrupt */
gpio->INT_FLAG.reg = bitpos;
}
}
rt_interrupt_leave();
isr_sp_leave();
}
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#ifndef __CH56X_GPIO_H__
#define __CH56X_GPIO_H__
#include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Fixed linear mapping : 32 pins per port, for ports A,B,C,D...
*/
#define GET_PIN(port,pin) (GPIO_P##port##_PIN_START + pin)
#ifdef SOC_SERIES_CH569
#define GPIO_INT_PINS { \
GET_PIN(A,2), GET_PIN(A,3), GET_PIN(A,4), GET_PIN(B,3), \
GET_PIN(B,4), GET_PIN(B,11), GET_PIN(B,12), GET_PIN(B,15) \
}
#else
#define GPIO_INT_PINS { \
GET_PIN(A,3), GET_PIN(A,4), GET_PIN(A,6), GET_PIN(A,10), \
GET_PIN(A,11), GET_PIN(A,12), GET_PIN(B,4), GET_PIN(B,10), \
}
#endif
/*
* R8_GPIO_INT_FLAG / R8_GPIO_INT_STATUS (CH567,CH568):
* write 1 to specific bit to clear int flag
*
* R8_GPIO_INT_ENABLE:
* To use EXTIx function, pin should be set as input.
* For wakeup function, also set RB_SLP_GPIO_WAKE.
*
* R8_GPIO_INT_MODE:
* R8_GPIO_INT_POLAR:
*/
#if defined(SOC_SERIES_CH569)
union _gpio_interrupt
{
uint8_t reg;
struct
{
uint8_t pa2 : 1;
uint8_t pa3 : 1;
uint8_t pa4 : 1;
uint8_t pb3 : 1;
uint8_t pb4 : 1;
uint8_t pb11 : 1;
uint8_t pb12 : 1;
uint8_t pb15 : 1;
};
};
#else
union _gpio_interrupt
{
uint8_t reg;
struct
{
uint8_t pa3 : 1;
uint8_t pa4 : 1;
uint8_t pa6 : 1;
uint8_t pa10 : 1;
uint8_t pa11 : 1;
uint8_t pa12 : 1;
uint8_t pb4 : 1;
uint8_t pb10 : 1;
};
};
#endif
#define GPIO_IE_DISABLE 0
#define GPIO_IE_ENABLE 1
#define GPIO_IM_LEVEL 0
#define GPIO_IM_EDGE 1
#define GPIO_IP_LOW_FALLING 0
#define GPIO_IP_HIGH_RISING 1
/*
* R8_PIN_ALTERNATE (CH569) : reset value is 0x01
* R8_PORT_PIN (CH567/CH568) : reset value is 0x00
*/
union _gpio_pin_alternate
{
uint8_t reg;
struct
{
uint8_t pin_mii : 1; // RW, ETH uses RMII/RGMII (CH565W/CH569W)
uint8_t pin_tmr1 : 1; // RW, TMR1/PWM5/CAP1 remapping
uint8_t pin_tmr2 : 1; // RW, TMR2/PWM6/CAP2 remapping
uint8_t resv_3 : 1;
uint8_t pin_uart0 : 1; // RW, RXD0/TXD0 remapping
uint8_t pin_uart1 : 1; // RW, CH567 only
uint8_t resv_6 : 2;
};
};
#define RB_PIN_MII 0x01
#define RB_PIN_TMR1 0x02
#define RB_PIN_TMR2 0x04
#define RB_PIN_UART0 0x10
#define RB_PIN_UART1 0x20
#ifdef SOC_SERIES_CH569
#define GPIO_ALT_RMII 0
#define GPIO_ALT_RGMII 1
#define GPIO_ALT_TMR1_PB15 0
#define GPIO_ALT_TMR1_PB0 1
#define GPIO_ALT_TMR2_PA4 0
#define GPIO_ALT_TMR2_PB3 1
#define GPIO_ALT_UART0_PB5_6 0
#define GPIO_ALT_UART0_PA5_6 1
#else
#define GPIO_ALT_TMR1_PA10 0
#define GPIO_ALT_TMR1_PB2 1
#define GPIO_ALT_TMR2_PA11 0
#define GPIO_ALT_TMR2_PB11 1
#define GPIO_ALT_UART0_PB4_7 0
#define GPIO_ALT_UART0_PA15_14 1
#define GPIO_ALT_UART1_PA8_9 0
#define GPIO_ALT_UART1_PB8_9 1
#endif
struct gpio_px_regs
{
uint32_t DIR; // reset value for pins is 0, input pins
uint32_t PIN; // RO
uint32_t OUT; // reset value is 0
uint32_t CLR; // reset value is 0
uint32_t PU; // reset value is 0
uint32_t PD; // reset value is 0
uint32_t DRV; // reset value for pins is 0, 8mA
uint32_t SMT; // reset value for pins is 1, enable schmitt trigger
} __packed;
CHECK_STRUCT_SIZE(struct gpio_px_regs, 0x20);
#define GPIO_PX_DIR_IN 0
#define GPIO_PX_DIR_OUT 1
#define GPIO_PX_PU_DISABLE 0
#define GPIO_PX_PU_ENABLE 1
#define GPIO_PX_PD_DISABLE 0 // for DIR_IN
#define GPIO_PX_PD_ENABLE 1 // for DIR_IN
#define GPIO_PX_PD_PUSH_PULL 0 // for DIR_OUT
#define GPIO_PX_PD_OPEN_DRAIN 1 // for DIR_OUT
#define GPIO_PX_DRV_8mA 0
#define GPIO_PX_DRV_16mA 1
#define GPIO_PX_SMT_DISABLE 0
#define GPIO_PX_SMT_SLOW 1 // for DIR_OUT
#define GPIO_PX_SMT_ENABLE 1 // for DIR_IN
/*
* 0x12 R8_PIN_ALTERNATE: GPIO multi-use remapping register
* 0x1c R8_GPIO_INT_FLAG: GPIO interrupt flag register
* 0x1d R8_GPIO_INT_ENABLE: GPIO interrupt enable register
* 0x1e R8_GPIO_INT_MODE: GPIO interrupt mode register
* 0x1f R8_GPIO_INT_POLAR: GPIO interrupt polarity register
*
* 0x40 R32_PA_DIR: PA pin direction control
* 0x44 R32_PA_PIN: PA pin input status
* 0x48 R32_PA_OUT: PA pin output register
* 0x4c R32_PA_CLR: PA pin output clear
* 0x50 R32_PA_PU: PA pin pull-up resistor enable register
* 0x54 R32_PA_PD: PA pin open drain output / input pull-down control
* 0x58 R32_PA_DRV: PA pin output driving capability register
* 0x5c R32_PA_SMT: PA pin slow output / schmitt trigger input control
*
* 0x60 R32_PB_DIR:
* 0x64 R32_PB_PIN:
* 0x68 R32_PB_OUT:
* 0x6c R32_PB_CLR:
* 0x70 R32_PB_PU:
* 0x74 R32_PB_PD:
* 0x78 R32_PB_DRV:
* 0x7c R32_PB_SMT:
*
* CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
* Be careful for those with side effect for read.
*/
struct gpio_registers
{
uint32_t resv_00[4];
uint8_t resv_10[2];
union _gpio_pin_alternate PIN_ALTERNATE;
uint8_t resv_13;
uint32_t resv_14[2];
union _gpio_interrupt INT_FLAG;
union _gpio_interrupt INT_ENABLE;
union _gpio_interrupt INT_MODE;
union _gpio_interrupt INT_POLAR;
uint32_t resv_20[8];
struct gpio_px_regs PA;
struct gpio_px_regs PB;
} __packed;
CHECK_STRUCT_SIZE(struct gpio_registers, 0x80);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#include <rthw.h>
#include <rtdebug.h>
#include "ch56x_pfic.h"
#include "ch56x_sys.h"
#include "isr_sp.h"
void rt_hw_interrupt_mask(int vector)
{
pfic_interrupt_mask(vector);
}
void rt_hw_interrupt_umask(int vector)
{
pfic_interrupt_umask(vector);
}
/**
* @brief Trigger software interrupt.
*/
void pfic_swi_pendset(void)
{
volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
_pfic_ireg_bit_set(pfic, IPSR, SWI_IRQn);
}
/**
* @brief Clear software interrupt.
*/
void pfic_swi_pendreset(void)
{
volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
_pfic_ireg_bit_set(pfic, IPRR, SWI_IRQn);
}
/**
* @brief Write PFIC interrupt configuration register.
*
* @param key_bit is (PFIC_CFGR_KEYx + bit_position), one of the following :
* PFIC_CFGR_NMISET / PFIC_CFGR_NMIRESET
* PFIC_CFGR_EXCSET / PFIC_CFGR_EXCRESET
* PFIC_CFGR_PFICRESET
* PFIC_CFGR_SYSRESET
* All others are treated as NEST/HWSTK (B.1/B.0) write.
*/
void pfic_cfgr_set(uint32_t key_bit)
{
volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
uint32_t u32v;
switch (key_bit)
{
case PFIC_CFGR_NMISET:
case PFIC_CFGR_NMIRESET:
case PFIC_CFGR_EXCSET:
case PFIC_CFGR_EXCRESET:
case PFIC_CFGR_PFICRESET:
case PFIC_CFGR_SYSRESET:
pfic->CFGR = key_bit;
default:
/* B.1/B.0 hold NEST/HWSTK, key ignored */
u32v = key_bit & (CFGR_NESTCTRL_MASK | CFGR_HWSTKCTRL_MASK);
pfic->CFGR = cfgr_nest_hwstk(u32v);
}
}
/**
* @brief Make SysTick ready, systick/swi irq are enabled.
*
* @param count is (HCLK/8) clocks count to generate systick irq.
* if 0 => calculate with current HCLK and RT_TICK_PER_SECOND
*/
void systick_init(uint32_t count)
{
volatile struct systick_registers *systick = (void *)SysTick_REG_BASE;
volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
if (count == 0)
count = sys_hclk_get() / 8 / RT_TICK_PER_SECOND;
_pfic_irqn_disable(pfic, SysTick_IRQn);
pfic->IPRIOR[SysTick_IRQn] = 0xe0;
pfic->IPRIOR[SWI_IRQn] = 0xf0;
systick->CTLR.reg = 0;
systick->CNTL = 0;
systick->CNTH = 0;
systick->CMPLR = count - 1;
systick->CMPHR = 0;
systick->CNTFG.cntif = 0;
/* enable & reload SysTick, with HCLK/8 */
systick->CTLR.reg = RB_STKCTL_STRELOAD | RB_STKCTL_STIE | RB_STKCTL_STE;
_pfic_irqn_enable(pfic, SysTick_IRQn);
_pfic_irqn_enable(pfic, SWI_IRQn);
}
void systick_handler(void) __attribute__((interrupt()));
void systick_handler(void)
{
volatile struct systick_registers *systick;
isr_sp_enter();
rt_interrupt_enter();
rt_tick_increase();
systick = (struct systick_registers *)SysTick_REG_BASE;
/* clear count-to-zero flag */
systick->CNTFG.cntif = 0;
rt_interrupt_leave();
isr_sp_leave();
}
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#ifndef __CH56X_PFIC_H__
#define __CH56X_PFIC_H__
#include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
/* IREG: IENR/IRER/IRSR/IPRR, make sure irqn be 12~59
*/
#define PFIC_IREG1_MASK 0xfffff000
#define PFIC_IREG2_MASK 0x0fffffff
#define PFIC_MAX_IREG_BITS 60
#define _pfic_ireg_bit_get(pfic, IREG, irqn) \
((pfic->IREG[(irqn) >> 5] >> ((irqn) & 0x1f)) & 1)
#define _pfic_ireg_bit_set(pfic, IREG, irqn) \
do pfic->IREG[(irqn) >> 5] = 1 << ((irqn) & 0x1f); while(0)
#define _pfic_irqn_enable(pfic, irqn) _pfic_ireg_bit_set(pfic, IENR, irqn)
#define _pfic_irqn_disable(pfic, irqn) _pfic_ireg_bit_set(pfic, IRER, irqn)
/* Note: `union _pfic_cfgr` is not used directly in the reg structure */
union _pfic_cfgr
{
uint32_t reg;
struct
{
uint32_t hwstkctrl : 1; // RW, hw stack push/pop control (0:enable)
uint32_t nestctrl : 1; // RW, nested intr enable control (0:enable)
uint32_t nmiset : 1; // WO, write 1 to set NMI pending
uint32_t nmireset : 1; // WO, write 1 to reset NMI pending
uint32_t excset : 1; // WO, write 1 to set exception pending
uint32_t excreset : 1; // WO, write 1 to reset exception pending
uint32_t pficreset : 1; // WO, write 1 to reset PFIC module, auto clear
uint32_t sysreset : 1; // WO, write 1 for a system reset, auto clear
uint32_t resv_8 : 8;
uint32_t keycode : 16; // WO, write protection keycode
};
};
#define PFIC_CFGR_KEY1 0xfa05 // for hwstkctrl & nestctrl
#define PFIC_CFGR_KEY2 0xbcaf // for nmi & exc set/reset
#define PFIC_CFGR_KEY3 0xbeef // for sysreset
#define PFIC_CFGR_NMISET (PFIC_CFGR_KEY2 << 16 | 1 << 2)
#define PFIC_CFGR_NMIRESET (PFIC_CFGR_KEY2 << 16 | 1 << 3)
#define PFIC_CFGR_EXCSET (PFIC_CFGR_KEY2 << 16 | 1 << 4)
#define PFIC_CFGR_EXCRESET (PFIC_CFGR_KEY2 << 16 | 1 << 5)
#define PFIC_CFGR_PFICRESET (1 << 6)
#define PFIC_CFGR_SYSRESET (PFIC_CFGR_KEY3 << 16 | 1 << 7)
#define CFGR_HWSTKCTRL_ENABLE (0 << 0)
#define CFGR_HWSTKCTRL_DISABLE (1 << 0)
#define CFGR_HWSTKCTRL_MASK (1 << 0)
#define CFGR_NESTCTRL_ENABLE (0 << 1)
#define CFGR_NESTCTRL_DISABLE (1 << 1)
#define CFGR_NESTCTRL_MASK (1 << 1)
#define cfgr_nest_hwstk(v) (PFIC_CFGR_KEY1 << 16 | (v))
union _pfic_gisr
{
uint32_t reg;
struct
{
uint32_t neststa : 8; // RO, nested interrupt state (0/1/2)
uint32_t gactsta : 1; // RO, global interrupt active status
uint32_t gpendsta : 1; // RO, global interrupt pending status
uint32_t resv_10 : 22;
};
};
#define PFIC_NESTSTA_NONE 0
#define PFIC_NESTSTA_L1 1
#define PFIC_NESTSTA_L2 2
union _pfic_fiofaddrr
{
uint32_t reg;
struct
{
uint32_t offaddr : 24; // RW
uint32_t irqid : 8; // RW
};
};
union _pfic_sctlr
{
uint32_t reg;
struct
{
uint32_t resv_0 : 1;
uint32_t sleeponexit : 1; // enter (deep) sleep mode on isr exiting
uint32_t sleepdeep : 1; // RW, 0/1 for sleep/deep-sleep mode
uint32_t wfitowfe : 1; // RW, treat WFI as WFE
uint32_t sevonpend : 1; // RW
uint32_t setevent : 1; // WO, set event for WFE
uint32_t resv_6 : 26;
};
};
/*
* 0x000 R32_PFIC_ISR1: PFIC interrupt enable status (# 12-31)
* 0x004 R32_PFIC_ISR2: PFIC interrupt enable status (# 32-59)
* 0x020 R32_PFIC_IPR1: PFIC interrupt pending status (# 12-31)
* 0x024 R32_PFIC_IPR2: PFIC interrupt pending status (# 32-59)
* 0x040 R32_PFIC_ITHRESDR: PFIC interrupt priority threshold (B.7-4)
* 0x044 R32_PFIC_FIBADDRR: PFIC fast intr base address (B.31-28)
* 0x048 R32_PFIC_CFGR: PFIC interrupt configuration register
* 0x04c R32_PFIC_GISR: PFIC global interrupt status register
* 0x060 R32_PFIC_FIOFADDRR0: PFIC fast intr 0 offset address (B.23-0)
* 0x064 R32_PFIC_FIOFADDRR1: PFIC fast intr 1 offset address (B.23-0)
* 0x068 R32_PFIC_FIOFADDRR2: PFIC fast intr 2 offset address (B.23-0)
* 0x06c R32_PFIC_FIOFADDRR3: PFIC fast intr 3 offset address (B.23-0)
* 0x100 R32_PFIC_IENR1: PFIC interrupt enable register (# 12-31)
* 0x104 R32_PFIC_IENR2: PFIC interrupt enable register (# 32-59)
* 0x180 R32_PFIC_IRER1: PFIC interrupt reset register (# 12-31)
* 0x184 R32_PFIC_IRER2: PFIC interrupt reset register (# 32-59)
* 0x200 R32_PFIC_IPSR1: PFIC interrupt pending set register (# 12-31)
* 0x204 R32_PFIC_IPSR2: PFIC interrupt pending set register (# 32-59)
* 0x280 R32_PFIC_IPRR1: PFIC interrupt pending reset register (# 12-31)
* 0x284 R32_PFIC_IPRR2: PFIC interrupt pending reset register (# 32-59)
* 0x300 R32_PFIC_IACTR1: PFIC interrupt active status register (# 12-31)
* 0x304 R32_PFIC_IACTR2: PFIC interrupt active status register (# 32-59)
* 0x400 R32_PFIC_IPRIORx: PFIC interrupt priority registers
* 0xd10 R32_PFIC_SCTLR: PFIC system control register
*
* CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
* Be careful for those with side effect for read.
*/
struct pfic_registers
{
uint32_t ISR[2];
uint32_t resv_08[6];
uint32_t IPR[2];
uint32_t resv_28[6];
uint32_t ITHRESDR;
uint32_t FIBADDRR;
uint32_t CFGR;
union _pfic_gisr GISR;
uint32_t resv_50[4];
union _pfic_fiofaddrr FIOFADDRR[4];
uint32_t resv_70[36];
uint32_t IENR[2];
uint32_t resv_108[30];
uint32_t IRER[2];
uint32_t resv_188[30];
uint32_t IPSR[2];
uint32_t resv_208[30];
uint32_t IPRR[2];
uint32_t resv_288[30];
uint32_t IACTR[2];
uint32_t resv_308[62];
uint8_t IPRIOR[256];
uint32_t resv_500[516];
union _pfic_sctlr SCTLR;
} __packed;
CHECK_STRUCT_SIZE(struct pfic_registers, 0xd14);
union _systick_ctlr
{
uint32_t reg;
struct
{
uint32_t ste : 1; // RW, systick enable
uint32_t stie : 1; // RW, systick interrupt enable
uint32_t stclk : 1; // RW, systick clock source select
uint32_t resv_3 : 5;
uint32_t streload : 1; // W1, write 1 to reload systick
uint32_t resv_9 : 23;
};
};
#define RB_STKCTL_STE 0x001
#define RB_STKCTL_STIE 0x002
#define RB_STKCTL_STCLK 0x004
#define RB_STKCTL_STRELOAD 0x100
#define SYSTICK_SRC_HCLK_8 0
#define SYSTICK_SRC_HCLK 1
union _systick_cntfg
{
uint32_t reg;
struct
{
uint32_t swie : 1; // RW, software interrupt enable
uint32_t cntif : 1; // RW0, counter dec to 0 (write 0 to clear)
uint32_t resv_2 : 30;
};
};
#define RB_CNTFG_SWIE 0X01
#define RB_CNTFG_CNTIF 0X02
/*
* 0x00 R32_STK_CTLR: SysTick control register
* 0x04 R32_STK_CNTL: SysTick counter, Lo.32
* 0x08 R32_STK_CNTH: SysTick counter, Hi.32
* 0x0c R32_STK_CMPLR: SysTick compare-reload register, Lo.32
* 0x10 R32_STK_CMPHR: SysTick compare-reload register, Hi.32
* 0x14 R32_STK_CNTFG: SysTick counter flags
*
* CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
* Be careful for those with side effect for read.
*/
struct systick_registers
{
union _systick_ctlr CTLR;
uint32_t CNTL;
uint32_t CNTH;
uint32_t CMPLR;
uint32_t CMPHR;
union _systick_cntfg CNTFG;
} __packed;
CHECK_STRUCT_SIZE(struct systick_registers, 0x18);
rt_inline void pfic_interrupt_umask(uint8_t irqn)
{
volatile struct pfic_registers *pfic;
if (irqn < PFIC_MAX_IREG_BITS)
{
pfic = (void *)PFIC_REG_BASE;
_pfic_ireg_bit_set(pfic, IENR, irqn);
}
}
rt_inline void pfic_interrupt_mask(uint8_t irqn)
{
volatile struct pfic_registers *pfic;
if (irqn < PFIC_MAX_IREG_BITS)
{
pfic = (void *)PFIC_REG_BASE;
_pfic_ireg_bit_set(pfic, IRER, irqn);
}
}
void pfic_swi_pendset(void);
void pfic_swi_pendreset(void);
void pfic_cfgr_set(uint32_t key_bit);
void systick_init(uint32_t count);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#include <rthw.h>
#include <rtdebug.h>
#include "ch56x_sys.h"
rt_inline uint8_t _slp_clk_off0_irqn_bit(uint8_t irqn)
{
uint8_t bitpos;
switch (irqn)
{
case TMR0_IRQn: bitpos = RB_SLP_CLK_TMR0; break;
case TMR1_IRQn: bitpos = RB_SLP_CLK_TMR1; break;
case TMR2_IRQn: bitpos = RB_SLP_CLK_TMR2; break;
/* special case to control PWMX clock in irqn way */
case PWMX_OFFn: bitpos = RB_SLP_CLK_PWMX; break;
case UART0_IRQn: bitpos = RB_SLP_CLK_UART0; break;
case UART1_IRQn: bitpos = RB_SLP_CLK_UART1; break;
case UART2_IRQn: bitpos = RB_SLP_CLK_UART2; break;
case UART3_IRQn: bitpos = RB_SLP_CLK_UART3; break;
default:
bitpos = 0;
}
return bitpos;
}
rt_inline uint8_t _slp_clk_off1_irqn_bit(uint8_t irqn)
{
uint8_t bitpos;
switch (irqn)
{
case SPI0_IRQn: bitpos = RB_SLP_CLK_SPI0; break;
case SPI1_IRQn: bitpos = RB_SLP_CLK_SPI1; break;
#if defined(SOC_CH567)
case SDC_IRQn: bitpos = RB_SLP_CLK_SDC; break;
case LED_IRQn: bitpos = RB_SLP_CLK_LED; break;
case USB0_IRQn: bitpos = RB_SLP_CLK_USB0; break;
case USB1_IRQn: bitpos = RB_SLP_CLK_USB1; break;
case ECDC_IRQn: bitpos = RB_SLP_CLK_ECDC; break;
#elif defined(SOC_CH568)
case SDC_IRQn: bitpos = RB_SLP_CLK_SDC; break;
case LED_IRQn: bitpos = RB_SLP_CLK_LED; break;
case USB1_IRQn: bitpos = RB_SLP_CLK_USB1; break;
case USB0_IRQn: bitpos = RB_SLP_CLK_SATA; break;
case ECDC_IRQn: bitpos = RB_SLP_CLK_ECDC; break;
#else
case EMMC_IRQn: bitpos = RB_SLP_CLK_EMMC; break;
case HSPI_IRQn: bitpos = RB_SLP_CLK_HSPI; break;
case USBHS_IRQn: bitpos = RB_SLP_CLK_USBHS; break;
case USBSS_IRQn: bitpos = RB_SLP_CLK_USBSS; break;
case SerDes_IRQn: bitpos = RB_SLP_CLK_SERD; break;
case DVP_IRQn: bitpos = RB_SLP_CLK_DVP; break;
#endif
default:
bitpos = 0;
}
return bitpos;
}
#if defined(SOC_SERIES_CH569)
rt_inline uint8_t _wake_clk_off_irqn_bit(uint8_t irqn)
{
uint8_t bitpos;
switch (irqn)
{
case ETH_IRQn: bitpos = RB_SLP_CLK_ETH; break;
case ECDC_IRQn: bitpos = RB_SLP_CLK_ECDC; break;
default:
bitpos = 0;
}
return bitpos;
}
#endif
/**
* @brief Turn on/off device clock for group clk_off0.
*
* @param bits is a bit mask to select corresponding devices.
*
* @param off is to turn off the clock (1) or trun on (0).
*/
void sys_slp_clk_off0(uint8_t bits, int off)
{
volatile struct sys_registers *sys = (void *)SYS_REG_BASE;
rt_base_t level;
uint8_t u8v;
u8v = sys->SLP_CLK_OFF0.reg;
u8v = off ? (u8v | bits) : (u8v & ~bits);
level = rt_hw_interrupt_disable();
sys_safe_access_enter(sys);
sys->SLP_CLK_OFF0.reg = u8v;
sys_safe_access_leave(sys);
rt_hw_interrupt_enable(level);
}
/**
* @brief Turn on/off device clock for group clk_off1.
*
* @param bits is a bit mask to select corresponding devices.
*
* @param off is to turn off the clock (1) or trun on (0).
*/
void sys_slp_clk_off1(uint8_t bits, int off)
{
volatile struct sys_registers *sys = (void *)SYS_REG_BASE;
rt_base_t level;
uint8_t u8v;
u8v = sys->SLP_CLK_OFF1.reg;
u8v = off ? (u8v | bits) : (u8v & ~bits);
level = rt_hw_interrupt_disable();
sys_safe_access_enter(sys);
sys->SLP_CLK_OFF1.reg = u8v;
sys_safe_access_leave(sys);
rt_hw_interrupt_enable(level);
}
/**
* @brief Turn on/off device clock, specified by its irq number.
*
* @param irqn is the irq number of the target device.
* PWMX does not have irqn, use special PWMX_OFFn number.
*
* @param off is to turn off the clock (1) or trun on (0).
*
* @return Returns if irqn-device has corresponding clk off bit :
* 0 if device not found; otherwise bit position of off0/off1.
*/
int sys_clk_off_by_irqn(uint8_t irqn, int off)
{
volatile struct sys_registers *sys = (void *)SYS_REG_BASE;
uint8_t u8v;
size_t offset;
uint8_t bitpos = 0;
if (irqn < END_OF_IRQn)
{
if ((bitpos = _slp_clk_off0_irqn_bit(irqn)) != 0)
{
offset = offsetof(struct sys_registers, SLP_CLK_OFF0);
}
else if ((bitpos = _slp_clk_off1_irqn_bit(irqn)) != 0)
{
offset = offsetof(struct sys_registers, SLP_CLK_OFF1);
}
#if defined(SOC_SERIES_CH569)
else if ((bitpos = _wake_clk_off_irqn_bit(irqn)) != 0)
{
offset = offsetof(struct sys_registers, SLP_WAKE_CTRL);
}
#endif
if (bitpos)
{
volatile uint8_t *cxreg = (void *)sys;
rt_base_t level;
u8v = cxreg[offset];
u8v = off ? (u8v | bitpos) : (u8v & ~bitpos);
level = rt_hw_interrupt_disable();
sys_safe_access_enter(sys);
cxreg[offset] = u8v;
sys_safe_access_leave(sys);
rt_hw_interrupt_enable(level);
}
}
return bitpos;
}
/**
* @brief Setup HCLK frequency.
*
* @param freq is the desired hclk frequency.
* supported : 120/96/80/60/48/40/32/30/15/10/6/3/2 MHz
*
* @return Returns 0 if hclk is successfully set.
*/
int sys_hclk_set(uint32_t freq)
{
volatile struct sys_registers *sys = (void *)SYS_REG_BASE;
uint8_t plldiv;
int clksel = -1;
if (freq >= 30000000)
{
if (freq <= 120000000)
{
/* supported : 120/96/80/60/48/40/32/30 MHz */
plldiv = 480000000 / freq; // 30M => 16 & 0xf => 0
clksel = RB_CLK_SEL_PLL;
}
}
else if (freq >= 2000000)
{
/* supported : 15/10/6/3/2 MHz */
plldiv = 30000000 / freq;
clksel = 0;
}
if (clksel >= 0)
{
rt_base_t level = rt_hw_interrupt_disable();
sys_safe_access_enter(sys);
sys->CLK_PLL_DIV.reg = clk_pll_div_wdat(plldiv);
sys->CLK_CFG_CTRL.reg = clk_cfg_ctrl_wdat(clksel);
sys_safe_access_leave(sys);
rt_hw_interrupt_enable(level);
clksel = 0;
}
return clksel;
}
/**
* @brief Get current HCLK frequency.
*
* @return Returns current HCLK frequency (Hz).
*/
uint32_t sys_hclk_get(void)
{
volatile struct sys_registers *sys = (void *)SYS_REG_BASE;
uint8_t plldiv = sys->CLK_PLL_DIV.pll_div;
if (sys->CLK_CFG_CTRL.sel_pll == CLK_SEL_PLL_USB_480M)
{
return plldiv ? 480000000 / plldiv : 30000000;
}
else
{
return plldiv ? 30000000 / plldiv : 2000000;
}
}
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#ifndef __CH56X_SYS_H__
#define __CH56X_SYS_H__
#include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
#define sys_safe_access_enter(sys) \
do { \
sys->SAFE_ACCESS_SIG.reg = SAFE_ACCESS_SIG_1; \
sys->SAFE_ACCESS_SIG.reg = SAFE_ACCESS_SIG_2; \
} while(0)
#define sys_safe_access_leave(sys) \
do sys->SAFE_ACCESS_SIG.reg = 0; while(0)
union _sys_safe_access_sig
{
uint8_t reg;
struct
{
uint8_t safe_acc_mode : 2; // RO, current safe access, 11b => RWA ok
uint8_t resv_2 : 2;
uint8_t safe_acc_timer : 3; // RO, current safe access time count
uint8_t resv_7 : 1;
};
};
#define RB_SAFE_ACC_MODE 0x03
#define RB_SAFE_ACC_TIMER 0x70
#define SAFE_ACCESS_SIG_1 0x57
#define SAFE_ACCESS_SIG_2 0xa8
union _sys_glob_rom_cfg
{
uint8_t reg;
struct
{
uint8_t rom_ext_re : 1; // RO, allow programmer to read FlashROM
uint8_t code_ram_we : 1; // RWA, code SRAM writaboe
uint8_t rom_data_we : 1; // RWA, FlashROM data erasable/writable
uint8_t rom_code_we : 1; // RWA, FlashROM code erasable/writable
uint8_t rom_code_ofs : 1; // RWA, FlashROM offset for user code
uint8_t resv_5 : 3;
};
};
#define RB_ROM_EXT_RE 0x01
#define RB_CODE_RAM_WE 0x02
#define RB_ROM_DATA_WE 0x04
#define RB_ROM_CODE_WE 0x08
#define RB_ROM_CODE_OFS 0x10
#define ROM_CODE_OFS_0x00000 0
#define ROM_CODE_OFS_0x04000 1
union _sys_rst_boot_stat
{
uint8_t reg;
struct
{
uint8_t reset_flag : 2; // RO, last reset cause
uint8_t cfg_reset_en : 1; // RO, external reset pin (#RST) status
uint8_t cfg_boot_en : 1; // RO, reset as 1
uint8_t cfg_debug_en : 1; // RO
uint8_t boot_loader : 1; // RO
uint8_t resv_6 : 2;
};
};
#define RB_RESET_FLAG 0x03
#define RB_CFG_RESET_EN 0x04
#define RB_CFG_BOOT_EN 0x08
#define RB_CFG_DEBUG_EN 0x10
#define RB_BOOT_LOADER 0x20
#define RESET_FLAG_IS_SOFT 0
#define RESET_FLAG_IS_POR 1
#define RESET_FLAG_IS_WDOG 2
#define RESET_FLAG_IS_RSTPIN 3
union _sys_rst_wdog_ctrl
{
uint8_t reg;
struct
{
uint8_t software_reset : 1; // WA/WZ, system software reset, auto clear
#if defined(SOC_SERIES_CH569)
uint8_t wdog_rst_en : 1; // RWA, enable watchdog overflow to reset
uint8_t wdog_int_en : 1; // RWA, enable watchdog overflow interrupt
uint8_t wdog_int_flag : 1; // RW1, watchdog counter overflow
#else
uint8_t resv_2 : 3;
#endif
uint8_t resv_4 : 4; // RO, B.7-6 must write 01b
};
};
#define RB_SOFTWARE_RESET 0x01
#ifdef SOC_SERIES_CH569
#define RB_WDOG_RST_EN 0x02
#define RB_WDOG_INT_EN 0x04
#define RB_WDOG_INT_FLAG 0x08
#endif
#define wdog_ctrl_wdat(v) (0x40 | (v))
union _sys_clk_pll_div
{
uint8_t reg;
struct
{
uint8_t pll_div : 4; // RWA, min 2
uint8_t resv_4 : 4; // RWA, B.7-6 must write 01b
};
};
#define clk_pll_div_wdat(div) (0x40 | (div))
union _sys_clk_cfg_ctrl
{
uint8_t reg;
struct
{
uint8_t pll_sleep : 1; // RWA, PLL sleep control
uint8_t sel_pll : 1; // RWA, clock source select
uint8_t resv_6 : 6; // RWA, must write 10b
};
};
#define RB_CLK_PLL_SLEEP 0x01
#define RB_CLK_SEL_PLL 0x02
#define CLK_PLL_SLEEP_DISABLE 0
#define CLK_PLL_SLEEP_ENABLE 1
#define CLK_SEL_PLL_HSE_30M 0
#define CLK_SEL_PLL_USB_480M 1
#define clk_cfg_ctrl_wdat(v) (0x80 | (v))
union _sys_clk_mod_aux
{
uint8_t reg;
struct
{
uint8_t int_125m_en : 1; // RWA, USB PHY 125MHz to ETH
uint8_t ext_125m_en : 1; // RWA, external 125MHz to ETH
uint8_t mco_sel_msk : 2; // RWA, MCO output select
uint8_t mco_en : 1; // RWA, MCO output enable
uint8_t resv_5 : 3;
};
};
#define RB_INT_125M_EN 0x01
#define RB_EXT_125M_EN 0x02
#define RB_MCO_SEL_MSK 0x0c
#define RB_MCO_EN 0x10
#define MCO_SEL_MSK_125M 0
#define MCO_SEL_MSK_25M 1
#define MCO_SEL_MSK_2_5M 2
/* All bits are RWA (need safe_access_sig), 0/1 : clock on/off
*/
union _sys_slp_clk_off0
{
uint8_t reg;
struct
{
uint8_t tmr0 : 1;
uint8_t tmr1 : 1;
uint8_t tmr2 : 1;
uint8_t pwmx : 1;
uint8_t uart0 : 1;
uint8_t uart1 : 1;
uint8_t uart2 : 1;
uint8_t uart3 : 1;
};
};
#define RB_SLP_CLK_TMR0 0x01
#define RB_SLP_CLK_TMR1 0x02
#define RB_SLP_CLK_TMR2 0x04
#define RB_SLP_CLK_PWMX 0x08
#define RB_SLP_CLK_UART0 0x10
#define RB_SLP_CLK_UART1 0x20
#define RB_SLP_CLK_UART2 0x40
#define RB_SLP_CLK_UART3 0x80
#define SYS_SLP_CLK_ON 0
#define SYS_SLP_CLK_OFF 1
/* All writable bits are RWA (need safe_access_sig), 0/1 : clock on/off
*/
union _sys_slp_clk_off1
{
uint8_t reg;
struct
{
uint8_t spi0 : 1;
uint8_t spi1 : 1;
#if defined(SOC_CH567)
uint8_t sdc : 1;
uint8_t led : 1;
uint8_t usb0 : 1;
uint8_t usb1 : 1;
uint8_t resv_6 : 1;
#elif defined(SOC_CH568)
uint8_t sdc : 1;
uint8_t led : 1;
uint8_t resv_4 : 1;
uint8_t usb1 : 1;
uint8_t sata : 1;
uint8_t ecdc : 1;
#else
uint8_t emmc : 1;
uint8_t hspi : 1;
uint8_t usbhs : 1;
uint8_t usbss : 1;
uint8_t serd : 1;
uint8_t dvp : 1;
#endif
};
};
#define RB_SLP_CLK_SPI0 0x01
#define RB_SLP_CLK_SPI1 0x02
#if defined(SOC_WCH_CH567)
#define RB_SLP_CLK_SDC 0x04
#define RB_SLP_CLK_LED 0x08
#define RB_SLP_CLK_USB0 0x10
#define RB_SLP_CLK_USB1 0x20
#define RB_SLP_CLK_ECDC 0x80
#elif defined(SOC_WCH_CH568)
#define RB_SLP_CLK_SDC 0x04
#define RB_SLP_CLK_LED 0x08
#define RB_SLP_CLK_USB1 0x20
#define RB_SLP_CLK_SATA 0x40
#define RB_SLP_CLK_ECDC 0x80
#else
#define RB_SLP_CLK_EMMC 0x04
#define RB_SLP_CLK_HSPI 0x08
#define RB_SLP_CLK_USBHS 0x10
#define RB_SLP_CLK_USBSS 0x20
#define RB_SLP_CLK_SERD 0x40
#define RB_SLP_CLK_DVP 0x80
#endif
/* All writable bits are RWA (need safe_access_sig)
*/
union _sys_slp_wake_ctrl
{
uint8_t reg;
struct
{
#if defined(SOC_WCH_CH567)
uint8_t usb0_wake : 1;
uint8_t usb1_wake : 1;
uint8_t resv_2 : 2;
uint8_t gpio_wake : 1;
uint8_t resv_5 : 3;
#elif defined(SOC_WCH_CH568)
uint8_t resv_0 : 1;
uint8_t usb1_wake : 1;
uint8_t sata_wake : 1;
uint8_t resv_3 : 1;
uint8_t gpio_wake : 1;
uint8_t resv_5 : 3;
#else
uint8_t usbhs_wake : 1;
uint8_t usbss_wake : 1;
uint8_t clk_eth : 1;
uint8_t clk_ecdc : 1;
uint8_t gpio_wake : 1;
uint8_t eth_wake : 1;
uint8_t resv_6 : 2;
#endif
};
};
#if defined(SOC_WCH_CH567)
#define RB_SLP_USB0_WAKE 0x01
#define RB_SLP_USB1_WAKE 0x02
#define RB_SLP_GPIO_WAKE 0x10
#elif defined(SOC_WCH_CH568)
#define RB_SLP_USB1_WAKE 0x02
#define RB_SLP_SATA_WAKE 0x04
#define RB_SLP_GPIO_WAKE 0x10
#else
#define RB_SLP_USBHS_WAKE 0x01
#define RB_SLP_USBSS_WAKE 0x02
#define RB_SLP_CLK_ETH 0x04
#define RB_SLP_CLK_ECDC 0x08
#define RB_SLP_GPIO_WAKE 0x10
#define RB_SLP_ETH_WAKE 0x20
#endif
union _sys_slp_power_ctrl
{
uint8_t reg;
struct
{
uint8_t usbhs_pwrdn : 1; // RWA, USBHS power down (0:PWRUP)
uint8_t resv_2 : 7;
};
};
#define RB_SLP_USBHS_PWRDN 0x01
union _sys_serd_ana_cfg1
{
uint16_t reg;
struct
{
uint8_t serd_pll_cfg; // RWA, reset as 0x5a
uint8_t serd_30m_sel : 1; // RWA
uint8_t serd_dn_tst : 1; // RWA
uint8_t resv_10 : 6;
};
};
#define RB_SERD_PLL_CFG 0x0ff
#define RB_SERD_30M_SEL 0x100
#define RB_SERD_DN_TST 0x200
union _sys_serd_ana_cfg2
{
uint32_t reg;
struct
{
uint32_t serd_trx_cfg : 25; // RWA, reset as 423015h
uint32_t resv_25 : 7;
};
};
#define RB_SERD_TRX_CFG 0x1000000
/*
* 0x00 R8_SAFE_ACCESS_SIG: safe access signature register
* 0x01 R8_CHIP_ID: RF, chip ID register
* 0x02 R8_SAFE_ACCESS_ID: RF, read as 02h
* 0x03 R8_WDOG_COUNT RW, watchdog counter
* 0x04 R8_GLOB_ROM_CFG: ROM config register
* 0x05 R8_RST_BOOT_STAT: RO, boot state register
* 0x06 R8_RST_WDOG_CTRL: software reset & watchdog control register
* 0x07 R8_GLOB_RESET_KEEP: RW, only power-on-reset can clear this register
* 0x08 R8_CLK_PLL_DIV: RWA, PLL output divisor register
* 0x0a R8_CLK_CFG_CTRL: RWA, clock config register
* 0x0b R8_CLK_MOD_AUX: RWA, clock auxiliary register
* 0x0c R8_SLP_CLK_OFF0: RWA, sleep control register 0
* 0x0d R8_SLP_CLK_OFF1: RWA, sleep control register 1
* 0x0e R8_SLP_WAKE_CTRL: RWA, wakeup control register
* 0x0f R8_SLP_POWER_CTRL: RWA, low power management register
* 0x20 R16_SERD_ANA_CFG1: RWA, SerDes PHY analog param config register 1
* 0x24 R32_SERD_ANA_CFG2: RWA, SerDes PHY analog param config register 2
*
* CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
* Be careful for those with side effect for read.
*/
struct sys_registers
{
union _sys_safe_access_sig SAFE_ACCESS_SIG;
uint8_t CHIP_ID;
uint8_t SAFE_ACCESS_ID;
uint8_t WDOG_COUNT;
union _sys_glob_rom_cfg GLOB_ROM_CFG;
union _sys_rst_boot_stat RST_BOOT_STAT;
union _sys_rst_wdog_ctrl RST_WDOG_CTRL;
uint8_t GLOB_RESET_KEEP;
union _sys_clk_pll_div CLK_PLL_DIV;
uint8_t resv_9;
union _sys_clk_cfg_ctrl CLK_CFG_CTRL;
union _sys_clk_mod_aux CLK_MOD_AUX;
union _sys_slp_clk_off0 SLP_CLK_OFF0;
union _sys_slp_clk_off1 SLP_CLK_OFF1;
union _sys_slp_wake_ctrl SLP_WAKE_CTRL;
union _sys_slp_power_ctrl SLP_POWER_CTRL;
#if defined(SOC_SERIES_CH569)
uint32_t resv_10[4];
union _sys_serd_ana_cfg1 SERD_ANA_CFG1;
uint16_t resv_22;
union _sys_serd_ana_cfg2 SERD_ANA_CFG2;
#endif
} __packed;
CHECK_STRUCT_SIZE(struct sys_registers, 0x28);
uint32_t sys_hclk_get(void);
int sys_hclk_set(uint32_t freq);
int sys_clk_off_by_irqn(uint8_t irqn, int off);
void sys_slp_clk_off0(uint8_t bits, int off);
void sys_slp_clk_off1(uint8_t bits, int off);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#include <rthw.h>
#include <rtdebug.h>
#include <drivers/hwtimer.h>
#include "ch56x_sys.h"
#include "ch56x_timer.h"
#include "isr_sp.h"
struct hwtimer_device
{
struct rt_hwtimer_device parent;
struct rt_hwtimer_info hwtimer_info;
volatile struct timer_registers *reg_base;
rt_hwtimer_mode_t tmode;
irq_number_t irqn;
char *name;
};
#ifdef BSP_USING_TMR0
static struct hwtimer_device hwtimer_device_0 =
{
.hwtimer_info =
{
.maxfreq = 80000000,
.minfreq = 80000000,
.maxcnt = 0x3ffffff,
.cntmode = HWTIMER_CNTMODE_UP,
},
.reg_base = (struct timer_registers *)TMR0_REG_BASE,
.tmode = HWTIMER_MODE_PERIOD,
.irqn = TMR0_IRQn,
.name = "timer0",
};
#endif
#ifdef BSP_USING_TMR1
static struct hwtimer_device hwtimer_device_1 =
{
.hwtimer_info =
{
.maxfreq = 80000000,
.minfreq = 80000000,
.maxcnt = 0x3ffffff,
.cntmode = HWTIMER_CNTMODE_UP,
},
.reg_base = (struct timer_registers *)TMR1_REG_BASE,
.tmode = HWTIMER_MODE_PERIOD,
.irqn = TMR1_IRQn,
.name = "timer1",
};
#endif
#ifdef BSP_USING_TMR2
static struct hwtimer_device hwtimer_device_2 =
{
.hwtimer_info =
{
.maxfreq = 80000000,
.minfreq = 80000000,
.maxcnt = 0x3ffffff,
.cntmode = HWTIMER_CNTMODE_UP,
},
.reg_base = (struct timer_registers *)TMR2_REG_BASE,
.tmode = HWTIMER_MODE_PERIOD,
.irqn = TMR2_IRQn,
.name = "timer2",
};
#endif
static void hwtimer_stop(struct rt_hwtimer_device *timer);
static void hwtimer_init(struct rt_hwtimer_device *timer, uint32_t state)
{
struct hwtimer_device *hwtimer_device = (void *)timer;
RT_ASSERT(hwtimer_device != RT_NULL);
/* no resource processing, `state` ignored */
hwtimer_stop(timer);
if (hwtimer_device->irqn != TMR0_IRQn)
{
hwtimer_device->reg_base->CTRL_DMA.reg = 0;
}
}
static rt_err_t hwtimer_start(struct rt_hwtimer_device *timer, uint32_t cnt, rt_hwtimer_mode_t mode)
{
struct hwtimer_device *hwtimer_device = (void *)timer;
volatile struct timer_registers *txreg;
RT_ASSERT(hwtimer_device != RT_NULL);
/* hwtimer_device->tmode may be different from timer->mode.
* For multi-cycle ONESHOT, tmode is set to PERIOD at hwtimer_start.
*/
hwtimer_device->tmode = mode;
sys_clk_off_by_irqn(hwtimer_device->irqn, SYS_SLP_CLK_ON);
txreg = hwtimer_device->reg_base;
txreg->CNT_END = cnt;
txreg->CTRL_MOD.reg = RB_TMR_ALL_CLEAR;
txreg->CTRL_MOD.reg = RB_TMR_COUNT_EN;
txreg->INTER_EN.cyc_end = 1;
rt_hw_interrupt_umask(hwtimer_device->irqn);
return RT_EOK;
}
static void hwtimer_stop(struct rt_hwtimer_device *timer)
{
struct hwtimer_device *hwtimer_device = (void *)timer;
volatile struct timer_registers *txreg;
RT_ASSERT(hwtimer_device != RT_NULL);
rt_hw_interrupt_mask(hwtimer_device->irqn);
/* note: RB_TMR_COUNT_EN cleared */
txreg = hwtimer_device->reg_base;
txreg->CTRL_MOD.reg = RB_TMR_ALL_CLEAR;
txreg->INTER_EN.reg = 0;
sys_clk_off_by_irqn(hwtimer_device->irqn, SYS_SLP_CLK_OFF);
}
static uint32_t hwtimer_count_get(struct rt_hwtimer_device *timer)
{
struct hwtimer_device *hwtimer_device = (void *)timer;
RT_ASSERT(hwtimer_device != RT_NULL);
return hwtimer_device->reg_base->COUNT;
}
static rt_err_t hwtimer_control(
struct rt_hwtimer_device *timer, uint32_t cmd, void *args)
{
struct hwtimer_device *hwtimer_device = (void *)timer;
rt_err_t result = RT_EOK;
RT_ASSERT(hwtimer_device != RT_NULL);
switch (cmd)
{
case HWTIMER_CTRL_FREQ_SET:
/* clocking for ch56x timers are fixed to Fsys */
if (args == RT_NULL || *(uint32_t *)args != timer->info->minfreq)
{
result = -RT_EINVAL;
}
break;
case HWTIMER_CTRL_STOP:
case HWTIMER_CTRL_INFO_GET:
case HWTIMER_CTRL_MODE_SET:
default:
result = -RT_ENOSYS;
}
return result;
}
static const struct rt_hwtimer_ops hwtimer_ops =
{
.init = hwtimer_init,
.start = hwtimer_start,
.stop = hwtimer_stop,
.count_get = hwtimer_count_get,
.control = hwtimer_control,
};
static int rt_hw_hwtimer_init(void)
{
struct hwtimer_device *devices[3];
uint32_t Fsys = sys_hclk_get();
int n = 0;
#ifdef BSP_USING_TMR2
devices[n++] = &hwtimer_device_2;
#endif
#ifdef BSP_USING_TMR1
devices[n++] = &hwtimer_device_1;
#endif
#ifdef BSP_USING_TMR0
devices[n++] = &hwtimer_device_0;
#endif
while (--n >= 0)
{
struct hwtimer_device *hwtimer_device = devices[n];
/* counting frequency is fixed to Fsys */
hwtimer_device->hwtimer_info.maxfreq = Fsys;
hwtimer_device->hwtimer_info.minfreq = Fsys;
hwtimer_device->parent.info = &hwtimer_device->hwtimer_info;
hwtimer_device->parent.ops = &hwtimer_ops;
rt_device_hwtimer_register(
&hwtimer_device->parent, hwtimer_device->name, RT_NULL);
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_hwtimer_init);
static void _hwtimer_isr_common(struct hwtimer_device *hwtimer_device)
{
volatile struct timer_registers *txreg = hwtimer_device->reg_base;
if (txreg->INT_FLAG.cyc_end)
{
if (hwtimer_device->tmode == HWTIMER_MODE_ONESHOT)
{
/* disable timer to emulate oneshot */
txreg->CTRL_MOD.reg = 0;
}
rt_device_hwtimer_isr(&hwtimer_device->parent);
txreg->INT_FLAG.cyc_end = 1;
}
}
#ifdef BSP_USING_TMR0
void tmr0_irq_handler(void) __attribute__((interrupt()));
void tmr0_irq_handler(void)
{
isr_sp_enter();
rt_interrupt_enter();
_hwtimer_isr_common(&hwtimer_device_0);
rt_interrupt_leave();
isr_sp_leave();
}
#endif
#ifdef BSP_USING_TMR1
void tmr1_irq_handler(void) __attribute__((interrupt()));
void tmr1_irq_handler(void)
{
isr_sp_enter();
rt_interrupt_enter();
_hwtimer_isr_common(&hwtimer_device_1);
rt_interrupt_leave();
isr_sp_leave();
}
#endif
#ifdef BSP_USING_TMR2
void tmr2_irq_handler(void) __attribute__((interrupt()));
void tmr2_irq_handler(void)
{
isr_sp_enter();
rt_interrupt_enter();
_hwtimer_isr_common(&hwtimer_device_2);
rt_interrupt_leave();
isr_sp_leave();
}
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#ifndef __CH56X_TIMER_H__
#define __CH56X_TIMER_H__
#include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
union _timer_ctrl_mod
{
uint8_t reg;
struct
{
uint8_t mode_in : 1; // B.0 : RW, timer mode setting
uint8_t all_clear : 1; // B.1 : RW, clear FIFO/count/int-flag
uint8_t count_en : 1; // B.2 : RW, enable timer module
uint8_t out_en : 1; // B.3 : RW, timer output enable
uint8_t out_polar : 1; // B.4 : RW, output polarity for PWM mode
uint8_t resv_5 : 1;
uint8_t pwm_repeat : 2; // B.7-6 : RW, PWM repeat count, 1/4/8/16
};
struct
{
uint8_t stuff_0 : 6;
uint8_t cap_edge : 2; // B.7-6 : RW, capture edge mode
};
};
#define RB_TMR_MODE_IN 0x01
#define RB_TMR_ALL_CLEAR 0x02
#define RB_TMR_COUNT_EN 0x04
#define RB_TMR_OUT_EN 0x08
#define RB_TMR_OUT_POLAR 0x10
#define RB_TMR_CAP_COUNT 0x10
#define RB_TMR_PWM_REPEAT 0xc0
#define RB_TMR_CAP_EDGE 0xc0
#define TMR_MODE_TIMER_PWM 0
#define TMR_MODE_CAP_COUNT 1
#define TMR_PWM_REPEAT_1 0
#define TMR_PWM_REPEAT_4 1
#define TMR_PWM_REPEAT_8 2
#define TMR_PWM_REPEAT_16 3
#define TMR_CAP_EDGE_NONE 0
#define TMR_CAP_EDGE_BOTH 1
#define TMR_CAP_EDGE_F2F 2
#define TMR_CAP_EDGE_R2R 3
union _timer_ctrl_dma
{
uint8_t reg;
struct
{
uint8_t dma_enable : 1; // B.0 : RW, enable DMA
uint8_t resv_1 : 1;
uint8_t dma_loop : 1; // B.2 : RW, enable DMA address looping
uint8_t resv_3 : 5;
};
};
#define RB_TMR_DMA_ENABLE 0x01
#define RB_TMR_DMA_LOOP 0x04
union _timer_interrupt
{
uint8_t reg;
struct
{
uint8_t cyc_end : 1; // B.0
uint8_t data_act : 1; // B.1
uint8_t fifo_hf : 1; // B.2
uint8_t dma_end : 1; // B.3
uint8_t fifo_ov : 1; // B.4
uint8_t resv_5 : 3;
};
};
#define RB_TMR_IX_MASK 0x1f
#define RB_TMR_IE_CYC_END 0x01 // RW, enable interrupt for timer capture count timeout or PWM cycle end
#define RB_TMR_IE_DATA_ACT 0x02 // RW, enable interrupt for timer capture input action or PWM trigger
#define RB_TMR_IE_FIFO_HF 0x04 // RW, enable interrupt for timer FIFO half (capture fifo >=4 or PWM fifo <=3)
#define RB_TMR_IE_DMA_END 0x08 // RW, enable interrupt for timer1/2 DMA completion
#define RB_TMR_IE_FIFO_OV 0x10 // RW, enable interrupt for timer FIFO overflow
#define RB_TMR_IF_CYC_END 0x01 // RW1, interrupt flag for timer capture count timeout or PWM cycle end
#define RB_TMR_IF_DATA_ACT 0x02 // RW1, interrupt flag for timer capture input action or PWM trigger
#define RB_TMR_IF_FIFO_HF 0x04 // RW1, interrupt flag for timer FIFO half (capture fifo >=4 or PWM fifo <=3)
#define RB_TMR_IF_DMA_END 0x08 // RW1, interrupt flag for timer1/2 DMA completion
#define RB_TMR_IF_FIFO_OV 0x10 // RW1, interrupt flag for timer FIFO overflow
/*
* 0x00 R8_TMRx_CTRL_MOD: mode setting register
* 0x01 R8_TMRx_CTRL_DMA: DMA control register
* 0x02 R8_TMRx_INTER_EN: interrupt enable register
* 0x06 R8_TMRx_INT_FLAG: interrupt flag register
* 0x07 R8_TMRx_FIFO_COUNT: RO, FIFO count register
* 0x08 R32_TMRx_COUNT: RO, timer current count register
* 0x0c R32_TMRx_CNT_END: RW, timer count end register
* 0x10 R32_TMRx_FIFO: RO/WO, FIFO data register, LSB 26 bits
* 0x14 R32_TMRx_DMA_NOW: RW, DMA buffer current address, LSB 18 bits
* 0x18 R32_TMRx_DMA_BEG: RW, DMA buffer begin address, LSB 18 bits
* 0x1c R32_TMRx_DMA_END: RW, DMA buffer end address (exclusive), LSB 18 bits
*
* Note: DMA related registers (0x10,0x14,0x18,0x1c) are TMR1/2 only
*
* CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
* Be careful for those with side effect for read.
*/
struct timer_registers
{
union _timer_ctrl_mod CTRL_MOD;
union _timer_ctrl_dma CTRL_DMA;
union _timer_interrupt INTER_EN;
uint8_t resv_3[3];
union _timer_interrupt INT_FLAG;
uint8_t FIFO_COUNT;
uint32_t COUNT;
uint32_t CNT_END;
uint32_t FIFO;
uint32_t DMA_NOW;
uint32_t DMA_BEG;
uint32_t DMA_END;
} __packed;
CHECK_STRUCT_SIZE(struct timer_registers, 0x20);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#include <rthw.h>
#include <rtdebug.h>
#include <ipc/completion.h>
#include <ipc/dataqueue.h>
#ifdef RT_USING_SERIAL_V2
#include <drivers/serial_v2.h>
#else
#include <drivers/serial.h>
#endif
#include "ch56x_sys.h"
#include "ch56x_uart.h"
#include "isr_sp.h"
#if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && \
!defined(BSP_USING_UART2) && !defined(BSP_USING_UART3)
#error "Please define at least one UARTx"
#endif
struct serial_device
{
struct rt_serial_device parent;
volatile struct uart_registers *reg_base;
irq_number_t irqn;
char *name;
};
#ifdef BSP_USING_UART0
static struct serial_device serial_device_0 =
{
.reg_base = (struct uart_registers *)UART0_REG_BASE,
.irqn = UART0_IRQn,
.name = "uart0",
};
#endif
#ifdef BSP_USING_UART1
static struct serial_device serial_device_1 =
{
.reg_base = (struct uart_registers *)UART1_REG_BASE,
.irqn = UART1_IRQn,
.name = "uart1",
};
#endif
#ifdef BSP_USING_UART2
static struct serial_device serial_device_2 =
{
.reg_base = (struct uart_registers *)UART2_REG_BASE,
.irqn = UART2_IRQn,
.name = "uart2",
};
#endif
#ifdef BSP_USING_UART3
static struct serial_device serial_device_3 =
{
.reg_base = (struct uart_registers *)UART3_REG_BASE,
.irqn = UART3_IRQn,
.name = "uart3",
};
#endif
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
struct serial_device *serial_device = (struct serial_device *)serial;
volatile struct uart_registers *uxreg = serial_device->reg_base;
union _uart_fcr fcr;
union _uart_lcr lcr;
uint32_t x;
x = 10 * sys_hclk_get() / 8 / cfg->baud_rate;
x = (x + 5) / 10;
uxreg->DL = x;
uxreg->DIV = 1;
lcr.reg = 0;
switch (cfg->data_bits)
{
case DATA_BITS_5:
lcr.word_sz = LCR_DATA_BITS_5;
break;
case DATA_BITS_6:
lcr.word_sz = LCR_DATA_BITS_6;
break;
case DATA_BITS_7:
lcr.word_sz = LCR_DATA_BITS_7;
break;
case DATA_BITS_8:
default:
lcr.word_sz = LCR_DATA_BITS_8;
break;
}
switch (cfg->stop_bits)
{
case STOP_BITS_2:
lcr.stop_bit = LCR_STOP_BITS_2;
break;
case STOP_BITS_1:
default:
lcr.stop_bit = LCR_STOP_BITS_1;
break;
}
switch (cfg->parity)
{
case PARITY_ODD:
lcr.par_mod = LCR_PARITY_ODD;
lcr.par_en = 1;
break;
case PARITY_EVEN:
lcr.par_mod = LCR_PARITY_EVEN;
lcr.par_en = 1;
break;
case PARITY_NONE:
default:
lcr.par_en = 0;
break;
}
uxreg->LCR.reg = lcr.reg;
fcr.reg = RB_FCR_FIFO_EN | RB_FCR_RX_FIFO_CLR | RB_FCR_TX_FIFO_CLR;
fcr.fifo_trig = UART_1BYTE_TRIG;
uxreg->FCR.reg = fcr.reg;
/* TXD pin output enable */
uxreg->IER.txd_en = 1;
return RT_EOK;
}
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *args)
{
struct serial_device *serial_device = (struct serial_device *)serial;
volatile struct uart_registers *uxreg = serial_device->reg_base;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
uxreg->IER.recv_rdy = 0;
uxreg->IER.line_stat = 0;
uxreg->IER.thr_empty = 0;
rt_hw_interrupt_mask(serial_device->irqn);
break;
case RT_DEVICE_CTRL_SET_INT:
uxreg->FCR.fifo_trig = UART_1BYTE_TRIG;
uxreg->MCR.int_oe = 1;
uxreg->IER.recv_rdy = 1;
uxreg->IER.line_stat = 1;
if (serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX)
{
uxreg->IER.thr_empty = 1;
}
rt_hw_interrupt_umask(serial_device->irqn);
break;
default:
break;
}
return RT_EOK;
}
static int uart_putc(struct rt_serial_device *serial, char ch)
{
struct serial_device *serial_device = (struct serial_device *)serial;
volatile struct uart_registers *uxreg = serial_device->reg_base;
if (serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX)
{
if (uxreg->TFC >= UART_FIFO_SIZE)
return -1;
}
else
{
while (uxreg->TFC >= UART_FIFO_SIZE)
{
if (rt_thread_self() && rt_interrupt_get_nest() == 0)
rt_thread_yield();
}
}
uxreg->THR = ch;
return 1;
}
static int uart_getc(struct rt_serial_device *serial)
{
struct serial_device *serial_device = (struct serial_device *)serial;
volatile struct uart_registers *uxreg = serial_device->reg_base;
/* UART_II_RECV_RDY is cleared by reading RBR */
return (uxreg->RFC > 0) ? uxreg->RBR : -1;
}
static const struct rt_uart_ops uart_ops =
{
.configure = uart_configure,
.control = uart_control,
.putc = uart_putc,
.getc = uart_getc,
.dma_transmit = RT_NULL,
};
int rt_hw_uart_init(void)
{
struct serial_device *devices[4];
/* Note: HCLK should be at least 8MHz for default 115200 baud to work */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
int n = 0;
#ifdef BSP_USING_UART3
devices[n++] = &serial_device_3;
#endif
#ifdef BSP_USING_UART2
devices[n++] = &serial_device_2;
#endif
#ifdef BSP_USING_UART1
devices[n++] = &serial_device_1;
#endif
#ifdef BSP_USING_UART0
devices[n++] = &serial_device_0;
#endif
/* IMPORTANT: pin mode should be set properly @ board init */
while (--n >= 0)
{
uint32_t flag;
struct serial_device *serial = devices[n];
serial->parent.ops = &uart_ops;
serial->parent.config = config;
sys_clk_off_by_irqn(serial->irqn, SYS_SLP_CLK_ON);
flag = RT_DEVICE_FLAG_RDWR |
RT_DEVICE_FLAG_STREAM | // for converting '\n'
RT_DEVICE_FLAG_INT_TX |
RT_DEVICE_FLAG_INT_RX ;
rt_hw_serial_register(&serial->parent, serial->name, flag, RT_NULL);
/* rt_serial_open => uart_control with RT_DEVICE_CTRL_SET_INT */
}
return 0;
}
static void _uart_isr_common(struct serial_device *serial_device)
{
struct rt_serial_device *serial = &serial_device->parent;
volatile struct uart_registers *uxreg = serial_device->reg_base;
switch (uxreg->IIR.int_mask)
{
case UART_II_RECV_TOUT:
/* FIXME: It's a bad idea to read RBR to clear UART_II_RECV_TOUT.
* Race condition may happen that actual rx data is dropped.
*/
if (uxreg->RFC == 0)
{
uxreg->RBR;
//rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_TIMEOUT);
break;
}
/* pass through as if UART_II_RECV_RDY */
case UART_II_RECV_RDY:
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
break;
case UART_II_THR_EMPTY:
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
break;
case UART_II_LINE_STAT:
uxreg->LSR;
break;
case UART_II_MODEM_CHG:
uxreg->MSR;
break;
case UART_II_SLV_ADDR:
uxreg->IIR;
break;
default:
break;
}
}
#ifdef BSP_USING_UART0
void uart0_irq_handler(void) __attribute__((interrupt()));
void uart0_irq_handler(void)
{
isr_sp_enter();
rt_interrupt_enter();
_uart_isr_common(&serial_device_0);
rt_interrupt_leave();
isr_sp_leave();
}
#endif
#ifdef BSP_USING_UART1
void uart1_irq_handler(void) __attribute__((interrupt()));
void uart1_irq_handler(void)
{
isr_sp_enter();
rt_interrupt_enter();
_uart_isr_common(&serial_device_1);
rt_interrupt_leave();
isr_sp_leave();
}
#endif
#ifdef BSP_USING_UART2
void uart2_irq_handler(void) __attribute__((interrupt()));
void uart2_irq_handler(void)
{
isr_sp_enter();
rt_interrupt_enter();
_uart_isr_common(&serial_device_2);
rt_interrupt_leave();
isr_sp_leave();
}
#endif
#ifdef BSP_USING_UART3
void uart3_irq_handler(void) __attribute__((interrupt()));
void uart3_irq_handler(void)
{
isr_sp_enter();
rt_interrupt_enter();
_uart_isr_common(&serial_device_3);
rt_interrupt_leave();
isr_sp_leave();
}
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#ifndef __CH56X_UART_H__
#define __CH56X_UART_H__
#include "soc.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef UART_FIFO_SIZE
#define UART_FIFO_SIZE 8
#endif
#ifndef UART_RECV_RDY_SZ
#define UART_RECV_RDY_SZ 7 // FIFO trigger level for rx data available
#endif
union _uart_mcr
{
uint8_t reg;
struct
{
uint8_t dtr : 1; // B.0 : RW, DTR output (UART0 only)
uint8_t rts : 1; // B.1 : RW, RTS output (UART0 only)
uint8_t out1 : 1; // B.2 : RW, user defined modem control (UART0 only)
uint8_t int_oe : 1; // B.3 : RW, interrupt output enable / OUT2
uint8_t loop : 1; // B.4 : RW, enable internal loop test (UART0 only)
uint8_t au_flow_en : 1; // B.5 : RW, enable CTS/RTS autoflow control
uint8_t tnow : 1; // B.6 : RW, enable DTR TNOW output (UART0 only)
uint8_t half : 1; // B.7 : RW, enable half-duplex mode (UART0 only)
};
};
#define RB_MCR_DTR 0x01
#define RB_MCR_RTS 0x02
#define RB_MCR_OUT1 0x04
#define RB_MCR_OUT2 0x08
#define RB_MCR_INT_OE 0x08
#define RB_MCR_LOOP 0x10
#define RB_MCR_AU_FLOW_EN 0x20
#define RB_MCR_TNOW 0x40
#define RB_MCR_HALF 0x80
union _uart_ier
{
uint8_t reg;
struct
{
uint8_t recv_rdy : 1; // B.0 : RW, enable rx data ready intr
uint8_t thr_empty : 1; // B.1 : RW, enable THR empty intr
uint8_t line_stat : 1; // B.2 : RW, enable rx line status intr
uint8_t modem_chg : 1; // B.3 : RW, enable modem status change intr (UART0 only)
uint8_t dtr_en : 1; // B.4 : RW, DTR/TNOW output pin enable (UART0 only)
uint8_t rts_en : 1; // B.5 : RW, RTS output pin enable (UART0 only)
uint8_t txd_en : 1; // B.6 : RW, TXD pin enable
uint8_t reset : 1; // B.7 : WZ, software reset control, active high, auto clear
};
};
#define RB_IER_RECV_RDY 0x01
#define RB_IER_THR_EMPTY 0x02
#define RB_IER_LINE_STAT 0x04
#define RB_IER_MODEM_CHG 0x08
#define RB_IER_DTR_EN 0x10
#define RB_IER_RTS_EN 0x20
#define RB_IER_TXD_EN 0x40
#define RB_IER_RESET 0x80
union _uart_fcr
{
uint8_t reg;
struct
{
uint8_t fifo_en : 1; // B.0 : RW, FIFO enable
uint8_t rx_fifo_clr : 1; // B.1 : WZ, write 1 to clear rx FIFO, auto clear
uint8_t tx_fifo_clr : 1; // B.2 : WZ, write 1 to clear tx FIFO, auto clear
uint8_t resv_3 : 3;
uint8_t fifo_trig : 2; // B.7-6 : RW, rx FIFO trigger level, 1/2/4/7 bytes
};
};
#define RB_FCR_FIFO_EN 0x01
#define RB_FCR_RX_FIFO_CLR 0x02
#define RB_FCR_TX_FIFO_CLR 0x04
#define RB_FCR_FIFO_TRIG 0xc0
#define UART_1BYTE_TRIG 0
#define UART_2BYTE_TRIG 1
#define UART_4BYTE_TRIG 2
#define UART_7BYTE_TRIG 3
union _uart_lcr
{
uint8_t reg;
struct
{
uint8_t word_sz : 2; // B.1-0 : RW, word bit length, 5/6/7/8 bits
uint8_t stop_bit : 1; // B.2 : RW, stop bit length, 1/2 bits
uint8_t par_en : 1; // B.3 : RW, parity enable
uint8_t par_mod : 2; // B.5-4 : RW, parity mode, odd/even/mark/space
uint8_t break_en : 1; // B.6 : RW, force BREAK line condition
uint8_t dlab : 1; // B.7 : RW, user defined general purpose bit
};
};
#define RB_LCR_WORD_SZ 0x03
#define RB_LCR_STOP_BIT 0x04
#define RB_LCR_PAR_EN 0x08
#define RB_LCR_PAR_MOD 0x30
#define RB_LCR_BREAK_EN 0x40
#define RB_LCR_DLAB 0x80
#define RB_LCR_GP_BIT 0x80
#define LCR_DATA_BITS_5 0
#define LCR_DATA_BITS_6 1
#define LCR_DATA_BITS_7 2
#define LCR_DATA_BITS_8 3
#define LCR_STOP_BITS_1 0
#define LCR_STOP_BITS_2 1
#define LCR_PARITY_ODD 0
#define LCR_PARITY_EVEN 1
#define LCR_PARITY_MARK 2
#define LCR_PARITY_SPACE 3
union _uart_iir
{
uint8_t reg;
struct
{
uint8_t int_mask : 4; // B.3-0 : RO, interrupt mask (intr if B.0 is 0)
uint8_t resv_4 : 2;
uint8_t fifo_id : 2; // B.7-6 : RO, FIFO enabled flag
};
};
#define RB_IIR_NO_INT 0x01
#define RB_IIR_INT_MASK 0x0f
#define RB_IIR_FIFO_ID 0xc0
/* RB_IIR_INT_MASK (IIR bits 3:0) definition
*/
#define UART_II_SLV_ADDR 0x0e // UART0 slave address match interrupt
#define UART_II_LINE_STAT 0x06 // rx line status interrupt
#define UART_II_RECV_RDY 0x04 // rx data available interrupt
#define UART_II_RECV_TOUT 0x0c // rx fifo timeout interrupt
#define UART_II_THR_EMPTY 0x02 // THR empty interrupt
#define UART_II_MODEM_CHG 0x00 // UART0 modem status change interrupt
#define UART_II_NO_INTER 0x01 // no interrupt pending
union _uart_lsr
{
uint8_t reg;
struct
{
uint8_t data_rdy : 1; // B.0 : RO, rx FIFO data ready
uint8_t over_err : 1; // B.1 : RZ, rx FIFO data overrun
uint8_t par_err : 1; // B.2 : RZ, rx parity error
uint8_t frame_err : 1; // B.3 : RZ, rx frame error
uint8_t break_err : 1; // B.4 : RZ, rx BREAK detected
uint8_t tx_fifo_emp : 1; // B.5 : RO, tx FIFO empty
uint8_t tx_all_emp : 1; // B.6 : RO, THR/TSR all empty
uint8_t err_rx_fifo : 1; // B.7 : RO, PAR/FRAME/BREAK ERR in rx FIFO
};
};
#define RB_LSR_DATA_RDY 0x01
#define RB_LSR_OVER_ERR 0x02
#define RB_LSR_PAR_ERR 0x04
#define RB_LSR_FRAME_ERR 0x08
#define RB_LSR_BREAK_ERR 0x10
#define RB_LSR_TX_FIFO_EMP 0x20
#define RB_LSR_TX_ALL_EMP 0x40
#define RB_LSR_ERR_RX_FIFO 0x80
union _uart_msr
{
uint8_t reg;
struct
{
uint8_t cts_chg : 1; // B.0 : RZ, CTS input changed
uint8_t dsr_chg : 1; // B.1 : RZ, DSR input changed
uint8_t ri_chg : 1; // B.2 : RZ, RI input changed
uint8_t dcd_chg : 1; // B.3 : RZ, DCD input changed
uint8_t cts : 1; // B.4 : RO, CTS action status
uint8_t dsr : 1; // B.5 : RO, DSR action status
uint8_t ri : 1; // B.6 : RO, RI action status
uint8_t dcd : 1; // B.7 : RO, DCD action status
};
};
#define RB_MSR_CTS_CHG 0x01
#define RB_MSR_DSR_CHG 0x02
#define RB_MSR_RI_CHG 0x04
#define RB_MSR_DCD_CHG 0x08
#define RB_MSR_CTS 0x10
#define RB_MSR_DSR 0x20
#define RB_MSR_RI 0x40
#define RB_MSR_DCD 0x80
/*
* 0x00 R8_UARTx_MCR: Modem Control Register
* 0x01 R8_UARTx_IER: Interrupt Enable Register
* 0x02 R8_UARTx_FCR: FIFO Control Register
* 0x03 R8_UARTx_LCR: Line Control Register
* 0x04 R8_UARTx_IIR: Interrupt Identification Register
* 0x05 R8_UARTx_LSR: Line Status Register
* 0x06 R8_UARTx_MSR: Modem Status Register (UART0 only)
* 0x08 R8_UARTx_RBR: Rx Buffer Register
* 0x08 R8_UARTx_THR: Tx Hold Register
* 0x0a R8_UARTx_RFC: Rx FIFO count register
* 0x0b R8_UARTx_TFC: Tx FIFO count register
* 0x0c R16_UARTx_DL: Divisor Latch
* 0x0e R8_UARTx_DIV: frequency pre divider
* 0x0f R8_UARTx_ADR: Address Register (UART0 only)
*
* CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test.
* Be careful for those with side effect for read (e.g. RBR, IIR).
*/
struct uart_registers
{
union _uart_mcr MCR;
union _uart_ier IER;
union _uart_fcr FCR;
union _uart_lcr LCR;
union _uart_iir IIR;
union _uart_lsr LSR;
union _uart_lsr MSR;
uint8_t resv_7;
union
{
uint8_t RBR;
uint8_t THR;
};
uint8_t resv_9;
uint8_t RFC;
uint8_t TFC;
uint16_t DL;
uint8_t DIV;
uint8_t ADR;
} __packed;
CHECK_STRUCT_SIZE(struct uart_registers, 0x10);
int rt_hw_uart_init(void);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-20 Emuzit first version
*/
#include <rthw.h>
#include <rtdebug.h>
#include <drivers/watchdog.h>
#include "ch56x_sys.h"
#define WDOG_HICOUNT_MAX 0xfff // enough to hold (4095 * 120M/524288) >> 8
struct watchdog_device
{
rt_watchdog_t parent;
volatile uint32_t hicount;
uint32_t timeout;
uint32_t reload;
uint8_t is_start;
};
static struct watchdog_device watchdog_device;
static void wdt_reload_counter(rt_watchdog_t *wdt, int cmd)
{
struct watchdog_device *wdt_dev = (void *)wdt;
volatile struct sys_registers *sys = (void *)SYS_REG_BASE;
rt_base_t level;
level = rt_hw_interrupt_disable();
/* reload WDOG_COUNT also clears RB_WDOG_INT_FLAG*/
sys->WDOG_COUNT = (uint8_t)wdt_dev->reload;
wdt_dev->hicount = wdt_dev->reload >> 8;
if (cmd != RT_DEVICE_CTRL_WDT_KEEPALIVE && wdt_dev->is_start)
{
sys_safe_access_enter(sys);
if ((wdt_dev->reload >> 8) == WDOG_HICOUNT_MAX)
{
/* WDOG_COUNT can work on its own, no wdog_irq needed */
sys->RST_WDOG_CTRL.reg = wdog_ctrl_wdat(RB_WDOG_RST_EN);
rt_hw_interrupt_mask(WDOG_IRQn);
}
else
{
/* Extend wdt with wdt_dev->hicount through wdog_irq.
* CAVEAT: wdt not effective if global interrupt disabled !!
*/
sys->RST_WDOG_CTRL.reg = wdog_ctrl_wdat(RB_WDOG_INT_EN);
rt_hw_interrupt_umask(WDOG_IRQn);
}
sys_safe_access_leave(sys);
}
rt_hw_interrupt_enable(level);
}
static uint32_t wdt_get_timeleft(rt_watchdog_t *wdt)
{
struct watchdog_device *wdt_dev = (void *)wdt;
volatile struct sys_registers *sys = (void *)SYS_REG_BASE;
uint32_t countleft;
uint64_t count64;
if ((wdt_dev->reload >> 8) == WDOG_HICOUNT_MAX)
{
/* WDOG_COUNT can work on its own, without hicount */
countleft = 0xff - sys->WDOG_COUNT;
}
else
{
uint32_t c1 = sys->WDOG_COUNT;
uint32_t hc = wdt_dev->hicount;
uint32_t c2 = sys->WDOG_COUNT;
/* check if WDOG_COUNT overflows between c1/c2 reads */
if (c2 < c1)
{
rt_base_t level = rt_hw_interrupt_disable();
hc = wdt_dev->hicount;
if (sys->RST_WDOG_CTRL.wdog_int_flag && sys->RST_WDOG_CTRL.wdog_int_en)
{
hc++;
}
rt_hw_interrupt_enable(level);
}
countleft = ((WDOG_HICOUNT_MAX << 8) + 0xff) - ((hc << 8) + c2);
}
/* convert wdt count to seconds : count / (Fsys/524288) */
count64 = countleft;
return (uint32_t)((count64 << 19) / sys_hclk_get());
}
static uint32_t _convert_timeout_to_reload(uint32_t seconds)
{
uint32_t N, R, Fsys, reload = -1;
/* timeout is limited to 4095, not to overflow 32-bit (T * 2^19) */
if (seconds < 4096)
{
/* watchdog timer is clocked at Fsys/524288, arround 3~228Hz */
Fsys = sys_hclk_get();
/* T * (Fsys/2^19) => (T * N) + T * (R/2^19) */
N = Fsys >> 19;
R = Fsys & 0x7ffff;
reload = (WDOG_HICOUNT_MAX << 8) + 0xff;
reload -= seconds * N + ((seconds * R) >> 19) + 1;
}
return reload;
}
static void _stop_wdog_operation()
{
volatile struct sys_registers *sys = (void *)SYS_REG_BASE;
rt_base_t level = rt_hw_interrupt_disable();
sys_safe_access_enter(sys);
sys->RST_WDOG_CTRL.reg = wdog_ctrl_wdat(RB_WDOG_INT_FLAG);
sys_safe_access_leave(sys);
rt_hw_interrupt_enable(level);
rt_hw_interrupt_mask(WDOG_IRQn);
}
static rt_err_t wdt_init(rt_watchdog_t *wdt)
{
struct watchdog_device *wdt_dev = (void *)wdt;
_stop_wdog_operation();
wdt_dev->is_start = 0;
wdt_dev->timeout = -1;
wdt_dev->reload = -1;
return RT_EOK;
}
static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
{
struct watchdog_device *wdt_dev = (void *)wdt;
uint32_t reload, timeout;
switch (cmd)
{
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
wdt_reload_counter(wdt, cmd);
break;
case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
*((uint32_t *)arg) = wdt_get_timeleft(wdt);
break;
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
*((uint32_t *)arg) = wdt_dev->timeout;
break;
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
/* CAVEAT: Setting timeout larger than an 8-bit WDOG_COUNT can
* hold turns the wdog into interrupt mode, which makes wdog
* usless if cause of death is lost global interrupt enable.
*/
timeout = *((uint32_t *)arg);
reload = _convert_timeout_to_reload(timeout);
if ((reload >> 8) > WDOG_HICOUNT_MAX)
{
return -RT_EINVAL;
}
wdt_dev->timeout = timeout;
wdt_dev->reload = reload;
/* FIXME: code example implies wdt started by SET_TIMEOUT ? */
case RT_DEVICE_CTRL_WDT_START:
if ((wdt_dev->reload >> 8) > WDOG_HICOUNT_MAX)
{
return -RT_EINVAL;
}
wdt_dev->is_start = 1;
wdt_reload_counter(wdt, cmd);
break;
case RT_DEVICE_CTRL_WDT_STOP:
_stop_wdog_operation();
wdt_dev->is_start = 0;
break;
default:
return -RT_ERROR;
}
return RT_EOK;
}
static struct rt_watchdog_ops watchdog_ops =
{
.init = wdt_init,
.control = wdt_control,
};
int rt_hw_wdt_init(void)
{
rt_uint32_t flag;
watchdog_device.parent.ops = &watchdog_ops;
flag = RT_DEVICE_FLAG_DEACTIVATE;
return rt_hw_watchdog_register(&watchdog_device.parent, "wdt", flag, RT_NULL);
}
INIT_BOARD_EXPORT(rt_hw_wdt_init);
void wdog_irq_handler(void) __attribute__((interrupt()));
void wdog_irq_handler(void)
{
volatile struct pfic_registers *pfic;
volatile struct sys_registers *sys;
rt_interrupt_enter();
sys = (struct sys_registers *)SYS_REG_BASE;
/* FIXME: RB_WDOG_INT_FLAG seems completely not functioning at all !!
* It's not set at WDOG_COUNT overflow, writing 1 to it does not clear
* wdt interrupt. Bit 16 of pfic->IPR[0] is not effective thereof.
*/
if (watchdog_device.hicount < WDOG_HICOUNT_MAX)
{
watchdog_device.hicount++;
/* clear interrupt flag */
//sys->RST_WDOG_CTRL.reg |= RB_WDOG_INT_FLAG;
sys->WDOG_COUNT = sys->WDOG_COUNT;
}
else
{
/* reset system if watchdog timeout */
uint8_t u8v = RB_SOFTWARE_RESET | RB_WDOG_INT_FLAG;
sys_safe_access_enter(sys);
sys->RST_WDOG_CTRL.reg = wdog_ctrl_wdat(u8v);
sys_safe_access_leave(sys);
}
rt_interrupt_leave();
}
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-27 Emuzit first version
*/
#ifndef __ISR_SP_H__
#define __ISR_SP_H__
/* usrstack is no more in use right after rt_system_scheduler_start().
* It is also the time global interrupt is enabled.
*/
#define isr_sp_enter() \
asm("la t0, rt_interrupt_nest"); \
asm("bnez t0, 1f"); \
asm("la t0, _eusrstack"); \
asm("sw sp, -4(t0)"); \
asm("addi sp, t0, -4"); \
asm("1:")
#define isr_sp_leave() \
asm("la t0, rt_interrupt_nest"); \
asm("bnez t0, 1f"); \
asm("la t0, _eusrstack"); \
asm("lw sp, -4(t0)"); \
asm("1:")
#endif
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#ifndef __SOC_H__
#define __SOC_H__
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#if !defined(SOC_CH567) && \
!defined(SOC_CH568) && \
!defined(SOC_SERIES_CH569)
#define SOC_SERIES_CH569
#endif
#define CHECK_STRUCT_SIZE(s, size) \
static_assert(sizeof(s) == size, #s " has wrong size")
#define BITS_SET(x, bits) do x |= bits; while(0)
#define BITS_CLR(x, bits) do x &= ~bits; while(0)
#define FLASH_BASE_ADDRESS 0x00000000
#define RAMS_BASE_ADDRESS 0x20000000
#define RAMX_BASE_ADDRESS 0x20020000
#define BUS8_BASE_ADDRESS 0x80000000
#ifdef SOC_SERIES_CH569
#define RAMS_SIZE 16
#else
#define RAMS_SIZE 32
#endif
#define RAMS_END (RAMS_BASE_ADDRESS + RAMS_SIZE * 1024)
#define SYS_REG_BASE 0x40001000
#define GPIO_REG_BASE 0x40001000
#define GPIO_REG_BASE_PA 0x40001040
#define GPIO_REG_BASE_PB 0x40001060
#define GPIO_PORTS 2 // 2 ports : PA & PB
#define GPIO_PA_PIN_START 0 // PA : pin number 0~31
#define GPIO_PB_PIN_START 32 // PB : pin number 32~63
#ifdef SOC_SERIES_CH569
#define GPIO_PA_PIN_MARK 0x00ffffff // PA : bits 0~23
#define GPIO_PB_PIN_MARK 0x01ffffff // PB : bits 0~24
#else
#define GPIO_PA_PIN_MARK 0x0000ffff // PA : bits 0~15
#define GPIO_PB_PIN_MARK 0x00003fff // PB : bits 0~13
#endif
#define TMR0_REG_BASE 0x40002000
#define TMR1_REG_BASE 0x40002400
#define TMR2_REG_BASE 0x40002800
#define UART0_REG_BASE 0x40003000
#define UART1_REG_BASE 0x40003400
#define UART2_REG_BASE 0x40003800
#define UART3_REG_BASE 0x40003c00
#define SPI0_REG_BASE 0x40004000
#define SPI1_REG_BASE 0x40004400
#define PWMX_REG_BASE 0x40005000
#define PFIC_REG_BASE 0xe000e000
#define SysTick_REG_BASE 0xe000f000
#ifdef SOC_SERIES_CH569
#define HSPI_REG_BASE 0x40006000 // CH569W
#define ECDC_REG_BASE 0x40007000
#define USBSS_REG_BASE 0x40008000
#define USBHS_REG_BASE 0x40009000
#define EMMC_REG_BASE 0x4000a000
#define SERDES_REG_BASE 0x4000b000
#define ETH_REG_BASE 0x4000c000 // CH565W/CH569W
#define DVP_REG_BASE 0x4000e000 // CH565W/CH565M
#else
#define LED_REG_BASE 0x40006000
#define USB0_REG_BASE 0x40008000 // CH567
#define USB1_REG_BASE 0x40009000 // CH567
#define USB_REG_BASE 0x40009000 // CH568
#define SDC_REG_BASE 0x4000a000
#define SATA_REG_BASE 0x4000b000 // CH568
#define ECDC_REG_BASE 0x4000c400
#endif
#if defined(SOC_SERIES_CH569)
typedef enum
{
PWMX_OFFn = 0,
NMI_IRQn = 2,
EXC_IRQn = 3,
SysTick_IRQn = 12,
SWI_IRQn = 14,
WDOG_IRQn = 16,
TMR0_IRQn = 17,
GPIO_IRQn = 18,
SPI0_IRQn = 19,
USBSS_IRQn = 20,
LINK_IRQn = 21,
TMR1_IRQn = 22,
TMR2_IRQn = 23,
UART0_IRQn = 24,
USBHS_IRQn = 25,
EMMC_IRQn = 26,
DVP_IRQn = 27,
HSPI_IRQn = 28,
SPI1_IRQn = 29,
UART1_IRQn = 30,
UART2_IRQn = 31,
UART3_IRQn = 32,
SerDes_IRQn = 33,
ETH_IRQn = 34,
PMT_IRQn = 35,
ECDC_IRQn = 36,
END_OF_IRQn
} irq_number_t;
#else
typedef enum
{
PWMX_OFFn = 0,
SOFT_IRQn = 0,
TMR0_IRQn = 1,
GPIO_IRQn = 2,
SPI0_IRQn = 3,
USB0_IRQn = 4, // CH567
SATA_IRQn = 4, // CH568
TMR1_IRQn = 5,
TMR2_IRQn = 6,
UART0_IRQn = 7,
USB1_IRQn = 8,
SDC_IRQn = 9,
ECDC_IRQn = 10,
LED_IRQn = 11,
SPI1_IRQn = 12,
UART1_IRQn = 13,
UART2_IRQn = 14,
UART3_IRQn = 15,
END_OF_IRQn
} irq_number_t;
#endif
#endif
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-09-09 WCH the first version
* 2022-07-15 Emuzit adapt to ch569w-evt
*/
#include "cpuport.h"
.global swi_handler
.align 2
swi_handler:
/* save all from thread context */
#ifdef ARCH_RISCV_FPU
addi sp, sp, -32 * FREGBYTES
FSTORE f0, 0 * FREGBYTES(sp)
FSTORE f1, 1 * FREGBYTES(sp)
FSTORE f2, 2 * FREGBYTES(sp)
FSTORE f3, 3 * FREGBYTES(sp)
FSTORE f4, 4 * FREGBYTES(sp)
FSTORE f5, 5 * FREGBYTES(sp)
FSTORE f6, 6 * FREGBYTES(sp)
FSTORE f7, 7 * FREGBYTES(sp)
FSTORE f8, 8 * FREGBYTES(sp)
FSTORE f9, 9 * FREGBYTES(sp)
FSTORE f10, 10 * FREGBYTES(sp)
FSTORE f11, 11 * FREGBYTES(sp)
FSTORE f12, 12 * FREGBYTES(sp)
FSTORE f13, 13 * FREGBYTES(sp)
FSTORE f14, 14 * FREGBYTES(sp)
FSTORE f15, 15 * FREGBYTES(sp)
FSTORE f16, 16 * FREGBYTES(sp)
FSTORE f17, 17 * FREGBYTES(sp)
FSTORE f18, 18 * FREGBYTES(sp)
FSTORE f19, 19 * FREGBYTES(sp)
FSTORE f20, 20 * FREGBYTES(sp)
FSTORE f21, 21 * FREGBYTES(sp)
FSTORE f22, 22 * FREGBYTES(sp)
FSTORE f23, 23 * FREGBYTES(sp)
FSTORE f24, 24 * FREGBYTES(sp)
FSTORE f25, 25 * FREGBYTES(sp)
FSTORE f26, 26 * FREGBYTES(sp)
FSTORE f27, 27 * FREGBYTES(sp)
FSTORE f28, 28 * FREGBYTES(sp)
FSTORE f29, 29 * FREGBYTES(sp)
FSTORE f30, 30 * FREGBYTES(sp)
FSTORE f31, 31 * FREGBYTES(sp)
#endif
addi sp, sp, -32 * REGBYTES
STORE x1, 1 * REGBYTES(sp)
/* saved MPIE */
li x1, 0x80
STORE x1, 2 * REGBYTES(sp)
STORE x4, 4 * REGBYTES(sp)
STORE x5, 5 * REGBYTES(sp)
STORE x6, 6 * REGBYTES(sp)
STORE x7, 7 * REGBYTES(sp)
STORE x8, 8 * REGBYTES(sp)
STORE x9, 9 * REGBYTES(sp)
STORE x10, 10 * REGBYTES(sp)
STORE x11, 11 * REGBYTES(sp)
STORE x12, 12 * REGBYTES(sp)
STORE x13, 13 * REGBYTES(sp)
STORE x14, 14 * REGBYTES(sp)
STORE x15, 15 * REGBYTES(sp)
STORE x16, 16 * REGBYTES(sp)
STORE x17, 17 * REGBYTES(sp)
STORE x18, 18 * REGBYTES(sp)
STORE x19, 19 * REGBYTES(sp)
STORE x20, 20 * REGBYTES(sp)
STORE x21, 21 * REGBYTES(sp)
STORE x22, 22 * REGBYTES(sp)
STORE x23, 23 * REGBYTES(sp)
STORE x24, 24 * REGBYTES(sp)
STORE x25, 25 * REGBYTES(sp)
STORE x26, 26 * REGBYTES(sp)
STORE x27, 27 * REGBYTES(sp)
STORE x28, 28 * REGBYTES(sp)
STORE x29, 29 * REGBYTES(sp)
STORE x30, 30 * REGBYTES(sp)
STORE x31, 31 * REGBYTES(sp)
/* rt_thread_switch_interrupt_flag not 0 => clear & switch thread */
la t0, rt_thread_switch_interrupt_flag
lw t1, 0(t0)
beqz t1, .L_restore
sw zero, 0(t0)
/* prepare to switch to rt_interrupt_to_thread */
csrr t1, mepc
STORE t1, 0 * REGBYTES(sp)
la t0, rt_interrupt_from_thread
LOAD t1, 0(t0)
STORE sp, 0(t1)
la t0, rt_interrupt_to_thread
LOAD t1, 0(t0)
LOAD sp, 0(t1)
LOAD t1, 0 * REGBYTES(sp)
csrw mepc, t1
.L_restore:
/* clear software interrupt */
jal pfic_swi_pendreset
LOAD x1, 1 * REGBYTES(sp)
li t0, 0x1800
csrs mstatus, t0
LOAD t0, 2 * REGBYTES(sp)
csrs mstatus, t0
LOAD x4, 4 * REGBYTES(sp)
LOAD x5, 5 * REGBYTES(sp)
LOAD x6, 6 * REGBYTES(sp)
LOAD x7, 7 * REGBYTES(sp)
LOAD x8, 8 * REGBYTES(sp)
LOAD x9, 9 * REGBYTES(sp)
LOAD x10, 10 * REGBYTES(sp)
LOAD x11, 11 * REGBYTES(sp)
LOAD x12, 12 * REGBYTES(sp)
LOAD x13, 13 * REGBYTES(sp)
LOAD x14, 14 * REGBYTES(sp)
LOAD x15, 15 * REGBYTES(sp)
LOAD x16, 16 * REGBYTES(sp)
LOAD x17, 17 * REGBYTES(sp)
LOAD x18, 18 * REGBYTES(sp)
LOAD x19, 19 * REGBYTES(sp)
LOAD x20, 20 * REGBYTES(sp)
LOAD x21, 21 * REGBYTES(sp)
LOAD x22, 22 * REGBYTES(sp)
LOAD x23, 23 * REGBYTES(sp)
LOAD x24, 24 * REGBYTES(sp)
LOAD x25, 25 * REGBYTES(sp)
LOAD x26, 26 * REGBYTES(sp)
LOAD x27, 27 * REGBYTES(sp)
LOAD x28, 28 * REGBYTES(sp)
LOAD x29, 29 * REGBYTES(sp)
LOAD x30, 30 * REGBYTES(sp)
LOAD x31, 31 * REGBYTES(sp)
addi sp, sp, 32 * REGBYTES
/* load float reg */
#ifdef ARCH_RISCV_FPU
FLOAD f0, 0 * FREGBYTES(sp)
FLOAD f1, 1 * FREGBYTES(sp)
FLOAD f2, 2 * FREGBYTES(sp)
FLOAD f3, 3 * FREGBYTES(sp)
FLOAD f4, 4 * FREGBYTES(sp)
FLOAD f5, 5 * FREGBYTES(sp)
FLOAD f6, 6 * FREGBYTES(sp)
FLOAD f7, 7 * FREGBYTES(sp)
FLOAD f8, 8 * FREGBYTES(sp)
FLOAD f9, 9 * FREGBYTES(sp)
FLOAD f10, 10 * FREGBYTES(sp)
FLOAD f11, 11 * FREGBYTES(sp)
FLOAD f12, 12 * FREGBYTES(sp)
FLOAD f13, 13 * FREGBYTES(sp)
FLOAD f14, 14 * FREGBYTES(sp)
FLOAD f15, 15 * FREGBYTES(sp)
FLOAD f16, 16 * FREGBYTES(sp)
FLOAD f17, 17 * FREGBYTES(sp)
FLOAD f18, 18 * FREGBYTES(sp)
FLOAD f19, 19 * FREGBYTES(sp)
FLOAD f20, 20 * FREGBYTES(sp)
FLOAD f21, 21 * FREGBYTES(sp)
FLOAD f22, 22 * FREGBYTES(sp)
FLOAD f23, 23 * FREGBYTES(sp)
FLOAD f24, 24 * FREGBYTES(sp)
FLOAD f25, 25 * FREGBYTES(sp)
FLOAD f26, 26 * FREGBYTES(sp)
FLOAD f27, 27 * FREGBYTES(sp)
FLOAD f28, 28 * FREGBYTES(sp)
FLOAD f29, 29 * FREGBYTES(sp)
FLOAD f30, 30 * FREGBYTES(sp)
FLOAD f31, 31 * FREGBYTES(sp)
addi sp, sp, 32 * FREGBYTES
#endif
mret
#
# Automatically generated file; DO NOT EDIT.
# RT-Thread Configuration
#
#
# RT-Thread Kernel
#
CONFIG_RT_NAME_MAX=8
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_ALIGN_SIZE=4
# CONFIG_RT_THREAD_PRIORITY_8 is not set
CONFIG_RT_THREAD_PRIORITY_32=y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX=32
CONFIG_RT_TICK_PER_SECOND=200
# CONFIG_RT_USING_OVERFLOW_CHECK is not set
CONFIG_RT_USING_HOOK=y
CONFIG_RT_HOOK_USING_FUNC_PTR=y
CONFIG_RT_USING_IDLE_HOOK=y
CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
CONFIG_IDLE_THREAD_STACK_SIZE=384
# CONFIG_RT_USING_TIMER_SOFT is not set
#
# kservice optimization
#
CONFIG_RT_KSERVICE_USING_STDLIB=y
# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set
# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
# CONFIG_RT_USING_TINY_FFS is not set
# CONFIG_RT_KPRINTF_USING_LONGLONG is not set
# CONFIG_RT_DEBUG is not set
#
# Inter-Thread communication
#
CONFIG_RT_USING_SEMAPHORE=y
CONFIG_RT_USING_MUTEX=y
# CONFIG_RT_USING_EVENT is not set
CONFIG_RT_USING_MAILBOX=y
# CONFIG_RT_USING_MESSAGEQUEUE is not set
# CONFIG_RT_USING_SIGNALS is not set
#
# Memory Management
#
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
# CONFIG_RT_USING_MEMHEAP is not set
CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y
# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
# CONFIG_RT_USING_SLAB_AS_HEAP is not set
# CONFIG_RT_USING_USERHEAP is not set
# CONFIG_RT_USING_NOHEAP is not set
# CONFIG_RT_USING_MEMTRACE is not set
# CONFIG_RT_USING_HEAP_ISR is not set
CONFIG_RT_USING_HEAP=y
#
# Kernel Device Object
#
CONFIG_RT_USING_DEVICE=y
# CONFIG_RT_USING_DEVICE_OPS is not set
CONFIG_RT_USING_INTERRUPT_INFO=y
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
CONFIG_RT_VER_NUM=0x40101
# CONFIG_RT_USING_CPU_FFS is not set
CONFIG_ARCH_RISCV=y
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
#
# RT-Thread Components
#
CONFIG_RT_USING_COMPONENTS_INIT=y
CONFIG_RT_USING_USER_MAIN=y
CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
CONFIG_RT_MAIN_THREAD_PRIORITY=10
# CONFIG_RT_USING_LEGACY is not set
CONFIG_RT_USING_MSH=y
CONFIG_RT_USING_FINSH=y
CONFIG_FINSH_USING_MSH=y
CONFIG_FINSH_THREAD_NAME="tshell"
CONFIG_FINSH_THREAD_PRIORITY=20
CONFIG_FINSH_THREAD_STACK_SIZE=4096
CONFIG_FINSH_USING_HISTORY=y
CONFIG_FINSH_HISTORY_LINES=5
CONFIG_FINSH_USING_SYMTAB=y
CONFIG_FINSH_CMD_SIZE=80
CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
CONFIG_FINSH_USING_DESCRIPTION=y
# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
# CONFIG_FINSH_USING_AUTH is not set
CONFIG_FINSH_ARG_MAX=10
# CONFIG_RT_USING_DFS is not set
# CONFIG_RT_USING_FAL is not set
#
# Device Drivers
#
CONFIG_RT_USING_DEVICE_IPC=y
# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
CONFIG_RT_USING_SERIAL=y
CONFIG_RT_USING_SERIAL_V1=y
# CONFIG_RT_USING_SERIAL_V2 is not set
# CONFIG_RT_SERIAL_USING_DMA is not set
CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_CAN is not set
CONFIG_RT_USING_HWTIMER=y
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
# CONFIG_RT_USING_PHY is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_DAC is not set
# CONFIG_RT_USING_PWM is not set
# CONFIG_RT_USING_MTD_NOR is not set
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_PM is not set
# CONFIG_RT_USING_RTC is not set
# CONFIG_RT_USING_SDIO is not set
# CONFIG_RT_USING_SPI is not set
CONFIG_RT_USING_WDT=y
# CONFIG_RT_USING_AUDIO is not set
# CONFIG_RT_USING_SENSOR is not set
# CONFIG_RT_USING_TOUCH is not set
# CONFIG_RT_USING_HWCRYPTO is not set
# CONFIG_RT_USING_PULSE_ENCODER is not set
# CONFIG_RT_USING_INPUT_CAPTURE is not set
# CONFIG_RT_USING_WIFI is not set
#
# Using USB
#
# CONFIG_RT_USING_USB is not set
# CONFIG_RT_USING_USB_HOST is not set
# CONFIG_RT_USING_USB_DEVICE is not set
#
# C/C++ and POSIX layer
#
CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
#
# POSIX (Portable Operating System Interface) layer
#
# CONFIG_RT_USING_POSIX_FS is not set
# CONFIG_RT_USING_POSIX_DELAY is not set
# CONFIG_RT_USING_POSIX_CLOCK is not set
# CONFIG_RT_USING_POSIX_TIMER is not set
# CONFIG_RT_USING_PTHREADS is not set
# CONFIG_RT_USING_MODULE is not set
#
# Interprocess Communication (IPC)
#
# CONFIG_RT_USING_POSIX_PIPE is not set
# CONFIG_RT_USING_POSIX_MESSAGE_QUEUE is not set
# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set
#
# Socket is in the 'Network' category
#
# CONFIG_RT_USING_CPLUSPLUS is not set
#
# Network
#
# CONFIG_RT_USING_SAL is not set
# CONFIG_RT_USING_NETDEV is not set
# CONFIG_RT_USING_LWIP is not set
# CONFIG_RT_USING_AT is not set
#
# Utilities
#
# CONFIG_RT_USING_RYM is not set
# CONFIG_RT_USING_ULOG is not set
# CONFIG_RT_USING_UTEST is not set
# CONFIG_RT_USING_VAR_EXPORT is not set
# CONFIG_RT_USING_RT_LINK is not set
# CONFIG_RT_USING_VBUS is not set
#
# RT-Thread Utestcases
#
# CONFIG_RT_USING_UTESTCASES is not set
#
# RT-Thread online packages
#
#
# IoT - internet of things
#
# CONFIG_PKG_USING_LWIP is not set
# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
# CONFIG_PKG_USING_PAHOMQTT is not set
# CONFIG_PKG_USING_UMQTT is not set
# CONFIG_PKG_USING_WEBCLIENT is not set
# CONFIG_PKG_USING_WEBNET is not set
# CONFIG_PKG_USING_MONGOOSE is not set
# CONFIG_PKG_USING_MYMQTT is not set
# CONFIG_PKG_USING_KAWAII_MQTT is not set
# CONFIG_PKG_USING_BC28_MQTT is not set
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_LIBMODBUS is not set
# CONFIG_PKG_USING_FREEMODBUS is not set
# CONFIG_PKG_USING_NANOPB is not set
#
# Wi-Fi
#
#
# Marvell WiFi
#
# CONFIG_PKG_USING_WLANMARVELL is not set
#
# Wiced WiFi
#
# CONFIG_PKG_USING_WLAN_WICED is not set
# CONFIG_PKG_USING_RW007 is not set
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
# CONFIG_PKG_USING_NETUTILS is not set
# CONFIG_PKG_USING_CMUX is not set
# CONFIG_PKG_USING_PPP_DEVICE is not set
# CONFIG_PKG_USING_AT_DEVICE is not set
# CONFIG_PKG_USING_ATSRV_SOCKET is not set
# CONFIG_PKG_USING_WIZNET is not set
# CONFIG_PKG_USING_ZB_COORDINATOR is not set
#
# IoT Cloud
#
# CONFIG_PKG_USING_ONENET is not set
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
# CONFIG_PKG_USING_ALI_IOTKIT is not set
# CONFIG_PKG_USING_AZURE is not set
# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
# CONFIG_PKG_USING_JIOT-C-SDK is not set
# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
# CONFIG_PKG_USING_JOYLINK is not set
# CONFIG_PKG_USING_EZ_IOT_OS is not set
# CONFIG_PKG_USING_IOTSHARP_SDK is not set
# CONFIG_PKG_USING_NIMBLE is not set
# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
# CONFIG_PKG_USING_IPMSG is not set
# CONFIG_PKG_USING_LSSDP is not set
# CONFIG_PKG_USING_AIRKISS_OPEN is not set
# CONFIG_PKG_USING_LIBRWS is not set
# CONFIG_PKG_USING_TCPSERVER is not set
# CONFIG_PKG_USING_PROTOBUF_C is not set
# CONFIG_PKG_USING_DLT645 is not set
# CONFIG_PKG_USING_QXWZ is not set
# CONFIG_PKG_USING_SMTP_CLIENT is not set
# CONFIG_PKG_USING_ABUP_FOTA is not set
# CONFIG_PKG_USING_LIBCURL2RTT is not set
# CONFIG_PKG_USING_CAPNP is not set
# CONFIG_PKG_USING_AGILE_TELNET is not set
# CONFIG_PKG_USING_NMEALIB is not set
# CONFIG_PKG_USING_PDULIB is not set
# CONFIG_PKG_USING_BTSTACK is not set
# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
# CONFIG_PKG_USING_MAVLINK is not set
# CONFIG_PKG_USING_BSAL is not set
# CONFIG_PKG_USING_AGILE_MODBUS is not set
# CONFIG_PKG_USING_AGILE_FTP is not set
# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
# CONFIG_PKG_USING_RT_LINK_HW is not set
# CONFIG_PKG_USING_LORA_PKT_FWD is not set
# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
# CONFIG_PKG_USING_HM is not set
# CONFIG_PKG_USING_SMALL_MODBUS is not set
# CONFIG_PKG_USING_NET_SERVER is not set
# CONFIG_PKG_USING_ZFTP is not set
#
# security packages
#
# CONFIG_PKG_USING_MBEDTLS is not set
# CONFIG_PKG_USING_LIBSODIUM is not set
# CONFIG_PKG_USING_LIBHYDROGEN is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
# CONFIG_PKG_USING_TFM is not set
# CONFIG_PKG_USING_YD_CRYPTO is not set
#
# language packages
#
#
# JSON: JavaScript Object Notation, a lightweight data-interchange format
#
# CONFIG_PKG_USING_CJSON is not set
# CONFIG_PKG_USING_LJSON is not set
# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
# CONFIG_PKG_USING_RAPIDJSON is not set
# CONFIG_PKG_USING_JSMN is not set
# CONFIG_PKG_USING_AGILE_JSMN is not set
#
# XML: Extensible Markup Language
#
# CONFIG_PKG_USING_SIMPLE_XML is not set
# CONFIG_PKG_USING_EZXML is not set
# CONFIG_PKG_USING_LUATOS_SOC is not set
# CONFIG_PKG_USING_LUA is not set
# CONFIG_PKG_USING_JERRYSCRIPT is not set
# CONFIG_PKG_USING_MICROPYTHON is not set
# CONFIG_PKG_USING_PIKASCRIPT is not set
# CONFIG_PKG_USING_RTT_RUST is not set
#
# multimedia packages
#
#
# LVGL: powerful and easy-to-use embedded GUI library
#
# CONFIG_PKG_USING_LVGL is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
#
# u8g2: a monochrome graphic library
#
# CONFIG_PKG_USING_U8G2_OFFICIAL is not set
# CONFIG_PKG_USING_U8G2 is not set
# CONFIG_PKG_USING_OPENMV is not set
# CONFIG_PKG_USING_MUPDF is not set
# CONFIG_PKG_USING_STEMWIN is not set
# CONFIG_PKG_USING_WAVPLAYER is not set
# CONFIG_PKG_USING_TJPGD is not set
# CONFIG_PKG_USING_PDFGEN is not set
# CONFIG_PKG_USING_HELIX is not set
# CONFIG_PKG_USING_AZUREGUIX is not set
# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
# CONFIG_PKG_USING_NUEMWIN is not set
# CONFIG_PKG_USING_MP3PLAYER is not set
# CONFIG_PKG_USING_TINYJPEG is not set
# CONFIG_PKG_USING_UGUI is not set
#
# PainterEngine: A cross-platform graphics application framework written in C language
#
# CONFIG_PKG_USING_PAINTERENGINE is not set
# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
# CONFIG_PKG_USING_MCURSES is not set
# CONFIG_PKG_USING_TERMBOX is not set
# CONFIG_PKG_USING_VT100 is not set
# CONFIG_PKG_USING_QRCODE is not set
# CONFIG_PKG_USING_GUIENGINE is not set
#
# tools packages
#
# CONFIG_PKG_USING_CMBACKTRACE is not set
# CONFIG_PKG_USING_EASYFLASH is not set
# CONFIG_PKG_USING_EASYLOGGER is not set
# CONFIG_PKG_USING_SYSTEMVIEW is not set
# CONFIG_PKG_USING_SEGGER_RTT is not set
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
# CONFIG_PKG_USING_ULOG_FILE is not set
# CONFIG_PKG_USING_LOGMGR is not set
# CONFIG_PKG_USING_ADBD is not set
# CONFIG_PKG_USING_COREMARK is not set
# CONFIG_PKG_USING_DHRYSTONE is not set
# CONFIG_PKG_USING_MEMORYPERF is not set
# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
# CONFIG_PKG_USING_BS8116A is not set
# CONFIG_PKG_USING_GPS_RMC is not set
# CONFIG_PKG_USING_URLENCODE is not set
# CONFIG_PKG_USING_UMCN is not set
# CONFIG_PKG_USING_LWRB2RTT is not set
# CONFIG_PKG_USING_CPU_USAGE is not set
# CONFIG_PKG_USING_GBK2UTF8 is not set
# CONFIG_PKG_USING_VCONSOLE is not set
# CONFIG_PKG_USING_KDB is not set
# CONFIG_PKG_USING_WAMR is not set
# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
# CONFIG_PKG_USING_LWLOG is not set
# CONFIG_PKG_USING_ANV_TRACE is not set
# CONFIG_PKG_USING_ANV_MEMLEAK is not set
# CONFIG_PKG_USING_ANV_TESTSUIT is not set
# CONFIG_PKG_USING_ANV_BENCH is not set
# CONFIG_PKG_USING_DEVMEM is not set
# CONFIG_PKG_USING_REGEX is not set
# CONFIG_PKG_USING_MEM_SANDBOX is not set
# CONFIG_PKG_USING_SOLAR_TERMS is not set
# CONFIG_PKG_USING_GAN_ZHI is not set
# CONFIG_PKG_USING_FDT is not set
# CONFIG_PKG_USING_CBOX is not set
# CONFIG_PKG_USING_SNOWFLAKE is not set
# CONFIG_PKG_USING_HASH_MATCH is not set
# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
#
# system packages
#
#
# enhanced kernel services
#
# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
#
# acceleration: Assembly language or algorithmic acceleration packages
#
# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
# CONFIG_PKG_USING_QFPLIB_M3 is not set
#
# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
#
# CONFIG_PKG_USING_CMSIS_5 is not set
# CONFIG_PKG_USING_CMSIS_RTOS1 is not set
# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
#
# Micrium: Micrium software products porting for RT-Thread
#
# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
# CONFIG_PKG_USING_UC_CRC is not set
# CONFIG_PKG_USING_UC_CLK is not set
# CONFIG_PKG_USING_UC_COMMON is not set
# CONFIG_PKG_USING_UC_MODBUS is not set
# CONFIG_PKG_USING_RTDUINO is not set
# CONFIG_PKG_USING_CAIRO is not set
# CONFIG_PKG_USING_PIXMAN is not set
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_PERF_COUNTER is not set
# CONFIG_PKG_USING_FLASHDB is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
# CONFIG_PKG_USING_DFS_YAFFS is not set
# CONFIG_PKG_USING_LITTLEFS is not set
# CONFIG_PKG_USING_DFS_JFFS2 is not set
# CONFIG_PKG_USING_DFS_UFFS is not set
# CONFIG_PKG_USING_LWEXT4 is not set
# CONFIG_PKG_USING_THREAD_POOL is not set
# CONFIG_PKG_USING_ROBOTS is not set
# CONFIG_PKG_USING_EV is not set
# CONFIG_PKG_USING_SYSWATCH is not set
# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
# CONFIG_PKG_USING_PLCCORE is not set
# CONFIG_PKG_USING_RAMDISK is not set
# CONFIG_PKG_USING_MININI is not set
# CONFIG_PKG_USING_QBOOT is not set
# CONFIG_PKG_USING_PPOOL is not set
# CONFIG_PKG_USING_OPENAMP is not set
# CONFIG_PKG_USING_LPM is not set
# CONFIG_PKG_USING_TLSF is not set
# CONFIG_PKG_USING_EVENT_RECORDER is not set
# CONFIG_PKG_USING_ARM_2D is not set
# CONFIG_PKG_USING_MCUBOOT is not set
# CONFIG_PKG_USING_TINYUSB is not set
# CONFIG_PKG_USING_CHERRYUSB is not set
# CONFIG_PKG_USING_KMULTI_RTIMER is not set
# CONFIG_PKG_USING_TFDB is not set
# CONFIG_PKG_USING_QPC is not set
#
# peripheral libraries and drivers
#
# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_SHT3X is not set
# CONFIG_PKG_USING_AS7341 is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ICM20608 is not set
# CONFIG_PKG_USING_BUTTON is not set
# CONFIG_PKG_USING_PCF8574 is not set
# CONFIG_PKG_USING_SX12XX is not set
# CONFIG_PKG_USING_SIGNAL_LED is not set
# CONFIG_PKG_USING_LEDBLINK is not set
# CONFIG_PKG_USING_LITTLED is not set
# CONFIG_PKG_USING_LKDGUI is not set
# CONFIG_PKG_USING_NRF5X_SDK is not set
# CONFIG_PKG_USING_NRFX is not set
# CONFIG_PKG_USING_WM_LIBRARIES is not set
# CONFIG_PKG_USING_KENDRYTE_SDK is not set
# CONFIG_PKG_USING_INFRARED is not set
# CONFIG_PKG_USING_MULTI_INFRARED is not set
# CONFIG_PKG_USING_AGILE_BUTTON is not set
# CONFIG_PKG_USING_AGILE_LED is not set
# CONFIG_PKG_USING_AT24CXX is not set
# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_PCA9685 is not set
# CONFIG_PKG_USING_I2C_TOOLS is not set
# CONFIG_PKG_USING_NRF24L01 is not set
# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
# CONFIG_PKG_USING_WS2812B is not set
# CONFIG_PKG_USING_EMBARC_BSP is not set
# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
# CONFIG_PKG_USING_MULTI_RTIMER is not set
# CONFIG_PKG_USING_MAX7219 is not set
# CONFIG_PKG_USING_BEEP is not set
# CONFIG_PKG_USING_EASYBLINK is not set
# CONFIG_PKG_USING_PMS_SERIES is not set
# CONFIG_PKG_USING_NUCLEI_SDK is not set
# CONFIG_PKG_USING_CAN_YMODEM is not set
# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
# CONFIG_PKG_USING_QLED is not set
# CONFIG_PKG_USING_PAJ7620 is not set
# CONFIG_PKG_USING_AGILE_CONSOLE is not set
# CONFIG_PKG_USING_LD3320 is not set
# CONFIG_PKG_USING_WK2124 is not set
# CONFIG_PKG_USING_LY68L6400 is not set
# CONFIG_PKG_USING_DM9051 is not set
# CONFIG_PKG_USING_SSD1306 is not set
# CONFIG_PKG_USING_QKEY is not set
# CONFIG_PKG_USING_RS485 is not set
# CONFIG_PKG_USING_RS232 is not set
# CONFIG_PKG_USING_NES is not set
# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
# CONFIG_PKG_USING_VDEVICE is not set
# CONFIG_PKG_USING_SGM706 is not set
# CONFIG_PKG_USING_STM32WB55_SDK is not set
# CONFIG_PKG_USING_RDA58XX is not set
# CONFIG_PKG_USING_LIBNFC is not set
# CONFIG_PKG_USING_MFOC is not set
# CONFIG_PKG_USING_TMC51XX is not set
# CONFIG_PKG_USING_TCA9534 is not set
# CONFIG_PKG_USING_KOBUKI is not set
# CONFIG_PKG_USING_ROSSERIAL is not set
# CONFIG_PKG_USING_MICRO_ROS is not set
# CONFIG_PKG_USING_MCP23008 is not set
# CONFIG_PKG_USING_BLUETRUM_SDK is not set
# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
# CONFIG_PKG_USING_BL_MCU_SDK is not set
# CONFIG_PKG_USING_SOFT_SERIAL is not set
# CONFIG_PKG_USING_MB85RS16 is not set
# CONFIG_PKG_USING_CW2015 is not set
# CONFIG_PKG_USING_RFM300 is not set
#
# AI packages
#
# CONFIG_PKG_USING_LIBANN is not set
# CONFIG_PKG_USING_NNOM is not set
# CONFIG_PKG_USING_ONNX_BACKEND is not set
# CONFIG_PKG_USING_ONNX_PARSER is not set
# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
# CONFIG_PKG_USING_ELAPACK is not set
# CONFIG_PKG_USING_ULAPACK is not set
# CONFIG_PKG_USING_QUEST is not set
# CONFIG_PKG_USING_NAXOS is not set
#
# miscellaneous packages
#
#
# project laboratory
#
#
# samples: kernel and components samples
#
# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
#
# entertainment: terminal games and other interesting software packages
#
# CONFIG_PKG_USING_CMATRIX is not set
# CONFIG_PKG_USING_SL is not set
# CONFIG_PKG_USING_CAL is not set
# CONFIG_PKG_USING_ACLOCK is not set
# CONFIG_PKG_USING_THREES is not set
# CONFIG_PKG_USING_2048 is not set
# CONFIG_PKG_USING_SNAKE is not set
# CONFIG_PKG_USING_TETRIS is not set
# CONFIG_PKG_USING_DONUT is not set
# CONFIG_PKG_USING_COWSAY is not set
# CONFIG_PKG_USING_LIBCSV is not set
# CONFIG_PKG_USING_OPTPARSE is not set
# CONFIG_PKG_USING_FASTLZ is not set
# CONFIG_PKG_USING_MINILZO is not set
# CONFIG_PKG_USING_QUICKLZ is not set
# CONFIG_PKG_USING_LZMA is not set
# CONFIG_PKG_USING_MULTIBUTTON is not set
# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
# CONFIG_PKG_USING_CANFESTIVAL is not set
# CONFIG_PKG_USING_ZLIB is not set
# CONFIG_PKG_USING_MINIZIP is not set
# CONFIG_PKG_USING_HEATSHRINK is not set
# CONFIG_PKG_USING_DSTR is not set
# CONFIG_PKG_USING_TINYFRAME is not set
# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
# CONFIG_PKG_USING_DIGITALCTRL is not set
# CONFIG_PKG_USING_UPACKER is not set
# CONFIG_PKG_USING_UPARAM is not set
# CONFIG_PKG_USING_HELLO is not set
# CONFIG_PKG_USING_VI is not set
# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_CRCLIB is not set
# CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_STATE_MACHINE is not set
# CONFIG_PKG_USING_DESIGN_PATTERN is not set
# CONFIG_PKG_USING_CONTROLLER is not set
# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
# CONFIG_PKG_USING_MFBD is not set
# CONFIG_PKG_USING_SLCAN2RTT is not set
# CONFIG_PKG_USING_SOEM is not set
CONFIG_SOC_FAMILY_CH56X=y
CONFIG_SOC_SERIES_CH569=y
#
# Hardware Drivers Config
#
CONFIG_SOC_CH569W=y
#
# On-chip Peripheral Drivers
#
CONFIG_BSP_USING_UART=y
# CONFIG_BSP_USING_UART0 is not set
CONFIG_BSP_USING_UART1=y
# CONFIG_BSP_USING_UART2 is not set
# CONFIG_BSP_USING_UART3 is not set
CONFIG_BSP_USING_TIMER=y
CONFIG_BSP_USING_TMR0=y
CONFIG_BSP_USING_TMR1=y
# CONFIG_BSP_USING_TMR2 is not set
#
# Onboard Peripheral Drivers
#
#
# Board extended module Drivers
#
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "../../../.."
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
source "../Libraries/Kconfig"
source "board/Kconfig"
import os
from building import *
objs = []
cwd = GetCurrentDir()
list = os.listdir(cwd)
for d in list:
if os.path.isfile(os.path.join(cwd, d, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../../../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
try:
from building import *
except:
print('Cannot find RT-Thread root directory, please check RTT_ROOT')
print('RTT_ROOT: ' + RTT_ROOT)
exit(-1)
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
DefaultEnvironment(tools=[])
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
objs.extend(SConscript('../Libraries/ch56x_drivers/SConscript',
variant_dir='build/libraries/ch56x_drivers', duplicate=0))
# make a building
DoBuilding(TARGET, objs)
from building import *
cwd = GetCurrentDir()
src = Split("""
main.c
""")
path = [cwd, str(Dir('#'))]
group = DefineGroup('Applications', src, depend=[''], CPPPATH=path)
Return('group')
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
* 2022-07-20 Emuzit add watchdog test
* 2022-07-26 Emuzit add hwtimer test
*/
#include <rtthread.h>
#include <rtdebug.h>
#include <drivers/pin.h>
#include <drivers/watchdog.h>
#include <drivers/hwtimer.h>
#include "board.h"
static const rt_base_t gpio_int_pins[8] = GPIO_INT_PINS;
/* note : PIN_IRQ_MODE_RISING_FALLING not supported */
static const uint32_t gpint_mode[] =
{
PIN_IRQ_MODE_RISING,
PIN_IRQ_MODE_RISING,
PIN_IRQ_MODE_RISING,
PIN_IRQ_MODE_RISING,
PIN_IRQ_MODE_FALLING,
PIN_IRQ_MODE_FALLING,
PIN_IRQ_MODE_FALLING,
PIN_IRQ_MODE_FALLING,
};
static struct rt_mailbox *gpint_mb = RT_NULL;
static struct rt_thread *gpint_thread = RT_NULL;
static rt_base_t led0, led1;
static rt_device_t wdg_dev;
static struct rt_device *tmr_dev_0;
static struct rt_device *tmr_dev_1;
static void gpio_int_callback(void *pin)
{
led1 = (led1 == PIN_LOW) ? PIN_HIGH : PIN_LOW;
rt_pin_write(LED1_PIN, led1);
if (gpint_mb != RT_NULL)
{
/* non-block, silently ignore RT_EFULL */
rt_mb_send(gpint_mb, (uint32_t)pin);
}
}
static void gpio_int_thread(void *param)
{
while (1)
{
rt_err_t res;
uint32_t pin;
res = rt_mb_recv(gpint_mb, &pin, RT_WAITING_FOREVER);
if (res == RT_EOK)
{
rt_kprintf("gpio_int #%d (%d)\n", pin, rt_pin_read(pin));
}
rt_thread_mdelay(100);
#ifdef RT_USING_WDT
rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, RT_NULL);
#endif
}
}
#ifdef RT_USING_HWTIMER
static rt_err_t tmr_timeout_cb(rt_device_t dev, rt_size_t size)
{
rt_tick_t tick = rt_tick_get();
int tmr = (dev == tmr_dev_1) ? 1 : 0;
rt_kprintf("hwtimer %d timeout callback fucntion @tick %d\n", tmr, tick);
return RT_EOK;
}
#endif
void main(void)
{
rt_hwtimerval_t timerval;
rt_hwtimer_mode_t mode;
rt_size_t tsize;
uint32_t seconds;
rt_err_t res;
int i;
rt_kprintf("\nCH569W-R0-1v0, HCLK: %dMHz\n\n", sys_hclk_get() / 1000000);
/* Enable all gpio interrupt with various modes.
* LED0 or GND touching can be used to trigger pin interrupt.
*/
gpint_mb = rt_mb_create("pximb", 8, RT_IPC_FLAG_FIFO);
if (gpint_mb == RT_NULL)
{
rt_kprintf("gpint mailbox create failed !\n");
}
else
{
gpint_thread = rt_thread_create("pxith", gpio_int_thread, RT_NULL,
512, RT_MAIN_THREAD_PRIORITY, 50);
if (gpint_thread == RT_NULL)
{
rt_kprintf("gpint thread create failed !\n");
}
else
{
rt_thread_startup(gpint_thread);
for (i = 0; i < 8; i++)
{
rt_base_t pin = gpio_int_pins[i];
rt_pin_mode(pin, PIN_MODE_INPUT_PULLUP);
res = rt_pin_attach_irq(
pin, gpint_mode[i], gpio_int_callback, (void *)pin);
if (res != RT_EOK)
{
rt_kprintf("rt_pin_attach_irq failed (%d:%d)\n", i, res);
}
else
{
rt_pin_irq_enable(pin, PIN_IRQ_ENABLE);
}
}
}
}
#ifdef RT_USING_WDT
/* Test watchdog with 30s timeout, keepalive with gpio interrupt.
*
* CAVEAT: With only 8-bit WDOG_COUNT and fixed clocking at Fsys/524288,
* watchdog of ch56x may be quite limited with very short timeout.
*/
seconds = 30;
wdg_dev = rt_device_find("wdt");
if (!wdg_dev)
{
rt_kprintf("watchdog device not found !\n");
}
else if (rt_device_init(wdg_dev) != RT_EOK ||
rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &seconds) != RT_EOK)
{
rt_kprintf("watchdog setup failed !\n");
}
else
{
rt_kprintf("WDT_TIMEOUT in %d seconds, trigger gpio interrupt to keep alive.\n\n", seconds);
}
#endif
#ifdef RT_USING_HWTIMER
/* setup two timers, ONESHOT & PERIOD each
*/
tmr_dev_0 = rt_device_find("timer0");
tmr_dev_1 = rt_device_find("timer1");
if (tmr_dev_0 == RT_NULL || tmr_dev_1 == RT_NULL)
{
rt_kprintf("hwtimer device(s) not found !\n");
}
else if (rt_device_open(tmr_dev_0, RT_DEVICE_OFLAG_RDWR) != RT_EOK ||
rt_device_open(tmr_dev_1, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
{
rt_kprintf("hwtimer device(s) open failed !\n");
}
else
{
rt_device_set_rx_indicate(tmr_dev_0, tmr_timeout_cb);
rt_device_set_rx_indicate(tmr_dev_1, tmr_timeout_cb);
timerval.sec = 3;
timerval.usec = 500000;
tsize = sizeof(timerval);
mode = HWTIMER_MODE_ONESHOT;
if (rt_device_control(tmr_dev_0, HWTIMER_CTRL_MODE_SET, &mode) != RT_EOK)
{
rt_kprintf("timer0 set mode failed !\n");
}
else if (rt_device_write(tmr_dev_0, 0, &timerval, tsize) != tsize)
{
rt_kprintf("timer0 start failed !\n");
}
else
{
rt_kprintf("timer0 started !\n");
}
timerval.sec = 5;
timerval.usec = 0;
tsize = sizeof(timerval);
mode = HWTIMER_MODE_PERIOD;
if (rt_device_control(tmr_dev_1, HWTIMER_CTRL_MODE_SET, &mode) != RT_EOK)
{
rt_kprintf("timer1 set mode failed !\n");
}
else if (rt_device_write(tmr_dev_1, 0, &timerval, tsize) != tsize)
{
rt_kprintf("timer1 start failed !\n");
}
else
{
rt_kprintf("timer1 started !\n");
}
}
#endif
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LED1_PIN, led1 = PIN_HIGH);
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LED0_PIN, led0 = PIN_LOW);
while (1)
{
/* flashing LED0 every 1 second */
rt_thread_mdelay(500);
led0 = (led0 == PIN_LOW) ? PIN_HIGH : PIN_LOW;
rt_pin_write(LED0_PIN, led0);
}
}
menu "Hardware Drivers Config"
config SOC_CH569W
bool
select SOC_FAMILY_CH56X
select SOC_SERIES_CH569
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
menu "On-chip Peripheral Drivers"
config BSP_USING_UART
bool "using on-chip uart"
select RT_USING_SERIAL
default y
if BSP_USING_UART
config BSP_USING_UART0
bool "using UART0"
default n
config BSP_USING_UART1
bool "using UART1"
default y
config BSP_USING_UART2
bool "using UART2"
default n
config BSP_USING_UART3
bool "using UART3"
default n
endif
config BSP_USING_TIMER
bool "using on-chip timer"
select RT_USING_HWTIMER
default n
if BSP_USING_TIMER
config BSP_USING_TMR0
bool "using TMR0"
default y
config BSP_USING_TMR1
bool "using TMR1"
default n
config BSP_USING_TMR2
bool "using TMR2"
default n
endif
endmenu
menu "Onboard Peripheral Drivers"
endmenu
menu "Board extended module Drivers"
endmenu
endmenu
from building import *
cwd = GetCurrentDir()
src = Split('''
board.c
startup_gcc.S
''')
path = [cwd]
group = DefineGroup('Drivers', src, depend=[''], CPPPATH=path)
Return('group')
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#include <rthw.h>
#include <drivers/pin.h>
#include "board.h"
#include "ch56x_pfic.h"
#include "ch56x_uart.h"
extern rt_uint32_t rt_thread_switch_interrupt_flag;
/* FIXME: Use rt_interrupt_leave_hook to trigger SWI for context switch.
* Hopefully there's a standard riscv way instead of this clumsy patch.
*/
static void irq_leave_hook(void)
{
if (rt_thread_switch_interrupt_flag)
{
pfic_swi_pendset();
}
}
/*
* _start -> handle_reset
* src/components.c/entry() -> rtthread_startup()
* libcpu/risc-v/common/context_gcc.S/rt_hw_interrupt_disable
*/
void rt_hw_board_init()
{
volatile struct pfic_registers *pfic = (void *)PFIC_REG_BASE;
/* disable all pfic interrupts */
pfic->IRER[0] = PFIC_IREG1_MASK;
pfic->IRER[1] = PFIC_IREG2_MASK;
/* disable hwstack push/pop & nested interrupt */
pfic->CFGR = cfgr_nest_hwstk(CFGR_NESTCTRL_DISABLE | CFGR_HWSTKCTRL_DISABLE);
/* disable clock input for all peripheral devices */
sys_slp_clk_off0(0xff, SYS_SLP_CLK_OFF);
sys_slp_clk_off1(0xff, SYS_SLP_CLK_OFF);
sys_clk_off_by_irqn(ETH_IRQn, SYS_SLP_CLK_OFF);
sys_clk_off_by_irqn(ECDC_IRQn, SYS_SLP_CLK_OFF);
/* setup HCLK for systick & peripheral devices */
sys_hclk_set(SYS_HCLK_FREQ);
/* set SysTick to RT_TICK_PER_SECOND with current HCLK */
systick_init(0);
/* Note: keep MSTATUS_MIE disabled to prevent SysTick from processing
* thread scheduling, which may not be ready upon 1st systick irq.
* MSTATUS_MIE will be set when rt_system_scheduler_start() starts
* the first thread and copies mstatus from stack_frame.
*/
#ifdef RT_USING_HEAP
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#ifdef RT_USING_CONSOLE
/* console is uart1, TXD1/RXD1 : PA8/PA7 */
rt_pin_mode(GET_PIN(A, 8), PIN_MODE_OUTPUT);
rt_pin_mode(GET_PIN(A, 7), PIN_MODE_INPUT_PULLUP);
rt_hw_uart_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
rt_interrupt_leave_sethook(irq_leave_hook);
}
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-15 Emuzit first version
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <stdint.h>
#include "ch56x_sys.h"
#include "ch56x_gpio.h"
#define LED0_PIN GET_PIN(B, 24)
#define LED1_PIN GET_PIN(B, 22)
#define LED2_PIN GET_PIN(B, 23)
#define SYS_HCLK_FREQ 80000000 // 80 MHz
#define RAMX_SIZE 32 // USER_MEM 00/01/1x : 32/64/96 KB
#define RAMX_END (RAMX_BASE_ADDRESS + RAMX_SIZE * 1024)
extern uint32_t _ebss, _heap_end;
extern uint32_t _susrstack, _eusrstack;
#define HEAP_BEGIN ((void *)&_ebss)
#define HEAP_END ((void *)&_heap_end)
#define SUSRSTACK ((void *)&_susrstack)
#define EUSRSTACK ((void *)&_eusrstack)
void rt_hw_board_init(void);
#endif /* __BOARD_H__ */
ENTRY( _start )
__stack_size = 2048;
PROVIDE( _stack_size = __stack_size );
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 96K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
RAMX (xrw) : ORIGIN = 0x20020000, LENGTH = 32K
}
SECTIONS
{
.init :
{
_sinit = .;
. = ALIGN(4);
KEEP(*(SORT_NONE(.init)))
. = ALIGN(4);
_einit = .;
} >FLASH AT>FLASH
.vector :
{
*(.vector);
. = ALIGN(64);
} >FLASH AT>FLASH
.text :
{
. = ALIGN(4);
*(.text)
*(.text.*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t.*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
/* section information for modules */
. = ALIGN(4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
. = ALIGN(4);
} >FLASH AT>FLASH
.fini :
{
KEEP(*(SORT_NONE(.fini)))
. = ALIGN(4);
} >FLASH AT>FLASH
PROVIDE( _etext = . );
PROVIDE( _eitcm = . );
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >FLASH AT>FLASH
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >FLASH AT>FLASH
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >FLASH AT>FLASH
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >FLASH AT>FLASH
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >FLASH AT>FLASH
.dalign :
{
. = ALIGN(4);
PROVIDE(_data_vma = .);
} >RAM AT>FLASH
.dlalign :
{
. = ALIGN(4);
PROVIDE(_data_lma = .);
} >FLASH AT>FLASH
.data :
{
*(.gnu.linkonce.r.*)
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.*)
*(.sdata2.*)
*(.gnu.linkonce.s.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
. = ALIGN(4);
PROVIDE( _edata = .);
} >RAM AT>FLASH
.bss :
{
. = ALIGN(4);
PROVIDE( _sbss = .);
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss*)
*(.gnu.linkonce.b.*)
*(COMMON*)
. = ALIGN(4);
PROVIDE( _ebss = .);
} >RAM AT>FLASH
PROVIDE( _end = _ebss);
PROVIDE( end = . );
.dmadata :
{
. = ALIGN(16);
PROVIDE( _dmadata_start = .);
*(.dmadata*)
*(.dmadata.*)
. = ALIGN(16);
PROVIDE( _dmadata_end = .);
} >RAMX AT>FLASH /**/
.stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
{
PROVIDE( _heap_end = . );
. = ALIGN(4);
PROVIDE(_susrstack = . );
. = . + __stack_size;
PROVIDE( _eusrstack = .);
} >RAM
}
/********************************** (C) COPYRIGHT *******************************
* File Name : startup_gcc.s
* Author : WCH
* Version : V1.0
* Date : 2020/07/31
* Description : CH56x vector table for eclipse toolchain.
*******************************************************************************/
.section .init,"ax",@progbits
.global _start
.align 1
_start:
j handle_reset
.section .vector,"ax",@progbits
.align 1
_vector_base:
.option norvc;
.word 0
.word 0
j nmi_handler
j hardfault_handler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
j systick_handler
.word 0
j swi_handler
.word 0
/* External Interrupts */
j wdog_irq_handler
j tmr0_irq_handler
j gpio_irq_handler
j spi0_irq_handler
j usbss_irq_handler
j link_irq_handler
j tmr1_irq_handler
j tmr2_irq_handler
j uart0_irq_handler
j usbhs_irq_handler
j emmc_irq_handler
j dvp_irq_handler
j hspi_irq_handler
j spi1_irq_handler
j uart1_irq_handler
j uart2_irq_handler
j uart3_irq_handler
j serdes_irq_handler
j eth_irq_handler
j pmt_irq_handler
j ecdc_irq_handler
.option rvc;
.section .text.vector_handler,"ax", @prsocogbits
.weak nmi_handler
.weak hardfault_handler
.weak systick_handler
.weak swi_handler
.weak wdog_irq_handler
.weak tmr0_irq_handler
.weak gpio_irq_handler
.weak spi0_irq_handler
.weak usbss_irq_handler
.weak link_irq_handler
.weak tmr1_irq_handler
.weak tmr2_irq_handler
.weak uart0_irq_handler
.weak usbhs_irq_handler
.weak emmc_irq_handler
.weak dvp_irq_handler
.weak hspi_irq_handler
.weak spi1_irq_handler
.weak uart1_irq_handler
.weak uart2_irq_handler
.weak uart3_irq_handler
.weak serdes_irq_handler
.weak eth_irq_handler
.weak pmt_irq_handler
.weak ecdc_irq_handler
nmi_handler: j .L_rip
hardfault_handler: j .L_rip
systick_handler: j .L_rip
swi_handler: j .L_rip
wdog_irq_handler: j .L_rip
tmr0_irq_handler: j .L_rip
gpio_irq_handler: j .L_rip
spi0_irq_handler: j .L_rip
usbss_irq_handler: j .L_rip
link_irq_handler: j .L_rip
tmr1_irq_handler: j .L_rip
tmr2_irq_handler: j .L_rip
uart0_irq_handler: j .L_rip
usbhs_irq_handler: j .L_rip
emmc_irq_handler: j .L_rip
dvp_irq_handler: j .L_rip
hspi_irq_handler: j .L_rip
spi1_irq_handler: j .L_rip
uart1_irq_handler: j .L_rip
uart2_irq_handler: j .L_rip
uart3_irq_handler: j .L_rip
serdes_irq_handler: j .L_rip
eth_irq_handler: j .L_rip
pmt_irq_handler: j .L_rip
ecdc_irq_handler: j .L_rip
.L_rip:
csrr t0, mepc
csrr t1, mstatus
csrr t2, mcause
csrr t3, mtval
csrr t4, mscratch
1: j 1b
.section .text.handle_reset,"ax",@progbits
.weak handle_reset
.align 1
handle_reset:
.option push
.option norelax
la gp, __global_pointer$
.option pop
1:
la sp, _eusrstack
/* Load data section from flash to RAM */
2:
la a0, _data_lma
la a1, _data_vma
la a2, _edata
bgeu a1, a2, 2f
1:
lw t0, (a0)
sw t0, (a1)
addi a0, a0, 4
addi a1, a1, 4
bltu a1, a2, 1b
/* clear bss section */
2:
la a0, _sbss
la a1, _ebss
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
/* clear dmadata section */
2:
la a0, _dmadata_start
la a1, _dmadata_end
bgeu a0, a1, 2f
1:
sw zero, (a0)
addi a0, a0, 4
bltu a0, a1, 1b
2:
/* leave all interrupt disabled */
li t0, 0x1800
csrs mstatus, t0
la t0, _vector_base
ori t0, t0, 1
csrw mtvec, t0
la t0, entry
csrw mepc, t0
mret
#ifndef RT_CONFIG_H__
#define RT_CONFIG_H__
/* Automatically generated file; DO NOT EDIT. */
/* RT-Thread Configuration */
/* RT-Thread Kernel */
#define RT_NAME_MAX 8
#define RT_ALIGN_SIZE 4
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 200
#define RT_USING_HOOK
#define RT_HOOK_USING_FUNC_PTR
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 384
/* kservice optimization */
#define RT_KSERVICE_USING_STDLIB
/* Inter-Thread communication */
#define RT_USING_SEMAPHORE
#define RT_USING_MUTEX
#define RT_USING_MAILBOX
/* Memory Management */
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
#define RT_USING_HEAP
/* Kernel Device Object */
#define RT_USING_DEVICE
#define RT_USING_INTERRUPT_INFO
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLE_DEVICE_NAME "uart1"
#define RT_VER_NUM 0x40101
#define ARCH_RISCV
/* RT-Thread Components */
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 2048
#define RT_MAIN_THREAD_PRIORITY 10
#define RT_USING_MSH
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_THREAD_NAME "tshell"
#define FINSH_THREAD_PRIORITY 20
#define FINSH_THREAD_STACK_SIZE 4096
#define FINSH_USING_HISTORY
#define FINSH_HISTORY_LINES 5
#define FINSH_USING_SYMTAB
#define FINSH_CMD_SIZE 80
#define MSH_USING_BUILT_IN_COMMANDS
#define FINSH_USING_DESCRIPTION
#define FINSH_ARG_MAX 10
/* Device Drivers */
#define RT_USING_DEVICE_IPC
#define RT_USING_SERIAL
#define RT_USING_SERIAL_V1
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_HWTIMER
#define RT_USING_PIN
#define RT_USING_WDT
/* Using USB */
/* C/C++ and POSIX layer */
#define RT_LIBC_DEFAULT_TIMEZONE 8
/* POSIX (Portable Operating System Interface) layer */
/* Interprocess Communication (IPC) */
/* Socket is in the 'Network' category */
/* Network */
/* Utilities */
/* RT-Thread Utestcases */
/* RT-Thread online packages */
/* IoT - internet of things */
/* Wi-Fi */
/* Marvell WiFi */
/* Wiced WiFi */
/* IoT Cloud */
/* security packages */
/* language packages */
/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
/* XML: Extensible Markup Language */
/* multimedia packages */
/* LVGL: powerful and easy-to-use embedded GUI library */
/* u8g2: a monochrome graphic library */
/* PainterEngine: A cross-platform graphics application framework written in C language */
/* tools packages */
/* system packages */
/* enhanced kernel services */
/* acceleration: Assembly language or algorithmic acceleration packages */
/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
/* Micrium: Micrium software products porting for RT-Thread */
/* peripheral libraries and drivers */
/* AI packages */
/* miscellaneous packages */
/* project laboratory */
/* samples: kernel and components samples */
/* entertainment: terminal games and other interesting software packages */
#define SOC_FAMILY_CH56X
#define SOC_SERIES_CH569
/* Hardware Drivers Config */
#define SOC_CH569W
/* On-chip Peripheral Drivers */
#define BSP_USING_UART
#define BSP_USING_UART1
#define BSP_USING_TIMER
#define BSP_USING_TMR0
#define BSP_USING_TMR1
/* Onboard Peripheral Drivers */
/* Board extended module Drivers */
#endif
import os
ARCH = 'risc-v'
CPU = 'ch56x'
# toolchains options
CROSS_TOOL = 'gcc'
#------- toolchains path -------------------------------------------------------
if os.getenv('RTT_CC'):
CROSS_TOOL = os.getenv('RTT_CC')
if CROSS_TOOL == 'gcc':
PLATFORM = 'gcc'
EXEC_PATH = r'/opt/mrs-riscv-none-embed/bin'
else:
print('Please make sure your toolchains is GNU GCC!')
exit(0)
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
#BUILD = 'debug'
BUILD = 'release'
CORE = 'risc-v'
MAP_FILE = 'rtthread.map'
LINK_FILE = './board/linker_scripts/link.lds'
TARGET_NAME = 'rtthread.bin'
#------- GCC settings ----------------------------------------------------------
if PLATFORM == 'gcc':
# toolchains
PREFIX = 'riscv-none-embed-'
CC = PREFIX + 'gcc'
CXX= PREFIX + 'g++'
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -march=rv32imac -mabi=ilp32 -DUSE_PLIC -DUSE_M_TIME -DNO_INIT -mcmodel=medany -msmall-data-limit=8 -L. -nostartfiles -lc '
CFLAGS = DEVICE
CFLAGS += ' -save-temps=obj'
AFLAGS = '-c'+ DEVICE + ' -x assembler-with-cpp'
LFLAGS = DEVICE
LFLAGS += ' -Wl,--gc-sections,-cref,-Map=' + MAP_FILE
LFLAGS += ' -T ' + LINK_FILE
LFLAGS += ' -Wl,-wrap=memset'
CPATH = ''
LPATH = ''
if BUILD == 'debug':
CFLAGS += ' -O0 -g3'
AFLAGS += ' -g3'
else:
CFLAGS += ' -O2'
POST_ACTION = OBJCPY + ' -O binary $TARGET ' + TARGET_NAME + '\n'
POST_ACTION += SIZE + ' $TARGET\n'
......@@ -24,7 +24,7 @@ else :
# cpu porting code files
if rtconfig.CPU == "e9xx" :
group = group + SConscript(os.path.join(rtconfig.VENDOR, rtconfig.CPU, 'SConscript'))
else :
elif rtconfig.CPU in list:
group = group + SConscript(os.path.join(rtconfig.CPU, 'SConscript'))
Return('group')
......@@ -138,7 +138,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry,
* #endif
*/
#ifndef RT_USING_SMP
void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to)
RT_WEAK void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to)
{
if (rt_thread_switch_interrupt_flag == 0)
rt_interrupt_from_thread = from;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册