ch569w-evt : add pwm driver, and spi_xfer bug fix (#6240)

add PWM driver, output checked with logic analyzer
spi_xfer() bug fix for cs_pin and message looping
uart pin_mode init moved to uart driver
This commit is contained in:
emuzit 2022-08-10 00:18:20 +08:00 committed by GitHub
parent 8cd7ee268f
commit 77067f8729
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 910 additions and 377 deletions

View File

@ -12,6 +12,9 @@ if GetDepend('SOC_SERIES_CH569'):
if GetDepend('RT_USING_WDT'):
src += ['ch56x_wdt.c']
if GetDepend('RT_USING_PWM'):
src += ['ch56x_pwm.c']
if GetDepend('RT_USING_HWTIMER'):
src += ['ch56x_timer.c']

View File

@ -0,0 +1,288 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-04 Emuzit first version
*/
#include <rthw.h>
#include <rtdebug.h>
#include <drivers/rt_drv_pwm.h>
#include <drivers/pin.h>
#include "ch56x_pwm.h"
#include "ch56x_sys.h"
#define PWM_CYCLE_MAX 255 // must be 255 for 0%~100% duty cycle
struct pwm_device
{
struct rt_device_pwm parent;
volatile struct pwm_registers *reg_base;
uint32_t period;
};
static struct pwm_device pwmx_device;
static const uint8_t pwmx_pin[] = {PWM0_PIN, PWM1_PIN, PWM2_PIN, PWM3_PIN};
/**
* @brief Enable or disable PWM channel output.
* Make sure PWM clock is ON for writing registers.
*
* @param device is pointer to the rt_device_pwm device.
*
* @param channel is the PWM channel (0~3) to operate on.
*
* @param enable is to enable PWM when RT_TRUE, or disable when RT_FALSE.
*
* @return None.
*/
static void pwm_channel_enable(struct rt_device_pwm *device,
uint32_t channel, rt_bool_t enable)
{
struct pwm_device *pwm_device = (struct pwm_device *)device;
volatile struct pwm_registers *pxreg = pwm_device->reg_base;
uint8_t ctrl_mod, polar;
if (enable)
{
/* set pwm_out_en to allow pwm output */
ctrl_mod = pxreg->CTRL_MOD.reg;
pxreg->CTRL_MOD.reg = ctrl_mod | (RB_PWM0_OUT_EN << channel);
}
else
{
/* ch56x has no disable bit, set pin out to quiesce */
ctrl_mod = pxreg->CTRL_MOD.reg;
polar = ctrl_mod & (RB_PWM0_POLAR << channel);
rt_pin_write(pwmx_pin[channel], polar ? PIN_HIGH : PIN_LOW);
ctrl_mod &= ~(RB_PWM0_OUT_EN << channel);
pxreg->CTRL_MOD.reg = ctrl_mod;
}
}
/**
* @brief Set period of the PWM channel.
* Make sure PWM clock is ON for writing registers.
*
* @param device is pointer to the rt_device_pwm device.
*
* @param channel is the PWM channel (0~3) to operate on.
*
* @param period is PWM period in nanoseconds.
*
* @return RT_EOK if successful.
*/
static rt_err_t pwm_channel_period(struct rt_device_pwm *device,
uint32_t channel, uint32_t period)
{
struct pwm_device *pwm_device = (struct pwm_device *)device;
uint32_t clock_div;
/* All ch56x PWMX channels share the same period, channel ignored.
*
* Max allowed period is when Fsys@2MHz and CLOCK_DIV is 0 (256) :
* (1 / 2MHz) * 256 * PWM_CYCLE_MAX => 32640000 ns
* Note that `period * F_MHz` won't overflow in calculation below.
*/
if (period > (256 * PWM_CYCLE_MAX * 1000 / 2))
return -RT_EINVAL;
if (period != pwm_device->period)
{
uint32_t Fsys = sys_hclk_get();
uint32_t F_MHz = Fsys / 1000000;
uint32_t F_mod = Fsys % 1000000;
/* period = (clock_div / Fsys) * 10^9 * PWM_CYCLE_MAX */
clock_div = period * F_MHz + (1000 * PWM_CYCLE_MAX / 2);
/* Fsys is mostly in integer MHz, likely to be skipped */
if (F_mod != 0)
{
uint64_t u64v = ((uint64_t)period * F_mod) / 1000000;
clock_div += (uint32_t)u64v;
}
clock_div = clock_div / (1000 * PWM_CYCLE_MAX);
if (clock_div > 256)
return -RT_EINVAL;
/* CLOCK_DIV will be 0 if `clock_div` is 256 */
pwm_device->reg_base->CLOCK_DIV = (uint8_t)clock_div;
/* cycle_sel set to PWM_CYCLE_SEL_255 for 0%~100% duty cycle */
pwmx_device.reg_base->CTRL_CFG.cycle_sel = PWM_CYCLE_SEL_255;
pwm_device->period = period;
}
return RT_EOK;
}
/**
* @brief Set pulse duration of the PWM channel.
* Make sure PWM clock is ON for writing registers.
*
* @param device is pointer to the rt_device_pwm device.
*
* @param channel is the PWM channel (0~3) to operate on.
*
* @param pulse is PWM pulse duration in nanoseconds.
*
* @return RT_EOK if successful.
*/
static rt_err_t pwm_channel_pulse(struct rt_device_pwm *device,
uint32_t channel, uint32_t pulse)
{
struct pwm_device *pwm_device = (struct pwm_device *)device;
uint32_t pdata, period;
/* duty cycle is calculated with "raw" period setting */
period = pwm_device->period;
if (!period || pulse > period)
return -RT_EINVAL;
pdata = (pulse * PWM_CYCLE_MAX + (period >> 1)) / period;
pwm_device->reg_base->PWM_DATA[channel] = pdata;
return RT_EOK;
}
/**
* @brief Set period & pulse of the PWM channel, remain disabled.
* Make sure PWM clock is ON for writing registers.
*
* @param device is pointer to the rt_device_pwm device.
*
* @param configuration is the channel/period/pulse specification.
* ch56x PWM has no complementary pin, complementary ignored.
* FIXME: can we specify PWM output polarity somehow ?
*
* @return RT_EOK if successful.
*/
static rt_err_t pwm_device_set(struct rt_device_pwm *device,
struct rt_pwm_configuration *configuration)
{
struct pwm_device *pwm_device = (struct pwm_device *)device;
uint32_t channel = configuration->channel;
rt_err_t res;
res = pwm_channel_period(device, channel, configuration->period);
if (res == RT_EOK)
{
res = pwm_channel_pulse(device, channel, configuration->pulse);
if (res == RT_EOK)
{
rt_pin_mode(pwmx_pin[channel], PIN_MODE_OUTPUT);
/* seems to be kept disabled according to sample code */
pwm_channel_enable(device, channel, RT_FALSE);
}
}
return res;
}
/**
* @brief Get period & pulse of the PWM channel.
* The returned information is calculated with h/w setting.
*
* @param device is pointer to the rt_device_pwm device.
*
* @param configuration->channel specify the PWM channel (0~3).
* configuration->period & pulse return the calculated result.
*
* @return RT_EOK if successful.
*/
static rt_err_t pwm_device_get(struct rt_device_pwm *device,
struct rt_pwm_configuration *configuration)
{
struct pwm_device *pwm_device = (struct pwm_device *)device;
volatile struct pwm_registers *pxreg = pwm_device->reg_base;
uint32_t channel = configuration->channel;
uint32_t Fsys = sys_hclk_get();
uint32_t clock_div;
uint32_t pdata;
uint64_t u64v;
/* clock_div is actually 256 when CLOCK_DIV is 0 */
clock_div = pxreg->CLOCK_DIV;
if (clock_div == 0)
clock_div = 256;
u64v = clock_div;
u64v = (u64v * 1000*1000*1000 * PWM_CYCLE_MAX + (Fsys >> 1)) / Fsys;
configuration->period = (uint32_t)u64v;
/* `pdata` <= PWM_CYCLE_MAX, calculated pulse won't exceed period */
pdata = pxreg->PWM_DATA[channel];
u64v = clock_div;
u64v = (u64v * 1000*1000*1000 * pdata + (Fsys >> 1)) / Fsys;
configuration->pulse = (uint32_t)u64v;
return RT_EOK;
}
static rt_err_t pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
{
struct pwm_device *pwm_device = (struct pwm_device *)device;
struct rt_pwm_configuration *configuration = arg;
uint32_t channel = configuration->channel;
rt_err_t res = RT_EOK;
RT_ASSERT(device != RT_NULL);
if (channel >= PWM_CHANNELS)
return -RT_EINVAL;
/* PWM clock needs to be ON to write PWM registers */
sys_slp_clk_off0(RB_SLP_CLK_PWMX, SYS_SLP_CLK_ON);
switch (cmd)
{
case PWM_CMD_ENABLE:
pwm_channel_enable(device, channel, RT_TRUE);
break;
case PWM_CMD_DISABLE:
pwm_channel_enable(device, channel, RT_FALSE);
break;
case PWM_CMD_SET:
return pwm_device_set(device, configuration);
case PWM_CMD_GET:
return pwm_device_get(device, configuration);
case PWM_CMD_SET_PERIOD:
return pwm_channel_period(device, channel, configuration->period);
case PWM_CMD_SET_PULSE:
return pwm_channel_pulse(device, channel, configuration->pulse);
default:
res = -RT_EINVAL;
}
/* disable PWMX clocking, if all channels are disabled */
if ((pwm_device->reg_base->CTRL_MOD.reg & PWM_OUT_EN_MASK) == 0)
sys_slp_clk_off0(RB_SLP_CLK_PWMX, SYS_SLP_CLK_OFF);
return res;
}
static struct rt_pwm_ops pwm_ops =
{
.control = pwm_control
};
static int rt_hw_pwm_init(void)
{
/* init pwmx_device with code to save some flash space */
pwmx_device.reg_base = (struct pwm_registers *)PWMX_REG_BASE;
/* Note: PWM clock OFF here => PWM registers not writable */
return rt_device_pwm_register(
&pwmx_device.parent, PWM_DEVICE_NAME, &pwm_ops, RT_NULL);
}
INIT_DEVICE_EXPORT(rt_hw_pwm_init);

View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-04 Emuzit first version
*/
#ifndef __CH56X_PWM_H__
#define __CH56X_PWM_H__
#include "soc.h"
#include "ch56x_gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PWM_DEVICE_NAME "pwmx"
#define PWM_CHANNELS 4
#define PWM0_PIN GET_PIN(B, 15)
#define PWM1_PIN GET_PIN(A, 4)
#define PWM2_PIN GET_PIN(B, 1)
#define PWM3_PIN GET_PIN(B, 2)
union _pwm_ctrl_mod
{
uint8_t reg;
struct
{
uint8_t pwm0_out_en : 1; // RW, PWM output enable
uint8_t pwm1_out_en : 1;
uint8_t pwm2_out_en : 1;
uint8_t pwm3_out_en : 1;
uint8_t pwm0_polar : 1; // RW, PWM output polarity
uint8_t pwm1_polar : 1;
uint8_t pwm2_polar : 1;
uint8_t pwm3_polar : 1;
};
};
#define RB_PWM0_OUT_EN 0x01
#define RB_PWM1_OUT_EN 0x02
#define RB_PWM2_OUT_EN 0x04
#define RB_PWM3_OUT_EN 0x08
#define RB_PWM0_POLAR 0x10
#define RB_PWM1_POLAR 0x20
#define RB_PWM2_POLAR 0x40
#define RB_PWM3_POLAR 0x80
#define PWM_OUT_EN_MASK 0x0f
union _pwm_ctrl_cfg
{
uint8_t reg;
struct
{
uint8_t cycle_sel : 1; // RW, PWM cycle select, 0/1 for 256/255
uint8_t resv_1 : 7;
};
};
#define RB_PWM_CYCLE_SEL 0x01
#define PWM_CYCLE_SEL_256 0
#define PWM_CYCLE_SEL_255 1
/*
* 0x00 R8_PWM_CTRL_MOD: PWM control register
* 0x01 R8_PWM_CTRL_CFG: PWM control configuration register
* 0x02 R8_PWM_CLOCK_DIV: PWM clock divisor register
* 0x04 R8_PWM0_DATA: PWM0 data holding register
* 0x05 R8_PWM1_DATA: PWM1 data holding register
* 0x06 R8_PWM2_DATA: PWM2 data holding register
* 0x07 R8_PWM3_DATA: PWM3 data holding register
*/
struct pwm_registers
{
union _pwm_ctrl_mod CTRL_MOD;
union _pwm_ctrl_cfg CTRL_CFG;
uint8_t CLOCK_DIV;
uint8_t resv_3;
union
{
uint32_t R32_PWM_DATA;
uint8_t PWM_DATA[4];
struct
{
uint8_t PWM0_DATA;
uint8_t PWM1_DATA;
uint8_t PWM2_DATA;
uint8_t PWM3_DATA;
};
};
};
CHECK_STRUCT_SIZE(struct pwm_registers, 8);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -164,11 +164,25 @@ static rt_err_t spi_configure(struct rt_spi_device *device, struct rt_spi_config
return RT_EOK;
}
static rt_uint32_t _spi_xfer_1(struct rt_spi_device *device, struct rt_spi_message *message)
/**
* @brief Transfer SPI data for single message.
* Message traversing is done by rt_spi_message().
*
* @param device is pointer to the rt_spi_device device.
*
* @param message is a link list for data/control information,
* only the first entry is processed.
* Note: ch56x can't do SPI send & recv at the same time.
*
* @return `message->length1 if successful, 0 otherwise.
*/
static rt_uint32_t spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
struct spi_bus *spi_bus = (struct spi_bus *)device->bus;
volatile struct spi_registers *sxreg = spi_bus->reg_base;
union _spi_ctrl_mod ctrl_mod;
uint8_t *data;
uint32_t size;
@ -179,22 +193,28 @@ static rt_uint32_t _spi_xfer_1(struct rt_spi_device *device, struct rt_spi_messa
if (size == 0 || size > 4095)
return 0;
ctrl_mod.reg = sxreg->CTRL_MOD.reg | RB_SPI_ALL_CLEAR;
/* ch56x can't do SPI send & recv at the same time */
if (message->send_buf && !message->recv_buf)
{
data = (uint8_t *)message->send_buf;
sxreg->CTRL_MOD.fifo_dir = SPI_FIFO_DIR_OUTPUT;
ctrl_mod.fifo_dir = SPI_FIFO_DIR_OUTPUT;
}
else if (!message->send_buf && message->recv_buf)
{
data = (uint8_t *)message->recv_buf;
sxreg->CTRL_MOD.fifo_dir = SPI_FIFO_DIR_INPUT;
ctrl_mod.fifo_dir = SPI_FIFO_DIR_INPUT;
}
else
{
return 0;
}
sxreg->CTRL_MOD.reg = ctrl_mod.reg;
ctrl_mod.all_clear = 0;
sxreg->CTRL_MOD.reg = ctrl_mod.reg;
/* set MISO pin direction to match xfer if shared SI/SO pin */
if (device->config.mode & RT_SPI_3WIRE)
{
@ -202,7 +222,7 @@ static rt_uint32_t _spi_xfer_1(struct rt_spi_device *device, struct rt_spi_messa
rt_pin_mode(spi_bus->miso_pin, mode);
}
cs_pin = (rt_base_t)device->user_data;
cs_pin = (rt_base_t)device->parent.user_data;
cs_high = device->config.mode & RT_SPI_CS_HIGH;
if (message->cs_take)
@ -236,6 +256,8 @@ static rt_uint32_t _spi_xfer_1(struct rt_spi_device *device, struct rt_spi_messa
/* wait for transfer done */
while (sxreg->TOTAL_COUNT > 0);
/* disable DMA, anyway */
sxreg->CTRL_CFG.dma_enable = 0;
/* non-DMA recv => read data from FIFO */
if (size > 0)
@ -259,26 +281,6 @@ static rt_uint32_t _spi_xfer_1(struct rt_spi_device *device, struct rt_spi_messa
return message->length;
}
static rt_uint32_t spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
uint32_t total_xsize = 0;
uint32_t xsize;
RT_ASSERT(device != NULL);
RT_ASSERT(message != NULL);
while (message != RT_NULL)
{
xsize = _spi_xfer_1(device, message);
if (xsize != message->length)
return 0;
total_xsize += xsize;
message = message->next;
}
return total_xsize;
}
static const struct rt_spi_ops spi_ops =
{
.configure = spi_configure,

View File

@ -179,9 +179,6 @@ union _spi_int_flag
* 0x14 R32_SPIx_DMA_NOW: SPI DMA current address
* 0x18 R32_SPIx_DMA_BEG: SPI DMA start address
* 0x1c R32_SPIx_DMA_END: SPI DMA end address
*
* 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 spi_registers
{

View File

@ -101,12 +101,15 @@ void sys_slp_clk_off0(uint8_t bits, int off)
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);
if ((u8v & bits) != (off ? bits : 0))
{
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);
}
}
/**
@ -123,12 +126,15 @@ void sys_slp_clk_off1(uint8_t bits, int off)
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);
if ((u8v & bits) != (off ? bits : 0))
{
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);
}
}
/**
@ -171,12 +177,15 @@ int sys_clk_off_by_irqn(uint8_t irqn, int off)
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);
if ((u8v & bitpos) != (off ? bitpos : 0))
{
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);
}
}
}

View File

@ -16,6 +16,7 @@
#else
#include <drivers/serial.h>
#endif
#include <drivers/pin.h>
#include "ch56x_sys.h"
#include "ch56x_uart.h"
#include "isr_sp.h"
@ -25,11 +26,17 @@
#error "Please define at least one UARTx"
#endif
/* Type of irqn/rxd_pin/txd_pin are per uart driver perspective
* to save some space, still compatible to RT api call, anyway.
*/
struct serial_device
{
struct rt_serial_device parent;
volatile struct uart_registers *reg_base;
irq_number_t irqn;
uint8_t irqn;
uint8_t resv;
uint8_t rxd_pin;
uint8_t txd_pin;
char *name;
};
@ -38,6 +45,8 @@ static struct serial_device serial_device_0 =
{
.reg_base = (struct uart_registers *)UART0_REG_BASE,
.irqn = UART0_IRQn,
.rxd_pin = UART_RXD0_PIN,
.txd_pin = UART_TXD0_PIN,
.name = "uart0",
};
#endif
@ -47,6 +56,8 @@ static struct serial_device serial_device_1 =
{
.reg_base = (struct uart_registers *)UART1_REG_BASE,
.irqn = UART1_IRQn,
.rxd_pin = UART_RXD1_PIN,
.txd_pin = UART_TXD1_PIN,
.name = "uart1",
};
#endif
@ -56,6 +67,8 @@ static struct serial_device serial_device_2 =
{
.reg_base = (struct uart_registers *)UART2_REG_BASE,
.irqn = UART2_IRQn,
.rxd_pin = UART_RXD2_PIN,
.txd_pin = UART_TXD2_PIN,
.name = "uart2",
};
#endif
@ -65,6 +78,8 @@ static struct serial_device serial_device_3 =
{
.reg_base = (struct uart_registers *)UART3_REG_BASE,
.irqn = UART3_IRQn,
.rxd_pin = UART_RXD3_PIN,
.txd_pin = UART_TXD3_PIN,
.name = "uart3",
};
#endif
@ -233,15 +248,25 @@ int rt_hw_uart_init(void)
devices[n++] = &serial_device_0;
#endif
/* IMPORTANT: pin mode should be set properly @ board init */
while (--n >= 0)
{
uint32_t flag;
uint32_t flag, txd_pin, rxd_pin;
struct serial_device *serial = devices[n];
serial->parent.ops = &uart_ops;
serial->parent.config = config;
txd_pin = serial->txd_pin;
rxd_pin = serial->rxd_pin;
#ifdef BSP_USING_UART0_PIN_ALT
if (serial->irqn == UART0_IRQn)
{
txd_pin = UART_TXD0_ALT;
rxd_pin = UART_RXD0_ALT;
}
#endif
rt_pin_mode(txd_pin, PIN_MODE_OUTPUT);
rt_pin_mode(rxd_pin, PIN_MODE_INPUT_PULLUP);
sys_clk_off_by_irqn(serial->irqn, SYS_SLP_CLK_ON);
flag = RT_DEVICE_FLAG_RDWR |

View File

@ -11,11 +11,24 @@
#define __CH56X_UART_H__
#include "soc.h"
#include "ch56x_gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
#define UART_RXD0_ALT GET_PIN(A, 5)
#define UART_TXD0_ALT GET_PIN(A, 6)
#define UART_RXD0_PIN GET_PIN(B, 5)
#define UART_TXD0_PIN GET_PIN(B, 6)
#define UART_RXD1_PIN GET_PIN(A, 7)
#define UART_TXD1_PIN GET_PIN(A, 8)
#define UART_RXD2_PIN GET_PIN(A, 2)
#define UART_TXD2_PIN GET_PIN(A, 3)
#define UART_RXD3_PIN GET_PIN(B, 3)
#define UART_TXD3_PIN GET_PIN(B, 4)
#ifndef UART_FIFO_SIZE
#define UART_FIFO_SIZE 8
#endif

View File

@ -13,6 +13,7 @@
#include <stdint.h>
#include <stddef.h>
#include <assert.h>
#include <rtdef.h>
#if !defined(SOC_CH567) && \
!defined(SOC_CH568) && \

View File

@ -110,7 +110,7 @@ CONFIG_RT_USING_SERIAL_V1=y
# 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_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
# CONFIG_RT_USING_PHY is not set
@ -123,14 +123,8 @@ CONFIG_RT_USING_PIN=y
# 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=y
# CONFIG_RT_USING_SPI_BITOPS is not set
# CONFIG_RT_USING_QSPI is not set
# CONFIG_RT_USING_SPI_MSD is not set
# CONFIG_RT_USING_SFUD is not set
# CONFIG_RT_USING_ENC28J60 is not set
# CONFIG_RT_USING_SPI_WIFI is not set
CONFIG_RT_USING_WDT=y
# CONFIG_RT_USING_SPI is not set
# CONFIG_RT_USING_WDT is not set
# CONFIG_RT_USING_AUDIO is not set
# CONFIG_RT_USING_SENSOR is not set
# CONFIG_RT_USING_TOUCH is not set
@ -313,6 +307,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# CONFIG_PKG_USING_RAPIDJSON is not set
# CONFIG_PKG_USING_JSMN is not set
# CONFIG_PKG_USING_AGILE_JSMN is not set
# CONFIG_PKG_USING_PARSON is not set
#
# XML: Extensible Markup Language
@ -491,8 +486,10 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
# 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_ADT74XX is not set
# CONFIG_PKG_USING_AS7341 is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_RTT_ESP_IDF is not set
# CONFIG_PKG_USING_ICM20608 is not set
# CONFIG_PKG_USING_BUTTON is not set
# CONFIG_PKG_USING_PCF8574 is not set
@ -656,13 +653,8 @@ CONFIG_BSP_USING_UART=y
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
CONFIG_BSP_USING_SPI=y
CONFIG_BSP_USING_SPI0=y
# CONFIG_BSP_USING_SPI1 is not set
# CONFIG_BSP_USING_TIMER is not set
# CONFIG_BSP_USING_SPI is not set
#
# Onboard Peripheral Drivers

View File

@ -5,304 +5,23 @@
*
* 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
* 2022-07-30 Emuzit add spi master test
* 2018-11-27 balanceTWK first version
*/
#include <rtthread.h>
#include <rtdebug.h>
#include <rtdevice.h>
#include <drivers/pin.h>
#include <drivers/watchdog.h>
#include <drivers/hwtimer.h>
#include <drivers/spi.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_device_t wdg_dev;
static rt_base_t led0, led1;
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
}
}
static void test_gpio_int(void)
{
rt_err_t res;
int i;
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LED1_PIN, led1 = PIN_HIGH);
/* 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
static void test_watchdog(uint32_t seconds)
{
/* 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);
}
}
#else
#define test_watchdog(tov) do {} while(0)
#endif
#ifdef RT_USING_HWTIMER
static struct rt_device *tmr_dev_0;
static struct rt_device *tmr_dev_1;
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;
}
static void test_hwtimer(void)
{
rt_hwtimerval_t timerval;
rt_hwtimer_mode_t mode;
rt_size_t tsize;
/* 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\n");
}
}
}
#else
#define test_hwtimer() do {} while(0)
#endif
#ifdef RT_USING_SPI
static struct rt_spi_device spi_dev_w25q;
static void test_spi_master(void)
{
struct rt_spi_configuration cfg;
struct rt_spi_message msg1, msg2;
rt_err_t res;
uint8_t buf[16];
cfg.max_hz = 25 * 1000000;
cfg.data_width = 8;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB | RT_SPI_CS_HIGH;
res = rt_spi_bus_attach_device(
&spi_dev_w25q, W25Q32_SPI_NAME, SPI0_BUS_NAME, (void *)W25Q32_CS_PIN);
if (res == RT_EOK && rt_spi_configure(&spi_dev_w25q, &cfg) == RT_EOK)
{
/* cmd : Read Manufacturer / Device ID (90h) */
buf[0] = 0x90;
/* address : 0 */
buf[1] = buf[2] = buf[3] = 0;
msg1.send_buf = buf;
msg1.recv_buf = RT_NULL;
msg1.length = 4;
msg1.cs_take = 1;
msg1.cs_release = 0;
msg1.next = &msg2;
msg2.send_buf = RT_NULL;
msg2.recv_buf = buf;
msg2.length = 2;
msg2.cs_take = 0;
msg2.cs_release = 1;
msg2.next = RT_NULL;
rt_spi_transfer_message(&spi_dev_w25q, &msg1);
rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", buf[0], buf[1]);
/* cmd : Read Data (03h) */
buf[0] = 0x03;
/* address : 0 */
buf[1] = buf[2] = buf[3] = 0;
msg2.length = 16;
if (rt_spi_transfer_message(&spi_dev_w25q, &msg1) == RT_NULL)
{
rt_kprintf("rt_spi_transfer_message() 16-byte-read DMA done\n\n");
}
}
else
{
rt_kprintf("w25q32 attach/configure failed (%d) !\n", res);
}
}
#else
#define test_spi_master() do {} while(0)
#endif
void main(void)
{
uint32_t wdog_timeout = 32;
rt_kprintf("\nCH569W-R0-1v0, HCLK: %dMHz\n\n", sys_hclk_get() / 1000000);
test_gpio_int();
test_watchdog(wdog_timeout);
test_hwtimer();
test_spi_master();
/* set LED0 pin mode to output */
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LED0_PIN, led0 = PIN_LOW);
while (1)
{
/* flashing LED0 every 1 second */
rt_pin_write(LED0_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED0_PIN, PIN_LOW);
rt_thread_mdelay(500);
led0 = (led0 == PIN_LOW) ? PIN_HIGH : PIN_LOW;
rt_pin_write(LED0_PIN, led0);
}
}

View File

@ -0,0 +1,386 @@
/*
* 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
* 2022-07-30 Emuzit add spi master test
* 2022-08-04 Emuzit add pwm test
*/
#include <rtthread.h>
#include <rtdebug.h>
#include <drivers/pin.h>
#include <drivers/watchdog.h>
#include <drivers/hwtimer.h>
#include <drivers/spi.h>
#include <drivers/rt_drv_pwm.h>
#include "board.h"
#define PWM_CYCLE_MAX 255
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_device_t wdg_dev;
static rt_base_t led0, led1;
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
}
}
static void test_gpio_int(void)
{
rt_err_t res;
int i;
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LED1_PIN, led1 = PIN_HIGH);
/* 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];
#ifdef RT_USING_PWM
if (pin == PWM0_PIN || pin == PWM1_PIN)
continue;
#endif
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
static void test_watchdog(uint32_t seconds)
{
/* 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);
}
}
#else
#define test_watchdog(tov) do {} while(0)
#endif
#ifdef RT_USING_HWTIMER
static struct rt_device *tmr_dev_0;
static struct rt_device *tmr_dev_1;
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;
}
static void test_hwtimer(void)
{
rt_hwtimerval_t timerval;
rt_hwtimer_mode_t mode;
rt_size_t tsize;
/* 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\n");
}
}
}
#else
#define test_hwtimer() do {} while(0)
#endif
#ifdef RT_USING_SPI
static struct rt_spi_device spi_dev_w25q;
static void test_spi_master(void)
{
struct rt_spi_configuration cfg;
struct rt_spi_message msg1, msg2;
rt_err_t res;
uint8_t buf[16];
int i;
cfg.max_hz = 25 * 1000000;
cfg.data_width = 8;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
res = rt_spi_bus_attach_device(
&spi_dev_w25q, W25Q32_SPI_NAME, SPI0_BUS_NAME, (void *)W25Q32_CS_PIN);
if (res == RT_EOK && rt_spi_configure(&spi_dev_w25q, &cfg) == RT_EOK)
{
/* cmd : Read Manufacturer / Device ID (90h) */
buf[0] = 0x90;
/* address : 0 */
buf[1] = buf[2] = buf[3] = 0;
msg1.send_buf = buf;
msg1.recv_buf = RT_NULL;
msg1.length = 4;
msg1.cs_take = 1;
msg1.cs_release = 0;
msg1.next = &msg2;
msg2.send_buf = RT_NULL;
msg2.recv_buf = buf;
msg2.length = 2;
msg2.cs_take = 0;
msg2.cs_release = 1;
msg2.next = RT_NULL;
rt_spi_transfer_message(&spi_dev_w25q, &msg1);
rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", buf[0], buf[1]);
/* cmd : Read Data (03h) */
buf[0] = 0x03;
/* address : 0 */
buf[1] = buf[2] = buf[3] = 0;
msg2.length = 16;
if (rt_spi_transfer_message(&spi_dev_w25q, &msg1) == RT_NULL)
{
rt_kprintf("SPI0 16-byte DMA read :");
for (i = 0; i < 16; i++)
rt_kprintf(" %02x", buf[i]);
rt_kprintf("\n\n");
}
}
else
{
rt_kprintf("w25q32 attach/configure failed (%d) !\n", res);
}
}
#else
#define test_spi_master() do {} while(0)
#endif
#ifdef RT_USING_PWM
static struct rt_device_pwm *pwm_dev;
static uint32_t pwm_period;
rt_err_t rt_pwm_get(struct rt_device_pwm *device,
struct rt_pwm_configuration *cfg);
static void pwm_tick_hook(void)
{
uint32_t pulse;
if (pwm_dev)
{
/* PWM.CH3 duty cycle : 0%->100% for every ~2.5 seconds */
pulse = (rt_tick_get() >> 1) % (PWM_CYCLE_MAX + 1);
pulse = (pwm_period * pulse + PWM_CYCLE_MAX/2) / PWM_CYCLE_MAX;
rt_pwm_set_pulse(pwm_dev, 3, pulse);
}
}
static void test_pwm(void)
{
struct rt_pwm_configuration cfg;
uint32_t pulse[4];
int ch;
pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEVICE_NAME);
if (pwm_dev == RT_NULL)
{
rt_kprintf("can't find %s device !\n", PWM_DEVICE_NAME);
}
else
{
/* for HCLK@80MHz, allowed period is 3187 ~ 812812 */
pwm_period = 800*1000;
pulse[0] = 100*1000;
pulse[1] = 400*1000;
pulse[2] = 600*1000;
pulse[3] = 0;
for (ch = 0; ch < PWM_CHANNELS; ch++)
{
rt_pwm_set(pwm_dev, ch, pwm_period, pulse[ch]);
rt_pwm_enable(pwm_dev, ch);
cfg.channel = ch;
rt_pwm_get(pwm_dev, &cfg);
rt_kprintf("pwm%d period set/get : %d/%d\n", ch, pwm_period, cfg.period);
rt_kprintf("pwm%d pulse set/get : %d/%d\n\n", ch, pulse[ch], cfg.pulse);
}
/* disable PWM.CH0 after 1 second, also start changing CH3 */
rt_thread_mdelay(1000);
rt_pwm_disable(pwm_dev, 0);
/* connect PWM3 (PB.2) to LED2 for a visualized PWM effect */
rt_pin_mode(LED2_PIN, PIN_MODE_INPUT);
rt_tick_sethook(pwm_tick_hook);
}
}
#else
#define test_pwm() do {} while(0)
#endif
void main(void)
{
uint32_t wdog_timeout = 32;
rt_kprintf("\nCH569W-R0-1v0, HCLK: %dMHz\n\n", sys_hclk_get() / 1000000);
test_gpio_int();
test_watchdog(wdog_timeout);
test_hwtimer();
test_spi_master();
test_pwm();
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);
}
}

View File

@ -17,20 +17,25 @@ config BSP_USING_UART
if BSP_USING_UART
config BSP_USING_UART0
bool "using UART0"
default n
bool "using UART0"
default n
if BSP_USING_UART0
config BSP_USING_UART0_PIN_ALT
bool "UART0 PIN_ALTERNATE (PA5/PA6)"
default n
endif
config BSP_USING_UART1
bool "using UART1"
default y
bool "using UART1"
default y
config BSP_USING_UART2
bool "using UART2"
default n
bool "using UART2"
default n
config BSP_USING_UART3
bool "using UART3"
default n
bool "using UART3"
default n
endif
config BSP_USING_TIMER
@ -40,16 +45,16 @@ config BSP_USING_TIMER
if BSP_USING_TIMER
config BSP_USING_TMR0
bool "using TMR0"
default y
bool "using TMR0"
default n
config BSP_USING_TMR1
bool "using TMR1"
default n
bool "using TMR1"
default n
config BSP_USING_TMR2
bool "using TMR2"
default n
bool "using TMR2"
default n
endif
config BSP_USING_SPI

View File

@ -69,9 +69,6 @@ void rt_hw_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

View File

@ -14,6 +14,7 @@
#include "ch56x_sys.h"
#include "ch56x_gpio.h"
#include "ch56x_spi.h"
#include "ch56x_pwm.h"
#define LED0_PIN GET_PIN(B, 24)
#define LED1_PIN GET_PIN(B, 22)

View File

@ -70,10 +70,7 @@
#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_SPI
#define RT_USING_WDT
/* Using USB */
@ -181,11 +178,6 @@
#define BSP_USING_UART
#define BSP_USING_UART1
#define BSP_USING_TIMER
#define BSP_USING_TMR0
#define BSP_USING_TMR1
#define BSP_USING_SPI
#define BSP_USING_SPI0
/* Onboard Peripheral Drivers */