未验证 提交 0189987d 编写于 作者: W woody 提交者: GitHub

add synwit swm341 bsp (#6235)

华芯微特SWM341芯片的bsp支持包
* 修改dac.c函数名称错误
* delete swm320-lq100 bsp
* 修复sdio读写块的地址偏移问题
* add synwit swm341 bsp
* 修复gcc下启动文件错误
* 为测试用例添加说明
上级 e4d6dd88
......@@ -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"}
......
此差异已折叠。
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
# 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.0B(29Bit标识符)
- 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片内时钟源
- 2~32MHz片外晶振
芯片更多详细信息请参考[华芯微特技术支持](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/)
# 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')
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)
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')
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')
/*
* 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
/*
* 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);
}
/*
* 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();
}
/*
* 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();
}
此差异已折叠。
#
# 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
#
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
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')
/*
* 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
}
/*
* 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__ */
/*
* 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 */
/*
* 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__ */
/*
* 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
*/
#include "drv_can.h"
#ifdef RT_USING_CAN
#ifdef BSP_USING_CAN
//#define DRV_DEBUG
#define LOG_TAG "drv.can"
#include <drv_log.h>
#if !defined(BSP_USING_CAN0) && !defined(BSP_USING_CAN1)
#error "Please define at least one BSP_USING_CANx"
/* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
#endif
#ifdef BSP_USING_CAN0
#ifndef CAN0_CFG
#define CAN0_CFG \
{ \
.name = "can0", \
.CANx = CAN0, \
}
#endif /* CAN0_CFG */
#endif /* BSP_USING_CAN0 */
#ifdef BSP_USING_CAN1
#ifndef CAN1_CFG
#define CAN1_CFG \
{ \
.name = "can1", \
.CANx = CAN1, \
}
#endif /* CAN1_CFG */
#endif /* BSP_USING_CAN1 */
#define PRESCL_Pos 0
#define BS1_Pos 16
#define BS2_Pos 20
#define SJW_Pos 24
#define PRESCL_Msk (0x3FF << PRESCL_Pos)
#define BS1_Msk ((0x0F) << BS1_Pos)
#define BS2_Msk ((0x07) << BS2_Pos)
#define SJW_Msk (0x3 << SJW_Pos)
struct swm_baud_rate_tab
{
rt_uint32_t baud_rate;
rt_uint32_t config_data;
};
#define BAUD_DATA(TYPE, NO) ((can_baud_rate_tab[NO].config_data & TYPE##_Msk) >> TYPE##_Pos)
struct swm_can_cfg
{
const char *name;
CAN_TypeDef *CANx;
CAN_InitStructure CAN_initstruct;
};
struct swm_can_device
{
struct swm_can_cfg *can_cfg;
struct rt_can_device can_device;
};
/* SystemCoreClock 152MHz(max) 150MHz不能生成CAN1MBaud */
static const struct swm_baud_rate_tab can_baud_rate_tab[] =
{
{CAN1MBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (1 << PRESCL_Pos))},
{CAN500kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (3 << PRESCL_Pos))},
{CAN250kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (7 << PRESCL_Pos))},
{CAN125kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (15 << PRESCL_Pos))},
{CAN100kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (19 << PRESCL_Pos))},
{CAN50kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (39 << PRESCL_Pos))},
{CAN20kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (99 << PRESCL_Pos))},
{CAN10kBaud, ((CAN_SJW_4tq << SJW_Pos) | (CAN_BS1_12tq << BS1_Pos) | (CAN_BS2_6tq << BS2_Pos) | (199 << PRESCL_Pos))}};
enum
{
#ifdef BSP_USING_CAN0
CAN0_INDEX,
#endif
#ifdef BSP_USING_CAN1
CAN1_INDEX,
#endif
};
static struct swm_can_cfg swm_can_cfg[] =
{
#ifdef BSP_USING_CAN0
CAN0_CFG,
#endif
#ifdef BSP_USING_CAN1
CAN1_CFG,
#endif
};
static struct swm_can_device can_obj[sizeof(swm_can_cfg) / sizeof(swm_can_cfg[0])];
static rt_uint32_t get_can_baud_index(rt_uint32_t baud)
{
rt_uint32_t len, index;
len = sizeof(can_baud_rate_tab) / sizeof(can_baud_rate_tab[0]);
for (index = 0; index < len; index++)
{
if (can_baud_rate_tab[index].baud_rate == baud)
return index;
}
return 0; /* default baud is CAN1MBaud */
}
static rt_err_t swm_can_config(struct rt_can_device *can_device, struct can_configure *cfg)
{
struct swm_can_device *can_dev;
rt_uint32_t baud_index;
rt_uint32_t can_mode;
RT_ASSERT(can_device);
RT_ASSERT(cfg);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
RT_ASSERT(can_dev);
switch (cfg->mode)
{
case RT_CAN_MODE_NORMAL:
can_mode = CAN_MODE_NORMAL;
break;
case RT_CAN_MODE_LISEN:
can_mode = CAN_MODE_LISTEN;
break;
case RT_CAN_MODE_LOOPBACK:
can_mode = CAN_MODE_SELFTEST;
break;
case RT_CAN_MODE_LOOPBACKANLISEN:
can_mode = CAN_MODE_SELFTEST;
break;
}
baud_index = get_can_baud_index(cfg->baud_rate);
CAN_Close(can_dev->can_cfg->CANx); //一些关键寄存器只能在CAN关闭时设置
can_dev->can_cfg->CANx->CR &= ~(CAN_CR_LOM_Msk | CAN_CR_STM_Msk);
can_dev->can_cfg->CANx->CR |= (can_mode << CAN_CR_LOM_Pos);
can_dev->can_cfg->CANx->BT1 = (0 << CAN_BT1_SAM_Pos) |
(BAUD_DATA(BS1, baud_index) << CAN_BT1_TSEG1_Pos) |
(BAUD_DATA(BS2, baud_index) << CAN_BT1_TSEG2_Pos);
can_dev->can_cfg->CANx->BT0 = (BAUD_DATA(SJW, baud_index) << CAN_BT0_SJW_Pos) |
((BAUD_DATA(PRESCL, baud_index) & 0x3F) << CAN_BT0_BRP_Pos);
can_dev->can_cfg->CANx->BT2 = ((BAUD_DATA(PRESCL, baud_index) >> 6) << CAN_BT2_BRP_Pos);
can_dev->can_cfg->CANx->RXERR = 0; //只能在复位模式下清除
can_dev->can_cfg->CANx->TXERR = 0;
/* can start */
CAN_Open(can_dev->can_cfg->CANx);
return RT_EOK;
}
static rt_err_t swm_can_control(struct rt_can_device *can_device, int cmd, void *arg)
{
rt_uint32_t argval;
struct swm_can_device *can_dev;
struct rt_can_filter_config *filter_cfg;
RT_ASSERT(can_device != RT_NULL);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
RT_ASSERT(can_dev != RT_NULL);
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
argval = (rt_uint32_t)arg;
if (argval == RT_DEVICE_FLAG_INT_RX)
{
can_dev->can_cfg->CANx->IE &= ~(CAN_IE_RXDA_Msk | CAN_IE_RXOV_Msk);
}
else if (argval == RT_DEVICE_FLAG_INT_TX)
{
can_dev->can_cfg->CANx->IE &= ~CAN_IE_TXBR_Msk;
}
else if (argval == RT_DEVICE_CAN_INT_ERR)
{
can_dev->can_cfg->CANx->IE &= ~(CAN_IE_ARBLOST_Msk | CAN_IE_BUSERR_Msk | CAN_IE_ERRWARN_Msk | CAN_IE_ERRPASS_Msk);
}
break;
case RT_DEVICE_CTRL_SET_INT:
argval = (rt_uint32_t)arg;
if (argval == RT_DEVICE_FLAG_INT_RX)
{
can_dev->can_cfg->CANx->IE |= (CAN_IE_RXDA_Msk | CAN_IE_RXOV_Msk);
}
else if (argval == RT_DEVICE_FLAG_INT_TX)
{
can_dev->can_cfg->CANx->IE |= CAN_IE_TXBR_Msk;
}
else if (argval == RT_DEVICE_CAN_INT_ERR)
{
can_dev->can_cfg->CANx->IE |= (CAN_IE_ARBLOST_Msk | CAN_IE_BUSERR_Msk | CAN_IE_ERRWARN_Msk | CAN_IE_ERRPASS_Msk);
}
break;
case RT_CAN_CMD_SET_FILTER:
{
rt_uint32_t filter_idx = 0;
if (RT_NULL == arg)
{
/* default filter config */
}
else
{
filter_cfg = (struct rt_can_filter_config *)arg;
/* get default filter */
for (int i = 0; i < filter_cfg->count; i++)
{
if (filter_cfg->items[i].hdr == -1)
{
filter_idx = i;
}
else
{
filter_idx = filter_cfg->items[i].hdr;
}
if (filter_cfg->items[i].ide == RT_CAN_STDID)
{
can_dev->can_cfg->CANx->AFM &= ~(1 << filter_idx);
can_dev->can_cfg->CANx->ACR[filter_idx] = __REV(filter_cfg->items[i].id << 5);
can_dev->can_cfg->CANx->AMR[filter_idx] = __REV(~(filter_cfg->items[i].mask << 5));
can_dev->can_cfg->CANx->AFE |= (1 << filter_idx);
}
else if (filter_cfg->items[i].ide == RT_CAN_EXTID)
{
can_dev->can_cfg->CANx->AFM |= (1 << filter_idx);
can_dev->can_cfg->CANx->ACR[filter_idx] = __REV(filter_cfg->items[i].id << 3);
can_dev->can_cfg->CANx->AMR[filter_idx] = __REV(~(filter_cfg->items[i].mask << 3));
can_dev->can_cfg->CANx->AFE |= (1 << filter_idx);
}
}
}
break;
}
case RT_CAN_CMD_SET_MODE:
argval = (rt_uint32_t)arg;
if (argval != RT_CAN_MODE_NORMAL &&
argval != RT_CAN_MODE_LISEN &&
argval != RT_CAN_MODE_LOOPBACK &&
argval != RT_CAN_MODE_LOOPBACKANLISEN)
{
return -RT_ERROR;
}
if (argval != can_dev->can_device.config.mode)
{
can_dev->can_device.config.mode = argval;
return swm_can_config(&can_dev->can_device, &can_dev->can_device.config);
}
break;
case RT_CAN_CMD_SET_BAUD:
argval = (rt_uint32_t)arg;
if (argval != CAN1MBaud &&
argval != CAN800kBaud &&
argval != CAN500kBaud &&
argval != CAN250kBaud &&
argval != CAN125kBaud &&
argval != CAN100kBaud &&
argval != CAN50kBaud &&
argval != CAN20kBaud &&
argval != CAN10kBaud)
{
return -RT_ERROR;
}
if (argval != can_dev->can_device.config.baud_rate)
{
can_dev->can_device.config.baud_rate = argval;
return swm_can_config(&can_dev->can_device, &can_dev->can_device.config);
}
break;
case RT_CAN_CMD_SET_PRIV:
argval = (rt_uint32_t)arg;
if (argval != RT_CAN_MODE_PRIV &&
argval != RT_CAN_MODE_NOPRIV)
{
return -RT_ERROR;
}
if (argval != can_dev->can_device.config.privmode)
{
can_dev->can_device.config.privmode = argval;
return swm_can_config(&can_dev->can_device, &can_dev->can_device.config);
}
break;
case RT_CAN_CMD_GET_STATUS:
{
can_dev->can_device.status.rcverrcnt = can_dev->can_cfg->CANx->RXERR;
can_dev->can_device.status.snderrcnt = can_dev->can_cfg->CANx->TXERR;
can_dev->can_device.status.lasterrtype = (can_dev->can_cfg->CANx->ECC >> 6) & 0x03;
can_dev->can_device.status.errcode = can_dev->can_cfg->CANx->ECC & 0x1F;
rt_memcpy(arg, &can_dev->can_device.status, sizeof(can_dev->can_device.status));
}
break;
}
return RT_EOK;
}
static int swm_can_sendmsg(struct rt_can_device *can_device, const void *buf, rt_uint32_t box_num)
{
uint32_t i;
struct swm_can_device *can_dev;
RT_ASSERT(can_device != RT_NULL);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
if (RT_CAN_STDID == pmsg->ide)
{
can_dev->can_cfg->CANx->FRAME.DATA[0] = pmsg->id >> 3;
can_dev->can_cfg->CANx->FRAME.DATA[1] = pmsg->id << 5;
if (RT_CAN_DTR == pmsg->rtr)
{
can_dev->can_cfg->CANx->FRAME.INFO = (0 << CAN_INFO_FF_Pos) |
(0 << CAN_INFO_RTR_Pos) |
(pmsg->len << CAN_INFO_DLC_Pos);
for(i = 0; i < pmsg->len; i++)
{
can_dev->can_cfg->CANx->FRAME.DATA[i+2] = pmsg->data[i];
}
if(can_dev->can_cfg->CANx->CR & CAN_CR_STM_Msk)
{
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_SRR_Pos);
}
else
{
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
}
else
{
can_dev->can_cfg->CANx->FRAME.INFO = (0 << CAN_INFO_FF_Pos) |
(1 << CAN_INFO_RTR_Pos) |
(0 << CAN_INFO_DLC_Pos);
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
}
else
{
can_dev->can_cfg->CANx->FRAME.DATA[0] = pmsg->id >> 21;
can_dev->can_cfg->CANx->FRAME.DATA[1] = pmsg->id >> 13;
can_dev->can_cfg->CANx->FRAME.DATA[2] = pmsg->id >> 5;
can_dev->can_cfg->CANx->FRAME.DATA[3] = pmsg->id << 3;
if (RT_CAN_DTR == pmsg->rtr)
{
can_dev->can_cfg->CANx->FRAME.INFO = (1 << CAN_INFO_FF_Pos) |
(0 << CAN_INFO_RTR_Pos) |
(pmsg->len << CAN_INFO_DLC_Pos);
for(i = 0; i < pmsg->len; i++)
{
can_dev->can_cfg->CANx->FRAME.DATA[i+4] = pmsg->data[i];
}
if(can_dev->can_cfg->CANx->CR & CAN_CR_STM_Msk)
{
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_SRR_Pos);
}
else
{
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
}
else
{
can_dev->can_cfg->CANx->FRAME.INFO = (1 << CAN_INFO_FF_Pos) |
(1 << CAN_INFO_RTR_Pos) |
(0 << CAN_INFO_DLC_Pos);
can_dev->can_cfg->CANx->CMD = (1 << CAN_CMD_TXREQ_Pos);
}
}
return RT_EOK;
}
static int swm_can_recvmsg(struct rt_can_device *can_device, void *buf, rt_uint32_t fifo)
{
uint32_t i;
struct swm_can_device *can_dev;
RT_ASSERT(can_device != RT_NULL);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
CAN_RXMessage CAN_RXMsg;
/* get data */
CAN_Receive(can_dev->can_cfg->CANx, &CAN_RXMsg);
/* get id */
if (CAN_RXMsg.format == CAN_FRAME_STD)
{
pmsg->ide = RT_CAN_STDID;
}
else
{
pmsg->ide = RT_CAN_EXTID;
}
pmsg->id = CAN_RXMsg.id;
/* get type */
if (CAN_RXMsg.remote == 0)
{
pmsg->rtr = RT_CAN_DTR;
}
else
{
pmsg->rtr = RT_CAN_RTR;
}
/* get len */
pmsg->len = CAN_RXMsg.size;
for(i = 0; i < pmsg->len; i++)
{
pmsg->data[i] = CAN_RXMsg.data[i];
}
return RT_EOK;
}
static const struct rt_can_ops swm_can_ops =
{
.configure = swm_can_config,
.control = swm_can_control,
.sendmsg = swm_can_sendmsg,
.recvmsg = swm_can_recvmsg,
};
static void swm_can_isr(struct rt_can_device *can_device)
{
struct swm_can_device *can_dev;
RT_ASSERT(can_device != RT_NULL);
can_dev = (struct swm_can_device *)can_device->parent.user_data;
uint32_t int_sr = CAN_INTStat(can_dev->can_cfg->CANx);
if(int_sr & CAN_IF_RXDA_Msk)
{
rt_hw_can_isr(can_device, RT_CAN_EVENT_RX_IND);
}
else if (int_sr & CAN_IF_RXOV_Msk)
{
rt_hw_can_isr(can_device, RT_CAN_EVENT_RXOF_IND);
}
else if (int_sr & CAN_IF_TXBR_Msk)
{
rt_hw_can_isr(can_device, RT_CAN_EVENT_TX_DONE);
}
else if (int_sr & CAN_IE_ERRWARN_Msk)
{
}
else if (int_sr & CAN_IE_ERRPASS_Msk)
{
}
else if (int_sr & CAN_IE_ARBLOST_Msk)
{
}
else if (int_sr & CAN_IE_BUSERR_Msk)
{
}
}
#ifdef BSP_USING_CAN0
/**
* @brief This function handles CAN0 interrupts.
*/
void CAN0_Handler(void)
{
rt_interrupt_enter();
swm_can_isr(&(can_obj[CAN0_INDEX].can_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_CAN0 */
#ifdef BSP_USING_CAN1
/**
* @brief This function handles CAN1 interrupts.
*/
void CAN1_Handler(void)
{
rt_interrupt_enter();
swm_can_isr(&(can_obj[CAN0_INDEX].can_device));
rt_interrupt_leave();
}
#endif /* BSP_USING_CAN1 */
int swm_can_init(void)
{
int i = 0;
int result = RT_EOK;
struct can_configure config = CANDEFAULTCONFIG;
config.privmode = RT_CAN_MODE_NOPRIV;
config.ticks = 50;
#ifdef RT_CAN_USING_HDR
config.maxhdr = 16;
#endif
#ifdef BSP_USING_CAN0
PORT_Init(PORTB, PIN5, PORTB_PIN5_CAN0_RX, 1);
PORT_Init(PORTB, PIN4, PORTB_PIN4_CAN0_TX, 0);
SYS->CLKEN0 |= (0x01 << SYS_CLKEN0_CAN0_Pos);
NVIC_EnableIRQ(CAN0_IRQn);
#endif
#ifdef BSP_USING_CAN1
PORT_Init(PORTB, PIN3, PORTB_PIN3_CAN1_RX, 1);
PORT_Init(PORTB, PIN2, PORTB_PIN2_CAN1_TX, 0);
SYS->CLKEN1 |= (0x01 << SYS_CLKEN1_CAN1_Pos);
NVIC_EnableIRQ(CAN1_IRQn);
#endif
for (i = 0; i < sizeof(swm_can_cfg) / sizeof(swm_can_cfg[0]); i++)
{
can_obj[i].can_device.config = config;
can_obj[i].can_cfg = &swm_can_cfg[i];
result = rt_hw_can_register(&can_obj[i].can_device,
can_obj[i].can_cfg->name,
&swm_can_ops,
&can_obj[i]);
if (result != RT_EOK)
{
LOG_E("%s register fail.", can_obj[i].can_cfg->name);
}
else
{
LOG_D("%s register success.", can_obj[i].can_cfg->name);
}
}
return result;
return 0;
}
INIT_BOARD_EXPORT(swm_can_init);
#endif /* BSP_USING_CAN */
#endif /* RT_USING_CAN */
/*
* 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__ */
/*
* 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 */
/*
* 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__ */
/*
* 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 */
/*
* 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__ */
/*
* 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_gpio.h"
#ifdef RT_USING_PIN
#ifdef BSP_USING_GPIO
//#define DRV_DEBUG
#define LOG_TAG "drv.gpio"
#include <drv_log.h>
#define __SWM_PIN(index, gpio, pin_index) \
{ \
index, GPIO##gpio, PIN##pin_index, GPIO##gpio##_IRQn \
}
struct swm_pin_device
{
uint32_t index;
GPIO_TypeDef *gpio;
uint32_t pin;
IRQn_Type irq;
};
static const struct swm_pin_device pin_obj[] =
{
__SWM_PIN(0, A, 0),
__SWM_PIN(1, A, 1),
__SWM_PIN(2, A, 2),
__SWM_PIN(3, A, 3),
__SWM_PIN(4, A, 4),
__SWM_PIN(5, A, 5),
__SWM_PIN(6, A, 6),
__SWM_PIN(7, A, 7),
__SWM_PIN(8, A, 8),
__SWM_PIN(9, A, 9),
__SWM_PIN(10, A, 10),
__SWM_PIN(11, A, 11),
__SWM_PIN(12, A, 12),
__SWM_PIN(13, A, 13),
__SWM_PIN(14, A, 14),
__SWM_PIN(15, A, 15),
__SWM_PIN(16, B, 0),
__SWM_PIN(17, B, 1),
__SWM_PIN(18, B, 2),
__SWM_PIN(19, B, 3),
__SWM_PIN(20, B, 4),
__SWM_PIN(21, B, 5),
__SWM_PIN(22, B, 6),
__SWM_PIN(23, B, 7),
__SWM_PIN(24, B, 8),
__SWM_PIN(25, B, 9),
__SWM_PIN(26, B, 10),
__SWM_PIN(27, B, 11),
__SWM_PIN(28, B, 12),
__SWM_PIN(29, B, 13),
__SWM_PIN(30, B, 14),
__SWM_PIN(31, B, 15),
__SWM_PIN(32, C, 0),
__SWM_PIN(33, C, 1),
__SWM_PIN(34, C, 2),
__SWM_PIN(35, C, 3),
__SWM_PIN(36, C, 4),
__SWM_PIN(37, C, 5),
__SWM_PIN(38, C, 6),
__SWM_PIN(39, C, 7),
__SWM_PIN(40, C, 8),
__SWM_PIN(41, C, 9),
__SWM_PIN(42, C, 10),
__SWM_PIN(43, C, 11),
__SWM_PIN(44, C, 12),
__SWM_PIN(45, C, 13),
__SWM_PIN(46, C, 14),
__SWM_PIN(47, C, 15),
__SWM_PIN(48, D, 0),
__SWM_PIN(49, D, 1),
__SWM_PIN(50, D, 2),
__SWM_PIN(51, D, 3),
__SWM_PIN(52, D, 4),
__SWM_PIN(53, D, 5),
__SWM_PIN(54, D, 6),
__SWM_PIN(55, D, 7),
__SWM_PIN(56, D, 8),
__SWM_PIN(57, D, 9),
__SWM_PIN(58, D, 10),
__SWM_PIN(59, D, 11),
__SWM_PIN(60, D, 12),
__SWM_PIN(61, D, 13),
__SWM_PIN(62, D, 14),
__SWM_PIN(63, D, 15),
__SWM_PIN(64, E, 0),
__SWM_PIN(65, E, 1),
__SWM_PIN(66, E, 2),
__SWM_PIN(67, E, 3),
__SWM_PIN(68, E, 4),
__SWM_PIN(69, E, 5),
__SWM_PIN(70, E, 6),
__SWM_PIN(71, E, 7),
__SWM_PIN(72, E, 8),
__SWM_PIN(73, E, 9),
__SWM_PIN(74, E, 10),
__SWM_PIN(75, E, 11),
__SWM_PIN(76, E, 12),
__SWM_PIN(77, E, 13),
__SWM_PIN(78, E, 14),
__SWM_PIN(79, E, 15),
__SWM_PIN(80, M, 0),
__SWM_PIN(81, M, 1),
__SWM_PIN(82, M, 2),
__SWM_PIN(83, M, 3),
__SWM_PIN(84, M, 4),
__SWM_PIN(85, M, 5),
__SWM_PIN(86, M, 6),
__SWM_PIN(87, M, 7),
__SWM_PIN(88, M, 8),
__SWM_PIN(89, M, 9),
__SWM_PIN(90, M, 10),
__SWM_PIN(91, M, 11),
__SWM_PIN(92, M, 12),
__SWM_PIN(93, M, 13),
__SWM_PIN(94, M, 14),
__SWM_PIN(95, M, 15),
__SWM_PIN(96, N, 0),
__SWM_PIN(97, N, 1),
__SWM_PIN(98, N, 2),
__SWM_PIN(99, N, 3),
__SWM_PIN(100, N, 4),
__SWM_PIN(101, N, 5),
__SWM_PIN(102, N, 6),
__SWM_PIN(103, N, 7),
__SWM_PIN(104, N, 8),
__SWM_PIN(105, N, 9),
__SWM_PIN(106, N, 10),
__SWM_PIN(107, N, 11),
__SWM_PIN(108, N, 12),
__SWM_PIN(109, N, 13),
__SWM_PIN(110, N, 14),
__SWM_PIN(111, N, 15)};
static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
{
{0, 0, RT_NULL, RT_NULL},
{1, 0, RT_NULL, RT_NULL},
{2, 0, RT_NULL, RT_NULL},
{3, 0, RT_NULL, RT_NULL},
{4, 0, RT_NULL, RT_NULL},
{5, 0, RT_NULL, RT_NULL},
{6, 0, RT_NULL, RT_NULL},
{7, 0, RT_NULL, RT_NULL},
{8, 0, RT_NULL, RT_NULL},
{9, 0, RT_NULL, RT_NULL},
{10, 0, RT_NULL, RT_NULL},
{11, 0, RT_NULL, RT_NULL},
{12, 0, RT_NULL, RT_NULL},
{13, 0, RT_NULL, RT_NULL},
{14, 0, RT_NULL, RT_NULL},
{15, 0, RT_NULL, RT_NULL},
{16, 0, RT_NULL, RT_NULL},
{17, 0, RT_NULL, RT_NULL},
{18, 0, RT_NULL, RT_NULL},
{19, 0, RT_NULL, RT_NULL},
{20, 0, RT_NULL, RT_NULL},
{21, 0, RT_NULL, RT_NULL},
{22, 0, RT_NULL, RT_NULL},
{23, 0, RT_NULL, RT_NULL},
{24, 0, RT_NULL, RT_NULL},
{25, 0, RT_NULL, RT_NULL},
{26, 0, RT_NULL, RT_NULL},
{27, 0, RT_NULL, RT_NULL},
{28, 0, RT_NULL, RT_NULL},
{29, 0, RT_NULL, RT_NULL},
{30, 0, RT_NULL, RT_NULL},
{31, 0, RT_NULL, RT_NULL},
{32, 0, RT_NULL, RT_NULL},
{33, 0, RT_NULL, RT_NULL},
{34, 0, RT_NULL, RT_NULL},
{35, 0, RT_NULL, RT_NULL},
{36, 0, RT_NULL, RT_NULL},
{37, 0, RT_NULL, RT_NULL},
{38, 0, RT_NULL, RT_NULL},
{39, 0, RT_NULL, RT_NULL},
{40, 0, RT_NULL, RT_NULL},
{41, 0, RT_NULL, RT_NULL},
{42, 0, RT_NULL, RT_NULL},
{43, 0, RT_NULL, RT_NULL},
{44, 0, RT_NULL, RT_NULL},
{45, 0, RT_NULL, RT_NULL},
{46, 0, RT_NULL, RT_NULL},
{47, 0, RT_NULL, RT_NULL},
{48, 0, RT_NULL, RT_NULL},
{49, 0, RT_NULL, RT_NULL},
{50, 0, RT_NULL, RT_NULL},
{51, 0, RT_NULL, RT_NULL},
{52, 0, RT_NULL, RT_NULL},
{53, 0, RT_NULL, RT_NULL},
{54, 0, RT_NULL, RT_NULL},
{55, 0, RT_NULL, RT_NULL},
{56, 0, RT_NULL, RT_NULL},
{57, 0, RT_NULL, RT_NULL},
{58, 0, RT_NULL, RT_NULL},
{59, 0, RT_NULL, RT_NULL},
{60, 0, RT_NULL, RT_NULL},
{61, 0, RT_NULL, RT_NULL},
{62, 0, RT_NULL, RT_NULL},
{63, 0, RT_NULL, RT_NULL},
{64, 0, RT_NULL, RT_NULL},
{65, 0, RT_NULL, RT_NULL},
{66, 0, RT_NULL, RT_NULL},
{67, 0, RT_NULL, RT_NULL},
{68, 0, RT_NULL, RT_NULL},
{69, 0, RT_NULL, RT_NULL},
{70, 0, RT_NULL, RT_NULL},
{71, 0, RT_NULL, RT_NULL},
{72, 0, RT_NULL, RT_NULL},
{73, 0, RT_NULL, RT_NULL},
{74, 0, RT_NULL, RT_NULL},
{75, 0, RT_NULL, RT_NULL},
{76, 0, RT_NULL, RT_NULL},
{77, 0, RT_NULL, RT_NULL},
{78, 0, RT_NULL, RT_NULL},
{79, 0, RT_NULL, RT_NULL},
{80, 0, RT_NULL, RT_NULL},
{81, 0, RT_NULL, RT_NULL},
{82, 0, RT_NULL, RT_NULL},
{83, 0, RT_NULL, RT_NULL},
{84, 0, RT_NULL, RT_NULL},
{85, 0, RT_NULL, RT_NULL},
{86, 0, RT_NULL, RT_NULL},
{87, 0, RT_NULL, RT_NULL},
{88, 0, RT_NULL, RT_NULL},
{89, 0, RT_NULL, RT_NULL},
{90, 0, RT_NULL, RT_NULL},
{91, 0, RT_NULL, RT_NULL},
{92, 0, RT_NULL, RT_NULL},
{93, 0, RT_NULL, RT_NULL},
{94, 0, RT_NULL, RT_NULL},
{95, 0, RT_NULL, RT_NULL},
{96, 0, RT_NULL, RT_NULL},
{97, 0, RT_NULL, RT_NULL},
{98, 0, RT_NULL, RT_NULL},
{99, 0, RT_NULL, RT_NULL},
{100, 0, RT_NULL, RT_NULL},
{101, 0, RT_NULL, RT_NULL},
{102, 0, RT_NULL, RT_NULL},
{103, 0, RT_NULL, RT_NULL},
{104, 0, RT_NULL, RT_NULL},
{105, 0, RT_NULL, RT_NULL},
{106, 0, RT_NULL, RT_NULL},
{107, 0, RT_NULL, RT_NULL},
{108, 0, RT_NULL, RT_NULL},
{109, 0, RT_NULL, RT_NULL},
{110, 0, RT_NULL, RT_NULL},
{111, 0, RT_NULL, RT_NULL}};
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
static const struct swm_pin_device *_pin2struct(uint8_t pin)
{
const struct swm_pin_device *gpio_obj;
if (pin < ITEM_NUM(pin_obj))
{
gpio_obj = &pin_obj[pin];
}
else
{
gpio_obj = RT_NULL;
}
return gpio_obj;
}
static void swm_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
const struct swm_pin_device *gpio_obj;
int dir = 0;
int pull_up = 0;
int pull_down = 0;
int open_drain = 0;
gpio_obj = _pin2struct(pin);
if (gpio_obj == RT_NULL)
{
return;
}
/* Configure GPIO_InitStructure */
switch (mode)
{
case PIN_MODE_OUTPUT:
/* output setting */
dir = 1;
break;
case PIN_MODE_INPUT:
/* input setting: not pull. */
dir = 0;
break;
case PIN_MODE_INPUT_PULLUP:
/* input setting: pull up. */
dir = 0;
pull_up = 1;
break;
case PIN_MODE_INPUT_PULLDOWN:
/* input setting: pull down. */
dir = 0;
pull_down = 1;
break;
case PIN_MODE_OUTPUT_OD:
/* output setting: od. */
dir = 1;
open_drain = 1;
break;
}
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, dir, pull_up, pull_down, open_drain);
}
static void swm_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
const struct swm_pin_device *gpio_obj;
gpio_obj = _pin2struct(pin);
if (gpio_obj == RT_NULL)
{
return;
}
if (value)
{
GPIO_AtomicSetBit(gpio_obj->gpio, gpio_obj->pin);
}
else
{
GPIO_AtomicClrBit(gpio_obj->gpio, gpio_obj->pin);
}
}
static int swm_pin_read(rt_device_t dev, rt_base_t pin)
{
const struct swm_pin_device *gpio_obj;
gpio_obj = _pin2struct(pin);
if (gpio_obj == RT_NULL)
{
return PIN_LOW;
}
return (int)GPIO_GetBit(gpio_obj->gpio, gpio_obj->pin);
}
static rt_err_t swm_pin_attach_irq(struct rt_device *device,
rt_int32_t pin,
rt_uint32_t mode,
void (*hdr)(void *args),
void *args)
{
rt_base_t level;
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[pin].pin == pin &&
pin_irq_hdr_tab[pin].mode == mode &&
pin_irq_hdr_tab[pin].hdr == hdr &&
pin_irq_hdr_tab[pin].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
pin_irq_hdr_tab[pin].pin = pin;
pin_irq_hdr_tab[pin].mode = mode;
pin_irq_hdr_tab[pin].hdr = hdr;
pin_irq_hdr_tab[pin].args = args;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t swm_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_base_t level;
level = rt_hw_interrupt_disable();
pin_irq_hdr_tab[pin].mode = 0;
pin_irq_hdr_tab[pin].hdr = RT_NULL;
pin_irq_hdr_tab[pin].args = RT_NULL;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t swm_pin_irq_enable(struct rt_device *device,
rt_base_t pin,
rt_uint32_t enabled)
{
const struct swm_pin_device *gpio_obj;
rt_base_t level = 0;
gpio_obj = _pin2struct(pin);
if (gpio_obj == RT_NULL)
{
return RT_ENOSYS;
}
if (enabled == PIN_IRQ_ENABLE)
{
switch (pin_irq_hdr_tab[pin].mode)
{
case PIN_IRQ_MODE_RISING:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 0, 1, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_RISE_EDGE);
break;
case PIN_IRQ_MODE_FALLING:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 1, 0, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_FALL_EDGE);
break;
case PIN_IRQ_MODE_RISING_FALLING:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 1, 1, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_BOTH_EDGE);
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 0, 1, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_HIGH_LEVEL);
break;
case PIN_IRQ_MODE_LOW_LEVEL:
GPIO_Init(gpio_obj->gpio, gpio_obj->pin, 0, 1, 0, 0);
EXTI_Init(gpio_obj->gpio, gpio_obj->pin, EXTI_LOW_LEVEL);
break;
default:
return RT_EINVAL;
}
level = rt_hw_interrupt_disable();
NVIC_EnableIRQ(gpio_obj->irq);
EXTI_Open(gpio_obj->gpio, gpio_obj->pin);
rt_hw_interrupt_enable(level);
}
else if (enabled == PIN_IRQ_DISABLE)
{
level = rt_hw_interrupt_disable();
// NVIC_DisableIRQ(gpio_obj->irq);
EXTI_Close(gpio_obj->gpio, gpio_obj->pin);
rt_hw_interrupt_enable(level);
}
else
{
return -RT_ENOSYS;
}
return RT_EOK;
}
static rt_base_t swm_pin_get(const char *name)
{
rt_base_t pin = 0;
int pin_num = 0;
int i, name_len;
name_len = rt_strlen(name);
if ((name_len < 4) || (name_len >= 6))
{
return -RT_EINVAL;
}
if ((name[0] != 'P') || (name[2] != '.'))
{
return -RT_EINVAL;
}
switch(name[1])
{
case 'A':
pin = 0;
break;
case 'B':
pin = 16;
break;
case 'C':
pin = 32;
break;
case 'D':
pin = 48;
break;
case 'E':
pin = 64;
break;
case 'M':
pin = 80;
break;
case 'N':
pin = 96;
break;
default:
return -RT_EINVAL;
}
for (i = 3; i < name_len; i++)
{
pin_num *= 10;
pin_num += name[i] - '0';
}
if(pin_num < 16)
{
pin += pin_num;
}
else
{
return -RT_EINVAL;
}
return pin;
}
const static struct rt_pin_ops swm_pin_ops =
{
.pin_mode = swm_pin_mode,
.pin_write = swm_pin_write,
.pin_read = swm_pin_read,
.pin_attach_irq = swm_pin_attach_irq,
.pin_detach_irq = swm_pin_detach_irq,
.pin_irq_enable = swm_pin_irq_enable,
.pin_get = swm_pin_get};
static void swm_pin_isr(GPIO_TypeDef *GPIOx)
{
static int gpio[16];
int index = 0;
static int init = 0;
const struct swm_pin_device *gpio_obj;
if (init == 0)
{
init = 1;
for (gpio_obj = &pin_obj[0];
gpio_obj->index < ITEM_NUM(pin_obj);
gpio_obj++)
{
if (gpio_obj->gpio == GPIOx)
{
gpio[index] = gpio_obj->index;
index++;
RT_ASSERT(index <= 16)
}
}
}
for (index = 0; index < 16; index++)
{
gpio_obj = _pin2struct(gpio[index]);
if (EXTI_State(gpio_obj->gpio, gpio_obj->pin))
{
EXTI_Clear(gpio_obj->gpio, gpio_obj->pin);
if (pin_irq_hdr_tab[gpio_obj->index].hdr)
{
pin_irq_hdr_tab[gpio_obj->index].hdr(pin_irq_hdr_tab[gpio_obj->index].args);
}
}
}
}
void GPIOA_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOA);
rt_interrupt_leave();
}
void GPIOB_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOB);
rt_interrupt_leave();
}
void GPIOC_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOC);
rt_interrupt_leave();
}
void GPIOD_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOD);
rt_interrupt_leave();
}
void GPIOE_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOE);
rt_interrupt_leave();
}
void GPIOM_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPIOM);
rt_interrupt_leave();
}
void GPION_Handler(void)
{
rt_interrupt_enter();
swm_pin_isr(GPION);
rt_interrupt_leave();
}
int swm_pin_init(void)
{
return rt_device_pin_register("pin", &swm_pin_ops, RT_NULL);
}
#endif /* BSP_USING_GPIO */
#endif /* RT_USING_PIN */
/*
* 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__ */
此差异已折叠。
/*
* 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__ */
/*
* 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>
此差异已折叠。
/*
* 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__ */
此差异已折叠。
/*
* 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__ */
此差异已折叠。
/*
* 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__ */
此差异已折叠。
/*
* 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__ */
/*
* 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 */
/*
* 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__ */
此差异已折叠。
/*
* 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__ */
此差异已折叠。
/*
* 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__ */
此差异已折叠。
/*
* 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__ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册