diff --git a/bsp/essemi/es32f0334/README.md b/bsp/essemi/es32f0334/README.md index a315447dda..369676b7d6 100644 --- a/bsp/essemi/es32f0334/README.md +++ b/bsp/essemi/es32f0334/README.md @@ -110,7 +110,7 @@ msh > ## 4. 联系人信息 -- [wangyongquan](https://github.com/wangyq2018) +- [liuhongyan](https://gitee.com/liuhongyan98) ## 5. 参考 diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/.gitignore b/bsp/essemi/es32f0334/drivers/bsp_driver_example/.gitignore new file mode 100644 index 0000000000..c6127b38c1 --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/README.md b/bsp/essemi/es32f0334/drivers/bsp_driver_example/README.md new file mode 100644 index 0000000000..80f12e1949 --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/README.md @@ -0,0 +1,47 @@ +# 外设驱动测试用例 + +## 1、介绍 + +这个软件包包含一些外设设备操作的例程。 + +### 1.1 例程说明 + +| 文件 | 说明 | +| ---------------- | ------------------------------- | +| adc_vol_sample.c | 使用 ADC 设备转换电压数据 | +| can_sample.c | 通过 CAN 设备发送一帧,并创建一个线程接收数据然后打印输出。 | +| hwtimer_sample.c | 使用 硬件定时器定时 | +| i2c_sample.c | 使用 i2c 设备进行读写 | +| pm.c | 反复进入不同程度的睡眠。 | +| led_blink_sample.c | 使用 pin 设备控制 LED 闪烁 | +| pin_beep_sample.c | 使用 pin 设备控制蜂鸣器 | +| pwm_led_sample.c | 使用 pwm 设备控制 LED 的亮度 | +| rtc_sample.c | 使用 rtc 设备设置年月日时分秒信息 | +| spi_sample.c | 使用 spi 设备进行读写 | +| uart_sample.c | 使用 serial 设备中断接收及轮询发送模式收发数据 | + +### 1.2 依赖 + +依赖设备管理模块提供的设备驱动。 + +## 2、如何打开 外设驱动测试用例 + +使用 外设驱动测试用例 需要在 RT-Thread 的menuconfig中选择它,具体路径如下: + +``` +Hardware Driver Config ---> + Peripheral Driver test example---> +``` + +## 3、使用 外设驱动测试用例 + +在打开 Peripheral Driver test example 后,当进行 BSP 编译时,选择的软件包相关源代码会被加入到 BSP 工程中进行编译。 + +## 4、注意事项 + +暂无。 + +## 5、联系方式 & 感谢 + +* 维护:[misonyo](https://github.com/misonyo) +* 主页:https://github.com/RT-Thread-packages/peripheral-sample diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/adc_vol_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/adc_vol_sample.c new file mode 100644 index 0000000000..19eed3f35d --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/adc_vol_sample.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-29 misonyo first implementation. + */ +/* + * 程序清单: ADC 设备使用例程 + * 例程导出了 adc_sample 命令到控制终端 + * 命令调用格式:adc_sample + * 程序功能:通过 ADC 设备采样电压值并转换为数值。 + * 示例代码参考电压为3.3V,转换位数为12位。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define ADC_DEV_NAME "adc0" /* ADC 设备名称 */ +#define ADC_DEV_CHANNEL 5 /* PA1 ADC 通道 */ +#define REFER_VOLTAGE 330 /* 参考电压 3.3V,数据精度乘以100保留2位小数*/ +#define CONVERT_BITS (1 << 12) /* 转换位数为12位 */ + +static int adc_vol_sample(int argc, char *argv[]) +{ + rt_adc_device_t adc_dev; + rt_uint32_t value, vol; + rt_err_t ret = RT_EOK; + + /* 查找设备 */ + adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME); + if (adc_dev == RT_NULL) + { + rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME); + return RT_ERROR; + } + + /* 使能设备 */ + ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL); + + /* 读取采样值 */ + value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL); + rt_kprintf("the value is :%d \n", value); + + /* 转换为对应电压值 */ + vol = value * REFER_VOLTAGE / CONVERT_BITS; + rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100); + + /* 关闭通道 */ + ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL); + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/can_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/can_sample.c new file mode 100644 index 0000000000..e63b11451d --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/can_sample.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-06-25 misonyo first implementation. + */ +/* + * 程序清单:这是一个 CAN 设备使用例程 + * 例程导出了 can_sample 命令到控制终端 + * 命令调用格式:can_sample can2 + * 命令解释:命令第二个参数是要使用的 CAN 设备名称,为空则使用默认的 CAN 设备 + * 程序功能:通过 CAN 设备发送一帧,并创建一个线程接收数据然后打印输出。 +*/ + +#include <rtthread.h> +#include "rtdevice.h" + +#define CAN_DEV_NAME "can2" /* CAN 设备名称 */ + +static struct rt_semaphore rx_sem; /* 用于接收消息的信号量 */ +static rt_device_t can_dev; /* CAN 设备句柄 */ + +/* 接收数据回调函数 */ +static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size) +{ + /* CAN 接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ + rt_sem_release(&rx_sem); + + return RT_EOK; +} + +static void can_rx_thread(void *parameter) +{ + int i; + struct rt_can_msg rxmsg = {0}; + + /* 设置接收回调函数 */ + rt_device_set_rx_indicate(can_dev, can_rx_call); + +#ifdef RT_CAN_USING_HDR + + rt_err_t res; + + struct rt_can_filter_item items[5] = + { + RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x100~0x1ff,hdr为-1,设置默认过滤表 */ + RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x300~0x3ff,hdr为-1 */ + RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 0, 0x7ff, RT_NULL, RT_NULL), /* std,match ID:0x211,hdr为-1 */ + RT_CAN_FILTER_STD_INIT(0x486, RT_NULL, RT_NULL), /* std,match ID:0x486,hdr为-1 */ + {0x555, 0, 0, 0, 0x7ff, 7,} /* std,match ID:0x555,hdr为7,指定设置7号过滤表 */ + }; + struct rt_can_filter_config cfg = {5, 1, items}; /* 一共有5个过滤表 */ + /* 设置硬件过滤表 */ + res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg); + RT_ASSERT(res == RT_EOK); +#endif + + while (1) + { + /* hdr值为-1,表示直接从uselist链表读取数据 */ + rxmsg.hdr = -1; + /* 阻塞等待接收信号量 */ + rt_sem_take(&rx_sem, RT_WAITING_FOREVER); + /* 从CAN读取一帧数据 */ + rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg)); + /* 打印数据ID及内容 */ + rt_kprintf("ID:%x ", rxmsg.id); + for (i = 0; i < 8; i++) + { + rt_kprintf("%2x ", rxmsg.data[i]); + } + + rt_kprintf("\n"); + } +} + +int can_sample(int argc, char *argv[]) +{ + struct rt_can_msg msg = {0}; + rt_err_t res; + rt_size_t size; + rt_thread_t thread; + char can_name[RT_NAME_MAX]; + + if (argc == 2) + { + rt_strncpy(can_name, argv[1], RT_NAME_MAX); + } + else + { + rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX); + } + + can_dev = rt_device_find(can_name); + if (!can_dev) + { + rt_kprintf("find %s failed!\n", can_name); + return RT_ERROR; + } + + /* 初始化CAN接收信号量 */ + rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); + + /* 以中断接收及发送方式打开CAN设备 */ + res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX); + RT_ASSERT(res == RT_EOK); + + thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10); + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + rt_kprintf("create can_rx thread failed!\n"); + } + + msg.id = 0x78; /* ID为0x78 */ + msg.ide = RT_CAN_STDID; /* 标准格式 */ + msg.rtr = RT_CAN_DTR; /* 数据帧 */ + msg.len = 8; /* 数据长度为8 */ + /* 待发送的8字节数据 */ + msg.data[0] = 0x00; + msg.data[1] = 0x11; + msg.data[2] = 0x22; + msg.data[3] = 0x33; + msg.data[4] = 0x44; + msg.data[5] = 0x55; + msg.data[6] = 0x66; + msg.data[7] = 0x77; + /* 发送一帧CAN数据 */ + size = rt_device_write(can_dev, 0, &msg, sizeof(msg)); + if (size == 0) + { + rt_kprintf("can dev write data failed!\n"); + } + + return res; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(can_sample, can device sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/hwtimer_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/hwtimer_sample.c new file mode 100644 index 0000000000..e2e39664f3 --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/hwtimer_sample.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-30 misonyo first implementation. + */ +/* + * 程序清单:这是一个 hwtimer 设备使用例程 + * 例程导出了 hwtimer_sample 命令到控制终端 + * 命令调用格式:hwtimer_sample + * 程序功能:硬件定时器超时回调函数周期性的打印当前tick值,2次tick值之差换算为时间等同于定时时间值。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define HWTIMER_DEV_NAME "timer0" /* 定时器名称 */ + +/* 定时器超时回调函数 */ +static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size) +{ + rt_kprintf("tick is :%d !\n", rt_tick_get()); + + return 0; +} + +static int hwtimer_sample(int argc, char *argv[]) +{ + rt_err_t ret = RT_EOK; + rt_hwtimerval_t timeout_s; /* 定时器超时值 */ + rt_device_t hw_dev = RT_NULL; /* 定时器设备句柄 */ + rt_hwtimer_mode_t mode; /* 定时器模式 */ + + /* 查找定时器设备 */ + hw_dev = rt_device_find(HWTIMER_DEV_NAME); + if (hw_dev == RT_NULL) + { + rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_NAME); + return RT_ERROR; + } + + /* 以读写方式打开设备 */ + ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR); + if (ret != RT_EOK) + { + rt_kprintf("open %s device failed!\n", HWTIMER_DEV_NAME); + return ret; + } + + /* 设置超时回调函数 */ + rt_device_set_rx_indicate(hw_dev, timeout_cb); + + /* 设置模式为周期性定时器 */ + mode = HWTIMER_MODE_PERIOD; + ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode); + if (ret != RT_EOK) + { + rt_kprintf("set mode failed! ret is :%d\n", ret); + return ret; + } + + /* 设置定时器超时值为5s并启动定时器 */ + timeout_s.sec = 5; /* 秒 */ + timeout_s.usec = 0; /* 微秒 */ + + if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s)) + { + rt_kprintf("set timeout value failed\n"); + return RT_ERROR; + } + + /* 延时3500ms */ + rt_thread_mdelay(3500); + + /* 读取定时器当前值 */ + rt_device_read(hw_dev, 0, &timeout_s, sizeof(timeout_s)); + rt_kprintf("Read: Sec = %d, Usec = %d\n", timeout_s.sec, timeout_s.usec); + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(hwtimer_sample, hwtimer sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/i2c_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/i2c_sample.c new file mode 100644 index 0000000000..2d386433c6 --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/i2c_sample.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy first implementation. + */ +/* + * 程序清单:这是一个 I2C 设备使用例程 + * 例程导出了 i2c_io_sample 命令到控制终端 + * 命令调用格式:i2c_io_sample + * 命令解释:使用默认的I2C总线设备 + * 程序功能:通过 I2C 设备接收数据并打印,然后将接收的字符加1输出。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define I2C_BUS_NAME "i2c1" /* I2C总线设备名称 */ +#define SLAVE_ADDR 0x2D /* 从机地址 */ +#define STR_LEN 16 /* 接收发送的数据长度 */ + +static void i2c_io_sample(int argc, char *argv[]) +{ + + struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄 */ + struct rt_i2c_msg temp_msg; /* I2C消息 */ + rt_uint8_t buffer[STR_LEN] = { 0U }; + rt_uint32_t i,num_msg; + rt_size_t s_stat; + + i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(I2C_BUS_NAME); /* 通过名字获取I2C总线设备的句柄 */ + + if( i2c_bus == RT_NULL) + { + rt_kprintf("can't find i2c device :%s !\n",I2C_BUS_NAME); + + return; + } + + /*初始化消息*/ + temp_msg.addr = SLAVE_ADDR; /* 从机地址 */ + temp_msg.len = STR_LEN; /* 传输的数据长度 */ + temp_msg.buf = buffer; /* 读写缓存器 */ + + num_msg = 1; /* 传输一条消息 */ + + temp_msg.flags = RT_I2C_RD; /* I2C读 */ + s_stat = rt_i2c_transfer(i2c_bus,&temp_msg,num_msg); /* 传输消息 */ + + rt_thread_mdelay(400); + + if( s_stat == num_msg ) + { + rt_kprintf("receive successful. \n receive messege : %s \n:",buffer); + + for( i = 0 ; i < STR_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + } + else + { + rt_kprintf("device s% recieve fail \n buffer : s%\n",I2C_BUS_NAME,buffer); + return; + } + + for( i = 0 ; i < STR_LEN ; i++) + buffer[i]++; + + temp_msg.flags = RT_I2C_WR; /* I2C写 */ + s_stat = rt_i2c_transfer(i2c_bus,&temp_msg,num_msg); /* 传输一条 */ + + rt_thread_mdelay(400); + + if( s_stat == num_msg ) + { + rt_kprintf(" send successful \n messege : %s \n:",buffer); + + for( i = 0 ; i < STR_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + } + else + { + rt_kprintf("device s% send fail \n",I2C_BUS_NAME); + return; + } + + return; + +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(i2c_io_sample, i2c io sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/led_blink_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/led_blink_sample.c new file mode 100644 index 0000000000..c073b5e5a7 --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/led_blink_sample.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-09-25 misonyo first edition. + */ +/* + * 程序清单:这是一个通过PIN脚控制LED亮灭的使用例程 + * 例程导出了 led_sample 命令到控制终端 + * 命令调用格式:led_sample + * 命令解释:命令第二个参数是要使用的PIN脚编号,为空则使用例程默认的引脚编号。 + * 程序功能:程序创建一个led线程,线程每隔1000ms改变PIN脚状态,达到控制led灯 + * 亮灭的效果。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> +#include <stdlib.h> + +/* PIN脚编号,查看驱动文件drv_gpio.c确定 */ +#define LED_PIN_NUM 45 /*PA12*/ +static int pin_num; + +static void led_entry(void *parameter) +{ + int count = 0; + /* 设置PIN脚模式为输出 */ + rt_pin_mode(pin_num, PIN_MODE_OUTPUT); + + while (1) + { + count++; + rt_kprintf("thread run count : %d\r\n", count); + /* 拉低PIN脚 */ + rt_pin_write(pin_num, PIN_LOW); + rt_kprintf("led on!\r\n"); + /* 延时1000ms */ + rt_thread_mdelay(1000); + + /* 拉高PIN脚 */ + rt_pin_write(pin_num, PIN_HIGH); + rt_kprintf("led off!\r\n"); + rt_thread_mdelay(1000); + } +} + +static int led_sample(int argc, char *argv[]) +{ + rt_thread_t tid; + rt_err_t ret = RT_EOK; + + /* 判断命令行参数是否给定了PIN脚编号 */ + if (argc == 2) + { + pin_num = atoi(argv[1]); + } + else + { + pin_num = LED_PIN_NUM; + } + + tid = rt_thread_create("led", + led_entry, + RT_NULL, + 512, + RT_THREAD_PRIORITY_MAX / 3, + 20); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } + else + { + ret = RT_ERROR; + } + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(led_sample, led sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/pin_beep_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/pin_beep_sample.c new file mode 100644 index 0000000000..911a0c800e --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/pin_beep_sample.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-08-15 misonyo first implementation. + */ +/* + * 程序清单:这是一个 PIN 设备使用例程 + * 例程导出了 pin_beep_sample 命令到控制终端 + * 命令调用格式:pin_beep_sample + * 程序功能:通过按键控制蜂鸣器对应引脚的电平状态控制蜂鸣器 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +/* 引脚编号,通过查看驱动文件drv_gpio.c确定 */ +#ifndef BEEP_PIN_NUM + #define BEEP_PIN_NUM 45 /* PA12 */ +#endif +#ifndef KEY0_PIN_NUM + #define KEY0_PIN_NUM 18 /* PF0 */ +#endif +#ifndef KEY1_PIN_NUM + #define KEY1_PIN_NUM 19 /* PF1 */ +#endif + +void beep_on(void *args) +{ + rt_kprintf("turn on beep!\n"); + + rt_pin_write(BEEP_PIN_NUM, PIN_HIGH); +} + +void beep_off(void *args) +{ + rt_kprintf("turn off beep!\n"); + + rt_pin_write(BEEP_PIN_NUM, PIN_LOW); +} + +static void pin_beep_sample(void) +{ + /* 蜂鸣器引脚为输出模式 */ + rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT); + /* 默认低电平 */ + rt_pin_write(BEEP_PIN_NUM, PIN_LOW); + + /* 按键0引脚为输入模式 */ + rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP); + /* 绑定中断,下降沿模式,回调函数名为beep_on */ + rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL); + /* 使能中断 */ + rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE); + + /* 按键1引脚为输入模式 */ + rt_pin_mode(KEY1_PIN_NUM, PIN_MODE_INPUT_PULLUP); + /* 绑定中断,下降沿模式,回调函数名为beep_off */ + rt_pin_attach_irq(KEY1_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_off, RT_NULL); + /* 使能中断 */ + rt_pin_irq_enable(KEY1_PIN_NUM, PIN_IRQ_ENABLE); +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(pin_beep_sample, pin beep sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/pm_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/pm_sample.c new file mode 100644 index 0000000000..08258b1650 --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/pm_sample.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy first implementation. + */ +/* + * 程序清单:这是一个 pm睡眠唤醒的使用例程 + * 例程导出了 pm_sample 命令到控制终端 + * 命令调用格式:pm_sample + * 命令解释:进入不同的睡眠模式,然后用按键唤醒 + * 程序功能:通过串口输出字符串,告知进入睡眠和唤醒睡眠的情况。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define PM_NAME "pm" /* 设备名称 */ +#define WAKE_UP_PIN 18 /* 唤醒源 */ +#define SLEEP_TIMES 12 /* 进入睡眠次数,轮流进入不同的睡眠模式,包括无睡眠模式 */ + +struct pm_callback_t +{ + volatile int in_fun_times; /*进入函数的次数*/ + volatile char flag; /*标志*/ + volatile int mode; /*需要打印的模式*/ +}; + +volatile struct pm_callback_t g_pm_data; + +/*进入睡眠前,睡眠唤醒后,都会进入。*/ +/*函数打印睡眠相关的信息*/ +void sleep_in_out_callback(rt_uint8_t event, rt_uint8_t mode, void *data) +{ + /*没有标志,不处理*/ + if(!(g_pm_data.flag)) + { + return; + } + + /*标志不正常,清空标志*/ + if((g_pm_data.flag) > 2) + { + (g_pm_data.flag) = 0; + return; + } + + /*模式不匹配*/ + if(g_pm_data.mode != mode ) + { + return; + } + + /*进入的事件*/ + switch(event) + { + /*进入睡眠前*/ + case RT_PM_ENTER_SLEEP: g_pm_data.flag = 1; + rt_kprintf("\n\r##%d : ENTER ",g_pm_data.in_fun_times); + g_pm_data.in_fun_times++; /*进入睡眠次数+1*/ + break; + /*睡眠唤醒后*/ + case RT_PM_EXIT_SLEEP: g_pm_data.flag = 0; /*睡眠唤醒后*/ + rt_kprintf("\n\rEXIT\n\r"); + rt_pm_release(mode); /*释放休眠模式*/ + return; + + default: break; + + }; + + /*当前的睡眠模式*/ + switch(mode) + { + case PM_SLEEP_MODE_NONE: rt_kprintf("PM_SLEEP_MODE_NONE\n\r"); + break; + case PM_SLEEP_MODE_IDLE: rt_kprintf("PM_SLEEP_MODE_IDLE\n\r"); + break; + case PM_SLEEP_MODE_LIGHT: rt_kprintf("PM_SLEEP_MODE_LIGHT\n\r"); + break; + case PM_SLEEP_MODE_DEEP: rt_kprintf("PM_SLEEP_MODE_DEEP\n\r"); + break; + case PM_SLEEP_MODE_STANDBY: rt_kprintf("PM_SLEEP_MODE_STANDBY\n\r"); + break; + case PM_SLEEP_MODE_SHUTDOWN: rt_kprintf("PM_SLEEP_MODE_SHUTDOWN\n\r"); + break; + case PM_SLEEP_MODE_MAX: rt_kprintf("PM_SLEEP_MODE_MAX\n\r"); + break; + default: break; + } + +} + +/* pm测试函数 */ +static void pm_test(void *parameter) +{ + int in_mode[7],i = 0; + + g_pm_data.in_fun_times = 0; + g_pm_data.flag = 0; + + in_mode[0] = PM_SLEEP_MODE_NONE; + in_mode[1] = PM_SLEEP_MODE_IDLE; + in_mode[2] = PM_SLEEP_MODE_LIGHT; + in_mode[3] = PM_SLEEP_MODE_DEEP; + in_mode[4] = PM_SLEEP_MODE_STANDBY; + in_mode[5] = PM_SLEEP_MODE_SHUTDOWN; + in_mode[6] = PM_SLEEP_MODE_MAX; + + /*设置回调函数和私有数据*/ + rt_pm_notify_set(sleep_in_out_callback,RT_NULL); + + while(i < SLEEP_TIMES) + { + + g_pm_data.mode = in_mode[i%6]; + + /*无休眠模式,不赋予标志*/ + if(g_pm_data.mode != PM_SLEEP_MODE_NONE) + { + g_pm_data.flag = 2; + + } + + /*请求选择的休眠模式*/ + rt_pm_request(in_mode[i%6]); + + rt_thread_mdelay(500); + + /*无休眠模式,不需要额外的等待*/ + while(( g_pm_data.flag != 0 )&&(g_pm_data.mode != PM_SLEEP_MODE_NONE)) + { + rt_thread_mdelay(500); + } + + /*释放选择的休眠模式*/ + rt_pm_release(in_mode[i%6]); + + i++; + + } + /*清除回调函数和私有数据*/ + rt_pm_notify_set(RT_NULL,RT_NULL); + rt_kprintf("thread pm_test close\n\r"); +} + +/*按键唤醒的回调函数*/ +void wake_by_pin(void *args) +{ + +} + +static int pm_sample(int argc, char *argv[]) +{ + rt_thread_t thread; + + /* 按键引脚为输入模式 */ + rt_pin_mode(WAKE_UP_PIN, PIN_MODE_INPUT_PULLUP); + + /* 绑定中断,下降沿模式,回调函数名为wake_by_pin */ + rt_pin_attach_irq(WAKE_UP_PIN, PIN_IRQ_MODE_RISING, wake_by_pin, RT_NULL); + /* 使能中断 */ + rt_pin_irq_enable(WAKE_UP_PIN, PIN_IRQ_ENABLE); + + thread = rt_thread_create("pm_test", pm_test, RT_NULL, 1024, 25, 10); + + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + rt_kprintf("create pm_test thread failed!\n\r"); + } + + return RT_EOK; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(pm_sample, pm sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/pwm_led_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/pwm_led_sample.c new file mode 100644 index 0000000000..1ac2361445 --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/pwm_led_sample.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-25 misonyo first implementation. + */ +/* + * 程序清单:这是一个 PWM 设备使用例程 + * 例程导出了 pwm_led_sample 命令到控制终端 + * 命令调用格式:pwm_led_sample + * 程序功能:通过 PWM 设备控制 LED 灯的亮度,可以看到LED不停的由暗变到亮,然后又从亮变到暗。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define LED_PIN_NUM 45 /* PA12 LED PIN脚编号,查看驱动文件drv_gpio.c确定 */ +#define PWM_DEV_NAME "pwm0" /* PWM设备名称 */ +#define PWM_DEV_CHANNEL 2 /* PA9 PWM通道 */ + +struct rt_device_pwm *pwm_dev; /* PWM设备句柄 */ + +static int pwm_led_sample(int argc, char *argv[]) +{ + rt_uint32_t period, pulse, dir; + + period = 500000; /* 周期为0.5ms,单位为纳秒ns */ + dir = 1; /* PWM脉冲宽度值的增减方向 */ + pulse = 0; /* PWM脉冲宽度值,单位为纳秒ns */ + + /* 查找设备 */ + pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME); + if (pwm_dev == RT_NULL) + { + rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME); + return RT_ERROR; + } + + /* 设置PWM周期和脉冲宽度默认值 */ + rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); + /* 使能设备 */ + rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL); + + while (1) + { + rt_thread_mdelay(50); + if (dir) + { + pulse += 5000; /* 从0值开始每次增加5000ns */ + } + else + { + pulse -= 5000; /* 从最大值开始每次减少5000ns */ + } + if (pulse >= period) + { + dir = 0; + } + if (0 == pulse) + { + dir = 1; + } + + /* 设置PWM周期和脉冲宽度 */ + rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); + } +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(pwm_led_sample, pwm sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/rtc_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/rtc_sample.c new file mode 100644 index 0000000000..711a3a0ebb --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/rtc_sample.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-30 misonyo first implementation. + */ +/* + * 程序清单:这是一个 RTC 设备使用例程 + * 例程导出了 rtc_sample 命令到控制终端 + * 命令调用格式:rtc_sample + * 程序功能:设置RTC设备的日期和时间,延时一段时间后获取当前时间并打印显示。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +static int rtc_sample(int argc, char *argv[]) +{ + rt_err_t ret = RT_EOK; + time_t now; + + /* 设置日期 */ + ret = set_date(2018, 12, 3); + if (ret != RT_EOK) + { + rt_kprintf("set RTC date failed\n"); + return ret; + } + + /* 设置时间 */ + ret = set_time(11, 15, 50); + if (ret != RT_EOK) + { + rt_kprintf("set RTC time failed\n"); + return ret; + } + + /* 延时3秒 */ + rt_thread_mdelay(3000); + + /* 获取时间 */ + now = time(RT_NULL); + rt_kprintf("%s\n", ctime(&now)); + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(rtc_sample, rtc sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/spi_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/spi_sample.c new file mode 100644 index 0000000000..994888cdb0 --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/spi_sample.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy first implementation. + */ +/* + * 程序清单:这是一个 SPI 设备使用例程 + * 例程导出了 spi_io_sample 命令到控制终端 + * 命令调用格式:spi_io_sample + * 程序功能:通过SPI设备先读取数据,然后每个字符加1后输出。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define SPI_DEVICE_NAME "spi00" +#define BUF_LEN 16 + +static void spi_io_sample(int argc, char *argv[]) +{ + struct rt_spi_device * spi_dev; /* spi设备的句柄 */ + struct rt_spi_configuration spi_config; + rt_uint8_t i,buffer[BUF_LEN] = { 0U }; + rt_err_t s_stat; + rt_err_t result; + + /* 查找 spi设备 获取spi设备句柄 */ + spi_dev = (struct rt_spi_device *)rt_device_find(SPI_DEVICE_NAME); + + if (spi_dev == RT_NULL) + { + rt_kprintf("spi sample run failed! can't find %s device!\n", SPI_DEVICE_NAME); + return; + } + + + /* 清空配置结构体 */ + rt_memset(&spi_config,0,sizeof(struct rt_spi_configuration)); + + spi_config.mode &= ~RT_SPI_SLAVE; /* 主机模式 */ + spi_config.mode &= ~RT_SPI_3WIRE; /* 4线,双向传输 */ + spi_config.mode |= RT_SPI_CPHA; /* 第二边沿采样 */ + spi_config.mode |= RT_SPI_CPOL; /* 空闲高电平 */ + spi_config.mode |= RT_SPI_NO_CS; /* 禁用软件从机选择管理 */ + spi_config.mode |= RT_SPI_MSB; /* 高位在前 */ + + spi_config.data_width = 8; /* 数据长度:8 */ + + spi_config.max_hz = 2000000; /* 最快时钟频率 */ + + /* 配置SPI设备 */ + s_stat = rt_spi_configure(spi_dev,&spi_config); + + if(s_stat != RT_EOK) + { + rt_kprintf(" spi config fail !\n "); + return; + } + + + /* 获取总线 ,防止总线被多个线程同时使用 */ + result = rt_spi_take_bus(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s take spi bus failed! \n", SPI_DEVICE_NAME); + return; + } + + /* 选中片选 */ + result = rt_spi_take(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s take spi cs failed! \n", SPI_DEVICE_NAME); + return; + } + + + /*接收一次数据*/ + result = rt_spi_recv(spi_dev,buffer,BUF_LEN); + + if(result != BUF_LEN) + { + rt_kprintf("receive fail. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + return; + } + + rt_kprintf("receive successful. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + /* 将接收到的数据加1 */ + for( i = 0 ; i < BUF_LEN ; i++) + buffer[i]++; + + /*发送数据*/ + result = rt_spi_send(spi_dev,buffer,BUF_LEN); + + if(result != BUF_LEN) + { + rt_kprintf("send fail. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + return; + } + + rt_kprintf("send successful. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + /* 释放片选 */ + result = rt_spi_release(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s release spi cs failed! \n", SPI_DEVICE_NAME); + return; + } + + /* 释放总线 */ + result = rt_spi_release_bus(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s release spi bus failed! \n", SPI_DEVICE_NAME); + return; + } + +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(spi_io_sample, spi sample); diff --git a/bsp/essemi/es32f0334/drivers/bsp_driver_example/uart_sample.c b/bsp/essemi/es32f0334/drivers/bsp_driver_example/uart_sample.c new file mode 100644 index 0000000000..cbfd6bccef --- /dev/null +++ b/bsp/essemi/es32f0334/drivers/bsp_driver_example/uart_sample.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-08-15 misonyo first implementation. + */ +/* + * 程序清单:这是一个 串口 设备使用例程 + * 例程导出了 uart_sample 命令到控制终端 + * 命令调用格式:uart_sample uart2 + * 命令解释:命令第二个参数是要使用的串口设备名称,为空则使用默认的串口设备 + * 程序功能:通过串口输出字符串"hello RT-Thread!",然后错位输出输入的字符 +*/ + +#include <rtthread.h> + +#define SAMPLE_UART_NAME "uart1" /* 串口设备名称 */ + +/* 用于接收消息的信号量 */ +static struct rt_semaphore rx_sem; +static rt_device_t serial; + +/* 接收数据回调函数 */ +static rt_err_t uart_input(rt_device_t dev, rt_size_t size) +{ + /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ + rt_sem_release(&rx_sem); + + return RT_EOK; +} + +static void serial_thread_entry(void *parameter) +{ + char ch; + + while (1) + { + /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */ + while (rt_device_read(serial, -1, &ch, 1) != 1) + { + /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ + rt_sem_take(&rx_sem, RT_WAITING_FOREVER); + } + /* 读取到的数据通过串口错位输出 */ + ch = ch + 1; + rt_device_write(serial, 0, &ch, 1); + } +} + +static int uart_sample(int argc, char *argv[]) +{ + rt_err_t ret = RT_EOK; + char uart_name[RT_NAME_MAX]; + char str[] = "hello RT-Thread!\r\n"; + + if (argc == 2) + { + rt_strncpy(uart_name, argv[1], RT_NAME_MAX); + } + else + { + rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); + } + + /* 查找串口设备 */ + serial = rt_device_find(uart_name); + if (!serial) + { + rt_kprintf("find %s failed!\n", uart_name); + return RT_ERROR; + } + + /* 初始化信号量 */ + rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); + /* 以中断接收及轮询发送方式打开串口设备 */ + rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); + /* 设置接收回调函数 */ + rt_device_set_rx_indicate(serial, uart_input); + /* 发送字符串 */ + rt_device_write(serial, 0, str, (sizeof(str) - 1)); + + /* 创建 serial 线程 */ + rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); + /* 创建成功则启动线程 */ + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + ret = RT_ERROR; + } + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(uart_sample, uart device sample); diff --git a/bsp/essemi/es32f0334/figures/ES-PDS-ES32F369x-V1.3.jpg b/bsp/essemi/es32f0334/figures/ES-PDS-ES32F369x-V1.3.jpg new file mode 100644 index 0000000000..e8d8cc653c Binary files /dev/null and b/bsp/essemi/es32f0334/figures/ES-PDS-ES32F369x-V1.3.jpg differ diff --git a/bsp/essemi/es32f0334/figures/内核用例.PNG b/bsp/essemi/es32f0334/figures/内核用例.PNG new file mode 100644 index 0000000000..4c4f8e05ba Binary files /dev/null and b/bsp/essemi/es32f0334/figures/内核用例.PNG differ diff --git a/bsp/essemi/es32f0334/figures/内核配置.PNG b/bsp/essemi/es32f0334/figures/内核配置.PNG new file mode 100644 index 0000000000..f5901c0e59 Binary files /dev/null and b/bsp/essemi/es32f0334/figures/内核配置.PNG differ diff --git a/bsp/essemi/es32f0334/figures/驱动用例.PNG b/bsp/essemi/es32f0334/figures/驱动用例.PNG new file mode 100644 index 0000000000..5abb7ac952 Binary files /dev/null and b/bsp/essemi/es32f0334/figures/驱动用例.PNG differ diff --git a/bsp/essemi/es32f0334/figures/驱动配置.PNG b/bsp/essemi/es32f0334/figures/驱动配置.PNG new file mode 100644 index 0000000000..925342ec24 Binary files /dev/null and b/bsp/essemi/es32f0334/figures/驱动配置.PNG differ diff --git a/bsp/essemi/es32f0334/libraries/ES32F033x_ALD_StdPeriph_Driver/EASTSOFT_ES32F033x_ALD.chm b/bsp/essemi/es32f0334/libraries/ES32F033x_ALD_StdPeriph_Driver/EASTSOFT_ES32F033x_ALD.chm new file mode 100644 index 0000000000..9f5df67080 Binary files /dev/null and b/bsp/essemi/es32f0334/libraries/ES32F033x_ALD_StdPeriph_Driver/EASTSOFT_ES32F033x_ALD.chm differ diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/.gitignore b/bsp/essemi/es32f0654/drivers/bsp_driver_example/.gitignore new file mode 100644 index 0000000000..c6127b38c1 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/README.md b/bsp/essemi/es32f0654/drivers/bsp_driver_example/README.md new file mode 100644 index 0000000000..80f12e1949 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/README.md @@ -0,0 +1,47 @@ +# 外设驱动测试用例 + +## 1、介绍 + +这个软件包包含一些外设设备操作的例程。 + +### 1.1 例程说明 + +| 文件 | 说明 | +| ---------------- | ------------------------------- | +| adc_vol_sample.c | 使用 ADC 设备转换电压数据 | +| can_sample.c | 通过 CAN 设备发送一帧,并创建一个线程接收数据然后打印输出。 | +| hwtimer_sample.c | 使用 硬件定时器定时 | +| i2c_sample.c | 使用 i2c 设备进行读写 | +| pm.c | 反复进入不同程度的睡眠。 | +| led_blink_sample.c | 使用 pin 设备控制 LED 闪烁 | +| pin_beep_sample.c | 使用 pin 设备控制蜂鸣器 | +| pwm_led_sample.c | 使用 pwm 设备控制 LED 的亮度 | +| rtc_sample.c | 使用 rtc 设备设置年月日时分秒信息 | +| spi_sample.c | 使用 spi 设备进行读写 | +| uart_sample.c | 使用 serial 设备中断接收及轮询发送模式收发数据 | + +### 1.2 依赖 + +依赖设备管理模块提供的设备驱动。 + +## 2、如何打开 外设驱动测试用例 + +使用 外设驱动测试用例 需要在 RT-Thread 的menuconfig中选择它,具体路径如下: + +``` +Hardware Driver Config ---> + Peripheral Driver test example---> +``` + +## 3、使用 外设驱动测试用例 + +在打开 Peripheral Driver test example 后,当进行 BSP 编译时,选择的软件包相关源代码会被加入到 BSP 工程中进行编译。 + +## 4、注意事项 + +暂无。 + +## 5、联系方式 & 感谢 + +* 维护:[misonyo](https://github.com/misonyo) +* 主页:https://github.com/RT-Thread-packages/peripheral-sample diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/adc_vol_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/adc_vol_sample.c new file mode 100644 index 0000000000..19eed3f35d --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/adc_vol_sample.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-29 misonyo first implementation. + */ +/* + * 程序清单: ADC 设备使用例程 + * 例程导出了 adc_sample 命令到控制终端 + * 命令调用格式:adc_sample + * 程序功能:通过 ADC 设备采样电压值并转换为数值。 + * 示例代码参考电压为3.3V,转换位数为12位。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define ADC_DEV_NAME "adc0" /* ADC 设备名称 */ +#define ADC_DEV_CHANNEL 5 /* PA1 ADC 通道 */ +#define REFER_VOLTAGE 330 /* 参考电压 3.3V,数据精度乘以100保留2位小数*/ +#define CONVERT_BITS (1 << 12) /* 转换位数为12位 */ + +static int adc_vol_sample(int argc, char *argv[]) +{ + rt_adc_device_t adc_dev; + rt_uint32_t value, vol; + rt_err_t ret = RT_EOK; + + /* 查找设备 */ + adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME); + if (adc_dev == RT_NULL) + { + rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME); + return RT_ERROR; + } + + /* 使能设备 */ + ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL); + + /* 读取采样值 */ + value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL); + rt_kprintf("the value is :%d \n", value); + + /* 转换为对应电压值 */ + vol = value * REFER_VOLTAGE / CONVERT_BITS; + rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100); + + /* 关闭通道 */ + ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL); + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/can_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/can_sample.c new file mode 100644 index 0000000000..4c16d1d555 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/can_sample.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-06-25 misonyo first implementation. + */ +/* + * 程序清单:这是一个 CAN 设备使用例程 + * 例程导出了 can_sample 命令到控制终端 + * 命令调用格式:can_sample can2 + * 命令解释:命令第二个参数是要使用的 CAN 设备名称,为空则使用默认的 CAN 设备 + * 程序功能:通过 CAN 设备发送一帧,并创建一个线程接收数据然后打印输出。 +*/ + +#include <rtthread.h> +#include "rtdevice.h" + +#define CAN_DEV_NAME "can" /* CAN 设备名称 */ + +static struct rt_semaphore rx_sem; /* 用于接收消息的信号量 */ +static rt_device_t can_dev; /* CAN 设备句柄 */ + +/* 接收数据回调函数 */ +static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size) +{ + /* CAN 接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ + rt_sem_release(&rx_sem); + + return RT_EOK; +} + +static void can_rx_thread(void *parameter) +{ + int i; + struct rt_can_msg rxmsg = {0}; + + /* 设置接收回调函数 */ + rt_device_set_rx_indicate(can_dev, can_rx_call); + +#ifdef RT_CAN_USING_HDR + + rt_err_t res; + + struct rt_can_filter_item items[5] = + { + RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x100~0x1ff,hdr为-1,设置默认过滤表 */ + RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x300~0x3ff,hdr为-1 */ + RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 0, 0x7ff, RT_NULL, RT_NULL), /* std,match ID:0x211,hdr为-1 */ + RT_CAN_FILTER_STD_INIT(0x486, RT_NULL, RT_NULL), /* std,match ID:0x486,hdr为-1 */ + {0x555, 0, 0, 0, 0x7ff, 7,} /* std,match ID:0x555,hdr为7,指定设置7号过滤表 */ + }; + struct rt_can_filter_config cfg = {5, 1, items}; /* 一共有5个过滤表 */ + /* 设置硬件过滤表 */ + res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg); + RT_ASSERT(res == RT_EOK); +#endif + + while (1) + { + /* hdr值为-1,表示直接从uselist链表读取数据 */ + rxmsg.hdr = -1; + /* 阻塞等待接收信号量 */ + rt_sem_take(&rx_sem, RT_WAITING_FOREVER); + /* 从CAN读取一帧数据 */ + rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg)); + /* 打印数据ID及内容 */ + rt_kprintf("ID:%x ", rxmsg.id); + for (i = 0; i < 8; i++) + { + rt_kprintf("%2x ", rxmsg.data[i]); + } + + rt_kprintf("\n"); + } +} + +int can_sample(int argc, char *argv[]) +{ + struct rt_can_msg msg = {0}; + rt_err_t res; + rt_size_t size; + rt_thread_t thread; + char can_name[RT_NAME_MAX]; + + if (argc == 2) + { + rt_strncpy(can_name, argv[1], RT_NAME_MAX); + } + else + { + rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX); + } + + can_dev = rt_device_find(can_name); + if (!can_dev) + { + rt_kprintf("find %s failed!\n", can_name); + return RT_ERROR; + } + + /* 初始化CAN接收信号量 */ + rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); + + /* 以中断接收及发送方式打开CAN设备 */ + res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX); + RT_ASSERT(res == RT_EOK); + + thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10); + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + rt_kprintf("create can_rx thread failed!\n"); + } + + msg.id = 0x78; /* ID为0x78 */ + msg.ide = RT_CAN_STDID; /* 标准格式 */ + msg.rtr = RT_CAN_DTR; /* 数据帧 */ + msg.len = 8; /* 数据长度为8 */ + /* 待发送的8字节数据 */ + msg.data[0] = 0x00; + msg.data[1] = 0x11; + msg.data[2] = 0x22; + msg.data[3] = 0x33; + msg.data[4] = 0x44; + msg.data[5] = 0x55; + msg.data[6] = 0x66; + msg.data[7] = 0x77; + /* 发送一帧CAN数据 */ + size = rt_device_write(can_dev, 0, &msg, sizeof(msg)); + if (size == 0) + { + rt_kprintf("can dev write data failed!\n"); + } + + return res; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(can_sample, can device sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/hwtimer_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/hwtimer_sample.c new file mode 100644 index 0000000000..e2e39664f3 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/hwtimer_sample.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-30 misonyo first implementation. + */ +/* + * 程序清单:这是一个 hwtimer 设备使用例程 + * 例程导出了 hwtimer_sample 命令到控制终端 + * 命令调用格式:hwtimer_sample + * 程序功能:硬件定时器超时回调函数周期性的打印当前tick值,2次tick值之差换算为时间等同于定时时间值。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define HWTIMER_DEV_NAME "timer0" /* 定时器名称 */ + +/* 定时器超时回调函数 */ +static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size) +{ + rt_kprintf("tick is :%d !\n", rt_tick_get()); + + return 0; +} + +static int hwtimer_sample(int argc, char *argv[]) +{ + rt_err_t ret = RT_EOK; + rt_hwtimerval_t timeout_s; /* 定时器超时值 */ + rt_device_t hw_dev = RT_NULL; /* 定时器设备句柄 */ + rt_hwtimer_mode_t mode; /* 定时器模式 */ + + /* 查找定时器设备 */ + hw_dev = rt_device_find(HWTIMER_DEV_NAME); + if (hw_dev == RT_NULL) + { + rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_NAME); + return RT_ERROR; + } + + /* 以读写方式打开设备 */ + ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR); + if (ret != RT_EOK) + { + rt_kprintf("open %s device failed!\n", HWTIMER_DEV_NAME); + return ret; + } + + /* 设置超时回调函数 */ + rt_device_set_rx_indicate(hw_dev, timeout_cb); + + /* 设置模式为周期性定时器 */ + mode = HWTIMER_MODE_PERIOD; + ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode); + if (ret != RT_EOK) + { + rt_kprintf("set mode failed! ret is :%d\n", ret); + return ret; + } + + /* 设置定时器超时值为5s并启动定时器 */ + timeout_s.sec = 5; /* 秒 */ + timeout_s.usec = 0; /* 微秒 */ + + if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s)) + { + rt_kprintf("set timeout value failed\n"); + return RT_ERROR; + } + + /* 延时3500ms */ + rt_thread_mdelay(3500); + + /* 读取定时器当前值 */ + rt_device_read(hw_dev, 0, &timeout_s, sizeof(timeout_s)); + rt_kprintf("Read: Sec = %d, Usec = %d\n", timeout_s.sec, timeout_s.usec); + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(hwtimer_sample, hwtimer sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/i2c_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/i2c_sample.c new file mode 100644 index 0000000000..2d386433c6 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/i2c_sample.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy first implementation. + */ +/* + * 程序清单:这是一个 I2C 设备使用例程 + * 例程导出了 i2c_io_sample 命令到控制终端 + * 命令调用格式:i2c_io_sample + * 命令解释:使用默认的I2C总线设备 + * 程序功能:通过 I2C 设备接收数据并打印,然后将接收的字符加1输出。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define I2C_BUS_NAME "i2c1" /* I2C总线设备名称 */ +#define SLAVE_ADDR 0x2D /* 从机地址 */ +#define STR_LEN 16 /* 接收发送的数据长度 */ + +static void i2c_io_sample(int argc, char *argv[]) +{ + + struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄 */ + struct rt_i2c_msg temp_msg; /* I2C消息 */ + rt_uint8_t buffer[STR_LEN] = { 0U }; + rt_uint32_t i,num_msg; + rt_size_t s_stat; + + i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(I2C_BUS_NAME); /* 通过名字获取I2C总线设备的句柄 */ + + if( i2c_bus == RT_NULL) + { + rt_kprintf("can't find i2c device :%s !\n",I2C_BUS_NAME); + + return; + } + + /*初始化消息*/ + temp_msg.addr = SLAVE_ADDR; /* 从机地址 */ + temp_msg.len = STR_LEN; /* 传输的数据长度 */ + temp_msg.buf = buffer; /* 读写缓存器 */ + + num_msg = 1; /* 传输一条消息 */ + + temp_msg.flags = RT_I2C_RD; /* I2C读 */ + s_stat = rt_i2c_transfer(i2c_bus,&temp_msg,num_msg); /* 传输消息 */ + + rt_thread_mdelay(400); + + if( s_stat == num_msg ) + { + rt_kprintf("receive successful. \n receive messege : %s \n:",buffer); + + for( i = 0 ; i < STR_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + } + else + { + rt_kprintf("device s% recieve fail \n buffer : s%\n",I2C_BUS_NAME,buffer); + return; + } + + for( i = 0 ; i < STR_LEN ; i++) + buffer[i]++; + + temp_msg.flags = RT_I2C_WR; /* I2C写 */ + s_stat = rt_i2c_transfer(i2c_bus,&temp_msg,num_msg); /* 传输一条 */ + + rt_thread_mdelay(400); + + if( s_stat == num_msg ) + { + rt_kprintf(" send successful \n messege : %s \n:",buffer); + + for( i = 0 ; i < STR_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + } + else + { + rt_kprintf("device s% send fail \n",I2C_BUS_NAME); + return; + } + + return; + +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(i2c_io_sample, i2c io sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/led_blink_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/led_blink_sample.c new file mode 100644 index 0000000000..42c956a060 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/led_blink_sample.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-09-25 misonyo first edition. + */ +/* + * 程序清单:这是一个通过PIN脚控制LED亮灭的使用例程 + * 例程导出了 led_sample 命令到控制终端 + * 命令调用格式:led_sample 41 + * 命令解释:命令第二个参数是要使用的PIN脚编号,为空则使用例程默认的引脚编号。 + * 程序功能:程序创建一个led线程,线程每隔1000ms改变PIN脚状态,达到控制led灯 + * 亮灭的效果。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> +#include <stdlib.h> + +/* PIN脚编号,查看驱动文件drv_gpio.c确定 */ +#define LED_PIN_NUM 40 /*PB9*/ +static int pin_num; + +static void led_entry(void *parameter) +{ + int count = 0; + /* 设置PIN脚模式为输出 */ + rt_pin_mode(pin_num, PIN_MODE_OUTPUT); + + while (1) + { + count++; + rt_kprintf("thread run count : %d\r\n", count); + /* 拉低PIN脚 */ + rt_pin_write(pin_num, PIN_LOW); + rt_kprintf("led on!\r\n"); + /* 延时1000ms */ + rt_thread_mdelay(1000); + + /* 拉高PIN脚 */ + rt_pin_write(pin_num, PIN_HIGH); + rt_kprintf("led off!\r\n"); + rt_thread_mdelay(1000); + } +} + +static int led_sample(int argc, char *argv[]) +{ + rt_thread_t tid; + rt_err_t ret = RT_EOK; + + /* 判断命令行参数是否给定了PIN脚编号 */ + if (argc == 2) + { + pin_num = atoi(argv[1]); + } + else + { + pin_num = LED_PIN_NUM; + } + + tid = rt_thread_create("led", + led_entry, + RT_NULL, + 512, + RT_THREAD_PRIORITY_MAX / 3, + 20); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } + else + { + ret = RT_ERROR; + } + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(led_sample, led sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/pin_beep_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/pin_beep_sample.c new file mode 100644 index 0000000000..29dfbe1b2f --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/pin_beep_sample.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-08-15 misonyo first implementation. + */ +/* + * 程序清单:这是一个 PIN 设备使用例程 + * 例程导出了 pin_beep_sample 命令到控制终端 + * 命令调用格式:pin_beep_sample + * 程序功能:通过按键控制蜂鸣器对应引脚的电平状态控制蜂鸣器 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +/* 引脚编号,通过查看驱动文件drv_gpio.c确定 */ +#ifndef BEEP_PIN_NUM + #define BEEP_PIN_NUM 40 /* PB9 */ +#endif +#ifndef KEY0_PIN_NUM + #define KEY0_PIN_NUM 18 /* PF0 */ +#endif +#ifndef KEY1_PIN_NUM + #define KEY1_PIN_NUM 19 /* PF1 */ +#endif + +void beep_on(void *args) +{ + rt_kprintf("turn on beep!\n"); + + rt_pin_write(BEEP_PIN_NUM, PIN_HIGH); +} + +void beep_off(void *args) +{ + rt_kprintf("turn off beep!\n"); + + rt_pin_write(BEEP_PIN_NUM, PIN_LOW); +} + +static void pin_beep_sample(void) +{ + /* 蜂鸣器引脚为输出模式 */ + rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT); + /* 默认低电平 */ + rt_pin_write(BEEP_PIN_NUM, PIN_LOW); + + /* 按键0引脚为输入模式 */ + rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP); + /* 绑定中断,下降沿模式,回调函数名为beep_on */ + rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL); + /* 使能中断 */ + rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE); + + /* 按键1引脚为输入模式 */ + rt_pin_mode(KEY1_PIN_NUM, PIN_MODE_INPUT_PULLUP); + /* 绑定中断,下降沿模式,回调函数名为beep_off */ + rt_pin_attach_irq(KEY1_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_off, RT_NULL); + /* 使能中断 */ + rt_pin_irq_enable(KEY1_PIN_NUM, PIN_IRQ_ENABLE); +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(pin_beep_sample, pin beep sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/pm_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/pm_sample.c new file mode 100644 index 0000000000..f7287e36ac --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/pm_sample.c @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy first implementation. + */ +/* + * 程序清单:这是一个 pm睡眠唤醒的使用例程 + * 例程导出了 pm_sample 命令到控制终端 + * 命令调用格式:pm_sample + * 命令解释:进入不同的睡眠模式,然后用按键唤醒 + * 程序功能:通过串口输出字符串,告知进入睡眠和唤醒睡眠的情况。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define PM_NAME "pm" /* 设备名称 */ +#define WAKE_UP_PIN 18 /* 唤醒源 */ +#define SLEEP_TIMES 12 /* 进入睡眠次数,轮流进入不同的睡眠模式,包括无睡眠模式 */ + + +struct pm_callback_t +{ + volatile int in_fun_times; /*进入函数的次数*/ + volatile char flag; /*标志*/ + volatile int mode; /*需要打印的模式*/ +}; + +volatile struct pm_callback_t g_pm_data; + +/*进入睡眠前,睡眠唤醒后,都会进入。*/ +/*函数打印睡眠相关的信息*/ +void sleep_in_out_callback(rt_uint8_t event, rt_uint8_t mode, void *data) +{ + /*没有标志,不处理*/ + if(!(g_pm_data.flag)) + { + return; + } + + /*标志不正常,清空标志*/ + if((g_pm_data.flag) > 2) + { + (g_pm_data.flag) = 0; + return; + } + + /*模式不匹配*/ + if(g_pm_data.mode != mode ) + { + return; + } + + /*进入的事件*/ + switch(event) + { + /*进入睡眠前*/ + case RT_PM_ENTER_SLEEP: g_pm_data.flag = 1; + rt_kprintf("\n\r##%d : ENTER ",g_pm_data.in_fun_times); + g_pm_data.in_fun_times++; /*进入睡眠次数+1*/ + break; + /*睡眠唤醒后*/ + case RT_PM_EXIT_SLEEP: g_pm_data.flag = 0; /*睡眠唤醒后*/ + rt_kprintf("\n\rEXIT\n\r"); + rt_pm_release(mode); /*释放休眠模式*/ + return; + + default: break; + + }; + + /*当前的睡眠模式*/ + switch(mode) + { + case PM_SLEEP_MODE_NONE: rt_kprintf("PM_SLEEP_MODE_NONE\n\r"); + break; + case PM_SLEEP_MODE_IDLE: rt_kprintf("PM_SLEEP_MODE_IDLE\n\r"); + break; + case PM_SLEEP_MODE_LIGHT: rt_kprintf("PM_SLEEP_MODE_LIGHT\n\r"); + break; + case PM_SLEEP_MODE_DEEP: rt_kprintf("PM_SLEEP_MODE_DEEP\n\r"); + break; + case PM_SLEEP_MODE_STANDBY: rt_kprintf("PM_SLEEP_MODE_STANDBY\n\r"); + break; + case PM_SLEEP_MODE_SHUTDOWN: rt_kprintf("PM_SLEEP_MODE_SHUTDOWN\n\r"); + break; + case PM_SLEEP_MODE_MAX: rt_kprintf("PM_SLEEP_MODE_MAX\n\r"); + break; + default: break; + } + +} + +/* pm测试函数 */ +static void pm_test(void *parameter) +{ + int in_mode[7],i = 0; + + g_pm_data.in_fun_times = 0; + g_pm_data.flag = 0; + + in_mode[0] = PM_SLEEP_MODE_NONE; + in_mode[1] = PM_SLEEP_MODE_IDLE; + in_mode[2] = PM_SLEEP_MODE_LIGHT; + in_mode[3] = PM_SLEEP_MODE_DEEP; + in_mode[4] = PM_SLEEP_MODE_STANDBY; + in_mode[5] = PM_SLEEP_MODE_SHUTDOWN; + in_mode[6] = PM_SLEEP_MODE_MAX; + + /*设置回调函数和私有数据*/ + rt_pm_notify_set(sleep_in_out_callback,RT_NULL); + + while(i < SLEEP_TIMES) + { + + g_pm_data.mode = in_mode[i%6]; + + /*无休眠模式,不赋予标志*/ + if(g_pm_data.mode != PM_SLEEP_MODE_NONE) + { + g_pm_data.flag = 2; + + } + + /*请求选择的休眠模式*/ + rt_pm_request(in_mode[i%6]); + + rt_thread_mdelay(500); + + /*无休眠模式,不需要额外的等待*/ + while(( g_pm_data.flag != 0 )&&(g_pm_data.mode != PM_SLEEP_MODE_NONE)) + { + rt_thread_mdelay(500); + } + + /*释放选择的休眠模式*/ + rt_pm_release(in_mode[i%6]); + + i++; + + } + /*清除回调函数和私有数据*/ + rt_pm_notify_set(RT_NULL,RT_NULL); + rt_kprintf("thread pm_test close\n\r"); +} + +/*按键唤醒的回调函数*/ +void wake_by_pin(void *args) +{ + +} + +static int pm_sample(int argc, char *argv[]) +{ + rt_thread_t thread; + + /* 按键引脚为输入模式 */ + rt_pin_mode(WAKE_UP_PIN, PIN_MODE_INPUT_PULLUP); + + /* 绑定中断,下降沿模式,回调函数名为wake_by_pin */ + rt_pin_attach_irq(WAKE_UP_PIN, PIN_IRQ_MODE_RISING, wake_by_pin, RT_NULL); + /* 使能中断 */ + rt_pin_irq_enable(WAKE_UP_PIN, PIN_IRQ_ENABLE); + + thread = rt_thread_create("pm_test", pm_test, RT_NULL, 1024, 25, 10); + + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + rt_kprintf("create pm_test thread failed!\n\r"); + } + + return RT_EOK; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(pm_sample, pm sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/pwm_led_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/pwm_led_sample.c new file mode 100644 index 0000000000..ce1573aa55 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/pwm_led_sample.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-25 misonyo first implementation. + */ +/* + * 程序清单:这是一个 PWM 设备使用例程 + * 例程导出了 pwm_led_sample 命令到控制终端 + * 命令调用格式:pwm_led_sample + * 程序功能:通过 PWM 设备控制 LED 灯的亮度,可以看到LED不停的由暗变到亮,然后又从亮变到暗。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define LED_PIN_NUM 16 /* LED PIN脚编号,查看驱动文件drv_gpio.c确定 */ +#define PWM_DEV_NAME "pwm1" /* PWM设备名称 */ +#define PWM_DEV_CHANNEL 4 /* PB9 PWM通道 */ + +struct rt_device_pwm *pwm_dev; /* PWM设备句柄 */ + +static int pwm_led_sample(int argc, char *argv[]) +{ + rt_uint32_t period, pulse, dir; + + period = 500000; /* 周期为0.5ms,单位为纳秒ns */ + dir = 1; /* PWM脉冲宽度值的增减方向 */ + pulse = 0; /* PWM脉冲宽度值,单位为纳秒ns */ + + /* 查找设备 */ + pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME); + if (pwm_dev == RT_NULL) + { + rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME); + return RT_ERROR; + } + + /* 设置PWM周期和脉冲宽度默认值 */ + rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); + /* 使能设备 */ + rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL); + + while (1) + { + rt_thread_mdelay(50); + if (dir) + { + pulse += 5000; /* 从0值开始每次增加5000ns */ + } + else + { + pulse -= 5000; /* 从最大值开始每次减少5000ns */ + } + if (pulse >= period) + { + dir = 0; + } + if (0 == pulse) + { + dir = 1; + } + + /* 设置PWM周期和脉冲宽度 */ + rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); + } +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(pwm_led_sample, pwm sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/rtc_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/rtc_sample.c new file mode 100644 index 0000000000..711a3a0ebb --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/rtc_sample.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-30 misonyo first implementation. + */ +/* + * 程序清单:这是一个 RTC 设备使用例程 + * 例程导出了 rtc_sample 命令到控制终端 + * 命令调用格式:rtc_sample + * 程序功能:设置RTC设备的日期和时间,延时一段时间后获取当前时间并打印显示。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +static int rtc_sample(int argc, char *argv[]) +{ + rt_err_t ret = RT_EOK; + time_t now; + + /* 设置日期 */ + ret = set_date(2018, 12, 3); + if (ret != RT_EOK) + { + rt_kprintf("set RTC date failed\n"); + return ret; + } + + /* 设置时间 */ + ret = set_time(11, 15, 50); + if (ret != RT_EOK) + { + rt_kprintf("set RTC time failed\n"); + return ret; + } + + /* 延时3秒 */ + rt_thread_mdelay(3000); + + /* 获取时间 */ + now = time(RT_NULL); + rt_kprintf("%s\n", ctime(&now)); + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(rtc_sample, rtc sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/spi_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/spi_sample.c new file mode 100644 index 0000000000..994888cdb0 --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/spi_sample.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy first implementation. + */ +/* + * 程序清单:这是一个 SPI 设备使用例程 + * 例程导出了 spi_io_sample 命令到控制终端 + * 命令调用格式:spi_io_sample + * 程序功能:通过SPI设备先读取数据,然后每个字符加1后输出。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define SPI_DEVICE_NAME "spi00" +#define BUF_LEN 16 + +static void spi_io_sample(int argc, char *argv[]) +{ + struct rt_spi_device * spi_dev; /* spi设备的句柄 */ + struct rt_spi_configuration spi_config; + rt_uint8_t i,buffer[BUF_LEN] = { 0U }; + rt_err_t s_stat; + rt_err_t result; + + /* 查找 spi设备 获取spi设备句柄 */ + spi_dev = (struct rt_spi_device *)rt_device_find(SPI_DEVICE_NAME); + + if (spi_dev == RT_NULL) + { + rt_kprintf("spi sample run failed! can't find %s device!\n", SPI_DEVICE_NAME); + return; + } + + + /* 清空配置结构体 */ + rt_memset(&spi_config,0,sizeof(struct rt_spi_configuration)); + + spi_config.mode &= ~RT_SPI_SLAVE; /* 主机模式 */ + spi_config.mode &= ~RT_SPI_3WIRE; /* 4线,双向传输 */ + spi_config.mode |= RT_SPI_CPHA; /* 第二边沿采样 */ + spi_config.mode |= RT_SPI_CPOL; /* 空闲高电平 */ + spi_config.mode |= RT_SPI_NO_CS; /* 禁用软件从机选择管理 */ + spi_config.mode |= RT_SPI_MSB; /* 高位在前 */ + + spi_config.data_width = 8; /* 数据长度:8 */ + + spi_config.max_hz = 2000000; /* 最快时钟频率 */ + + /* 配置SPI设备 */ + s_stat = rt_spi_configure(spi_dev,&spi_config); + + if(s_stat != RT_EOK) + { + rt_kprintf(" spi config fail !\n "); + return; + } + + + /* 获取总线 ,防止总线被多个线程同时使用 */ + result = rt_spi_take_bus(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s take spi bus failed! \n", SPI_DEVICE_NAME); + return; + } + + /* 选中片选 */ + result = rt_spi_take(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s take spi cs failed! \n", SPI_DEVICE_NAME); + return; + } + + + /*接收一次数据*/ + result = rt_spi_recv(spi_dev,buffer,BUF_LEN); + + if(result != BUF_LEN) + { + rt_kprintf("receive fail. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + return; + } + + rt_kprintf("receive successful. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + /* 将接收到的数据加1 */ + for( i = 0 ; i < BUF_LEN ; i++) + buffer[i]++; + + /*发送数据*/ + result = rt_spi_send(spi_dev,buffer,BUF_LEN); + + if(result != BUF_LEN) + { + rt_kprintf("send fail. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + return; + } + + rt_kprintf("send successful. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + /* 释放片选 */ + result = rt_spi_release(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s release spi cs failed! \n", SPI_DEVICE_NAME); + return; + } + + /* 释放总线 */ + result = rt_spi_release_bus(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s release spi bus failed! \n", SPI_DEVICE_NAME); + return; + } + +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(spi_io_sample, spi sample); diff --git a/bsp/essemi/es32f0654/drivers/bsp_driver_example/uart_sample.c b/bsp/essemi/es32f0654/drivers/bsp_driver_example/uart_sample.c new file mode 100644 index 0000000000..cb750efe6e --- /dev/null +++ b/bsp/essemi/es32f0654/drivers/bsp_driver_example/uart_sample.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-08-15 misonyo first implementation. + */ +/* + * 程序清单:这是一个 串口 设备使用例程 + * 例程导出了 uart_sample 命令到控制终端 + * 命令调用格式:uart_sample uart2 + * 命令解释:命令第二个参数是要使用的串口设备名称,为空则使用默认的串口设备 + * 程序功能:通过串口输出字符串"hello RT-Thread!",然后错位输出输入的字符 +*/ + +#include <rtthread.h> + +#define SAMPLE_UART_NAME "uart2" /* 串口设备名称 */ + +/* 用于接收消息的信号量 */ +static struct rt_semaphore rx_sem; +static rt_device_t serial; + +/* 接收数据回调函数 */ +static rt_err_t uart_input(rt_device_t dev, rt_size_t size) +{ + /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ + rt_sem_release(&rx_sem); + + return RT_EOK; +} + +static void serial_thread_entry(void *parameter) +{ + char ch; + + while (1) + { + /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */ + while (rt_device_read(serial, -1, &ch, 1) != 1) + { + /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ + rt_sem_take(&rx_sem, RT_WAITING_FOREVER); + } + /* 读取到的数据通过串口错位输出 */ + ch = ch + 1; + rt_device_write(serial, 0, &ch, 1); + } +} + +static int uart_sample(int argc, char *argv[]) +{ + rt_err_t ret = RT_EOK; + char uart_name[RT_NAME_MAX]; + char str[] = "hello RT-Thread!\r\n"; + + if (argc == 2) + { + rt_strncpy(uart_name, argv[1], RT_NAME_MAX); + } + else + { + rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); + } + + /* 查找串口设备 */ + serial = rt_device_find(uart_name); + if (!serial) + { + rt_kprintf("find %s failed!\n", uart_name); + return RT_ERROR; + } + + /* 初始化信号量 */ + rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); + /* 以中断接收及轮询发送方式打开串口设备 */ + rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); + /* 设置接收回调函数 */ + rt_device_set_rx_indicate(serial, uart_input); + /* 发送字符串 */ + rt_device_write(serial, 0, str, (sizeof(str) - 1)); + + /* 创建 serial 线程 */ + rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); + /* 创建成功则启动线程 */ + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + ret = RT_ERROR; + } + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(uart_sample, uart device sample); diff --git a/bsp/essemi/es32f0654/figures/内核用例.PNG b/bsp/essemi/es32f0654/figures/内核用例.PNG new file mode 100644 index 0000000000..4c4f8e05ba Binary files /dev/null and b/bsp/essemi/es32f0654/figures/内核用例.PNG differ diff --git a/bsp/essemi/es32f0654/figures/内核配置.PNG b/bsp/essemi/es32f0654/figures/内核配置.PNG new file mode 100644 index 0000000000..f5901c0e59 Binary files /dev/null and b/bsp/essemi/es32f0654/figures/内核配置.PNG differ diff --git a/bsp/essemi/es32f0654/figures/驱动用例.PNG b/bsp/essemi/es32f0654/figures/驱动用例.PNG new file mode 100644 index 0000000000..a93b4186ae Binary files /dev/null and b/bsp/essemi/es32f0654/figures/驱动用例.PNG differ diff --git a/bsp/essemi/es32f0654/figures/驱动配置.PNG b/bsp/essemi/es32f0654/figures/驱动配置.PNG new file mode 100644 index 0000000000..8ec566f7ab Binary files /dev/null and b/bsp/essemi/es32f0654/figures/驱动配置.PNG differ diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/.gitignore b/bsp/essemi/es32f369x/drivers/bsp_driver_example/.gitignore new file mode 100644 index 0000000000..c6127b38c1 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/README.md b/bsp/essemi/es32f369x/drivers/bsp_driver_example/README.md new file mode 100644 index 0000000000..80f12e1949 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/README.md @@ -0,0 +1,47 @@ +# 外设驱动测试用例 + +## 1、介绍 + +这个软件包包含一些外设设备操作的例程。 + +### 1.1 例程说明 + +| 文件 | 说明 | +| ---------------- | ------------------------------- | +| adc_vol_sample.c | 使用 ADC 设备转换电压数据 | +| can_sample.c | 通过 CAN 设备发送一帧,并创建一个线程接收数据然后打印输出。 | +| hwtimer_sample.c | 使用 硬件定时器定时 | +| i2c_sample.c | 使用 i2c 设备进行读写 | +| pm.c | 反复进入不同程度的睡眠。 | +| led_blink_sample.c | 使用 pin 设备控制 LED 闪烁 | +| pin_beep_sample.c | 使用 pin 设备控制蜂鸣器 | +| pwm_led_sample.c | 使用 pwm 设备控制 LED 的亮度 | +| rtc_sample.c | 使用 rtc 设备设置年月日时分秒信息 | +| spi_sample.c | 使用 spi 设备进行读写 | +| uart_sample.c | 使用 serial 设备中断接收及轮询发送模式收发数据 | + +### 1.2 依赖 + +依赖设备管理模块提供的设备驱动。 + +## 2、如何打开 外设驱动测试用例 + +使用 外设驱动测试用例 需要在 RT-Thread 的menuconfig中选择它,具体路径如下: + +``` +Hardware Driver Config ---> + Peripheral Driver test example---> +``` + +## 3、使用 外设驱动测试用例 + +在打开 Peripheral Driver test example 后,当进行 BSP 编译时,选择的软件包相关源代码会被加入到 BSP 工程中进行编译。 + +## 4、注意事项 + +暂无。 + +## 5、联系方式 & 感谢 + +* 维护:[misonyo](https://github.com/misonyo) +* 主页:https://github.com/RT-Thread-packages/peripheral-sample diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/adc_vol_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/adc_vol_sample.c new file mode 100644 index 0000000000..f9444982d4 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/adc_vol_sample.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-29 misonyo first implementation. + */ +/* + * 程序清单: ADC 设备使用例程 + * 例程导出了 adc_sample 命令到控制终端 + * 命令调用格式:adc_sample + * 程序功能:通过 ADC 设备采样电压值并转换为数值。 + * 示例代码参考电压为3.3V,转换位数为12位。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define ADC_DEV_NAME "adc0" /* ADC 设备名称 */ +#define ADC_DEV_CHANNEL 5 /* ADC 通道 5 PA1*/ +#define REFER_VOLTAGE 330 /* 参考电压 3.3V,数据精度乘以100保留2位小数*/ +#define CONVERT_BITS (1 << 12) /* 转换位数为12位 */ + +static int adc_vol_sample(int argc, char *argv[]) +{ + rt_adc_device_t adc_dev; + rt_uint32_t value, vol; + rt_err_t ret = RT_EOK; + + /* 查找设备 */ + adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME); + if (adc_dev == RT_NULL) + { + rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME); + return RT_ERROR; + } + + /* 使能设备 */ + ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL); + + /* 读取采样值 */ + value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL); + rt_kprintf("the value is :%d \n", value); + + /* 转换为对应电压值 */ + vol = value * REFER_VOLTAGE / CONVERT_BITS; + rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100); + + /* 关闭通道 */ + ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL); + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/can_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/can_sample.c new file mode 100644 index 0000000000..bfbd50095e --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/can_sample.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-06-25 misonyo first implementation. + */ +/* + * 程序清单:这是一个 CAN 设备使用例程 + * 例程导出了 can_sample 命令到控制终端 + * 命令调用格式:can_sample can + * 命令解释:命令第二个参数是要使用的 CAN 设备名称,为空则使用默认的 CAN 设备 + * 程序功能:通过 CAN 设备发送一帧,并创建一个线程接收数据然后打印输出。 +*/ + +#include <rtthread.h> +#include "rtdevice.h" + +#define CAN_DEV_NAME "can" /* CAN 设备名称 */ + +static struct rt_semaphore rx_sem; /* 用于接收消息的信号量 */ +static rt_device_t can_dev; /* CAN 设备句柄 */ + +/* 接收数据回调函数 */ +static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size) +{ + /* CAN 接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ + rt_sem_release(&rx_sem); + + return RT_EOK; +} + +static void can_rx_thread(void *parameter) +{ + int i; + struct rt_can_msg rxmsg = {0}; + + /* 设置接收回调函数 */ + rt_device_set_rx_indicate(can_dev, can_rx_call); + +#ifdef RT_CAN_USING_HDR + + rt_err_t res; + + struct rt_can_filter_item items[5] = + { + RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x100~0x1ff,hdr为-1,设置默认过滤表 */ + RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x300~0x3ff,hdr为-1 */ + RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 0, 0x7ff, RT_NULL, RT_NULL), /* std,match ID:0x211,hdr为-1 */ + RT_CAN_FILTER_STD_INIT(0x486, RT_NULL, RT_NULL), /* std,match ID:0x486,hdr为-1 */ + {0x555, 0, 0, 0, 0x7ff, 7,} /* std,match ID:0x555,hdr为7,指定设置7号过滤表 */ + }; + struct rt_can_filter_config cfg = {5, 1, items}; /* 一共有5个过滤表 */ + /* 设置硬件过滤表 */ + res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg); + RT_ASSERT(res == RT_EOK); +#endif + + while (1) + { + /* hdr值为-1,表示直接从uselist链表读取数据 */ + rxmsg.hdr = -1; + /* 阻塞等待接收信号量 */ + rt_sem_take(&rx_sem, RT_WAITING_FOREVER); + /* 从CAN读取一帧数据 */ + rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg)); + /* 打印数据ID及内容 */ + rt_kprintf("ID:%x ", rxmsg.id); + for (i = 0; i < 8; i++) + { + rt_kprintf("%2x ", rxmsg.data[i]); + } + + rt_kprintf("\n"); + } +} + +int can_sample(int argc, char *argv[]) +{ + struct rt_can_msg msg = {0}; + rt_err_t res; + rt_size_t size; + rt_thread_t thread; + char can_name[RT_NAME_MAX]; + + if (argc == 2) + { + rt_strncpy(can_name, argv[1], RT_NAME_MAX); + } + else + { + rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX); + } + + can_dev = rt_device_find(can_name); + if (!can_dev) + { + rt_kprintf("find %s failed!\n", can_name); + return RT_ERROR; + } + + /* 初始化CAN接收信号量 */ + rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); + + /* 以中断接收及发送方式打开CAN设备 */ + res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX); + RT_ASSERT(res == RT_EOK); + + thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10); + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + rt_kprintf("create can_rx thread failed!\n"); + } + + msg.id = 0x78; /* ID为0x78 */ + msg.ide = RT_CAN_STDID; /* 标准格式 */ + msg.rtr = RT_CAN_DTR; /* 数据帧 */ + msg.len = 8; /* 数据长度为8 */ + /* 待发送的8字节数据 */ + msg.data[0] = 0x00; + msg.data[1] = 0x11; + msg.data[2] = 0x22; + msg.data[3] = 0x33; + msg.data[4] = 0x44; + msg.data[5] = 0x55; + msg.data[6] = 0x66; + msg.data[7] = 0x77; + /* 发送一帧CAN数据 */ + size = rt_device_write(can_dev, 0, &msg, sizeof(msg)); + if (size == 0) + { + rt_kprintf("can dev write data failed!\n"); + } + + return res; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(can_sample, can device sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/hwtimer_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/hwtimer_sample.c new file mode 100644 index 0000000000..e2e39664f3 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/hwtimer_sample.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-30 misonyo first implementation. + */ +/* + * 程序清单:这是一个 hwtimer 设备使用例程 + * 例程导出了 hwtimer_sample 命令到控制终端 + * 命令调用格式:hwtimer_sample + * 程序功能:硬件定时器超时回调函数周期性的打印当前tick值,2次tick值之差换算为时间等同于定时时间值。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define HWTIMER_DEV_NAME "timer0" /* 定时器名称 */ + +/* 定时器超时回调函数 */ +static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size) +{ + rt_kprintf("tick is :%d !\n", rt_tick_get()); + + return 0; +} + +static int hwtimer_sample(int argc, char *argv[]) +{ + rt_err_t ret = RT_EOK; + rt_hwtimerval_t timeout_s; /* 定时器超时值 */ + rt_device_t hw_dev = RT_NULL; /* 定时器设备句柄 */ + rt_hwtimer_mode_t mode; /* 定时器模式 */ + + /* 查找定时器设备 */ + hw_dev = rt_device_find(HWTIMER_DEV_NAME); + if (hw_dev == RT_NULL) + { + rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_NAME); + return RT_ERROR; + } + + /* 以读写方式打开设备 */ + ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR); + if (ret != RT_EOK) + { + rt_kprintf("open %s device failed!\n", HWTIMER_DEV_NAME); + return ret; + } + + /* 设置超时回调函数 */ + rt_device_set_rx_indicate(hw_dev, timeout_cb); + + /* 设置模式为周期性定时器 */ + mode = HWTIMER_MODE_PERIOD; + ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode); + if (ret != RT_EOK) + { + rt_kprintf("set mode failed! ret is :%d\n", ret); + return ret; + } + + /* 设置定时器超时值为5s并启动定时器 */ + timeout_s.sec = 5; /* 秒 */ + timeout_s.usec = 0; /* 微秒 */ + + if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s)) + { + rt_kprintf("set timeout value failed\n"); + return RT_ERROR; + } + + /* 延时3500ms */ + rt_thread_mdelay(3500); + + /* 读取定时器当前值 */ + rt_device_read(hw_dev, 0, &timeout_s, sizeof(timeout_s)); + rt_kprintf("Read: Sec = %d, Usec = %d\n", timeout_s.sec, timeout_s.usec); + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(hwtimer_sample, hwtimer sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/i2c_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/i2c_sample.c new file mode 100644 index 0000000000..4fd42baf41 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/i2c_sample.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy first implementation. + */ +/* + * 程序清单:这是一个 I2C 设备使用例程 + * 例程导出了 i2c_io_sample 命令到控制终端 + * 命令调用格式:i2c_io_sample + * 命令解释:使用默认的I2C总线设备i2c0 + * 程序功能:通过 I2C 设备接收数据并打印,然后将接收的字符加1输出。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define I2C_BUS_NAME "i2c0" /* I2C总线设备名称 */ +#define SLAVE_ADDR 0x2D /* 从机地址 */ +#define STR_LEN 16 /* 接收发送的数据长度 */ + +static void i2c_io_sample(int argc, char *argv[]) +{ + + struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄 */ + struct rt_i2c_msg temp_msg; /* I2C消息 */ + rt_uint8_t buffer[STR_LEN] = { 0U }; + rt_uint32_t i,num_msg; + rt_size_t s_stat; + + i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(I2C_BUS_NAME); /* 通过名字获取I2C总线设备的句柄 */ + + if( i2c_bus == RT_NULL) + { + rt_kprintf("can't find i2c device :%s !\n",I2C_BUS_NAME); + + return; + } + + /*初始化消息*/ + temp_msg.addr = SLAVE_ADDR; /* 从机地址 */ + temp_msg.len = STR_LEN; /* 传输的数据长度 */ + temp_msg.buf = buffer; /* 读写缓存器 */ + + num_msg = 1; /* 传输一条消息 */ + + temp_msg.flags = RT_I2C_RD; /* I2C读 */ + s_stat = rt_i2c_transfer(i2c_bus,&temp_msg,num_msg); /* 传输消息 */ + + rt_thread_mdelay(400); + + if( s_stat == num_msg ) + { + rt_kprintf("receive successful. \n receive messege : %s \n:",buffer); + + for( i = 0 ; i < STR_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + } + else + { + rt_kprintf("device s% recieve fail \n buffer : s%\n",I2C_BUS_NAME,buffer); + return; + } + + for( i = 0 ; i < STR_LEN ; i++) + buffer[i]++; + + temp_msg.flags = RT_I2C_WR; /* I2C写 */ + s_stat = rt_i2c_transfer(i2c_bus,&temp_msg,num_msg); /* 传输一条 */ + + rt_thread_mdelay(400); + + if( s_stat == num_msg ) + { + rt_kprintf(" send successful \n messege : %s \n:",buffer); + + for( i = 0 ; i < STR_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + } + else + { + rt_kprintf("device s% send fail \n",I2C_BUS_NAME); + return; + } + + return; + +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(i2c_io_sample, i2c io sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/led_blink_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/led_blink_sample.c new file mode 100644 index 0000000000..f1c9901ad0 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/led_blink_sample.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-09-25 misonyo first edition. + */ +/* + * 程序清单:这是一个通过PIN脚控制LED亮灭的使用例程 + * 例程导出了 led_sample 命令到控制终端 + * 命令调用格式:led_sample 41 + * 命令解释:命令第二个参数是要使用的PIN脚编号,为空则使用例程默认的引脚编号。 + * 程序功能:程序创建一个led线程,线程每隔1000ms改变PIN脚状态,达到控制led灯 + * 亮灭的效果。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> +#include <stdlib.h> + +/* PIN脚编号,查看驱动文件drv_gpio.c确定 */ +#define LED_PIN_NUM 19 /*PF1*/ +static int pin_num; + +static void led_entry(void *parameter) +{ + int count = 0; + /* 设置PIN脚模式为输出 */ + rt_pin_mode(pin_num, PIN_MODE_OUTPUT); + + while (1) + { + count++; + rt_kprintf("thread run count : %d\r\n", count); + /* 拉低PIN脚 */ + rt_pin_write(pin_num, PIN_LOW); + rt_kprintf("led on!\r\n"); + /* 延时1000ms */ + rt_thread_mdelay(1000); + + /* 拉高PIN脚 */ + rt_pin_write(pin_num, PIN_HIGH); + rt_kprintf("led off!\r\n"); + rt_thread_mdelay(1000); + } +} + +static int led_sample(int argc, char *argv[]) +{ + rt_thread_t tid; + rt_err_t ret = RT_EOK; + + /* 判断命令行参数是否给定了PIN脚编号 */ + if (argc == 2) + { + pin_num = atoi(argv[1]); + } + else + { + pin_num = LED_PIN_NUM; + } + + tid = rt_thread_create("led", + led_entry, + RT_NULL, + 512, + RT_THREAD_PRIORITY_MAX / 3, + 20); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } + else + { + ret = RT_ERROR; + } + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(led_sample, led sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/pin_beep_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/pin_beep_sample.c new file mode 100644 index 0000000000..58a7bf1891 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/pin_beep_sample.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-08-15 misonyo first implementation. + */ +/* + * 程序清单:这是一个 PIN 设备使用例程 + * 例程导出了 pin_beep_sample 命令到控制终端 + * 命令调用格式:pin_beep_sample + * 程序功能:通过按键控制蜂鸣器对应引脚的电平状态控制蜂鸣器 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +/* 引脚编号,通过查看驱动文件drv_gpio.c确定 */ +#ifndef BEEP_PIN_NUM + #define BEEP_PIN_NUM 19 /* PF1 */ +#endif +#ifndef KEY0_PIN_NUM + #define KEY0_PIN_NUM 52 /* PC11 */ +#endif +#ifndef KEY1_PIN_NUM + #define KEY1_PIN_NUM 53 /* PC12 */ +#endif + +void beep_on(void *args) +{ + rt_kprintf("turn on beep!\n"); + + rt_pin_write(BEEP_PIN_NUM, PIN_HIGH); +} + +void beep_off(void *args) +{ + rt_kprintf("turn off beep!\n"); + + rt_pin_write(BEEP_PIN_NUM, PIN_LOW); +} + +static void pin_beep_sample(void) +{ + /* 蜂鸣器引脚为输出模式 */ + rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT); + /* 默认低电平 */ + rt_pin_write(BEEP_PIN_NUM, PIN_LOW); + + /* 按键0引脚为输入模式 */ + rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP); + /* 绑定中断,下降沿模式,回调函数名为beep_on */ + rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL); + /* 使能中断 */ + rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE); + + /* 按键1引脚为输入模式 */ + rt_pin_mode(KEY1_PIN_NUM, PIN_MODE_INPUT_PULLUP); + /* 绑定中断,下降沿模式,回调函数名为beep_off */ + rt_pin_attach_irq(KEY1_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_off, RT_NULL); + /* 使能中断 */ + rt_pin_irq_enable(KEY1_PIN_NUM, PIN_IRQ_ENABLE); +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(pin_beep_sample, pin beep sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/pm_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/pm_sample.c new file mode 100644 index 0000000000..b886876108 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/pm_sample.c @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy first implementation. + */ +/* + * 程序清单:这是一个 pm睡眠唤醒的使用例程 + * 例程导出了 pm_sample 命令到控制终端 + * 命令调用格式:pm_sample + * 命令解释:进入不同的睡眠模式,然后用按键唤醒 + * 程序功能:通过串口输出字符串,告知进入睡眠和唤醒睡眠的情况。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> +#include "drv_pm.h" + +#define PM_NAME "pm" /* 设备名称 */ +#define WAKE_UP_PIN 51 /* 唤醒源 */ +#define SLEEP_TIMES 12 /* 进入睡眠次数,轮流进入不同的睡眠模式,包括无睡眠模式 */ + + +struct pm_callback_t +{ + volatile int in_fun_times; /*进入函数的次数*/ + volatile char flag; /*标志*/ + volatile int mode; /*需要打印的模式*/ +}; + +volatile struct pm_callback_t g_pm_data; + +uint32_t save_load_mem[1024] __attribute__ ((aligned(4))); /*备份的空间*/ + +/*进入睡眠前,睡眠唤醒后,都会进入。*/ +/*函数打印睡眠相关的信息*/ +void sleep_in_out_callback(rt_uint8_t event, rt_uint8_t mode, void *data) +{ + /*没有标志,不处理*/ + if(!(g_pm_data.flag)) + { + return; + } + + /*标志不正常,清空标志*/ + if((g_pm_data.flag) > 2) + { + (g_pm_data.flag) = 0; + return; + } + + /*模式不匹配*/ + if(g_pm_data.mode != mode ) + { + return; + } + + /*进入的事件*/ + switch(event) + { + /*进入睡眠前*/ + case RT_PM_ENTER_SLEEP: g_pm_data.flag = 1; + rt_kprintf("\n\r##%d : ENTER ",g_pm_data.in_fun_times); + save_register(UART0,sizeof(UART_TypeDef),save_load_mem); /*备份寄存器的值*/ + g_pm_data.in_fun_times++; /*进入睡眠次数+1*/ + break; + /*睡眠唤醒后*/ + case RT_PM_EXIT_SLEEP: g_pm_data.flag = 0; /*睡眠唤醒后*/ + load_register(UART0,sizeof(UART_TypeDef),save_load_mem); /*还原寄存器的值*/ + rt_kprintf("\n\rEXIT\n\r"); + rt_pm_release(mode); /*释放休眠模式*/ + return; + + default: break; + + }; + + /*当前的睡眠模式*/ + switch(mode) + { + case PM_SLEEP_MODE_NONE: rt_kprintf("PM_SLEEP_MODE_NONE\n\r"); + break; + case PM_SLEEP_MODE_IDLE: rt_kprintf("PM_SLEEP_MODE_IDLE\n\r"); + break; + case PM_SLEEP_MODE_LIGHT: rt_kprintf("PM_SLEEP_MODE_LIGHT\n\r"); + break; + case PM_SLEEP_MODE_DEEP: rt_kprintf("PM_SLEEP_MODE_DEEP\n\r"); + break; + case PM_SLEEP_MODE_STANDBY: rt_kprintf("PM_SLEEP_MODE_STANDBY\n\r"); + break; + case PM_SLEEP_MODE_SHUTDOWN: rt_kprintf("PM_SLEEP_MODE_SHUTDOWN\n\r"); + break; + case PM_SLEEP_MODE_MAX: rt_kprintf("PM_SLEEP_MODE_MAX\n\r"); + break; + default: break; + } + +} + +/* pm测试函数 */ +static void pm_test(void *parameter) +{ + int in_mode[7],i = 0; + + g_pm_data.in_fun_times = 0; + g_pm_data.flag = 0; + + in_mode[0] = PM_SLEEP_MODE_NONE; + in_mode[1] = PM_SLEEP_MODE_IDLE; + in_mode[2] = PM_SLEEP_MODE_LIGHT; + in_mode[3] = PM_SLEEP_MODE_DEEP; + in_mode[4] = PM_SLEEP_MODE_STANDBY; + in_mode[5] = PM_SLEEP_MODE_SHUTDOWN; + in_mode[6] = PM_SLEEP_MODE_MAX; + + /*设置回调函数和私有数据*/ + rt_pm_notify_set(sleep_in_out_callback,RT_NULL); + + while(i < SLEEP_TIMES) + { + + g_pm_data.mode = in_mode[i%6]; + + /*无休眠模式,不赋予标志*/ + if(g_pm_data.mode != PM_SLEEP_MODE_NONE) + { + g_pm_data.flag = 2; + + } + + /*请求选择的休眠模式*/ + rt_pm_request(in_mode[i%6]); + + rt_thread_mdelay(500); + + /*无休眠模式,不需要额外的等待*/ + while(( g_pm_data.flag != 0 )&&(g_pm_data.mode != PM_SLEEP_MODE_NONE)) + { + rt_thread_mdelay(500); + } + + /*释放选择的休眠模式*/ + rt_pm_release(in_mode[i%6]); + + i++; + + } + /*清除回调函数和私有数据*/ + rt_pm_notify_set(RT_NULL,RT_NULL); + rt_kprintf("thread pm_test close\n\r"); + +} + +/*按键唤醒的回调函数*/ +void wake_by_pin(void *args) +{ + +} + +static int pm_sample(int argc, char *argv[]) +{ + rt_thread_t thread; + + /* 按键引脚为输入模式 */ + rt_pin_mode(WAKE_UP_PIN, PIN_MODE_INPUT_PULLUP); + + /* 绑定中断,下降沿模式,回调函数名为wake_by_pin */ + rt_pin_attach_irq(WAKE_UP_PIN, PIN_IRQ_MODE_RISING, wake_by_pin, RT_NULL); + /* 使能中断 */ + rt_pin_irq_enable(WAKE_UP_PIN, PIN_IRQ_ENABLE); + + thread = rt_thread_create("pm_test", pm_test, RT_NULL, 1024, 25, 10); + + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + rt_kprintf("create pm_test thread failed!\n\r"); + } + + return RT_EOK; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(pm_sample, pm sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/pwm_led_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/pwm_led_sample.c new file mode 100644 index 0000000000..df82c1b41c --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/pwm_led_sample.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-25 misonyo first implementation. + */ +/* + * 程序清单:这是一个 PWM 设备使用例程 + * 例程导出了 pwm_led_sample 命令到控制终端 + * 命令调用格式:pwm_led_sample + * 程序功能:通过 PWM 设备控制 LED 灯的亮度,可以看到LED不停的由暗变到亮,然后又从亮变到暗。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define LED_PIN_NUM 19 /* PF1 LED PIN脚编号,查看驱动文件drv_gpio.c确定 */ +#define PWM_DEV_NAME "pwm1" /* PWM设备名称 */ +#define PWM_DEV_CHANNEL 2 /* PA1 PWM通道 */ + +struct rt_device_pwm *pwm_dev; /* PWM设备句柄 */ + +static int pwm_led_sample(int argc, char *argv[]) +{ + rt_uint32_t period, pulse, dir; + + period = 500000; /* 周期为0.5ms,单位为纳秒ns */ + dir = 1; /* PWM脉冲宽度值的增减方向 */ + pulse = 0; /* PWM脉冲宽度值,单位为纳秒ns */ + + /* 查找设备 */ + pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME); + if (pwm_dev == RT_NULL) + { + rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME); + return RT_ERROR; + } + + /* 设置PWM周期和脉冲宽度默认值 */ + rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); + /* 使能设备 */ + rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL); + + while (1) + { + rt_thread_mdelay(50); + if (dir) + { + pulse += 5000; /* 从0值开始每次增加5000ns */ + } + else + { + pulse -= 5000; /* 从最大值开始每次减少5000ns */ + } + if (pulse >= period) + { + dir = 0; + } + if (0 == pulse) + { + dir = 1; + } + + /* 设置PWM周期和脉冲宽度 */ + rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse); + } +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(pwm_led_sample, pwm sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/rtc_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/rtc_sample.c new file mode 100644 index 0000000000..711a3a0ebb --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/rtc_sample.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-30 misonyo first implementation. + */ +/* + * 程序清单:这是一个 RTC 设备使用例程 + * 例程导出了 rtc_sample 命令到控制终端 + * 命令调用格式:rtc_sample + * 程序功能:设置RTC设备的日期和时间,延时一段时间后获取当前时间并打印显示。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +static int rtc_sample(int argc, char *argv[]) +{ + rt_err_t ret = RT_EOK; + time_t now; + + /* 设置日期 */ + ret = set_date(2018, 12, 3); + if (ret != RT_EOK) + { + rt_kprintf("set RTC date failed\n"); + return ret; + } + + /* 设置时间 */ + ret = set_time(11, 15, 50); + if (ret != RT_EOK) + { + rt_kprintf("set RTC time failed\n"); + return ret; + } + + /* 延时3秒 */ + rt_thread_mdelay(3000); + + /* 获取时间 */ + now = time(RT_NULL); + rt_kprintf("%s\n", ctime(&now)); + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(rtc_sample, rtc sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/spi_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/spi_sample.c new file mode 100644 index 0000000000..994888cdb0 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/spi_sample.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy first implementation. + */ +/* + * 程序清单:这是一个 SPI 设备使用例程 + * 例程导出了 spi_io_sample 命令到控制终端 + * 命令调用格式:spi_io_sample + * 程序功能:通过SPI设备先读取数据,然后每个字符加1后输出。 +*/ + +#include <rtthread.h> +#include <rtdevice.h> + +#define SPI_DEVICE_NAME "spi00" +#define BUF_LEN 16 + +static void spi_io_sample(int argc, char *argv[]) +{ + struct rt_spi_device * spi_dev; /* spi设备的句柄 */ + struct rt_spi_configuration spi_config; + rt_uint8_t i,buffer[BUF_LEN] = { 0U }; + rt_err_t s_stat; + rt_err_t result; + + /* 查找 spi设备 获取spi设备句柄 */ + spi_dev = (struct rt_spi_device *)rt_device_find(SPI_DEVICE_NAME); + + if (spi_dev == RT_NULL) + { + rt_kprintf("spi sample run failed! can't find %s device!\n", SPI_DEVICE_NAME); + return; + } + + + /* 清空配置结构体 */ + rt_memset(&spi_config,0,sizeof(struct rt_spi_configuration)); + + spi_config.mode &= ~RT_SPI_SLAVE; /* 主机模式 */ + spi_config.mode &= ~RT_SPI_3WIRE; /* 4线,双向传输 */ + spi_config.mode |= RT_SPI_CPHA; /* 第二边沿采样 */ + spi_config.mode |= RT_SPI_CPOL; /* 空闲高电平 */ + spi_config.mode |= RT_SPI_NO_CS; /* 禁用软件从机选择管理 */ + spi_config.mode |= RT_SPI_MSB; /* 高位在前 */ + + spi_config.data_width = 8; /* 数据长度:8 */ + + spi_config.max_hz = 2000000; /* 最快时钟频率 */ + + /* 配置SPI设备 */ + s_stat = rt_spi_configure(spi_dev,&spi_config); + + if(s_stat != RT_EOK) + { + rt_kprintf(" spi config fail !\n "); + return; + } + + + /* 获取总线 ,防止总线被多个线程同时使用 */ + result = rt_spi_take_bus(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s take spi bus failed! \n", SPI_DEVICE_NAME); + return; + } + + /* 选中片选 */ + result = rt_spi_take(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s take spi cs failed! \n", SPI_DEVICE_NAME); + return; + } + + + /*接收一次数据*/ + result = rt_spi_recv(spi_dev,buffer,BUF_LEN); + + if(result != BUF_LEN) + { + rt_kprintf("receive fail. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + return; + } + + rt_kprintf("receive successful. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + /* 将接收到的数据加1 */ + for( i = 0 ; i < BUF_LEN ; i++) + buffer[i]++; + + /*发送数据*/ + result = rt_spi_send(spi_dev,buffer,BUF_LEN); + + if(result != BUF_LEN) + { + rt_kprintf("send fail. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + return; + } + + rt_kprintf("send successful. \n buffer is : %s \n:",buffer); + + for( i = 0 ; i < BUF_LEN ; i++) + rt_kprintf(" %x",(unsigned int)buffer[i]); + + rt_kprintf("\n"); + + /* 释放片选 */ + result = rt_spi_release(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s release spi cs failed! \n", SPI_DEVICE_NAME); + return; + } + + /* 释放总线 */ + result = rt_spi_release_bus(spi_dev); + + if (result != RT_EOK) + { + rt_kprintf(" %s release spi bus failed! \n", SPI_DEVICE_NAME); + return; + } + +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(spi_io_sample, spi sample); diff --git a/bsp/essemi/es32f369x/drivers/bsp_driver_example/uart_sample.c b/bsp/essemi/es32f369x/drivers/bsp_driver_example/uart_sample.c new file mode 100644 index 0000000000..e059df32bb --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/bsp_driver_example/uart_sample.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-08-15 misonyo first implementation. + */ +/* + * 程序清单:这是一个 串口 设备使用例程 + * 例程导出了 uart_sample 命令到控制终端 + * 命令调用格式:uart_sample uart2 + * 命令解释:命令第二个参数是要使用的串口设备名称,为空则使用默认的串口设备 + * 程序功能:通过串口输出字符串"hello RT-Thread!",然后错位输出输入的字符 +*/ + +#include <rtthread.h> + +#define SAMPLE_UART_NAME "uart0" /* 串口设备名称 */ + +/* 用于接收消息的信号量 */ +static struct rt_semaphore rx_sem; +static rt_device_t serial; + +/* 接收数据回调函数 */ +static rt_err_t uart_input(rt_device_t dev, rt_size_t size) +{ + /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */ + rt_sem_release(&rx_sem); + + return RT_EOK; +} + +static void serial_thread_entry(void *parameter) +{ + char ch; + + while (1) + { + /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */ + while (rt_device_read(serial, -1, &ch, 1) != 1) + { + /* 阻塞等待接收信号量,等到信号量后再次读取数据 */ + rt_sem_take(&rx_sem, RT_WAITING_FOREVER); + } + /* 读取到的数据通过串口错位输出 */ + ch = ch + 1; + rt_device_write(serial, 0, &ch, 1); + } +} + +static int uart_sample(int argc, char *argv[]) +{ + rt_err_t ret = RT_EOK; + char uart_name[RT_NAME_MAX]; + char str[] = "hello RT-Thread!\r\n"; + + if (argc == 2) + { + rt_strncpy(uart_name, argv[1], RT_NAME_MAX); + } + else + { + rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); + } + + /* 查找串口设备 */ + serial = rt_device_find(uart_name); + if (!serial) + { + rt_kprintf("find %s failed!\n", uart_name); + return RT_ERROR; + } + + /* 初始化信号量 */ + rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); + /* 以中断接收及轮询发送方式打开串口设备 */ + rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); + /* 设置接收回调函数 */ + rt_device_set_rx_indicate(serial, uart_input); + /* 发送字符串 */ + rt_device_write(serial, 0, str, (sizeof(str) - 1)); + + /* 创建 serial 线程 */ + rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); + /* 创建成功则启动线程 */ + if (thread != RT_NULL) + { + rt_thread_startup(thread); + } + else + { + ret = RT_ERROR; + } + + return ret; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(uart_sample, uart device sample); diff --git a/bsp/essemi/es32f369x/drivers/drv_pm.c b/bsp/essemi/es32f369x/drivers/drv_pm.c new file mode 100644 index 0000000000..ffe46ff6f3 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/drv_pm.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-12-15 liuhy the first version + */ + +#include "drv_pm.h" + +#ifdef RT_USING_PM + +//uint32_t save_mem[1024] __attribute__ ((aligned(4))); + +void save_register(void *p_head,uint32_t size,void *p_save) +{ + memcpy(p_save,p_head,size); +} + +void load_register(void *p_head,uint32_t size,void *p_load) +{ + uint32_t tmp; + memcpy(p_head,p_load,size); + + if((p_head == UART0) || (p_head == UART1) || (p_head == UART2) || + (p_head == UART3) || (p_head == UART4) || (p_head == UART5) ) + { + tmp = ((UART_TypeDef*)p_load)->IVS; + ((UART_TypeDef*)p_head)->IER = tmp; + } +} + +static void uart_console_reconfig(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + + rt_device_control(rt_console_get_device(), RT_DEVICE_CTRL_CONFIG, &config); +} + +static void delay(void) +{ + long i; + rt_base_t level; + + level = rt_hw_interrupt_disable(); + i = 0; + do{ + i++; + } + while (i < 4000000); + + rt_hw_interrupt_enable(level); +} + +/** + * This function will put ES32F369x into sleep mode. + * + * @param pm pointer to power manage structure + */ + +struct pm_callback_t +{ + volatile int in_fun_times; /*进入函数的次数*/ + volatile char flag; /*标志*/ + volatile int mode; /*需要打印的模式*/ +}; + +extern volatile struct pm_callback_t g_pm_data; + +static void sleep(struct rt_pm *pm, uint8_t mode) +{ + + switch (mode) + { + case PM_SLEEP_MODE_NONE: + break; + + case PM_SLEEP_MODE_IDLE: + break; + + case PM_SLEEP_MODE_LIGHT: + /* Enter SLEEP Mode, Main regulator is ON */ + ald_pmu_stop1_enter(); + delay(); + + break; + + case PM_SLEEP_MODE_DEEP: + /* Enter STOP 2 mode */ + ald_pmu_stop2_enter(); + delay(); + break; + + case PM_SLEEP_MODE_STANDBY: + /* Enter STANDBY mode */ + ald_pmu_stop2_enter(); + delay(); + break; + + case PM_SLEEP_MODE_SHUTDOWN: + /* Enter SHUTDOWNN mode */ + ald_pmu_stop2_enter(); + delay(); + break; + + default: + RT_ASSERT(0); + break; + } + +} + +static uint8_t run_speed[PM_RUN_MODE_MAX][2] = +{ + {48, 0}, + {48, 1}, + {24, 2}, + {2, 3}, +}; + +static void run(struct rt_pm *pm, uint8_t mode) +{ + static uint8_t last_mode; + static char *run_str[] = PM_RUN_MODE_NAMES; + extern uint32_t __system_clock; + + if (mode == last_mode) + return; + last_mode = mode; + + ald_cmu_clock_config_default(); + __system_clock = 24000000; + switch (mode) + { + case PM_RUN_MODE_HIGH_SPEED: + case PM_RUN_MODE_NORMAL_SPEED: + /* hosc 12MHz, from hosc/3 pll to 48MHz */ + ald_cmu_pll1_config(CMU_PLL1_INPUT_HRC_6, CMU_PLL1_OUTPUT_48M); + /* MCLK 48MHz */ + ald_cmu_clock_config(CMU_CLOCK_PLL1, 48000000); + break; + case PM_RUN_MODE_MEDIUM_SPEED: + break; + case PM_RUN_MODE_LOW_SPEED: + ald_cmu_clock_config(CMU_CLOCK_HRC, 2000000); + break; + default: + break; + } + + /* 4. 更新外设时钟 */ + uart_console_reconfig(); + /* Re-Configure the Systick time */ + SysTick_Config(ald_cmu_get_sys_clock() / RT_TICK_PER_SECOND); + + rt_kprintf("switch to %s mode, frequency = %d MHz\n", run_str[mode], run_speed[mode][0]); +} + +/** + * This function caculate the PM tick from OS tick + * + * @param tick OS tick + * + * @return the PM tick + */ +static rt_tick_t es32f3_pm_tick_from_os_tick(rt_tick_t tick) +{ + rt_uint32_t freq = 1; + + return (freq * tick / RT_TICK_PER_SECOND); +} + +/** + * This function caculate the OS tick from PM tick + * + * @param tick PM tick + * + * @return the OS tick + */ +static rt_tick_t es32f3_os_tick_from_pm_tick(rt_uint32_t tick) +{ + static rt_uint32_t os_tick_remain = 0; + rt_uint32_t ret, freq; + + freq = 1; + ret = (tick * RT_TICK_PER_SECOND + os_tick_remain) / freq; + + os_tick_remain += (tick * RT_TICK_PER_SECOND); + os_tick_remain %= freq; + + return ret; +} + +/** + * This function start the timer of pm + * + * @param pm Pointer to power manage structure + * @param timeout How many OS Ticks that MCU can sleep + */ +static void pm_timer_start(struct rt_pm *pm, rt_uint32_t timeout) +{ + RT_ASSERT(pm != RT_NULL); + RT_ASSERT(timeout > 0); + + if (timeout != RT_TICK_MAX) + { + /* Convert OS Tick to pmtimer timeout value */ + timeout = es32f3_pm_tick_from_os_tick(timeout); + /* MAX 0xFFFF */ + if (timeout > 0xFFFF) + { + timeout = 0xFFFF; + } + } +} + +/** + * This function stop the timer of pm + * + * @param pm Pointer to power manage structure + */ +static void pm_timer_stop(struct rt_pm *pm) +{ + RT_ASSERT(pm != RT_NULL); +} + +/** + * This function calculate how many OS Ticks that MCU have suspended + * + * @param pm Pointer to power manage structure + * + * @return OS Ticks + */ +static rt_tick_t pm_timer_get_tick(struct rt_pm *pm) +{ + rt_uint32_t timer_tick; + + RT_ASSERT(pm != RT_NULL); + + timer_tick = 1; + + return es32f3_os_tick_from_pm_tick(timer_tick); +} + +/** + * This function initialize the power manager + */ +int drv_pm_hw_init(void) +{ + static const struct rt_pm_ops _ops = + { + sleep, + run, + pm_timer_start, + pm_timer_stop, + pm_timer_get_tick + }; + + rt_uint8_t timer_mask = 0; + + /* initialize timer mask */ + timer_mask = 1UL << PM_SLEEP_MODE_DEEP; + + /* initialize system pm module */ + rt_system_pm_init(&_ops, timer_mask, RT_NULL); + + return 0; +} +INIT_BOARD_EXPORT(drv_pm_hw_init); + +#endif diff --git a/bsp/essemi/es32f369x/drivers/drv_pm.h b/bsp/essemi/es32f369x/drivers/drv_pm.h new file mode 100644 index 0000000000..56de29eef5 --- /dev/null +++ b/bsp/essemi/es32f369x/drivers/drv_pm.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-04-01 wangyq the first version + */ + +#ifndef DRV_PM_H__ +#define DRV_PM_H__ + +#include <rthw.h> +#include <board.h> +#include <rtdevice.h> +#include <ald_cmu.h> +#include <ald_pmu.h> +#include "shell.h" + +int rt_hw_pm_init(void); + +extern void save_register(void *p_head,uint32_t size,void *p_save); + +extern void load_register(void *p_head,uint32_t size,void *p_load); + +#endif diff --git a/bsp/essemi/es32f369x/figures/内核用例.PNG b/bsp/essemi/es32f369x/figures/内核用例.PNG new file mode 100644 index 0000000000..4c4f8e05ba Binary files /dev/null and b/bsp/essemi/es32f369x/figures/内核用例.PNG differ diff --git a/bsp/essemi/es32f369x/figures/内核配置.PNG b/bsp/essemi/es32f369x/figures/内核配置.PNG new file mode 100644 index 0000000000..f5901c0e59 Binary files /dev/null and b/bsp/essemi/es32f369x/figures/内核配置.PNG differ diff --git a/bsp/essemi/es32f369x/figures/驱动用例.PNG b/bsp/essemi/es32f369x/figures/驱动用例.PNG new file mode 100644 index 0000000000..a93b4186ae Binary files /dev/null and b/bsp/essemi/es32f369x/figures/驱动用例.PNG differ diff --git a/bsp/essemi/es32f369x/figures/驱动配置.PNG b/bsp/essemi/es32f369x/figures/驱动配置.PNG new file mode 100644 index 0000000000..8ec566f7ab Binary files /dev/null and b/bsp/essemi/es32f369x/figures/驱动配置.PNG differ