add synwit swm341 bsp (#6235)

华芯微特SWM341芯片的bsp支持包
* 修改dac.c函数名称错误
* delete swm320-lq100 bsp
* 修复sdio读写块的地址偏移问题
* add synwit swm341 bsp
* 修复gcc下启动文件错误
* 为测试用例添加说明
This commit is contained in:
woody
2022-08-14 10:29:05 +08:00
committed by GitHub
parent e4d6dd88c9
commit 0189987d91
179 changed files with 82972 additions and 0 deletions
+1
View File
@@ -172,6 +172,7 @@ jobs:
- {RTT_BSP: "wch/arm/ch32f103c8-core", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "wch/arm/ch32f203r-evt", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "swm320", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "swm341", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "beaglebone", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "zynqmp-r5-axu4ev", RTT_TOOL_CHAIN: "sourcery-arm"}
- {RTT_BSP: "frdm-k64f", RTT_TOOL_CHAIN: "sourcery-arm"}
+702
View File
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
mainmenu "RT-Thread Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config RTT_DIR
string
option env="RTT_ROOT"
default "../.."
config PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
source "drivers/Kconfig"
config SOC_SWM341
bool
select ARCH_ARM_CORTEX_M33
default y
+156
View File
@@ -0,0 +1,156 @@
# SWM341 BSP 说明
标签: SYNWIT、Cortex-M33、SWM341、国产MCU
---
## 简介
本文档为SWM341开发板提供的 BSP (板级支持包) 说明。
通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。
## 芯片介绍
- 内核
- 32位ARM® Cortex™-M33 内核
- 24位系统定时器
- 工作频率最高150MHz
- 硬件单周期乘法
- 集成嵌套向量中断控制器(NVIC),提供最多104个、8级可配置优先级的中断
- 通过SWD接口烧录
- 内置LDO
- 供电电压范围为2.0V至3.6V
- 片上SRAM存储器
- 64KB
- 片上FLASH存储器
- 512KB
- 支持用户定制ISP(在系统编程)更新用户程序
- 自带Cache
- SDRAMC模块
- 支持16Bit位宽的SDRAM
- 支持兼容PC133标准的SDRAM颗粒
- 支持2MB到32MB的外部SDRAM颗粒
- SFC模块
- 最大支持外置16MB大小的SPI NOR FLASH
- GPIO
- 多达7组共112个GPIO
- 每个IO均支持位带操作
- 灵活的中断配置
- 触发类型设置(边沿检测、电平检测)
- 触发电平设置(高电平、低电平)
- 触发边沿设置(上升沿、下降沿、双边沿)
- 串行接口
- 4路UART模块,具有独立8字节FIFO
- 2路SPI模块,具有8字节独立FIFO,支持SPI、SSI协议,支持Master/Slave模式
- 2路I2C模块,支持7位、10位地址方式,支持Master/Slave模式
- 2路CAN模块,支持协议2.0A(11Bit标识符)和2.0B29Bit标识符)
- 1路SDIO模块
- 1路USB OTG模块
- TFT-LCD驱动模块
- 支持SYNC接口和MPU接口的外部LCD扩展
- 支持最高分辨率1024*768,实际分辨率可以配置
- RGB565和RGB888格式可选
- PWM控制模块
- 5组16位宽PWM发生器,每组PWM支持4路PWM输出
- 提供新周期开始中断,高电平结束中断、刹车中断以及中心对称模式下的半周期中断
- 支持死区控制
- 支持硬件自动触发 ADC 采样
- 定时器模块
- 5路32位通用定时器
- 12路32位基本定时器
- 32位看门狗定时器,溢出后可配置触发中断或复位芯片
- RTC模块
- 可自由设置日期(年、月、周、日)和时间(时、分、秒)
- 可自由设置闹钟(周、时、分、秒)
- 自动识别当前设置年份是否为闰年
- 支持RTC中断从Sleep模式下唤醒芯片
- DMA模块
- 4路DAM,支持特定外设和存储器之间或存储器和存储器之间的数据搬运
- 模拟外设
- 2路12位高精度SAR ADC
- 1路12位高精度DAC
- 3路比较器
- 4路运算放大器
- 欠压检测(BOD
- 支持欠压检测
- 支持欠压中断和复位选择
- 时钟源
- 20MHz/40MHz精度可达1%的片内时钟源
- 32K片内时钟源
- 232MHz片外晶振
芯片更多详细信息请参考[华芯微特技术支持](https://www.synwit.cn/)。
## 编译说明
本 BSP 为开发者提供 MDK5 工程。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。
双击 project.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。
> 工程默认配置使用 Jlink 仿真器下载程序,在通过 Jlink 连接开发板到 PC 的基础上,点击下载按钮即可下载程序到开发板
推荐熟悉 RT_Thread 的用户使用[env工具](https://www.rt-thread.org/page/download.html),可以在console下进入到 `bsp/swm341` 目录中,运行以下命令:
`scons`
来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。其中 rtthread.bin 可以烧写到设备中运行。
## 烧写及执行
### 硬件连接
- 使用 USB 数据线连接开发板到 PC(注意:需要下载安装串口驱动支持 CH340 芯片,使用 MDK5 需要安装 SWM341 相关的 pack)。
> USB 数据线用于串口通讯,同时供电
- 使用 Jlink 连接开发板到 PC (需要 Jlink 驱动)
将串口 0 引脚为:`[PM0/PM1]`和 USB 转串口模块 J8 相连,串口配置方式为115200-N-8-1。
当使用 [env工具](https://www.rt-thread.org/page/download.html) 正确编译产生出rtthread.bin映像文件后,可以使用 ISP 的方式来烧写到设备中。
**建议使用 keil 软件直接下载**。ISP 下载较复杂。
### 运行结果
如果编译 & 烧写无误,当复位设备后,会在串口上看到板子上的蓝色LED闪烁。串口打印RT-Thread的启动logo信息:
```
\ | /
- RT - Thread Operating System
/ | \ 4.1.1 build May 13 2022 10:16:43
2006 - 2022 Copyright by RT-Thread team
msh >
```
## 外设支持
本 BSP 目前对外设的支持情况如下:
| **片上外设** | **支持情况** | **备注** |
| :---------- | :----------: | :---------------------------------------- |
| GPIO | 支持 | 共112个 |
| UART | 支持 | UART0/1/2/3 |
| ADC | 支持 | ADC0/1 |
| DAC | 支持 | DAC |
| CAN | 支持 | CAN0/1 |
| TIM | 支持 | TIM0/1/2/3/4,BTIM0/1/2/3/4/5/6/7/8/9/10/11 |
| I2C | 支持 | 软件 I2C0/1 |
| PWM | 支持 | PWM0/1/2/3/4 |
| RTC | 支持 | RTC |
| SPI | 支持 | SPI0/1 |
| WDT | 支持 | WDT |
| CRC/RNG | 支持 | CRC/RNG |
| SDIO | 支持 | SDIO |
| SDRAM | 支持 | SDRAM |
## 维护人信息
- [yanmowudi](https://github.com/yanmowudi)
- [邮箱](lik@synwit.cn)
## 参考资料
* [RT-Thread 文档中心](https://www.rt-thread.org/document/site/)
* [SWM341数据手册](https://www.synwit.cn/)
+14
View File
@@ -0,0 +1,14 @@
# for module compiling
import os
from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')
+41
View File
@@ -0,0 +1,41 @@
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
try:
from building import *
except:
print('Cannot found RT-Thread root directory, please check RTT_ROOT')
print(RTT_ROOT)
exit(-1)
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
if rtconfig.PLATFORM in ['iccarm']:
env.Replace(CCCOM = ['$CC $CFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])
env.Replace(ARFLAGS = [''])
env.Replace(LINKCOM = env["LINKCOM"] + ' --map rtthread.map')
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
# make a building
DoBuilding(TARGET, objs)
+14
View File
@@ -0,0 +1,14 @@
from building import *
cwd = GetCurrentDir()
path = [cwd]
src = Glob('*.c') + Glob('*.cpp')
group = DefineGroup('Applications', src, depend = [''], CPPPATH = path)
list = os.listdir(cwd)
for item in list:
if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
group = group + SConscript(os.path.join(item, 'SConscript'))
Return('group')
+16
View File
@@ -0,0 +1,16 @@
from building import *
import os
cwd = GetCurrentDir()
group = []
src = Glob('*.c')
CPPPATH = [cwd]
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
group = group + SConscript(os.path.join(d, 'SConscript'))
group = group + DefineGroup('LVGL-port', src, depend = ['BSP_USING_LVGL'], CPPPATH = CPPPATH)
Return('group')
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-01-28 Rudy Lo The first version
*/
#ifndef LV_CONF_H
#define LV_CONF_H
#include <rtconfig.h>
#include "rgb_lcd_port.h"
#define LV_HOR_RES LCD_WIDTH
#define LV_VER_RES LCD_HEIGHT
#define LV_COLOR_DEPTH LCD_BITS_PER_PIXEL
#define LV_COLOR_16_SWAP 0
#define LV_USE_PERF_MONITOR 1
#define LV_USE_DEMO_WIDGETS 1
#define LV_USE_DEMO_BENCHMARK 0
#endif
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-01 Rudy Lo The first version
*/
#include <lvgl.h>
#include <rtthread.h>
#include "lv_conf.h"
#include "drv_rgb_lcd.h"
#define DRV_DEBUG
#define LOG_TAG "drv.lvgl"
#include <drv_log.h>
/*A static or global variable to store the buffers*/
static lv_disp_draw_buf_t disp_buf;
/*Descriptor of a display driver*/
static lv_disp_drv_t disp_drv;
static lv_color_t *lcdbuf_1;
static lv_color_t *lcdbuf_2;
/*Flush the content of the internal buffer the specific area on the display
*You can use DMA or any hardware acceleration to do this operation in the background but
*'lv_disp_flush_ready()' has to be called when finished.*/
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
/* color_p is a buffer pointer; the buffer is provided by LVGL */
LCD->L[0].ADDR = (uint32_t)color_p;
LCD->CR |= (1 << LCD_CR_VBPRELOAD_Pos);
while(LCD->CR & LCD_CR_VBPRELOAD_Msk) __NOP();
/*IMPORTANT!!!
*Inform the graphics library that you are ready with the flushing*/
lv_disp_flush_ready(disp_drv);
}
void lv_port_disp_init(void)
{
struct swm_rgb_lcd_device *rgb_lcd;
rgb_lcd = (struct swm_rgb_lcd_device *)rt_device_find("rgb_lcd");
lcdbuf_1 = (lv_color_t *)rgb_lcd->lcd_info.framebuffer;
lcdbuf_2 = (lv_color_t *)rt_malloc_align(LCD_BUF_SIZE,4);
if(lcdbuf_2 == RT_NULL)
{
LOG_E("init lcd buffer failed!\n");
return;
}
/*Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */
lv_disp_draw_buf_init(&disp_buf, lcdbuf_1, lcdbuf_2, LV_HOR_RES * LV_VER_RES);
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set the resolution of the display*/
disp_drv.hor_res = LV_HOR_RES;
disp_drv.ver_res = LV_VER_RES;
/*Set a display buffer*/
disp_drv.draw_buf = &disp_buf;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = disp_flush;
/*Required for Example 3)*/
disp_drv.full_refresh = 1;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
@@ -0,0 +1,113 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-01 Rudy Lo The first version
*/
#include <lvgl.h>
#include <stdbool.h>
#include <rtdevice.h>
#include <drv_gpio.h>
#include "gt9147.h"
#define TOUCH_DEVICE_NAME "gt9147" /* Touch device name */
#define TOUCH_DEVICE_I2C_BUS "i2c0" /* SCL -> PA1(1), SDA -> PA0(0) */
static rt_device_t ts; /* Touch device handle, Touchscreen */
static struct rt_touch_data *read_data;
static rt_int16_t last_x = 0;
static rt_int16_t last_y = 0;
static bool touchpad_is_pressed(void)
{
if (1 == rt_device_read(ts, 0, read_data, 1))
{
if ((read_data->event == RT_TOUCH_EVENT_DOWN) || (read_data->event == RT_TOUCH_EVENT_MOVE)) {
/* restore data */
last_x = read_data->x_coordinate;
last_y = read_data->y_coordinate;
// rt_kprintf("touch: x = %d, y = %d\n", last_x, last_y);
return true;
}
}
return false;
}
static void touchpad_get_xy(rt_int16_t *x, rt_int16_t *y)
{
*x = last_x;
*y = last_y;
}
static void touchpad_read(lv_indev_drv_t *indev, lv_indev_data_t *data)
{
/*`touchpad_is_pressed` and `touchpad_get_xy` needs to be implemented by you*/
if(touchpad_is_pressed()) {
data->state = LV_INDEV_STATE_PRESSED;
touchpad_get_xy(&data->point.x, &data->point.y);
} else {
data->state = LV_INDEV_STATE_RELEASED;
}
}
rt_err_t rt_hw_gt9147_register(void)
{
struct rt_touch_config config;
rt_uint8_t rst;
rst = GT9147_RST_PIN;
config.dev_name = TOUCH_DEVICE_I2C_BUS;
config.irq_pin.pin = GT9147_IRQ_PIN;
config.irq_pin.mode = PIN_MODE_INPUT_PULLDOWN;
config.user_data = &rst;
rt_hw_gt9147_init(TOUCH_DEVICE_NAME, &config);
ts = rt_device_find(TOUCH_DEVICE_NAME);
if (!ts) {
return -RT_ERROR;
}
read_data = (struct rt_touch_data *)rt_calloc(1, sizeof(struct rt_touch_data));
if (!read_data) {
return -RT_ENOMEM;
}
if (!rt_device_open(ts, RT_DEVICE_FLAG_RDONLY)) {
struct rt_touch_info info;
rt_device_control(ts, RT_TOUCH_CTRL_GET_INFO, &info);
rt_kprintf("type :%d\n", info.type);
rt_kprintf("vendor :%s\n", info.vendor);
rt_kprintf("point_num :%d\n", info.point_num);
rt_kprintf("range_x :%d\n", info.range_x);
rt_kprintf("range_y :%d\n", info.range_y);
return RT_EOK;
} else {
rt_kprintf("open touch device failed.\n");
return -RT_ERROR;
}
}
lv_indev_t * touch_indev;
void lv_port_indev_init(void)
{
static lv_indev_drv_t indev_drv; /* Descriptor of a input device driver */
lv_indev_drv_init(&indev_drv); /* Basic initialization */
indev_drv.type = LV_INDEV_TYPE_POINTER; /* Touch pad is a pointer-like device */
indev_drv.read_cb = touchpad_read; /* Set your driver function */
/* Register the driver in LVGL and save the created input device object */
touch_indev = lv_indev_drv_register(&indev_drv);
/* Register touch device */
rt_hw_gt9147_register();
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-01-28 Rudy Lo The first version
*/
#include <lvgl.h>
void lv_user_gui_init(void)
{
extern void lv_demo_widgets(void);
lv_demo_widgets();
}
File diff suppressed because it is too large Load Diff
+42
View File
@@ -0,0 +1,42 @@
#
# Automatically generated file; DO NOT EDIT.
# RootMenu
#
#
# Hardware Drivers Config
#
CONFIG_SOC_SWM341=y
#
# On-chip Peripheral Drivers
#
CONFIG_BSP_USING_UART=y
CONFIG_BSP_USING_UART0=y
# CONFIG_BSP_USING_UART1 is not set
# CONFIG_BSP_USING_UART2 is not set
# CONFIG_BSP_USING_UART3 is not set
CONFIG_BSP_USING_GPIO=y
# CONFIG_BSP_USING_ADC is not set
# CONFIG_BSP_USING_DAC is not set
# CONFIG_BSP_USING_CAN is not set
# CONFIG_BSP_USING_TIM is not set
# CONFIG_BSP_USING_I2C is not set
# CONFIG_BSP_USING_PWM is not set
# CONFIG_BSP_USING_RTC is not set
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_WDT is not set
# CONFIG_BSP_USING_CRC is not set
# CONFIG_BSP_USING_RNG is not set
# CONFIG_BSP_USING_SDIO is not set
# CONFIG_BSP_USING_SDRAM is not set
# CONFIG_BSP_USING_GT9147 is not set
# CONFIG_BSP_USING_RGB_LCD is not set
#
# Onboard Peripheral Drivers
#
#
# Offboard Peripheral Drivers
#
+406
View File
@@ -0,0 +1,406 @@
menu "Hardware Drivers Config"
config SOC_SWM341
bool
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
default y
menu "On-chip Peripheral Drivers"
menuconfig BSP_USING_UART
bool "Enable UART"
default y
select RT_USING_SERIAL
if BSP_USING_UART
config BSP_USING_UART0
bool "Enable UART0 (M0/RX,M1/TX)"
default y
config BSP_USING_UART1
bool "Enable UART1 (D4/RX,D3/TX)"
default n
config BSP_USING_UART2
bool "Enable UART2 (C1/RX,C0/TX)"
default n
config BSP_USING_UART3
bool "Enable UART3 (C2/RX,C3/TX)"
default n
endif
config BSP_USING_GPIO
bool "Enable GPIO"
select RT_USING_PIN
default y
menuconfig BSP_USING_ADC
bool "Enable ADC"
default n
select RT_USING_ADC
if BSP_USING_ADC
config BSP_USING_ADC0
bool "Enable ADC0"
default n
if BSP_USING_ADC0
config BSP_USING_ADC0_CHN0
bool "Enable ADC0_CHN0(C6)"
default n
config BSP_USING_ADC0_CHN1
bool "Enable ADC0_CHN1(C5)"
default n
config BSP_USING_ADC0_CHN2
bool "Enable ADC0_CHN2(C4)"
default n
config BSP_USING_ADC0_CHN3
bool "Enable ADC0_CHN3(C3)"
default n
config BSP_USING_ADC0_CHN4
bool "Enable ADC0_CHN4(C2)"
default n
config BSP_USING_ADC0_CHN5
bool "Enable ADC0_CHN5(C1)"
default n
config BSP_USING_ADC0_CHN6
bool "Enable ADC0_CHN6(C0)"
default n
config BSP_USING_ADC0_CHN7
bool "Enable ADC0_CHN7(A15)"
default n
config BSP_USING_ADC0_CHN8
bool "Enable ADC0_CHN8(A14)"
default n
config BSP_USING_ADC0_CHN9
bool "Enable ADC0_CHN9(A13)"
default n
config BSP_USING_ADC0_CHN10
bool "Enable ADC0_CHN10(A12)"
default n
config BSP_USING_ADC0_CHN11
bool "Enable ADC0_CHN11(A10)"
default n
endif
config BSP_USING_ADC1
bool "Enable ADC1"
default n
if BSP_USING_ADC1
config BSP_USING_ADC1_CHN0
bool "Enable ADC1_CHN0(D1)"
default n
config BSP_USING_ADC1_CHN1
bool "Enable ADC1_CHN1(D0)"
default n
config BSP_USING_ADC1_CHN2
bool "Enable ADC1_CHN2(C13)"
default n
config BSP_USING_ADC1_CHN3
bool "Enable ADC1_CHN3(C12)"
default n
config BSP_USING_ADC1_CHN4
bool "Enable ADC1_CHN4(C11)"
default n
config BSP_USING_ADC1_CHN5
bool "Enable ADC1_CHN5(C10)"
default n
config BSP_USING_ADC1_CHN6
bool "Enable ADC1_CHN6(C9)"
default n
endif
endif
config BSP_USING_DAC
bool "Enable DAC"
select RT_USING_DAC
default n
menuconfig BSP_USING_CAN
bool "Enable CAN"
default n
select RT_USING_CAN
if BSP_USING_CAN
config BSP_USING_CAN0
bool "Enable CAN0(TX/B4,RX/B5)"
default n
config BSP_USING_CAN1
bool "Enable CAN1(TX/B2,RX/B3)"
default n
endif
menuconfig BSP_USING_TIM
bool "Enable HWTIMER"
default n
select RT_USING_HWTIMER
if BSP_USING_TIM
config BSP_USING_TIM0
bool "Enable TIM0"
default n
config BSP_USING_TIM1
bool "Enable TIM1"
default n
config BSP_USING_TIM2
bool "Enable TIM2"
default n
config BSP_USING_TIM3
bool "Enable TIM3"
default n
config BSP_USING_TIM4
bool "Enable TIM4"
default n
config BSP_USING_BTIM0
bool "Enable BTIM0"
default n
config BSP_USING_BTIM1
bool "Enable BTIM1"
default n
config BSP_USING_BTIM2
bool "Enable BTIM2"
default n
config BSP_USING_BTIM3
bool "Enable BTIM3"
default n
config BSP_USING_BTIM4
bool "Enable BTIM4"
default n
config BSP_USING_BTIM5
bool "Enable BTIM5"
default n
config BSP_USING_BTIM6
bool "Enable BTIM6"
default n
config BSP_USING_BTIM7
bool "Enable BTIM7"
default n
config BSP_USING_BTIM8
bool "Enable BTIM8"
default n
config BSP_USING_BTIM9
bool "Enable BTIM9"
default n
config BSP_USING_BTIM10
bool "Enable BTIM10"
default n
config BSP_USING_BTIM11
bool "Enable BTIM11"
default n
endif
menuconfig BSP_USING_I2C
bool "Enable I2C BUS (software simulation)"
default n
select RT_USING_I2C
select RT_USING_I2C_BITOPS
select RT_USING_PIN
if BSP_USING_I2C
config BSP_USING_I2C0
bool "Enable I2C0"
default n
if BSP_USING_I2C0
config BSP_I2C0_SCL_PIN
int "I2C0 scl pin number"
range 0 111
default 1
config BSP_I2C0_SDA_PIN
int "I2C0 sda pin number"
range 0 111
default 0
endif
config BSP_USING_I2C1
bool "Enable I2C1"
default n
if BSP_USING_I2C1
config BSP_I2C1_SCL_PIN
int "I2C1 scl pin number"
range 0 111
default 37
config BSP_I2C1_SDA_PIN
int "I2C1 sda pin number"
range 0 111
default 36
endif
endif
menuconfig BSP_USING_PWM
bool "Enable PWM"
default n
select RT_USING_PWM
if BSP_USING_PWM
comment "Notice: PWMA,PWMAN,PWMB,PWMBN are all channel0,the performance is the same"
config BSP_USING_PWM0
bool "Enable PWM0"
default n
if BSP_USING_PWM0
config BSP_USING_PWM0A
bool "Enable PWM0A (M1)"
default n
config BSP_USING_PWM0AN
bool "Enable PWM0AN (M4)"
default n
config BSP_USING_PWM0B
bool "Enable PWM0B (M2)"
default n
config BSP_USING_PWM0BN
bool "Enable PWM0BN (M5)"
default n
endif
config BSP_USING_PWM1
bool "Enable PWM1"
default n
if BSP_USING_PWM1
config BSP_USING_PWM1A
bool "Enable PWM1A (M3)"
default n
config BSP_USING_PWM1AN
bool "Enable PWM1AN (M6)"
default n
config BSP_USING_PWM1B
bool "Enable PWM1B (D9)"
default n
config BSP_USING_PWM1BN
bool "Enable PWM1BN (D8)"
default n
endif
config BSP_USING_PWM2
bool "Enable PWM2"
default n
if BSP_USING_PWM2
config BSP_USING_PWM2A
bool "Enable PWM2A (M12)"
default n
config BSP_USING_PWM2AN
bool "Enable PWM2AN (M9)"
default n
config BSP_USING_PWM2B
bool "Enable PWM2B (M11)"
default n
config BSP_USING_PWM2BN
bool "Enable PWM2BN (M8)"
default n
endif
config BSP_USING_PWM3
bool "Enable PWM3"
default n
if BSP_USING_PWM3
config BSP_USING_PWM3A
bool "Enable PWM3A (C2)"
default n
config BSP_USING_PWM3AN
bool "Enable PWM3AN (C3)"
default n
config BSP_USING_PWM3B
bool "Enable PWM3B (B1)"
default n
config BSP_USING_PWM3BN
bool "Enable PWM3BN (B0)"
default n
endif
config BSP_USING_PWM4
bool "Enable PWM4"
default n
if BSP_USING_PWM4
config BSP_USING_PWM4A
bool "Enable PWM4A (B15)"
default n
config BSP_USING_PWM4AN
bool "Enable PWM4AN (B14) NOTICE:SWDIO"
default n
config BSP_USING_PWM4B
bool "Enable PWM4B (B13)"
default n
config BSP_USING_PWM4BN
bool "Enable PWM4BN (B12) NOTICE:SWDCK"
default n
endif
endif
config BSP_USING_RTC
bool "Enable RTC"
select RT_USING_RTC
select RT_USING_LIBC
default n
menuconfig BSP_USING_SPI
bool "Enable SPI BUS"
default n
select RT_USING_SPI
if BSP_USING_SPI
config BSP_USING_SPI0
bool "Enable SPI0 BUS(CS/M3,MISO/M4,MOSI/M5,CLK/M2)"
default n
config BSP_USING_SPI1
bool "Enable SPI1 BUS(CS/B5,MISO/B3,MOSI/B4,CLK/B2)"
default n
endif
config BSP_USING_WDT
bool "Enable Watchdog Timer"
select RT_USING_WDT
default n
config BSP_USING_CRC
bool "Enable CRC"
select RT_USING_HWCRYPTO
select RT_HWCRYPTO_USING_CRC
default n
config BSP_USING_RNG
bool "Enable RNG (Random Number Generator)"
select RT_USING_HWCRYPTO
select RT_HWCRYPTO_USING_RNG
default n
config BSP_USING_SDIO
bool "Enable SDCARD (sdio)"
select RT_USING_SDIO
select RT_USING_DFS
select RT_USING_DFS_ELMFAT
default n
menuconfig BSP_USING_SDRAM
bool "Enable SDRAM"
select RT_USING_MEMHEAP
select RT_USING_MEMHEAP_AS_HEAP
select RT_USING_MEMHEAP_AUTO_BINDING
default n
if BSP_USING_SDRAM
config BSP_SDRAM_SIZE
hex "SDRAM size"
default 0x800000
endif
menuconfig BSP_USING_GT9147
bool "Enable gt9147(use i2c0)"
select RT_USING_TOUCH
select RT_TOUCH_PIN_IRQ
select BSP_USING_I2C
select BSP_USING_I2C0
default n
if BSP_USING_GT9147
config GT9147_RST_PIN
int "GT9147 rst pin number"
range 0 111
default 39
config GT9147_IRQ_PIN
int "GT9147 irq pin number"
range 0 111
default 48
endif
menuconfig BSP_USING_RGB_LCD
bool "Enable RGB LCD"
select BSP_USING_SDRAM
default n
if BSP_USING_RGB_LCD
config BSP_USING_LVGL
bool "Enable LVGL for LCD"
select PKG_USING_LVGL
default n
endif
endmenu
menu "Onboard Peripheral Drivers"
endmenu
menu "Offboard Peripheral Drivers"
endmenu
endmenu
+58
View File
@@ -0,0 +1,58 @@
from building import *
cwd = GetCurrentDir()
CPPPATH = [cwd]
src = Split('''
board.c
''')
if GetDepend(['RT_USING_SERIAL']):
src += ['drv_uart.c']
if GetDepend(['RT_USING_PIN']):
src += ['drv_gpio.c']
if GetDepend(['RT_USING_ADC']):
src += ['drv_adc.c']
if GetDepend(['RT_USING_DAC']):
src += ['drv_dac.c']
if GetDepend(['RT_USING_CAN']):
src += ['drv_can.c']
if GetDepend(['RT_USING_HWTIMER']):
src += ['drv_hwtimer.c']
if GetDepend(['RT_USING_I2C']):
src += ['drv_soft_i2c.c']
if GetDepend(['RT_USING_PWM']):
src += ['drv_pwm.c']
if GetDepend(['RT_USING_RTC']):
src += ['drv_rtc.c']
if GetDepend(['RT_USING_SPI']):
src += ['drv_spi.c']
if GetDepend(['RT_USING_WDT']):
src += ['drv_wdt.c']
if GetDepend(['RT_USING_HWCRYPTO']):
src += ['drv_crypto.c']
if GetDepend(['RT_USING_SDIO']):
src += ['drv_sdio.c']
if GetDepend(['BSP_USING_SDRAM']):
src += ['drv_sdram.c']
if GetDepend(['BSP_USING_RGB_LCD']):
src += ['drv_rgb_lcd.c']
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
+64
View File
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "board.h"
#ifdef RT_USING_MEMHEAP_AS_HEAP
static struct rt_memheap system_heap;
#endif
static void bsp_clock_config(void)
{
SystemInit();
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
SysTick->CTRL |= 0x00000004UL;
}
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
void rt_hw_board_init()
{
bsp_clock_config();
/* Heap initialization */
#ifdef RT_USING_HEAP
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
#if defined(BSP_USING_SDRAM) && defined(RT_USING_MEMHEAP_AS_HEAP)
swm_sdram_init();
/* If RT_USING_MEMHEAP_AS_HEAP is enabled, SDRAM is initialized to the heap */
rt_memheap_init(&system_heap, "sdram", (void *)SDRAMM_BASE, BSP_SDRAM_SIZE);
#endif
/* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
swm_pin_init();
#endif
/* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
swm_uart_init();
#endif
/* Set the shell console output device */
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
/* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <string.h>
#include <SWM341.h>
#include "drv_gpio.h"
#include "drv_uart.h"
#include "drv_sdram.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define SRAM_BASE 0x20000000
#define SRAM_SIZE 0x10000
#define SRAM_END (SRAM_BASE + SRAM_SIZE)
#if defined(__ARMCC_VERSION)
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit)
#elif __ICCARM__
#pragma section = "HEAP"
#define HEAP_BEGIN (__segment_end("HEAP"))
#else
extern int __bss_end;
#define HEAP_BEGIN ((void *)&__bss_end)
#endif
#define HEAP_END SRAM_END
#define HEAP_SIZE (HEAP_END - (rt_uint32_t)HEAP_BEGIN)
extern void FPU_init(void);
void rt_hw_board_init(void);
#ifdef __cplusplus
}
#endif
#endif /* __BOARD_H__ */
+326
View File
@@ -0,0 +1,326 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_adc.h"
#ifdef RT_USING_ADC
#ifdef BSP_USING_ADC
//#define DRV_DEBUG
#define LOG_TAG "drv.adc"
#include <drv_log.h>
#if !defined(BSP_USING_ADC0) && !defined(BSP_USING_ADC1)
#error "Please define at least one BSP_USING_ADCx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
#ifdef BSP_USING_ADC0
#ifndef ADC0_CFG
#define ADC0_CFG \
{ \
.name = "adc0", \
.ADCx = ADC0, \
.ADC_initstruct.clk_src = ADC_CLKSRC_HRC_DIV8, \
.ADC_initstruct.samplAvg = ADC_AVG_SAMPLE1, \
.ADC_initstruct.EOC_IEn = 0, \
.ADC_initstruct.HalfIEn = 0, \
.ADC_SEQ_initstruct.trig_src = ADC_TRIGGER_SW, \
.ADC_SEQ_initstruct.conv_cnt = 1, \
.ADC_SEQ_initstruct.samp_tim = ADC_SAMPLE_1CLOCK, \
}
#endif /* ADC0_CFG */
#endif /* BSP_USING_ADC0 */
#ifdef BSP_USING_ADC1
#ifndef ADC1_CFG
#define ADC1_CFG \
{ \
.name = "adc1", \
.ADCx = ADC1, \
.ADC_initstruct.clk_src = ADC_CLKSRC_HRC_DIV8, \
.ADC_initstruct.samplAvg = ADC_AVG_SAMPLE1, \
.ADC_initstruct.EOC_IEn = 0, \
.ADC_initstruct.HalfIEn = 0, \
.ADC_SEQ_initstruct.trig_src = ADC_TRIGGER_SW, \
.ADC_SEQ_initstruct.conv_cnt = 1, \
.ADC_SEQ_initstruct.samp_tim = ADC_SAMPLE_1CLOCK, \
}
#endif /* ADC1_CFG */
#endif /* BSP_USING_ADC1 */
struct swm_adc_cfg
{
const char *name;
ADC_TypeDef *ADCx;
ADC_InitStructure ADC_initstruct;
ADC_SEQ_InitStructure ADC_SEQ_initstruct;
};
struct swm_adc_device
{
struct swm_adc_cfg *adc_cfg;
struct rt_adc_device adc_device;
};
static struct swm_adc_cfg swm_adc_cfg[] =
{
#ifdef BSP_USING_ADC0
ADC0_CFG,
#endif
#ifdef BSP_USING_ADC1
ADC1_CFG,
#endif
};
static struct swm_adc_device adc_obj[sizeof(swm_adc_cfg) / sizeof(swm_adc_cfg[0])];
static rt_uint32_t swm_adc_get_channel(rt_uint32_t channel)
{
rt_uint32_t swm_channel = 0;
switch (channel)
{
case 0:
swm_channel = ADC_CH0;
break;
case 1:
swm_channel = ADC_CH1;
break;
case 2:
swm_channel = ADC_CH2;
break;
case 3:
swm_channel = ADC_CH3;
break;
case 4:
swm_channel = ADC_CH4;
break;
case 5:
swm_channel = ADC_CH5;
break;
case 6:
swm_channel = ADC_CH6;
break;
case 7:
swm_channel = ADC_CH7;
break;
case 8:
swm_channel = ADC_CH8;
break;
case 9:
swm_channel = ADC_CH9;
break;
case 10:
swm_channel = ADC_CH10;
break;
case 11:
swm_channel = ADC_CH11;
break;
}
return swm_channel;
}
static rt_err_t swm_adc_enabled(struct rt_adc_device *adc_device, rt_uint32_t channel, rt_bool_t enabled)
{
uint32_t adc_chn;
struct swm_adc_cfg *adc_cfg;
RT_ASSERT(adc_device != RT_NULL);
adc_cfg = adc_device->parent.user_data;
if (channel < 12)
{
/* set swm ADC channel */
adc_chn = swm_adc_get_channel(channel);
}
else
{
LOG_E("ADC channel must be between 0 and 11.");
return -RT_ERROR;
}
if (enabled)
{
adc_cfg->ADCx->SEQCHN0 |= adc_chn;
}
else
{
adc_cfg->ADCx->SEQCHN0 &= ~adc_chn;
}
return RT_EOK;
}
static rt_err_t swm_adc_convert(struct rt_adc_device *adc_device, rt_uint32_t channel, rt_uint32_t *value)
{
uint32_t i, chn, val, adc_chn;
struct swm_adc_cfg *adc_cfg;
RT_ASSERT(adc_device != RT_NULL);
RT_ASSERT(value != RT_NULL);
adc_cfg = adc_device->parent.user_data;
if (channel < 12)
{
/* set swm ADC channel */
adc_chn = swm_adc_get_channel(channel);
}
else
{
LOG_E("ADC channel must be between 0 and 11.");
return -RT_ERROR;
}
*value = 0xFFFFFFFF;
/* start ADC */
ADC_Start(adc_cfg->ADCx, ADC_SEQ0);
/* Wait for the ADC to convert */
while (adc_cfg->ADCx->GO & ADC_GO_BUSY_Msk)
__NOP();
while ((adc_cfg->ADCx->SEQ[0].SR & ADC_SR_EMPTY_Msk) == 0)
{
val = ADC_Read(adc_cfg->ADCx, ADC_SEQ0, &chn);
if (chn == adc_chn)
{
*value = val;
}
}
if (*value == 0xFFFFFFFF)
{
LOG_E("ADC channel can not find.");
return -RT_ERROR;
}
return RT_EOK;
}
static const struct rt_adc_ops swm_adc_ops =
{
.enabled = swm_adc_enabled,
.convert = swm_adc_convert,
};
int swm_adc_init(void)
{
int i = 0;
int result = RT_EOK;
for (i = 0; i < sizeof(swm_adc_cfg) / sizeof(swm_adc_cfg[0]); i++)
{
/* ADC init */
adc_obj[i].adc_cfg = &swm_adc_cfg[i];
if (adc_obj[i].adc_cfg->ADCx == ADC0)
{
#ifdef BSP_USING_ADC0_CHN0
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH0;
PORT_Init(PORTC, PIN6, PORTC_PIN6_ADC0_CH0, 0); //PC.6 => ADC.CH0
#endif
#ifdef BSP_USING_ADC0_CHN1
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH1;
PORT_Init(PORTC, PIN5, PORTC_PIN5_ADC0_CH1, 0); //PC.5 => ADC.CH1
#endif
#ifdef BSP_USING_ADC0_CHN2
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH2;
PORT_Init(PORTC, PIN4, PORTC_PIN4_ADC0_CH2, 0); //PC.4 => ADC.CH2
#endif
#ifdef BSP_USING_ADC0_CHN3
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH3;
PORT_Init(PORTC, PIN3, PORTC_PIN3_ADC0_CH3, 0); //PC.3 => ADC.CH3
#endif
#ifdef BSP_USING_ADC0_CHN4
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH4;
PORT_Init(PORTC, PIN2, PORTC_PIN2_ADC0_CH4, 0); //PC.2 => ADC.CH4
#endif
#ifdef BSP_USING_ADC0_CHN5
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH5;
PORT_Init(PORTC, PIN1, PORTC_PIN1_ADC0_CH5, 0); //PC.1 => ADC.CH5
#endif
#ifdef BSP_USING_ADC0_CHN6
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH6;
PORT_Init(PORTC, PIN0, PORTC_PIN0_ADC0_CH6, 0); //PC.0 => ADC.CH6
#endif
#ifdef BSP_USING_ADC0_CHN7
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH7;
PORT_Init(PORTA, PIN15, PORTA_PIN15_ADC0_CH7, 0); //PA.15 => ADC.CH7
#endif
#ifdef BSP_USING_ADC0_CHN8
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH8;
PORT_Init(PORTA, PIN14, PORTA_PIN14_ADC0_CH8, 0); //PA.14 => ADC.CH8
#endif
#ifdef BSP_USING_ADC0_CHN9
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH9;
PORT_Init(PORTA, PIN13, PORTA_PIN13_ADC0_CH9, 0); //PA.13 => ADC.CH9
#endif
#ifdef BSP_USING_ADC0_CHN10
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH10;
PORT_Init(PORTA, PIN12, PORTA_PIN12_ADC0_CH10, 0); //PA.12 => ADC.CH10
#endif
#ifdef BSP_USING_ADC0_CHN11
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH11;
PORT_Init(PORTA, PIN10, PORTA_PIN10_ADC0_CH11, 0); //PA.10 => ADC.CH11
#endif
}
else if (adc_obj[i].adc_cfg->ADCx == ADC1)
{
#ifdef BSP_USING_ADC1_CHN0
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH0;
PORT_Init(PORTD, PIN1, PORTD_PIN1_ADC1_CH0, 0); //PD.1 => ADC1.CH0
#endif
#ifdef BSP_USING_ADC1_CHN1
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH1;
PORT_Init(PORTD, PIN0, PORTD_PIN0_ADC1_CH1, 0); //PD.0 => ADC1.CH1
#endif
#ifdef BSP_USING_ADC1_CHN2
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH2;
PORT_Init(PORTC, PIN13, PORTC_PIN13_ADC1_CH2, 0); //PC.13 => ADC1.CH2
#endif
#ifdef BSP_USING_ADC1_CHN3
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH3;
PORT_Init(PORTC, PIN12, PORTC_PIN12_ADC1_CH3, 0); //PC.12 => ADC1.CH3
#endif
#ifdef BSP_USING_ADC1_CHN4
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH4;
PORT_Init(PORTC, PIN11, PORTC_PIN11_ADC1_CH4, 0); //PC.11 => ADC1.CH4
#endif
#ifdef BSP_USING_ADC1_CHN5
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH5;
PORT_Init(PORTC, PIN10, PORTC_PIN10_ADC1_CH5, 0); //PC.10 => ADC1.CH5
#endif
#ifdef BSP_USING_ADC1_CHN6
adc_obj[i].adc_cfg->ADC_SEQ_initstruct.channels |= ADC_CH6;
PORT_Init(PORTC, PIN9, PORTC_PIN9_ADC1_CH6, 0); //PC.9 => ADC1.CH6
#endif
}
ADC_Init(adc_obj[i].adc_cfg->ADCx, &(adc_obj[i].adc_cfg->ADC_initstruct));
ADC_SEQ_Init(adc_obj[i].adc_cfg->ADCx, ADC_SEQ0, &(adc_obj[i].adc_cfg->ADC_SEQ_initstruct));
ADC_Open(adc_obj[i].adc_cfg->ADCx);
ADC_Calibrate(adc_obj[i].adc_cfg->ADCx);
result = rt_hw_adc_register(&adc_obj[i].adc_device, adc_obj[i].adc_cfg->name, &swm_adc_ops, adc_obj[i].adc_cfg);
if(result != RT_EOK)
{
LOG_E("%s register fail.", adc_obj[i].adc_cfg->name);
}
else
{
LOG_D("%s register success.", adc_obj[i].adc_cfg->name);
}
}
return result;
}
INIT_BOARD_EXPORT(swm_adc_init);
#endif /* BSP_USING_ADC */
#endif /* RT_USING_ADC */
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_ADC_H__
#define __DRV_ADC_H__
#include "board.h"
int swm_adc_init(void);
#endif /* __DRV_ADC_H__ */
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-16 lik first version
*/
#ifndef __DRV_CAN_H__
#define __DRV_CAN_H__
#include "board.h"
int swm_can_init(void);
#endif /* __DRV_CAN_H__ */
+316
View File
@@ -0,0 +1,316 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_crypto.h"
#include <string.h>
#ifdef RT_USING_HWCRYPTO
//#define DRV_DEBUG
#define LOG_TAG "drv.crypto"
#include <drv_log.h>
struct swm_hwcrypto_device
{
struct rt_hwcrypto_device dev;
struct rt_mutex mutex;
};
static struct swm_hwcrypto_device hwcrypto_obj;
#ifdef BSP_USING_CRC
struct swm_crc_cfg
{
CRC_TypeDef *CRCx;
CRC_InitStructure CRC_initstruct;
};
static struct hwcrypto_crc_cfg swm_crc_cfg;
static rt_uint32_t swm_crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, rt_size_t length)
{
rt_uint32_t result = 0;
struct swm_hwcrypto_device *hwcrypto_dev = (struct swm_hwcrypto_device *)ctx->parent.device->user_data;
struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->parent.contex);
rt_mutex_take(&hwcrypto_dev->mutex, RT_WAITING_FOREVER);
if (memcmp(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0)
{
crc_cfg->CRCx = CRC;
crc_cfg->CRC_initstruct.init_crc = ctx->crc_cfg.last_val;
switch (ctx->crc_cfg.poly)
{
case 0x07:
crc_cfg->CRC_initstruct.Poly = CRC_POLY_107;
break;
case 0x1021:
crc_cfg->CRC_initstruct.Poly = CRC_POLY_11021;
break;
case 0x8005:
crc_cfg->CRC_initstruct.Poly = CRC_POLY_18005;
break;
case 0x04C11DB7:
crc_cfg->CRC_initstruct.Poly = CRC_POLY_104C11DB7;
break;
default:
goto _exit;
}
switch (ctx->crc_cfg.width)
{
case 8:
crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_8;
break;
case 16:
crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_16;
break;
case 32:
crc_cfg->CRC_initstruct.in_width = CRC_WIDTH_32;
break;
default:
goto _exit;
}
switch (ctx->crc_cfg.flags)
{
case 0:
crc_cfg->CRC_initstruct.in_not = false;
crc_cfg->CRC_initstruct.out_not = false;
break;
case CRC_FLAG_REFIN:
crc_cfg->CRC_initstruct.in_not = true;
crc_cfg->CRC_initstruct.out_not = false;
break;
case CRC_FLAG_REFOUT:
crc_cfg->CRC_initstruct.in_not = false;
crc_cfg->CRC_initstruct.out_not = true;
break;
case CRC_FLAG_REFIN | CRC_FLAG_REFOUT:
crc_cfg->CRC_initstruct.in_not = true;
crc_cfg->CRC_initstruct.out_not = true;
break;
default:
goto _exit;
}
crc_cfg->CRC_initstruct.in_rev = CRC_REV_NOT;
crc_cfg->CRC_initstruct.out_rev = CRC_REV_NOT;
CRC_Init(crc_cfg->CRCx, &(crc_cfg->CRC_initstruct));
memcpy(&swm_crc_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg));
}
for (uint32_t i = 0; i < length; i++)
CRC_Write((uint32_t)in[i]);
result = CRC_Result();
ctx->crc_cfg.last_val = result;
swm_crc_cfg.last_val = ctx->crc_cfg.last_val;
result = (result ? result ^ (ctx->crc_cfg.xorout) : result);
_exit:
rt_mutex_release(&hwcrypto_dev->mutex);
return result;
}
static const struct hwcrypto_crc_ops swm_crc_ops =
{
.update = swm_crc_update,
};
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
struct swm_rng_cfg
{
SYS_TypeDef *SYSx;
};
static rt_uint32_t swm_rng_update(struct hwcrypto_rng *ctx)
{
rt_uint32_t gen_randoml = 0, gen_randomh = 0;
struct swm_rng_cfg *rng_cfg = (struct swm_rng_cfg *)(ctx->parent.contex);
while ((rng_cfg->SYSx->PRNGCR & SYS_PRNGCR_RDY_Msk) == 0)
__NOP();
gen_randoml = rng_cfg->SYSx->PRNGDL;
gen_randomh = rng_cfg->SYSx->PRNGDH;
return gen_randoml;
}
static const struct hwcrypto_rng_ops swm_rng_ops =
{
.update = swm_rng_update,
};
#endif /* BSP_USING_RNG */
static rt_err_t swm_crypto_create(struct rt_hwcrypto_ctx *ctx)
{
rt_err_t res = RT_EOK;
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
{
struct swm_crc_cfg *crc_cfg = rt_calloc(1, sizeof(struct swm_crc_cfg));
if (RT_NULL == crc_cfg)
{
res = -RT_ERROR;
break;
}
ctx->contex = crc_cfg;
((struct hwcrypto_crc *)ctx)->ops = &swm_crc_ops;
break;
}
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
{
struct swm_rng_cfg *rng_cfg = rt_calloc(1, sizeof(struct swm_rng_cfg));
if (RT_NULL == rng_cfg)
{
res = -RT_ERROR;
break;
}
rng_cfg->SYSx = SYS;
rng_cfg->SYSx->HRCCR |= (1 << SYS_HRCCR_ON_Pos);
rng_cfg->SYSx->LRCCR |= (1 << SYS_LRCCR_ON_Pos);
rng_cfg->SYSx->PRNGCR = (0 << SYS_PRNGCR_CLR_Pos) |
(3 << SYS_PRNGCR_MODE_Pos);
ctx->contex = rng_cfg;
((struct hwcrypto_rng *)ctx)->ops = &swm_rng_ops;
break;
}
#endif /* BSP_USING_RNG */
default:
res = -RT_ERROR;
break;
}
return res;
}
static void swm_crypto_destroy(struct rt_hwcrypto_ctx *ctx)
{
struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
break;
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
break;
#endif /* BSP_USING_RNG */
default:
break;
}
rt_free(ctx->contex);
}
static rt_err_t swm_crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
{
rt_err_t res = RT_EOK;
switch (src->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
if (des->contex && src->contex)
{
rt_memcpy(des->contex, src->contex, sizeof(struct swm_crc_cfg));
}
break;
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
if (des->contex && src->contex)
{
rt_memcpy(des->contex, src->contex, sizeof(struct swm_rng_cfg));
}
break;
#endif /* BSP_USING_RNG */
default:
res = -RT_ERROR;
break;
}
return res;
}
static void swm_crypto_reset(struct rt_hwcrypto_ctx *ctx)
{
struct swm_crc_cfg *crc_cfg = (struct swm_crc_cfg *)(ctx->contex);
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_CRC)
case HWCRYPTO_TYPE_CRC:
crc_cfg->CRCx->CR &= ~CRC_CR_EN_Msk;
break;
#endif /* BSP_USING_CRC */
#if defined(BSP_USING_RNG)
case HWCRYPTO_TYPE_RNG:
break;
#endif /* BSP_USING_RNG */
default:
break;
}
}
static const struct rt_hwcrypto_ops swm_hwcrypto_ops =
{
.create = swm_crypto_create,
.destroy = swm_crypto_destroy,
.copy = swm_crypto_clone,
.reset = swm_crypto_reset,
};
int swm_crypto_init(void)
{
rt_uint32_t cpuid[2] = {0};
hwcrypto_obj.dev.ops = &swm_hwcrypto_ops;
cpuid[0] = SCB->CPUID;
hwcrypto_obj.dev.id = 0;
rt_memcpy(&hwcrypto_obj.dev.id, cpuid, 8);
hwcrypto_obj.dev.user_data = &hwcrypto_obj;
if (rt_hwcrypto_register(&hwcrypto_obj.dev, RT_HWCRYPTO_DEFAULT_NAME) != RT_EOK)
{
return -1;
}
rt_mutex_init(&hwcrypto_obj.mutex, RT_HWCRYPTO_DEFAULT_NAME, RT_IPC_FLAG_FIFO);
return 0;
}
INIT_BOARD_EXPORT(swm_crypto_init);
#endif /* RT_USING_HWCRYPTO */
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_CRYPTO_H__
#define __DRV_CRYPTO_H__
#include "board.h"
int swm_crypto_init(void);
#endif /* __DRV_CRYPTO_H__ */
+99
View File
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-10 lik first version
*/
#include "drv_dac.h"
#ifdef BSP_USING_DAC
//#define DRV_DEBUG
#define LOG_TAG "drv.dac"
#include <drv_log.h>
static struct rt_dac_device swm_dac_device;
static rt_err_t swm_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
{
RT_ASSERT(device != RT_NULL);
if (channel != 0)
{
LOG_E("dac channel must be 0.");
return -RT_ERROR;
}
DAC_Open(DAC);
return RT_EOK;
}
static rt_err_t swm_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
{
RT_ASSERT(device != RT_NULL);
if (channel != 0)
{
LOG_E("dac channel must be 0.");
return -RT_ERROR;
}
DAC_Close(DAC);
return RT_EOK;
}
static rt_err_t swm_dac_convert(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(value != RT_NULL);
if (channel != 0)
{
LOG_E("dac channel must be 0.");
return -RT_ERROR;
}
DAC->DHR = *value;
while(DAC->SR & DAC_SR_DHRFULL_Msk) __NOP();
return RT_EOK;
}
static const struct rt_dac_ops swm_dac_ops =
{
.disabled = swm_dac_disabled,
.enabled = swm_dac_enabled,
.convert = swm_dac_convert,
};
int swm_dac_init(void)
{
int result = RT_EOK;
PORT_Init(PORTD, PIN2, PORTD_PIN2_DAC_OUT, 0);
DAC_Init(DAC, DAC_FORMAT_LSB12B);
SYS->DACCR &= ~SYS_DACCR_VRADJ_Msk;
SYS->DACCR |= (17 << SYS_DACCR_VRADJ_Pos);
/* register dac device */
result = rt_hw_dac_register(&swm_dac_device, "dac", &swm_dac_ops, RT_NULL);
if(result != RT_EOK)
{
LOG_E("dac register fail.");
}
else
{
LOG_D("dac register success.");
}
return result;
}
INIT_DEVICE_EXPORT(swm_dac_init);
#endif /* BSP_USING_DAC */
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-10 lik first version
*/
#ifndef __DRV_DAC_H__
#define __DRV_DAC_H__
#include "board.h"
int swm_dac_init(void);
#endif /* __DRV_DAC_H__ */
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__
#include "board.h"
#define GET_PIN(PORTx,PIN) (rt_uint8_t)__SWM_GET_PIN_##PORTx(PIN)
#define __SWM_GET_PIN_A(PIN) (PIN)
#define __SWM_GET_PIN_B(PIN) (16 + PIN)
#define __SWM_GET_PIN_C(PIN) (32 + PIN)
#define __SWM_GET_PIN_D(PIN) (48 + PIN)
#define __SWM_GET_PIN_E(PIN) (64 + PIN)
#define __SWM_GET_PIN_M(PIN) (80 + PIN)
#define __SWM_GET_PIN_N(PIN) (96 + PIN)
int swm_pin_init(void);
#endif /* __DRV_GPIO_H__ */
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_HWTIMER_H__
#define __DRV_HWTIMER_H__
#include "board.h"
int swm_timer_init(void);
#endif /* __DRV_HWTIMER_H__ */
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-15 SummerGift first version
*/
/*
* NOTE: DO NOT include this file on the header file.
*/
#ifndef LOG_TAG
#define DBG_TAG "drv"
#else
#define DBG_TAG LOG_TAG
#endif /* LOG_TAG */
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif /* DRV_DEBUG */
#include <rtdbg.h>
+408
View File
@@ -0,0 +1,408 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_pwm.h"
#ifdef RT_USING_PWM
#ifdef BSP_USING_PWM
//#define DRV_DEBUG
#define LOG_TAG "drv.pwm"
#include <drv_log.h>
#if !defined(BSP_USING_PWM0) && !defined(BSP_USING_PWM1) && !defined(BSP_USING_PWM2) && !defined(BSP_USING_PWM3) && !defined(BSP_USING_PWM4)
#error "Please define at least one BSP_USING_PWMx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
#define MIN_PERIOD 2
#define MIN_PULSE 1
#ifdef BSP_USING_PWM0
#ifndef PWM0_CFG
#define PWM0_CFG \
{ \
.name = "pwm0", \
.PWMx = PWM0, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM0_MSK, \
}
#endif /* PWM0_CFG */
#endif /* BSP_USING_PWM0 */
#ifdef BSP_USING_PWM1
#ifndef PWM1_CFG
#define PWM1_CFG \
{ \
.name = "pwm1", \
.PWMx = PWM1, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM1_MSK, \
}
#endif /* PWM1_CFG */
#endif /* BSP_USING_PWM1 */
#ifdef BSP_USING_PWM2
#ifndef PWM2_CFG
#define PWM2_CFG \
{ \
.name = "pwm2", \
.PWMx = PWM2, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM2_MSK, \
}
#endif /* PWM2_CFG */
#endif /* BSP_USING_PWM2 */
#ifdef BSP_USING_PWM3
#ifndef PWM3_CFG
#define PWM3_CFG \
{ \
.name = "pwm3", \
.PWMx = PWM3, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM3_MSK, \
}
#endif /* PWM3_CFG */
#endif /* BSP_USING_PWM3 */
#ifdef BSP_USING_PWM4
#ifndef PWM4_CFG
#define PWM4_CFG \
{ \
.name = "pwm4", \
.PWMx = PWM4, \
.pwm_initstruct.Mode = PWM_CENTER_ALIGNED, \
.pwm_initstruct.Clkdiv = 15, \
.pwm_initstruct.Period = 10000, \
.pwm_initstruct.HdutyA = 5000, \
.pwm_initstruct.DeadzoneA = 0, \
.pwm_initstruct.IdleLevelA = 0, \
.pwm_initstruct.IdleLevelAN = 0, \
.pwm_initstruct.OutputInvA = 0, \
.pwm_initstruct.OutputInvAN = 1, \
.pwm_initstruct.HdutyB = 5000, \
.pwm_initstruct.DeadzoneB = 0, \
.pwm_initstruct.IdleLevelB = 0, \
.pwm_initstruct.IdleLevelBN = 0, \
.pwm_initstruct.OutputInvB = 0, \
.pwm_initstruct.OutputInvBN = 1, \
.pwm_initstruct.UpOvfIE = 0, \
.pwm_initstruct.DownOvfIE = 0, \
.pwm_initstruct.UpCmpAIE = 0, \
.pwm_initstruct.DownCmpAIE = 0, \
.pwm_initstruct.UpCmpBIE = 0, \
.pwm_initstruct.DownCmpBIE = 0, \
.pwm_mask = PWM4_MSK, \
}
#endif /* PWM4_CFG */
#endif /* BSP_USING_PWM4 */
struct swm_pwm_cfg
{
const char *name;
PWM_TypeDef *PWMx;
PWM_InitStructure pwm_initstruct;
uint32_t pwm_mask;
};
struct swm_pwm_device
{
struct swm_pwm_cfg *pwm_cfg;
struct rt_device_pwm pwm_device;
};
static struct swm_pwm_cfg swm_pwm_cfg[] =
{
#ifdef BSP_USING_PWM0
PWM0_CFG,
#endif
#ifdef BSP_USING_PWM1
PWM1_CFG,
#endif
#ifdef BSP_USING_PWM2
PWM2_CFG,
#endif
#ifdef BSP_USING_PWM3
PWM3_CFG,
#endif
#ifdef BSP_USING_PWM4
PWM4_CFG,
#endif
};
static struct swm_pwm_device pwm_obj[sizeof(swm_pwm_cfg) / sizeof(swm_pwm_cfg[0])] = {0};
static rt_err_t swm_pwm_enable(struct rt_device_pwm *pwm_device, struct rt_pwm_configuration *configuration, rt_bool_t enable)
{
struct swm_pwm_cfg *pwm_cfg = RT_NULL;
RT_ASSERT(pwm_device != RT_NULL);
pwm_cfg = pwm_device->parent.user_data;
if (!enable)
{
PWM_Stop(pwm_cfg->pwm_mask);
}
else
{
PWM_Start(pwm_cfg->pwm_mask);
}
return RT_EOK;
}
static rt_err_t swm_pwm_get(struct rt_device_pwm *pwm_device, struct rt_pwm_configuration *configuration)
{
rt_uint64_t tim_clock;
struct swm_pwm_cfg *pwm_cfg = RT_NULL;
RT_ASSERT(pwm_device != RT_NULL);
pwm_cfg = pwm_device->parent.user_data;
configuration->period = PWM_GetPeriod(pwm_cfg->PWMx) * 1000UL; //中心对称模式下频率降低一半
configuration->pulse = PWM_GetHDuty(pwm_cfg->PWMx, configuration->channel) * 1000UL;
return RT_EOK;
}
static rt_err_t swm_pwm_set(struct rt_device_pwm *pwm_device, struct rt_pwm_configuration *configuration)
{
rt_uint32_t period, pulse;
rt_uint64_t tim_clock;
struct swm_pwm_cfg *pwm_cfg = RT_NULL;
RT_ASSERT(pwm_device != RT_NULL);
pwm_cfg = pwm_device->parent.user_data;
period = (unsigned long long)configuration->period / 1000UL; //中心对称模式下频率降低一半
pulse = (unsigned long long)configuration->pulse / 1000UL;
if (period < MIN_PERIOD)
{
period = MIN_PERIOD;
}
if (pulse < MIN_PULSE)
{
pulse = MIN_PULSE;
}
PWM_SetPeriod(pwm_cfg->PWMx, period);
PWM_SetHDuty(pwm_cfg->PWMx, PWM_CH_A, pulse);
PWM_SetHDuty(pwm_cfg->PWMx, PWM_CH_B, pulse);
return RT_EOK;
}
static rt_err_t swm_pwm_control(struct rt_device_pwm *pwm_device, int cmd, void *arg)
{
RT_ASSERT(pwm_device != RT_NULL);
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
switch (cmd)
{
case PWM_CMD_ENABLE:
return swm_pwm_enable(pwm_device, configuration, RT_TRUE);
case PWM_CMD_DISABLE:
return swm_pwm_enable(pwm_device, configuration, RT_FALSE);
case PWM_CMD_SET:
return swm_pwm_set(pwm_device, configuration);
case PWM_CMD_GET:
return swm_pwm_get(pwm_device, configuration);
default:
return RT_EINVAL;
}
}
static struct rt_pwm_ops pwm_ops =
{
.control = swm_pwm_control};
int swm_pwm_init(void)
{
int i = 0;
int result = RT_EOK;
for (i = 0; i < sizeof(swm_pwm_cfg) / sizeof(swm_pwm_cfg[0]); i++)
{
pwm_obj[i].pwm_cfg = &swm_pwm_cfg[i];
if (pwm_obj[i].pwm_cfg->PWMx == PWM0)
{
#ifdef BSP_USING_PWM0A
PORT_Init(PORTM, PIN1, PORTM_PIN1_PWM0A, 0);
#endif
#ifdef BSP_USING_PWM0AN
PORT_Init(PORTM, PIN4, PORTM_PIN4_PWM0AN, 0);
#endif
#ifdef BSP_USING_PWM0B
PORT_Init(PORTM, PIN2, PORTM_PIN2_PWM0B, 0);
#endif
#ifdef BSP_USING_PWM0BN
PORT_Init(PORTM, PIN5, PORTM_PIN5_PWM0BN, 0);
#endif
}
else if (pwm_obj[i].pwm_cfg->PWMx == PWM1)
{
#ifdef BSP_USING_PWM1A
PORT_Init(PORTM, PIN3, PORTM_PIN3_PWM1A, 0);
#endif
#ifdef BSP_USING_PWM1AN
PORT_Init(PORTM, PIN6, PORTM_PIN6_PWM1AN, 0);
#endif
#ifdef BSP_USING_PWM1B
PORT_Init(PORTD, PIN9, PORTD_PIN9_PWM1B, 0);
#endif
#ifdef BSP_USING_PWM1BN
PORT_Init(PORTD, PIN8, PORTD_PIN8_PWM1BN, 0);
#endif
}
else if (pwm_obj[i].pwm_cfg->PWMx == PWM2)
{
#ifdef BSP_USING_PWM2A
PORT_Init(PORTM, PIN12, PORTM_PIN12_PWM2A, 0);
#endif
#ifdef BSP_USING_PWM2AN
PORT_Init(PORTM, PIN9, PORTM_PIN9_PWM2AN, 0);
#endif
#ifdef BSP_USING_PWM2B
PORT_Init(PORTM, PIN11, PORTM_PIN11_PWM2B, 0);
#endif
#ifdef BSP_USING_PWM2BN
PORT_Init(PORTM, PIN8, PORTM_PIN8_PWM2BN, 0);
#endif
}
else if (pwm_obj[i].pwm_cfg->PWMx == PWM3)
{
#ifdef BSP_USING_PWM3A
PORT_Init(PORTC, PIN2, PORTC_PIN2_PWM3A, 0);
#endif
#ifdef BSP_USING_PWM3AN
PORT_Init(PORTC, PIN3, PORTC_PIN3_PWM3AN, 0);
#endif
#ifdef BSP_USING_PWM3B
PORT_Init(PORTB, PIN1, PORTB_PIN1_PWM3B, 0);
#endif
#ifdef BSP_USING_PWM3BN
PORT_Init(PORTB, PIN0, PORTB_PIN0_PWM3BN, 0);
#endif
}
else if (pwm_obj[i].pwm_cfg->PWMx == PWM4)
{
#ifdef BSP_USING_PWM4A
PORT_Init(PORTB, PIN15, PORTB_PIN15_PWM4A, 0);
#endif
#ifdef BSP_USING_PWM4AN
// PORT_Init(PORTB, PIN14, PORTB_PIN14_PWM4AN, 0); //SWDIO
#endif
#ifdef BSP_USING_PWM4B
PORT_Init(PORTB, PIN13, PORTB_PIN13_PWM4B, 0);
#endif
#ifdef BSP_USING_PWM4BN
// PORT_Init(PORTB, PIN12, PORTB_PIN12_PWM4BN, 0); //SWDCK
#endif
}
pwm_obj[i].pwm_cfg->pwm_initstruct.Clkdiv = SystemCoreClock / 1000000UL / 2; //中心对称模式下频率降低一半
PWM_Init(pwm_obj[i].pwm_cfg->PWMx, &(pwm_obj[i].pwm_cfg->pwm_initstruct));
result = rt_device_pwm_register(&pwm_obj[i].pwm_device, pwm_obj[i].pwm_cfg->name, &pwm_ops, pwm_obj[i].pwm_cfg);
if(result != RT_EOK)
{
LOG_E("%s register fail.", pwm_obj[i].pwm_cfg->name);
}
else
{
LOG_D("%s register success.", pwm_obj[i].pwm_cfg->name);
}
}
return result;
}
INIT_DEVICE_EXPORT(swm_pwm_init);
#endif /* BSP_USING_PWM */
#endif /* RT_USING_PWM */
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_PWM_H__
#define __DRV_PWM_H__
#include "board.h"
int swm_pwm_init(void);
#endif /* __DRV_PWM_H__ */
+230
View File
@@ -0,0 +1,230 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-25 lik first version
*/
#include "drv_rgb_lcd.h"
#ifdef BSP_USING_RGB_LCD
#include "rgb_lcd_port.h"
#define DRV_DEBUG
#define LOG_TAG "drv.rgb_lcd"
#include <drv_log.h>
#define LCD_DEVICE(dev) (struct swm_rgb_lcd_device *)(dev)
struct swm_rgb_lcd_device rgb_lcd_obj;
static rt_err_t swm_rgb_lcd_configure(struct rt_device *device)
{
struct swm_rgb_lcd_device *rgb_lcd = LCD_DEVICE(device);
/* nothing, right now */
rgb_lcd = rgb_lcd;
return RT_EOK;
}
static rt_err_t swm_rgb_lcd_control(struct rt_device *device, int cmd, void *args)
{
struct swm_rgb_lcd_device *rgb_lcd = LCD_DEVICE(device);
switch (cmd)
{
case RTGRAPHIC_CTRL_GET_INFO:
{
struct rt_device_graphic_info *info = (struct rt_device_graphic_info *)args;
RT_ASSERT(info != RT_NULL);
info->pixel_format = rgb_lcd->lcd_info.pixel_format;
info->bits_per_pixel = rgb_lcd->lcd_info.bits_per_pixel;
info->width = rgb_lcd->lcd_info.width;
info->height = rgb_lcd->lcd_info.height;
info->framebuffer = rgb_lcd->lcd_info.framebuffer;
}
break;
default:
return -RT_EINVAL;
}
return RT_EOK;
}
#if defined(LCD_BACKLIGHT_USING_PWM)
static void turn_on_lcd_backlight(void)
{
struct rt_device_pwm *pwm_dev;
/* turn on the LCD backlight */
pwm_dev = (struct rt_device_pwm *)rt_device_find(LCD_PWM_DEV_NAME);
/* pwm frequency:100K = 10000ns */
rt_pwm_set(pwm_dev, LCD_PWM_DEV_CHANNEL, 10000, 10000);
rt_pwm_enable(pwm_dev, LCD_PWM_DEV_CHANNEL);
}
#elif defined(LCD_BACKLIGHT_USING_GPIO)
static void turn_on_lcd_backlight(void)
{
rt_pin_mode(LCD_DISP_GPIO, PIN_MODE_OUTPUT);
rt_pin_write(LCD_DISP_GPIO, PIN_HIGH);
rt_pin_mode(LCD_BL_GPIO, PIN_MODE_OUTPUT);
rt_pin_write(LCD_BL_GPIO, PIN_HIGH);
}
#else
static void turn_on_lcd_backlight(void)
{
}
#endif
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops swm_lcd_ops =
{
.init = swm_rgb_lcd_configure,
.open = RT_NULL,
.close = RT_NULL,
.read = RT_NULL,
.write = RT_NULL,
.control = swm_rgb_lcd_control};
#endif
int swm_rgb_lcd_init(void)
{
rt_err_t result = RT_EOK;
struct rt_device *device = &rgb_lcd_obj.parent;
/* memset rgb_lcd_obj to zero */
memset(&rgb_lcd_obj, 0x00, sizeof(rgb_lcd_obj));
/* config LCD dev info */
rgb_lcd_obj.lcd_info.height = LCD_HEIGHT;
rgb_lcd_obj.lcd_info.width = LCD_WIDTH;
rgb_lcd_obj.lcd_info.bits_per_pixel = LCD_BITS_PER_PIXEL;
rgb_lcd_obj.lcd_info.pixel_format = LCD_PIXEL_FORMAT;
/* malloc memory for Triple Buffering */
rgb_lcd_obj.lcd_info.framebuffer = rt_malloc_align(LCD_BUF_SIZE,4);
if (rgb_lcd_obj.lcd_info.framebuffer == RT_NULL)
{
LOG_E("init frame buffer failed!\n");
result = -RT_ENOMEM;
goto __exit;
}
/* memset buff to 0xFF */
memset(rgb_lcd_obj.lcd_info.framebuffer, 0xFF, LCD_BUF_SIZE);
device->type = RT_Device_Class_Graphic;
#ifdef RT_USING_DEVICE_OPS
device->ops = &swm_lcd_ops;
#else
device->init = swm_rgb_lcd_configure;
device->control = swm_rgb_lcd_control;
#endif
/* register lcd device */
rt_device_register(device, "rgb_lcd", RT_DEVICE_FLAG_RDWR);
LCD_InitStructure LCD_initStruct;
// PORT_Init(PORTB, PIN1, PORTB_PIN1_LCD_B0, 0);
// PORT_Init(PORTB, PIN11, PORTB_PIN11_LCD_B1, 0);
// PORT_Init(PORTB, PIN13, PORTB_PIN13_LCD_B2, 0);
PORT_Init(PORTB, PIN15, PORTB_PIN15_LCD_B3, 0);
PORT_Init(PORTA, PIN2, PORTA_PIN2_LCD_B4, 0);
PORT_Init(PORTA, PIN9, PORTA_PIN9_LCD_B5, 0);
PORT_Init(PORTA, PIN10, PORTA_PIN10_LCD_B6, 0);
PORT_Init(PORTA, PIN11, PORTA_PIN11_LCD_B7, 0);
// PORT_Init(PORTA, PIN12, PORTA_PIN12_LCD_G0, 0);
// PORT_Init(PORTA, PIN13, PORTA_PIN13_LCD_G1, 0);
PORT_Init(PORTA, PIN14, PORTA_PIN14_LCD_G2, 0);
PORT_Init(PORTA, PIN15, PORTA_PIN15_LCD_G3, 0);
PORT_Init(PORTC, PIN0, PORTC_PIN0_LCD_G4, 0);
PORT_Init(PORTC, PIN1, PORTC_PIN1_LCD_G5, 0);
PORT_Init(PORTC, PIN2, PORTC_PIN2_LCD_G6, 0);
PORT_Init(PORTC, PIN3, PORTC_PIN3_LCD_G7, 0);
// PORT_Init(PORTC, PIN4, PORTC_PIN4_LCD_R0, 0);
// PORT_Init(PORTC, PIN5, PORTC_PIN5_LCD_R1, 0);
// PORT_Init(PORTC, PIN8, PORTC_PIN8_LCD_R2, 0);
PORT_Init(PORTC, PIN9, PORTC_PIN9_LCD_R3, 0);
PORT_Init(PORTC, PIN10, PORTC_PIN10_LCD_R4, 0);
PORT_Init(PORTC, PIN11, PORTC_PIN11_LCD_R5, 0);
PORT_Init(PORTC, PIN12, PORTC_PIN12_LCD_R6, 0);
PORT_Init(PORTC, PIN13, PORTC_PIN13_LCD_R7, 0);
PORT_Init(PORTB, PIN2, PORTB_PIN2_LCD_VSYNC, 0);
PORT_Init(PORTB, PIN3, PORTB_PIN3_LCD_HSYNC, 0);
PORT_Init(PORTB, PIN4, PORTB_PIN4_LCD_DEN, 0);
PORT_Init(PORTB, PIN5, PORTB_PIN5_LCD_DCLK, 0);
LCD_initStruct.ClkDiv = LCD_CLK_DIV;
LCD_initStruct.Format = ((LCD_BITS_PER_PIXEL == 16) ? LCD_FMT_RGB565 : LCD_FMT_RGB888);
LCD_initStruct.HnPixel = LCD_WIDTH;
LCD_initStruct.VnPixel = LCD_HEIGHT;
LCD_initStruct.Hfp = LCD_HFP;
LCD_initStruct.Hbp = LCD_HBP;
LCD_initStruct.Vfp = LCD_VFP;
LCD_initStruct.Vbp = LCD_VBP;
LCD_initStruct.HsyncWidth = LCD_HSYNC_WIDTH;
LCD_initStruct.VsyncWidth = LCD_VSYNC_WIDTH;
LCD_initStruct.DataSource = (uint32_t)rgb_lcd_obj.lcd_info.framebuffer;
LCD_initStruct.Background = 0xFFFFFF;
LCD_initStruct.SampleEdge = LCD_SAMPLE_FALL;
LCD_initStruct.IntEOTEn = 0;
LCD_Init(LCD, &LCD_initStruct);
LCD_Start(LCD);
turn_on_lcd_backlight();
__exit:
if (result != RT_EOK)
{
if (rgb_lcd_obj.lcd_info.framebuffer)
{
rt_free(rgb_lcd_obj.lcd_info.framebuffer);
}
}
return result;
}
INIT_BOARD_EXPORT(swm_rgb_lcd_init);
int lcd_test(void)
{
struct swm_rgb_lcd_device *rgb_lcd;
rgb_lcd = (struct swm_rgb_lcd_device *)rt_device_find("rgb_lcd");
// while (1)
{
/* red */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
rgb_lcd->lcd_info.framebuffer[2 * i] = 0x00;
rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0xF8;
}
rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
rt_thread_mdelay(1000);
/* green */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
rgb_lcd->lcd_info.framebuffer[2 * i] = 0xE0;
rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0x07;
}
rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
rt_thread_mdelay(1000);
/* blue */
for (int i = 0; i < LCD_BUF_SIZE / 2; i++)
{
rgb_lcd->lcd_info.framebuffer[2 * i] = 0x1F;
rgb_lcd->lcd_info.framebuffer[2 * i + 1] = 0x00;
}
rgb_lcd->parent.control(&rgb_lcd->parent, RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
rt_thread_mdelay(1000);
}
return 0;
}
MSH_CMD_EXPORT(lcd_test, lcd_test);
#endif /* BSP_USING_RGB_LCD */
+24
View File
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_RGB_LCD_H__
#define __DRV_RGB_LCD_H__
#include "board.h"
struct swm_rgb_lcd_device
{
struct rt_device parent;
struct rt_device_graphic_info lcd_info;
};
int swm_rgb_lcd_init(void);
#endif /* __DRV_RGB_LCD_H__ */
+191
View File
@@ -0,0 +1,191 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_rtc.h"
#ifdef RT_USING_RTC
#ifdef BSP_USING_RTC
//#define DRV_DEBUG
#define LOG_TAG "drv.rtc"
#include <drv_log.h>
static struct rt_device rtc_device;
static uint32_t calcWeekDay(uint32_t year, uint32_t month, uint32_t date)
{
uint32_t i, cnt = 0;
const uint32_t daysOfMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
for (i = 1; i < month; i++)
cnt += daysOfMonth[i];
cnt += date;
if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)) && (month >= 3))
cnt += 1;
cnt += (year - 1901) * 365;
for (i = 1901; i < year; i++)
{
if ((i % 4 == 0) && ((i % 100 != 0) || (i % 400 == 0)))
cnt += 1;
}
return (cnt + 1) % 7;
}
static time_t swm_get_rtc_time_stamp(void)
{
RTC_DateTime get_datetime = {0};
struct tm tm_new;
RTC_GetDateTime(RTC, &get_datetime);
tm_new.tm_sec = get_datetime.Second;
tm_new.tm_min = get_datetime.Minute;
tm_new.tm_hour = get_datetime.Hour;
tm_new.tm_mday = get_datetime.Date;
tm_new.tm_mon = get_datetime.Month - 1;
tm_new.tm_year = get_datetime.Year - 1900;
LOG_D("get rtc time.");
return mktime(&tm_new);
}
static rt_err_t swm_set_rtc_time_stamp(time_t time_stamp)
{
RTC_DateTime set_datetime = {0};
struct tm *p_tm;
p_tm = gmtime(&time_stamp);
set_datetime.Second = p_tm->tm_sec;
set_datetime.Minute = p_tm->tm_min;
set_datetime.Hour = p_tm->tm_hour;
set_datetime.Date = p_tm->tm_mday;
set_datetime.Month = p_tm->tm_mon + 1;
set_datetime.Year = p_tm->tm_year + 1900;
// set_datetime.Day = p_tm->tm_wday;
RTC_Stop(RTC);
while (RTC->CFGABLE == 0)
;
RTC->MINSEC = (set_datetime.Second << RTC_MINSEC_SEC_Pos) |
(set_datetime.Minute << RTC_MINSEC_MIN_Pos);
RTC->DATHUR = (set_datetime.Hour << RTC_DATHUR_HOUR_Pos) |
((set_datetime.Date) << RTC_DATHUR_DATE_Pos);
RTC->MONDAY = (calcWeekDay(set_datetime.Year, set_datetime.Month, set_datetime.Date)
<< RTC_MONDAY_DAY_Pos) |
((set_datetime.Month) << RTC_MONDAY_MON_Pos);
RTC->YEAR = set_datetime.Year;
RTC->LOAD = 1 << RTC_LOAD_TIME_Pos;
RTC_Start(RTC);
LOG_D("set rtc time.");
return RT_EOK;
}
static rt_err_t swm_rtc_control(rt_device_t rtc_device, int cmd, void *args)
{
rt_err_t result = RT_EOK;
RT_ASSERT(rtc_device != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_RTC_GET_TIME:
*(rt_uint32_t *)args = swm_get_rtc_time_stamp();
LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args);
break;
case RT_DEVICE_CTRL_RTC_SET_TIME:
if (swm_set_rtc_time_stamp(*(rt_uint32_t *)args))
{
result = -RT_ERROR;
}
LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
break;
default:
break;
}
return result;
}
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops swm_rtc_ops =
{
.init = RT_NULL,
.open = RT_NULL,
.close = RT_NULL,
.read = RT_NULL,
.write = RT_NULL,
.control = swm_rtc_control};
#endif
static void swm_rtc_configure(void)
{
RTC_InitStructure rtc_initstruct;
rtc_initstruct.clksrc = RTC_CLKSRC_XTAL32K;
rtc_initstruct.Year = 2020;
rtc_initstruct.Month = 2;
rtc_initstruct.Date = 29;
rtc_initstruct.Hour = 23;
rtc_initstruct.Minute = 59;
rtc_initstruct.Second = 55;
rtc_initstruct.SecondIEn = 0;
rtc_initstruct.MinuteIEn = 0;
RTC_Init(RTC, &rtc_initstruct);
RTC_Start(RTC);
}
static rt_err_t swm_onchip_rtc_register(rt_device_t rtc_device, const char *name, rt_uint32_t flag)
{
RT_ASSERT(rtc_device != RT_NULL);
swm_rtc_configure();
#ifdef RT_USING_DEVICE_OPS
rtc_device->ops = &swm_rtc_ops;
#else
rtc_device->init = RT_NULL;
rtc_device->open = RT_NULL;
rtc_device->close = RT_NULL;
rtc_device->read = RT_NULL;
rtc_device->write = RT_NULL;
rtc_device->control = swm_rtc_control;
#endif
rtc_device->type = RT_Device_Class_RTC;
rtc_device->rx_indicate = RT_NULL;
rtc_device->tx_complete = RT_NULL;
rtc_device->user_data = RT_NULL;
/* register a character device */
return rt_device_register(rtc_device, name, flag);
}
int swm_rtc_init(void)
{
rt_err_t result;
result = swm_onchip_rtc_register(&rtc_device, "rtc", RT_DEVICE_FLAG_RDWR);
if (result != RT_EOK)
{
LOG_E("rtc register fail.");
}
else
{
LOG_D("rtc register success.");
}
return result;
}
INIT_DEVICE_EXPORT(swm_rtc_init);
#endif /* BSP_USING_RTC */
#endif /* RT_USING_RTC */
+19
View File
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_RTC_H__
#define __DRV_RTC_H__
#include "board.h"
#include "sys/time.h"
int swm_rtc_init(void);
#endif /* __DRV_RTC_H__ */
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_SDIO_H__
#define __DRV_SDIO_H__
#include "board.h"
int swm_sdio_init(void);
#endif /* __DRV_SDIO_H__ */
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_sdram.h"
#ifdef BSP_USING_SDRAM
#define DRV_DEBUG
#define LOG_TAG "drv.sdram"
#include <drv_log.h>
int swm_sdram_init(void)
{
SDRAM_InitStructure SDRAM_InitStruct;
PORT_Init(PORTM, PIN13, PORTM_PIN13_SDR_CLK, 0);
PORT_Init(PORTM, PIN14, PORTM_PIN14_SDR_CKE, 0);
PORT_Init(PORTB, PIN7, PORTB_PIN7_SDR_WE, 0);
PORT_Init(PORTB, PIN8, PORTB_PIN8_SDR_CAS, 0);
PORT_Init(PORTB, PIN9, PORTB_PIN9_SDR_RAS, 0);
PORT_Init(PORTB, PIN10, PORTB_PIN10_SDR_CS, 0);
PORT_Init(PORTE, PIN15, PORTE_PIN15_SDR_BA0, 0);
PORT_Init(PORTE, PIN14, PORTE_PIN14_SDR_BA1, 0);
PORT_Init(PORTN, PIN14, PORTN_PIN14_SDR_A0, 0);
PORT_Init(PORTN, PIN13, PORTN_PIN13_SDR_A1, 0);
PORT_Init(PORTN, PIN12, PORTN_PIN12_SDR_A2, 0);
PORT_Init(PORTN, PIN11, PORTN_PIN11_SDR_A3, 0);
PORT_Init(PORTN, PIN10, PORTN_PIN10_SDR_A4, 0);
PORT_Init(PORTN, PIN9, PORTN_PIN9_SDR_A5, 0);
PORT_Init(PORTN, PIN8, PORTN_PIN8_SDR_A6, 0);
PORT_Init(PORTN, PIN7, PORTN_PIN7_SDR_A7, 0);
PORT_Init(PORTN, PIN6, PORTN_PIN6_SDR_A8, 0);
PORT_Init(PORTN, PIN3, PORTN_PIN3_SDR_A9, 0);
PORT_Init(PORTN, PIN15, PORTN_PIN15_SDR_A10, 0);
PORT_Init(PORTN, PIN2, PORTN_PIN2_SDR_A11, 0);
PORT_Init(PORTM, PIN15, PORTM_PIN15_SDR_A12, 0);
PORT_Init(PORTE, PIN7, PORTE_PIN7_SDR_D0, 1);
PORT_Init(PORTE, PIN6, PORTE_PIN6_SDR_D1, 1);
PORT_Init(PORTE, PIN5, PORTE_PIN5_SDR_D2, 1);
PORT_Init(PORTE, PIN4, PORTE_PIN4_SDR_D3, 1);
PORT_Init(PORTE, PIN3, PORTE_PIN3_SDR_D4, 1);
PORT_Init(PORTE, PIN2, PORTE_PIN2_SDR_D5, 1);
PORT_Init(PORTE, PIN1, PORTE_PIN1_SDR_D6, 1);
PORT_Init(PORTE, PIN0, PORTE_PIN0_SDR_D7, 1);
PORT_Init(PORTE, PIN8, PORTE_PIN8_SDR_D8, 1);
PORT_Init(PORTE, PIN9, PORTE_PIN9_SDR_D9, 1);
PORT_Init(PORTE, PIN10, PORTE_PIN10_SDR_D10, 1);
PORT_Init(PORTE, PIN11, PORTE_PIN11_SDR_D11, 1);
PORT_Init(PORTE, PIN12, PORTE_PIN12_SDR_D12, 1);
PORT_Init(PORTE, PIN13, PORTE_PIN13_SDR_D13, 1);
PORT_Init(PORTC, PIN14, PORTC_PIN14_SDR_D14, 1);
PORT_Init(PORTC, PIN15, PORTC_PIN15_SDR_D15, 1);
PORT_Init(PORTB, PIN6, PORTB_PIN6_SDR_LDQM, 0);
PORT_Init(PORTM, PIN12, PORTM_PIN12_SDR_UDQM, 0);
SDRAM_InitStruct.Size = SDRAM_SIZE_8MB;
SDRAM_InitStruct.ClkDiv = SDRAM_CLKDIV_1;
SDRAM_InitStruct.CASLatency = SDRAM_CASLATENCY_3;
SDRAM_InitStruct.TimeTRP = SDRAM_TRP_2;
SDRAM_InitStruct.TimeTRCD = SDRAM_TRCD_2;
SDRAM_InitStruct.TimeTRFC = SDRAM_TRFC_9;
SDRAM_Init(&SDRAM_InitStruct);
return 0;
}
#endif /* BSP_USING_SDRAM */
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_SDRAM_H__
#define __DRV_SDRAM_H__
#include "board.h"
int swm_sdram_init(void);
#endif /* __DRV_SDRAM_H__ */
+219
View File
@@ -0,0 +1,219 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_soft_i2c.h"
#ifdef RT_USING_I2C
#ifdef BSP_USING_I2C
//#define DRV_DEBUG
#define LOG_TAG "drv.i2c"
#include <drv_log.h>
#if !defined(BSP_USING_I2C0) && !defined(BSP_USING_I2C1)
#error "Please define at least one BSP_USING_I2Cx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
#ifdef BSP_USING_I2C0
#define I2C0_BUS_CFG \
{ \
.scl = BSP_I2C0_SCL_PIN, \
.sda = BSP_I2C0_SDA_PIN, \
.name = "i2c0", \
}
#endif
#ifdef BSP_USING_I2C1
#define I2C1_BUS_CFG \
{ \
.scl = BSP_I2C1_SCL_PIN, \
.sda = BSP_I2C1_SDA_PIN, \
.name = "i2c1", \
}
#endif
/* swm config class */
struct swm_soft_i2c_cfg
{
rt_uint8_t scl;
rt_uint8_t sda;
const char *name;
};
/* swm i2c dirver class */
struct swm_soft_i2c_device
{
struct rt_i2c_bit_ops ops;
struct rt_i2c_bus_device i2c2_bus;
};
static const struct swm_soft_i2c_cfg swm_soft_i2c_cfg[] =
{
#ifdef BSP_USING_I2C0
I2C0_BUS_CFG,
#endif
#ifdef BSP_USING_I2C1
I2C1_BUS_CFG,
#endif
};
static struct swm_soft_i2c_device i2c_obj[sizeof(swm_soft_i2c_cfg) / sizeof(swm_soft_i2c_cfg[0])];
/**
* This function initializes the i2c pin.
*
* @param swm i2c dirver class.
*/
static void swm_i2c_gpio_init(struct swm_soft_i2c_device *i2c)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)i2c->ops.data;
rt_pin_mode(soft_i2c_cfg->scl, PIN_MODE_OUTPUT_OD);
rt_pin_mode(soft_i2c_cfg->sda, PIN_MODE_OUTPUT_OD);
rt_pin_write(soft_i2c_cfg->scl, PIN_HIGH);
rt_pin_write(soft_i2c_cfg->sda, PIN_HIGH);
}
/**
* This function sets the sda pin.
*
* @param swm config class.
* @param The sda pin state.
*/
static void swm_i2_set_sda(void *data, rt_int32_t state)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
rt_pin_mode(soft_i2c_cfg->sda, PIN_MODE_OUTPUT_OD);
if (state)
{
rt_pin_write(soft_i2c_cfg->sda, PIN_HIGH);
}
else
{
rt_pin_write(soft_i2c_cfg->sda, PIN_LOW);
}
}
/**
* This function sets the scl pin.
*
* @param swm config class.
* @param The scl pin state.
*/
static void swm_i2c_set_scl(void *data, rt_int32_t state)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
rt_pin_mode(soft_i2c_cfg->scl, PIN_MODE_OUTPUT_OD);
if (state)
{
rt_pin_write(soft_i2c_cfg->scl, PIN_HIGH);
}
else
{
rt_pin_write(soft_i2c_cfg->scl, PIN_LOW);
}
}
/**
* This function gets the sda pin state.
*
* @param The sda pin state.
*/
static rt_int32_t swm_i2c_get_sda(void *data)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
rt_pin_mode(soft_i2c_cfg->sda, PIN_MODE_INPUT_PULLDOWN);
return rt_pin_read(soft_i2c_cfg->sda);
}
/**
* This function gets the scl pin state.
*
* @param The scl pin state.
*/
static rt_int32_t swm_i2c_get_scl(void *data)
{
struct swm_soft_i2c_cfg *soft_i2c_cfg = (struct swm_soft_i2c_cfg *)data;
rt_pin_mode(soft_i2c_cfg->scl, PIN_MODE_INPUT_PULLDOWN);
return rt_pin_read(soft_i2c_cfg->scl);
}
/**
* The time delay function.
*
* @param microseconds.
*/
static void swm_i2c_udelay(rt_uint32_t us)
{
rt_uint32_t ticks;
rt_uint32_t told, tnow, tcnt = 0;
rt_uint32_t reload = SysTick->LOAD;
ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
told = SysTick->VAL;
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
if (tnow < told)
{
tcnt += told - tnow;
}
else
{
tcnt += reload - tnow + told;
}
told = tnow;
if (tcnt >= ticks)
{
break;
}
}
}
}
static const struct rt_i2c_bit_ops swm_i2c_bit_ops =
{
.data = RT_NULL,
.set_sda = swm_i2_set_sda,
.set_scl = swm_i2c_set_scl,
.get_sda = swm_i2c_get_sda,
.get_scl = swm_i2c_get_scl,
.udelay = swm_i2c_udelay,
.delay_us = 1,
.timeout = 100};
/* I2C initialization function */
int swm_i2c_init(void)
{
rt_err_t result;
for (int i = 0; i < sizeof(i2c_obj) / sizeof(struct swm_soft_i2c_device); i++)
{
i2c_obj[i].ops = swm_i2c_bit_ops;
i2c_obj[i].ops.data = (void *)&swm_soft_i2c_cfg[i];
i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
swm_i2c_gpio_init(&i2c_obj[i]);
result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, swm_soft_i2c_cfg[i].name);
RT_ASSERT(result == RT_EOK);
LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
swm_soft_i2c_cfg[i].name,
swm_soft_i2c_cfg[i].scl,
swm_soft_i2c_cfg[i].sda);
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(swm_i2c_init);
#endif /* BSP_USING_I2C */
#endif /* RT_USING_I2C */
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_SOFT_I2C_H__
#define __DRV_SOFT_I2C_H__
#include "board.h"
int swm_i2c_init(void);
#endif /* __DRV_SOFT_I2C_H__ */
+375
View File
@@ -0,0 +1,375 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_spi.h"
#ifdef RT_USING_SPI
#ifdef BSP_USING_SPI
//#define DRV_DEBUG
#define LOG_TAG "drv.spi"
#include <drv_log.h>
#if !defined(BSP_USING_SPI0) && !defined(BSP_USING_SPI1)
#error "Please define at least one BSP_USING_SPIx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
struct swm_spi_cs
{
GPIO_TypeDef *GPIOx;
uint32_t gpio_pin;
};
struct swm_spi_cfg
{
const char *name;
SPI_TypeDef *SPIx;
SPI_InitStructure spi_initstruct;
};
/* swm spi dirver class */
struct swm_spi_device
{
struct swm_spi_cfg *spi_cfg;
struct rt_spi_configuration *configure;
struct rt_spi_bus spi_bus;
};
#ifdef BSP_USING_SPI0
#ifndef SPI0_BUS_CONFIG
#define SPI0_BUS_CONFIG \
{ \
.name = "spi0", \
.SPIx = SPI0, \
.spi_initstruct.clkDiv = SPI_CLKDIV_16, \
.spi_initstruct.FrameFormat = SPI_FORMAT_SPI, \
.spi_initstruct.SampleEdge = SPI_SECOND_EDGE, \
.spi_initstruct.IdleLevel = SPI_HIGH_LEVEL, \
.spi_initstruct.WordSize = 8, \
.spi_initstruct.Master = 1, \
.spi_initstruct.RXThreshold = 0, \
.spi_initstruct.RXThresholdIEn = 0, \
.spi_initstruct.TXThreshold = 0, \
.spi_initstruct.TXThresholdIEn = 0, \
.spi_initstruct.TXCompleteIEn = 0, \
}
#endif /* SPI0_BUS_CONFIG */
#endif /* BSP_USING_SPI0 */
#ifdef BSP_USING_SPI1
#ifndef SPI1_BUS_CONFIG
#define SPI1_BUS_CONFIG \
{ \
.name = "spi1", \
.SPIx = SPI1, \
.spi_initstruct.clkDiv = SPI_CLKDIV_16, \
.spi_initstruct.FrameFormat = SPI_FORMAT_SPI, \
.spi_initstruct.SampleEdge = SPI_SECOND_EDGE, \
.spi_initstruct.IdleLevel = SPI_HIGH_LEVEL, \
.spi_initstruct.WordSize = 8, \
.spi_initstruct.Master = 1, \
.spi_initstruct.RXThreshold = 0, \
.spi_initstruct.RXThresholdIEn = 0, \
.spi_initstruct.TXThreshold = 0, \
.spi_initstruct.TXThresholdIEn = 0, \
.spi_initstruct.TXCompleteIEn = 0, \
}
#endif /* SPI1_BUS_CONFIG */
#endif /* BSP_USING_SPI1 */
static struct swm_spi_cfg swm_spi_cfg[] =
{
#ifdef BSP_USING_SPI0
SPI0_BUS_CONFIG,
#endif
#ifdef BSP_USING_SPI1
SPI1_BUS_CONFIG,
#endif
};
static struct swm_spi_device spi_bus_obj[sizeof(swm_spi_cfg) / sizeof(swm_spi_cfg[0])] = {0};
static rt_err_t swm_spi_configure(struct rt_spi_device *device,
struct rt_spi_configuration *configure)
{
RT_ASSERT(device != RT_NULL);
RT_ASSERT(configure != RT_NULL);
struct swm_spi_device *spi_drv = rt_container_of(device->bus, struct swm_spi_device, spi_bus);
spi_drv->configure = configure;
struct swm_spi_cfg *spi_cfg = spi_drv->spi_cfg;
if (configure->mode & RT_SPI_SLAVE)
{
spi_cfg->spi_initstruct.Master = 0;
}
else
{
spi_cfg->spi_initstruct.Master = 1;
}
if (configure->mode & RT_SPI_3WIRE)
{
return RT_EINVAL;
}
if (configure->data_width == 8)
{
spi_cfg->spi_initstruct.WordSize = 8;
}
else if (configure->data_width == 16)
{
spi_cfg->spi_initstruct.WordSize = 16;
}
else
{
return RT_EIO;
}
if (configure->mode & RT_SPI_CPHA)
{
spi_cfg->spi_initstruct.SampleEdge = SPI_SECOND_EDGE;
}
else
{
spi_cfg->spi_initstruct.SampleEdge = SPI_FIRST_EDGE;
}
if (configure->mode & RT_SPI_CPOL)
{
spi_cfg->spi_initstruct.IdleLevel = SPI_HIGH_LEVEL;
}
else
{
spi_cfg->spi_initstruct.IdleLevel = SPI_LOW_LEVEL;
}
if (configure->max_hz >= SystemCoreClock / 2)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_4;
}
else if (configure->max_hz >= SystemCoreClock / 4)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_4;
}
else if (configure->max_hz >= SystemCoreClock / 8)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_8;
}
else if (configure->max_hz >= SystemCoreClock / 16)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_16;
}
else if (configure->max_hz >= SystemCoreClock / 32)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_32;
}
else if (configure->max_hz >= SystemCoreClock / 64)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_64;
}
else if (configure->max_hz >= SystemCoreClock / 128)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_128;
}
else if (configure->max_hz >= SystemCoreClock / 256)
{
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_256;
}
else
{
/* min prescaler 512 */
spi_cfg->spi_initstruct.clkDiv = SPI_CLKDIV_512;
}
SPI_Init(spi_cfg->SPIx, &(spi_cfg->spi_initstruct));
SPI_Open(spi_cfg->SPIx);
LOG_D("%s init done", spi_cfg->name);
return RT_EOK;
}
#define SPISTEP(datalen) (((datalen) == 8) ? 1 : 2)
#define SPISEND_1(reg, ptr, datalen) \
do \
{ \
if (datalen == 8) \
{ \
(reg) = *(rt_uint8_t *)(ptr); \
} \
else \
{ \
(reg) = *(rt_uint16_t *)(ptr); \
} \
} while (0)
#define SPIRECV_1(reg, ptr, datalen) \
do \
{ \
if (datalen == 8) \
{ \
*(rt_uint8_t *)(ptr) = (reg); \
} \
else \
{ \
*(rt_uint16_t *)(ptr) = reg; \
} \
} while (0)
static rt_err_t swm_spi_txrx1b(struct swm_spi_device *spi_drv, void *rcvb, const void *sndb)
{
rt_uint32_t padrcv = 0;
rt_uint32_t padsnd = 0xFF;
if (!rcvb && !sndb)
{
return RT_ERROR;
}
if (!rcvb)
{
rcvb = &padrcv;
}
if (!sndb)
{
sndb = &padsnd;
}
while (SPI_IsTXFull(spi_drv->spi_cfg->SPIx))
;
SPISEND_1(spi_drv->spi_cfg->SPIx->DATA, sndb, spi_drv->spi_cfg->spi_initstruct.WordSize);
while (SPI_IsRXEmpty(spi_drv->spi_cfg->SPIx))
;
SPIRECV_1(spi_drv->spi_cfg->SPIx->DATA, rcvb, spi_drv->spi_cfg->spi_initstruct.WordSize);
return RT_EOK;
}
static rt_uint32_t swm_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
rt_err_t res;
RT_ASSERT(device != RT_NULL);
RT_ASSERT(device->bus != RT_NULL);
RT_ASSERT(device->bus->parent.user_data != RT_NULL);
RT_ASSERT(message != RT_NULL);
struct swm_spi_device *spi_drv = rt_container_of(device->bus, struct swm_spi_device, spi_bus);
struct swm_spi_cfg *spi_cfg = spi_drv->spi_cfg;
struct swm_spi_cs *cs = device->parent.user_data;
if (message->cs_take)
{
GPIO_ClrBit(cs->GPIOx, cs->gpio_pin);
}
LOG_D("%s transfer prepare and start", spi_cfg->name);
LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d",
spi_cfg->name, (uint32_t)message->send_buf, (uint32_t)message->recv_buf, message->length);
const rt_uint8_t *sndb = message->send_buf;
rt_uint8_t *rcvb = message->recv_buf;
rt_int32_t length = message->length;
while (length)
{
res = swm_spi_txrx1b(spi_drv, rcvb, sndb);
if (rcvb)
{
rcvb += SPISTEP(spi_cfg->spi_initstruct.WordSize);
}
if (sndb)
{
sndb += SPISTEP(spi_cfg->spi_initstruct.WordSize);
}
if (res != RT_EOK)
{
break;
}
length--;
}
/* Wait until Busy flag is reset before disabling SPI */
while (!SPI_IsTXEmpty(spi_cfg->SPIx) && !SPI_IsRXEmpty(spi_cfg->SPIx))
;
if (message->cs_release)
{
GPIO_SetBit(cs->GPIOx, cs->gpio_pin);
}
return message->length - length;
}
const static struct rt_spi_ops swm_spi_ops =
{
.configure = swm_spi_configure,
.xfer = swm_spi_xfer,
};
//cannot be used before completion init
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef *cs_gpiox, uint32_t cs_gpio_pin)
{
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
rt_err_t result;
struct rt_spi_device *spi_device;
struct swm_spi_cs *cs_pin;
GPIO_Init(cs_gpiox, cs_gpio_pin, 1, 1, 0, 0);
GPIO_SetBit(cs_gpiox, cs_gpio_pin);
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
RT_ASSERT(spi_device != RT_NULL);
cs_pin = (struct swm_spi_cs *)rt_malloc(sizeof(struct swm_spi_cs));
RT_ASSERT(cs_pin != RT_NULL);
cs_pin->GPIOx = cs_gpiox;
cs_pin->gpio_pin = cs_gpio_pin;
result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
if (result != RT_EOK)
{
LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
}
RT_ASSERT(result == RT_EOK);
LOG_D("%s attach to %s done", device_name, bus_name);
return result;
}
int swm_spi_init(void)
{
rt_err_t result;
#ifdef BSP_USING_SPI0
PORT_Init(PORTM, PIN2, PORTM_PIN2_SPI0_SCLK, 0);
PORT_Init(PORTM, PIN4, PORTM_PIN4_SPI0_MISO, 1);
PORT_Init(PORTM, PIN5, PORTM_PIN5_SPI0_MOSI, 0);
#endif //BSP_USING_SPI0
#ifdef BSP_USING_SPI1
PORT_Init(PORTB, PIN2, PORTB_PIN2_SPI1_SCLK, 0);
PORT_Init(PORTB, PIN3, PORTB_PIN3_SPI1_MISO, 1);
PORT_Init(PORTB, PIN4, PORTB_PIN4_SPI1_MOSI, 0);
#endif //BSP_USING_SPI1
for (int i = 0; i < sizeof(swm_spi_cfg) / sizeof(swm_spi_cfg[0]); i++)
{
spi_bus_obj[i].spi_cfg = &swm_spi_cfg[i];
spi_bus_obj[i].spi_bus.parent.user_data = &swm_spi_cfg[i];
result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, swm_spi_cfg[i].name, &swm_spi_ops);
if (result != RT_EOK)
{
LOG_E("%s bus register fail.", swm_spi_cfg[i].name);
}
else
{
LOG_D("%s bus register success.", swm_spi_cfg[i].name);
}
}
return result;
}
INIT_BOARD_EXPORT(swm_spi_init);
#endif /* BSP_USING_SPI */
#endif /* RT_USING_SPI */
+20
View File
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include "board.h"
//cannot be used before completion init
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef *GPIOx, uint32_t n);
int swm_spi_init(void);
#endif /* __DRV_SPI_H__ */
+356
View File
@@ -0,0 +1,356 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_uart.h"
#ifdef RT_USING_SERIAL
#ifdef BSP_USING_UART
//#define DRV_DEBUG
#define LOG_TAG "drv.uart"
#include <drv_log.h>
#if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && \
!defined(BSP_USING_UART3)
#error "Please define at least one BSP_USING_UARTx"
/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
#endif
#ifdef BSP_USING_UART0
#ifndef UART0_CFG
#define UART0_CFG \
{ \
.name = "uart0", \
.UARTx = UART0, \
.irq = UART0_IRQn, \
.uart_initstruct.Baudrate = 115200, \
.uart_initstruct.DataBits = UART_DATA_8BIT, \
.uart_initstruct.Parity = UART_PARITY_NONE, \
.uart_initstruct.StopBits = UART_STOP_1BIT, \
.uart_initstruct.RXThreshold = 0, \
.uart_initstruct.RXThresholdIEn = 1, \
.uart_initstruct.TXThresholdIEn = 0, \
.uart_initstruct.TimeoutTime = 10, \
.uart_initstruct.TimeoutIEn = 1, \
}
#endif /* UART0_CFG */
#endif /* BSP_USING_UART0 */
#ifdef BSP_USING_UART1
#ifndef UART1_CFG
#define UART1_CFG \
{ \
.name = "uart1", \
.UARTx = UART1, \
.irq = UART1_IRQn, \
.uart_initstruct.Baudrate = 115200, \
.uart_initstruct.DataBits = UART_DATA_8BIT, \
.uart_initstruct.Parity = UART_PARITY_NONE, \
.uart_initstruct.StopBits = UART_STOP_1BIT, \
.uart_initstruct.RXThreshold = 0, \
.uart_initstruct.RXThresholdIEn = 1, \
.uart_initstruct.TXThresholdIEn = 0, \
.uart_initstruct.TimeoutTime = 10, \
.uart_initstruct.TimeoutIEn = 1, \
}
#endif /* UART1_CFG */
#endif /* BSP_USING_UART1 */
#ifdef BSP_USING_UART2
#ifndef UART2_CFG
#define UART2_CFG \
{ \
.name = "uart2", \
.UARTx = UART2, \
.irq = UART2_IRQn, \
.uart_initstruct.Baudrate = 115200, \
.uart_initstruct.DataBits = UART_DATA_8BIT, \
.uart_initstruct.Parity = UART_PARITY_NONE, \
.uart_initstruct.StopBits = UART_STOP_1BIT, \
.uart_initstruct.RXThreshold = 0, \
.uart_initstruct.RXThresholdIEn = 1, \
.uart_initstruct.TXThresholdIEn = 0, \
.uart_initstruct.TimeoutTime = 10, \
.uart_initstruct.TimeoutIEn = 1, \
}
#endif /* UART2_CFG */
#endif /* BSP_USING_UART2 */
#ifdef BSP_USING_UART3
#ifndef UART3_CFG
#define UART3_CFG \
{ \
.name = "uart3", \
.UARTx = UART3, \
.irq = UART3_IRQn, \
.uart_initstruct.Baudrate = 115200, \
.uart_initstruct.DataBits = UART_DATA_8BIT, \
.uart_initstruct.Parity = UART_PARITY_NONE, \
.uart_initstruct.StopBits = UART_STOP_1BIT, \
.uart_initstruct.RXThreshold = 0, \
.uart_initstruct.RXThresholdIEn = 1, \
.uart_initstruct.TXThresholdIEn = 0, \
.uart_initstruct.TimeoutTime = 10, \
.uart_initstruct.TimeoutIEn = 1, \
}
#endif /* UART3_CFG */
#endif /* BSP_USING_UART3 */
/* swm config class */
struct swm_uart_cfg
{
const char *name;
UART_TypeDef *UARTx;
IRQn_Type irq;
UART_InitStructure uart_initstruct;
};
/* swm uart dirver class */
struct swm_uart_device
{
struct swm_uart_cfg *uart_cfg;
struct rt_serial_device serial_device;
};
enum
{
#ifdef BSP_USING_UART0
UART0_INDEX,
#endif
#ifdef BSP_USING_UART1
UART1_INDEX,
#endif
#ifdef BSP_USING_UART2
UART2_INDEX,
#endif
#ifdef BSP_USING_UART3
UART3_INDEX,
#endif
};
static struct swm_uart_cfg swm_uart_cfg[] =
{
#ifdef BSP_USING_UART0
UART0_CFG,
#endif
#ifdef BSP_USING_UART1
UART1_CFG,
#endif
#ifdef BSP_USING_UART2
UART2_CFG,
#endif
#ifdef BSP_USING_UART3
UART3_CFG,
#endif
};
static struct swm_uart_device uart_obj[sizeof(swm_uart_cfg) / sizeof(swm_uart_cfg[0])] = {0};
static rt_err_t swm_uart_configure(struct rt_serial_device *serial_device, struct serial_configure *configure)
{
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
RT_ASSERT(configure != RT_NULL);
uart_cfg = serial_device->parent.user_data;
uart_cfg->uart_initstruct.Baudrate = configure->baud_rate;
switch (configure->data_bits)
{
case DATA_BITS_8:
uart_cfg->uart_initstruct.DataBits = UART_DATA_8BIT;
break;
case DATA_BITS_9:
uart_cfg->uart_initstruct.DataBits = UART_DATA_9BIT;
break;
default:
uart_cfg->uart_initstruct.DataBits = UART_DATA_8BIT;
break;
}
switch (configure->stop_bits)
{
case STOP_BITS_1:
uart_cfg->uart_initstruct.StopBits = UART_STOP_1BIT;
break;
case STOP_BITS_2:
uart_cfg->uart_initstruct.StopBits = UART_STOP_2BIT;
break;
default:
uart_cfg->uart_initstruct.StopBits = UART_STOP_1BIT;
break;
}
switch (configure->parity)
{
case PARITY_NONE:
uart_cfg->uart_initstruct.Parity = UART_PARITY_NONE;
break;
case PARITY_ODD:
uart_cfg->uart_initstruct.Parity = UART_PARITY_ODD;
break;
case PARITY_EVEN:
uart_cfg->uart_initstruct.Parity = UART_PARITY_EVEN;
break;
default:
uart_cfg->uart_initstruct.Parity = UART_PARITY_NONE;
break;
}
UART_Init(uart_cfg->UARTx, &(uart_cfg->uart_initstruct));
UART_Open(uart_cfg->UARTx);
return RT_EOK;
}
static rt_err_t swm_uart_control(struct rt_serial_device *serial_device, int cmd, void *arg)
{
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
uart_cfg = serial_device->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
/* disable rx irq */
NVIC_DisableIRQ(uart_cfg->irq);
break;
case RT_DEVICE_CTRL_SET_INT:
/* enable rx irq */
NVIC_EnableIRQ(uart_cfg->irq);
break;
}
return RT_EOK;
}
static int swm_uart_putc(struct rt_serial_device *serial_device, char c)
{
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
uart_cfg = serial_device->parent.user_data;
UART_WriteByte(uart_cfg->UARTx, c);
while (UART_IsTXBusy(uart_cfg->UARTx))
;
return 1;
}
static int swm_uart_getc(struct rt_serial_device *serial_device)
{
int ch;
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
uart_cfg = serial_device->parent.user_data;
ch = -1;
if (UART_IsRXFIFOEmpty(uart_cfg->UARTx) == 0)
{
UART_ReadByte(uart_cfg->UARTx, (uint32_t *)&ch);
}
return ch;
}
static const struct rt_uart_ops swm_uart_ops =
{
.configure = swm_uart_configure,
.control = swm_uart_control,
.putc = swm_uart_putc,
.getc = swm_uart_getc,
.dma_transmit = RT_NULL};
/**
* Uart common interrupt process. This need add to uart ISR.
*
* @param serial serial device
*/
static void swm_uart_isr(struct rt_serial_device *serial_device)
{
struct swm_uart_cfg *uart_cfg;
RT_ASSERT(serial_device != RT_NULL);
uart_cfg = serial_device->parent.user_data;
/* UART in mode Receiver -------------------------------------------------*/
if (UART_INTRXThresholdStat(uart_cfg->UARTx) || UART_INTTimeoutStat(uart_cfg->UARTx))
{
rt_hw_serial_isr(serial_device, RT_SERIAL_EVENT_RX_IND);
}
}
#if defined(BSP_USING_UART0)
void UART0_Handler(void)
{
rt_interrupt_enter();
swm_uart_isr(&(uart_obj[UART0_INDEX].serial_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_UART0 */
#if defined(BSP_USING_UART1)
void UART1_Handler(void)
{
rt_interrupt_enter();
swm_uart_isr(&(uart_obj[UART1_INDEX].serial_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_UART1 */
#if defined(BSP_USING_UART2)
void UART2_Handler(void)
{
rt_interrupt_enter();
swm_uart_isr(&(uart_obj[UART2_INDEX].serial_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_UART2 */
#if defined(BSP_USING_UART3)
void UART3_Handler(void)
{
rt_interrupt_enter();
swm_uart_isr(&(uart_obj[UART3_INDEX].serial_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_UART3 */
int swm_uart_init(void)
{
struct serial_configure serial_cfg = RT_SERIAL_CONFIG_DEFAULT;
int i = 0;
rt_err_t result = RT_EOK;
#ifdef BSP_USING_UART0
PORT_Init(PORTM, PIN0, PORTM_PIN0_UART0_RX, 1);
PORT_Init(PORTM, PIN1, PORTM_PIN1_UART0_TX, 0);
#endif
#ifdef BSP_USING_UART1
PORT_Init(PORTD, PIN4, PORTD_PIN4_UART1_RX, 1);
PORT_Init(PORTD, PIN3, PORTD_PIN3_UART1_TX, 0);
#endif
#ifdef BSP_USING_UART2
PORT_Init(PORTC, PIN1, PORTC_PIN1_UART2_RX, 1);
PORT_Init(PORTC, PIN0, PORTC_PIN0_UART2_TX, 0);
#endif
#ifdef BSP_USING_UART3
PORT_Init(PORTC, PIN2, PORTC_PIN2_UART3_RX, 1);
PORT_Init(PORTC, PIN3, PORTC_PIN3_UART3_TX, 0);
#endif
for (i = 0; i < sizeof(swm_uart_cfg) / sizeof(swm_uart_cfg[0]); i++)
{
uart_obj[i].uart_cfg = &swm_uart_cfg[i];
uart_obj[i].serial_device.ops = &swm_uart_ops;
uart_obj[i].serial_device.config = serial_cfg;
result = rt_hw_serial_register(&uart_obj[i].serial_device, uart_obj[i].uart_cfg->name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart_obj[i].uart_cfg);
RT_ASSERT(result == RT_EOK);
}
return result;
}
#endif /* BSP_USING_UART */
#endif /* RT_USING_SERIAL */
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_UART_H__
#define __DRV_UART_H__
#include "board.h"
int swm_uart_init(void);
#endif /* __DRV_UART_H__ */
+104
View File
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#include "drv_wdt.h"
#ifdef RT_USING_WDT
#ifdef BSP_USING_WDT
//#define DRV_DEBUG
#define LOG_TAG "drv.wdt"
#include <drv_log.h>
struct swm_wdt_cfg
{
const char *name;
WDT_TypeDef *WDTx;
};
struct swm_wdt_device
{
struct swm_wdt_cfg *wdt_cfg;
struct rt_watchdog_device wdt_device;
};
static struct swm_wdt_cfg swm_wdt_cfg =
{
.name = "wdt",
.WDTx = WDT,
};
static struct swm_wdt_device wdt_obj;
static rt_err_t swm_wdt_config(rt_watchdog_t *wdt_device)
{
return RT_EOK;
}
static rt_err_t swm_wdt_control(rt_watchdog_t *wdt_device, int cmd, void *arg)
{
struct swm_wdt_cfg *wdt_cfg;
RT_ASSERT(wdt_device != RT_NULL);
wdt_cfg = wdt_device->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
WDT_Feed(wdt_cfg->WDTx);
break;
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
WDT_Init(wdt_cfg->WDTx, 0, (1024 * (*(rt_uint32_t *)arg)));
break;
case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
*(rt_uint32_t *)arg = (wdt_cfg->WDTx->RSTVAL) / 1024;
break;
case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
// not support
break;
case RT_DEVICE_CTRL_WDT_START:
WDT_Start(wdt_cfg->WDTx);
break;
case RT_DEVICE_CTRL_WDT_STOP:
WDT_Stop(wdt_cfg->WDTx);
break;
default:
LOG_W("This command is not supported.");
return -RT_ERROR;
}
return RT_EOK;
}
const static struct rt_watchdog_ops swm_wdt_ops =
{
.init = swm_wdt_config,
.control = swm_wdt_control};
int swm_wdt_init(void)
{
int result = RT_EOK;
wdt_obj.wdt_cfg = &swm_wdt_cfg;
wdt_obj.wdt_device.ops = &swm_wdt_ops;
result = rt_hw_watchdog_register(&wdt_obj.wdt_device, wdt_obj.wdt_cfg->name, RT_DEVICE_FLAG_RDWR, wdt_obj.wdt_cfg);
if(result != RT_EOK)
{
LOG_E("wdt device register fail.");
}
else
{
LOG_D("wdt device register success.");
}
return result;
}
INIT_BOARD_EXPORT(swm_wdt_init);
#endif /* BSP_USING_WDT */
#endif /* RT_USING_WDT */
+18
View File
@@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2021, Synwit Technology Co.,Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-01 lik first version
*/
#ifndef __DRV_WDT_H__
#define __DRV_WDT_H__
#include "board.h"
int swm_wdt_init(void);
#endif /* __DRV_WDT_H__ */
@@ -0,0 +1,62 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_4.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_IROM1_start__ = 0x00000000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x0007FFFF;
define symbol __ICFEDIT_region_IROM2_start__ = 0x0;
define symbol __ICFEDIT_region_IROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM1_start__ = 0x0;
define symbol __ICFEDIT_region_EROM1_end__ = 0x0;
define symbol __ICFEDIT_region_EROM2_start__ = 0x0;
define symbol __ICFEDIT_region_EROM2_end__ = 0x0;
define symbol __ICFEDIT_region_EROM3_start__ = 0x0;
define symbol __ICFEDIT_region_EROM3_end__ = 0x0;
define symbol __ICFEDIT_region_IRAM1_start__ = 0x20000000;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x2000FFFF;
define symbol __ICFEDIT_region_IRAM2_start__ = 0x0;
define symbol __ICFEDIT_region_IRAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM1_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM2_end__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_start__ = 0x0;
define symbol __ICFEDIT_region_ERAM3_end__ = 0x0;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_proc_stack__ = 0x0;
define symbol __ICFEDIT_size_heap__ = 0x400;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region IROM_region = mem:[from __ICFEDIT_region_IROM1_start__ to __ICFEDIT_region_IROM1_end__]
| mem:[from __ICFEDIT_region_IROM2_start__ to __ICFEDIT_region_IROM2_end__];
define region EROM_region = mem:[from __ICFEDIT_region_EROM1_start__ to __ICFEDIT_region_EROM1_end__]
| mem:[from __ICFEDIT_region_EROM2_start__ to __ICFEDIT_region_EROM2_end__]
| mem:[from __ICFEDIT_region_EROM3_start__ to __ICFEDIT_region_EROM3_end__];
define region IRAM_region = mem:[from __ICFEDIT_region_IRAM1_start__ to __ICFEDIT_region_IRAM1_end__]
| mem:[from __ICFEDIT_region_IRAM2_start__ to __ICFEDIT_region_IRAM2_end__];
define region ERAM_region = mem:[from __ICFEDIT_region_ERAM1_start__ to __ICFEDIT_region_ERAM1_end__]
| mem:[from __ICFEDIT_region_ERAM2_start__ to __ICFEDIT_region_ERAM2_end__]
| mem:[from __ICFEDIT_region_ERAM3_start__ to __ICFEDIT_region_ERAM3_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block PROC_STACK with alignment = 8, size = __ICFEDIT_size_proc_stack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
do not initialize { section .noinit };
initialize by copy { readwrite };
if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
{
// Required in a multi-threaded application
initialize by copy with packing = none { section __DLIB_PERTHREAD };
}
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in IROM_region { readonly };
place in EROM_region { readonly section application_specific_ro };
place in IRAM_region { readwrite, block CSTACK, block PROC_STACK, block HEAP };
place in ERAM_region { readwrite section application_specific_rw };

Some files were not shown because too many files have changed in this diff Show More