optimize xidatong-riscv64 third_party_driver and connection_framework form Liu_weichao

it is OK
This commit is contained in:
xuedongliang 2022-08-29 11:57:43 +08:00
commit f376e568fd
43 changed files with 62 additions and 3934 deletions

View File

@ -3,13 +3,19 @@ config ADAPTER_4G_EC200T
default "ec200t"
if ADD_XIZI_FETURES
config ADAPTER_EC200T_PWRKEY
int "EC200T PWRKEY pin number"
default "97"
config ADAPTER_EC200T_USING_PWRKEY
bool "EC200T using PWRKEY pin number"
default n
config ADAPTER_EC200T_PIN_DRIVER
string "EC200T device pin driver path"
default "/dev/pin_dev"
if ADAPTER_EC200T_USING_PWRKEY
config ADAPTER_EC200T_PWRKEY
int "EC200T PWRKEY pin number"
default "97"
config ADAPTER_EC200T_PIN_DRIVER
string "EC200T device pin driver path"
default "/dev/pin_dev"
endif
config ADAPTER_EC200T_DRIVER_EXTUART
bool "Using extra uart to support 4G"
@ -35,7 +41,6 @@ if ADD_NUTTX_FETURES
config ADAPTER_EC200T_DRIVER
string "EC200T device uart driver path"
default "/dev/ttyS8"
endif
if ADD_RTTHREAD_FETURES

View File

@ -38,14 +38,9 @@
#define TRY_TIMES 10
#ifdef ADD_NUTTX_FETURES
static void Ec200tPowerSet(void){ return; }
#else
#ifdef ADD_RTTHREAD_FETURES
static void Ec200tPowerSet(void){ return; }
#else
static void Ec200tPowerSet(void)
{
static void Ec200tPowerSet(void)
{
#ifdef ADAPTER_EC200T_USING_PWRKEY
int pin_fd;
pin_fd = PrivOpen(ADAPTER_EC200T_PIN_DRIVER, O_RDWR);
if (pin_fd < 0) {
@ -76,9 +71,8 @@ static void Ec200tPowerSet(void){ return; }
PrivClose(pin_fd);
PrivTaskDelay(10000);
}
#endif
#endif
}
static int Ec200tOpen(struct Adapter *adapter)
{
@ -148,7 +142,6 @@ out:
return ret;
}
#ifdef ADD_NUTTX_FETURES
static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args){ return 0;}
#else
@ -174,6 +167,7 @@ static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args)
serial_cfg.serial_bit_order = STOP_BITS_1;
serial_cfg.serial_invert_mode = NRZ_NORMAL;
#ifdef ADAPTER_EC200T_DRIVER_EXT_PORT
serial_cfg.is_ext_uart = 1;
serial_cfg.ext_uart_no = ADAPTER_EC200T_DRIVER_EXT_PORT;
serial_cfg.port_configure = PORT_CFG_INIT;
#endif
@ -183,7 +177,6 @@ static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args)
ioctl_cfg.args = &serial_cfg;
PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg);
Ec200tPowerSet();
return 0;

View File

@ -21,32 +21,32 @@
#include <adapter.h>
#include <at_agent.h>
#define HC08_DETECT_CMD "AT"
#define HC08_DEFAULT_CMD "AT+DEFAULT"
#define HC08_RESET_CMD "AT+RESET"
#define HC08_CLEAR_CMD "AT+CLEAR"
#define HC08_DETECT_CMD "AT"
#define HC08_DEFAULT_CMD "AT+DEFAULT"
#define HC08_RESET_CMD "AT+RESET"
#define HC08_CLEAR_CMD "AT+CLEAR"
#define HC08_GET_DEVICE_INFO "AT+RX"
#define HC08_GET_BAUDRATE_CMD "AT+BAUD=?"
#define HC08_SET_BAUDRATE_CMD "AT+BAUD=%u"
#define HC08_GET_BAUDRATE_CMD "AT+BAUD=?"
#define HC08_SET_BAUDRATE_CMD "AT+BAUD=%u"
#define HC08_GET_CONNECTABLE "AT+CONT=?"
#define HC08_SET_CONNECTABLE "AT+CONT=%s"
#define HC08_GET_ROLE_CMD "AT+ROLE=?"
#define HC08_SET_ROLE_CMD "AT+ROLE=%s"
#define HC08_GET_ADDR_CMD "AT+ADDR=?"
#define HC08_SET_ADDR_CMD "AT+ADDR=%s"
#define HC08_GET_NAME_CMD "AT+NAME=%s"
#define HC08_SET_NAME_CMD "AT+NAME=?"
#define HC08_GET_LUUID_CMD "AT+LUUID=?"
#define HC08_SET_LUUID_CMD "AT+LUUID=%u"
#define HC08_GET_SUUID_CMD "AT+SUUID=?"
#define HC08_SET_SUUID_CMD "AT+SUUID=%u"
#define HC08_GET_TUUID_CMD "AT+TUUID=?"
#define HC08_SET_TUUID_CMD "AT+TUUID=%u"
#define HC08_GET_ROLE_CMD "AT+ROLE=?"
#define HC08_SET_ROLE_CMD "AT+ROLE=%s"
#define HC08_GET_ADDR_CMD "AT+ADDR=?"
#define HC08_SET_ADDR_CMD "AT+ADDR=%s"
#define HC08_GET_NAME_CMD "AT+NAME=%s"
#define HC08_SET_NAME_CMD "AT+NAME=?"
#define HC08_GET_LUUID_CMD "AT+LUUID=?"
#define HC08_SET_LUUID_CMD "AT+LUUID=%u"
#define HC08_GET_SUUID_CMD "AT+SUUID=?"
#define HC08_SET_SUUID_CMD "AT+SUUID=%u"
#define HC08_GET_TUUID_CMD "AT+TUUID=?"
#define HC08_SET_TUUID_CMD "AT+TUUID=%u"
#define HC08_OK_RESP "OK"
#define HC08_OK_RESP "OK"
#define HC08_CMD_STR_DEFAULT_SIZE 64
#define HC08_CMD_STR_DEFAULT_SIZE 64
#define HC08_RESP_DEFAULT_SIZE 64
enum Hc08AtCmd
@ -239,6 +239,7 @@ static int Hc08Open(struct Adapter *adapter)
serial_cfg.serial_bit_order = STOP_BITS_1;
serial_cfg.serial_invert_mode = NRZ_NORMAL;
#ifdef ADAPTER_HC08_DRIVER_EXT_PORT
serial_cfg.is_ext_uart = 1;
serial_cfg.ext_uart_no = ADAPTER_HC08_DRIVER_EXT_PORT;
serial_cfg.port_configure = PORT_CFG_INIT;
#endif
@ -330,6 +331,7 @@ static int Hc08Ioctl(struct Adapter *adapter, int cmd, void *args)
serial_cfg.serial_bit_order = STOP_BITS_1;
serial_cfg.serial_invert_mode = NRZ_NORMAL;
#ifdef ADAPTER_HC08_DRIVER_EXT_PORT
serial_cfg.is_ext_uart = 1;
serial_cfg.ext_uart_no = ADAPTER_HC08_DRIVER_EXT_PORT;
serial_cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -402,6 +402,7 @@ static int Hfa21EthernetIoctl(struct Adapter *adapter, int cmd, void *args)
serial_cfg.serial_bit_order = BIT_ORDER_LSB;
serial_cfg.serial_invert_mode = NRZ_NORMAL;
#ifdef ADAPTER_HFA21_DRIVER_EXT_PORT
serial_cfg.is_ext_uart = 1;
serial_cfg.ext_uart_no = ADAPTER_HFA21_DRIVER_EXT_PORT;
serial_cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -359,6 +359,7 @@ static int E220Open(struct Adapter *adapter)
/*aiit board use ch438, so it needs more serial configuration*/
#ifdef ADAPTER_E220_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = ADAPTER_E220_DRIVER_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -59,6 +59,7 @@ static int BC28UartOpen(struct Adapter *adapter)
/*aiit board use ch438, so it needs more serial configuration*/
#ifdef ADAPTER_BC28_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = ADAPTER_BC28_DRIVER_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -82,6 +82,7 @@ static int Esp07sUartOpen(struct Adapter *adapter)
cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
#ifdef ADAPTER_ESP07S_DRIVER_EXT_PORT
cfg.is_ext_uart = 1;
cfg.ext_uart_no = ADAPTER_ESP07S_DRIVER_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif
@ -512,6 +513,7 @@ static int Esp07sWifiIoctl(struct Adapter *adapter, int cmd, void *args)
cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
#ifdef ADAPTER_ESP07S_DRIVER_EXT_PORT
cfg.is_ext_uart = 1;
cfg.ext_uart_no = ADAPTER_ESP07S_DRIVER_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -474,6 +474,7 @@ static int Hfa21WifiIoctl(struct Adapter *adapter, int cmd, void *args)
serial_cfg.serial_bit_order = BIT_ORDER_LSB;
serial_cfg.serial_invert_mode = NRZ_NORMAL;
#ifdef ADAPTER_HFA21_DRIVER_EXT_PORT
serial_cfg.is_ext_uart = 1;
serial_cfg.ext_uart_no = ADAPTER_HFA21_DRIVER_EXT_PORT;
serial_cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -108,6 +108,7 @@ static int E18UartOpen(struct Adapter *adapter)
/*aiit board use ch438, so it needs more serial configuration*/
#ifdef ADAPTER_E18_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = ADAPTER_E18_DRIVER_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -65,6 +65,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_AS830_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_AS830_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -70,6 +70,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_G8S_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_G8S_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -76,6 +76,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_ZG09_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_ZG09_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -66,6 +66,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_TB600B_WQ_HCHO1OS_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_TB600B_WQ_HCHO1OS_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -73,6 +73,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_TB600B_IAQ10_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_TB600B_IAQ10_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -98,6 +98,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_PS5308_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_PS5308_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -66,6 +66,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_TB600B_TVOC10_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_TB600B_TVOC10_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -102,6 +102,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_D124_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_D124_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -66,6 +66,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_QS_FX_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_QS_FX_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -64,7 +64,8 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_parity_mode = PARITY_NONE;
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
#ifdef SENSOR_QS_FS_DRIVER_EXTUART
#ifdef SENSOR_QS_FS_DRIVER_EXTUART
cfg.is_ext_uart = 1;
cfg.ext_uart_no = SENSOR_DEVICE_QS_FS_DEV_EXT_PORT;
cfg.port_configure = PORT_CFG_INIT;
#endif

View File

@ -142,7 +142,8 @@ struct SerialDataCfg
uint8_t serial_invert_mode;
uint16_t serial_buffer_size;
uint8 ext_uart_no;
uint8_t is_ext_uart;
uint8_t ext_uart_no;
enum ExtSerialPortConfigure port_configure;
};

View File

@ -145,6 +145,7 @@ struct SerialDataCfg
uint8_t serial_invert_mode;
uint16_t serial_buffer_size;
uint8_t is_ext_uart;
uint8_t ext_uart_no;
enum ExtSerialPortConfigure port_configure;
};

View File

@ -133,6 +133,7 @@ struct SerialDataCfg
uint16_t serial_buffer_size;
int32 serial_timeout;
uint8_t is_ext_uart;
uint8_t ext_uart_no;
enum ExtSerialPortConfigure port_configure;
};

View File

@ -1,13 +1,5 @@
SRC_FILES := sleep.c
ifeq ($(CONFIG_BSP_USING_AUDIO),y)
SRC_DIR += audio
endif
ifeq ($(CONFIG_BSP_USING_CAMERA),y)
SRC_DIR += camera
endif
ifeq ($(CONFIG_BSP_USING_CH376),y)
SRC_DIR += ch376
endif
@ -32,14 +24,6 @@ ifeq ($(CONFIG_BSP_USING_I2C),y)
SRC_DIR += i2c
endif
ifeq ($(CONFIG_BSP_USING_I2S),y)
SRC_DIR += i2s
endif
ifeq ($(CONFIG_BSP_USING_KPU),y)
SRC_DIR += kpu
endif
ifeq ($(CONFIG_BSP_USING_LCD),y)
SRC_DIR += lcd
endif
@ -48,18 +32,10 @@ ifeq ($(CONFIG_BSP_USING_PLIC),y)
SRC_DIR += plic
endif
ifeq ($(CONFIG_BSP_USING_PWM),y)
SRC_DIR += pwm
endif
ifeq ($(CONFIG_BSP_USING_RTC),y)
SRC_DIR += rtc
endif
ifeq ($(CONFIG_BSP_USING_SECURITY),y)
SRC_DIR += security
endif
ifeq ($(CONFIG_BSP_USING_SPI),y)
SRC_DIR += spi
endif
@ -80,10 +56,6 @@ ifeq ($(CONFIG_BSP_USING_UART),y)
SRC_DIR += uart
endif
ifeq ($(CONFIG_BSP_USING_VIDEO),y)
SRC_DIR += video
endif
ifeq ($(CONFIG_BSP_USING_WDT),y)
SRC_DIR += watchdog
endif

View File

@ -1,13 +1,5 @@
SRC_FILES := sleep.c
ifeq ($(CONFIG_BSP_USING_AUDIO),y)
SRC_DIR += audio
endif
ifeq ($(CONFIG_BSP_USING_CAMERA),y)
SRC_DIR += camera
endif
ifeq ($(CONFIG_BSP_USING_DMA),y)
SRC_DIR += dma
endif
@ -20,10 +12,6 @@ ifeq ($(CONFIG_BSP_USING_I2C),y)
SRC_DIR += i2c
endif
ifeq ($(CONFIG_BSP_USING_I2S),y)
SRC_DIR += i2s
endif
ifeq ($(CONFIG_BSP_USING_PLIC),y)
SRC_DIR += plic
endif
@ -32,10 +20,6 @@ ifeq ($(CONFIG_BSP_USING_RTC),y)
SRC_DIR += rtc
endif
ifeq ($(CONFIG_BSP_USING_SECURITY),y)
SRC_DIR += security
endif
ifeq ($(CONFIG_BSP_USING_SPI),y)
SRC_DIR += spi
endif

View File

@ -55,13 +55,9 @@ extern x_base cpu2_boot_flag;
extern void entry(void);
extern void SecondaryCpuCStart(void);
extern int IoConfigInit(void);
extern int HwSpiInit(void);
extern int HwI2cInit(void);
extern int HwRtcInit(void);
extern int HwWdtInit(void);
extern int HwLcdInit(void);
extern int HwTouchInit(void);
extern int HwTimerInit(void);
#if defined(FS_VFS) && defined (MOUNT_SDCARD)
#include <iot-vfs.h>
@ -162,24 +158,12 @@ struct InitSequenceDesc _board_init[] =
{ "hw_pin", HwGpioInit },
{ "io_config", IoConfigInit },
#endif
#ifdef BSP_USING_SPI
{ "hw_spi", HwSpiInit },
#endif
#ifdef BSP_USING_I2C
{ "hw_i2c", HwI2cInit },
#endif
#ifdef BSP_USING_LCD
{ "hw_lcd", HwLcdInit },
#endif
#ifdef BSP_USING_HWTIMER
{ "hw_timer" , HwTimerInit },
#endif
#ifdef BSP_USING_WDT
{ "hw_wdt", HwWdtInit },
#endif
#ifdef BSP_USING_RTC
{"hw_rtc", HwRtcInit },
#endif
#ifdef BSP_USING_TOUCH
{"touch", HwTouchInit },
#endif

View File

@ -32,28 +32,11 @@ endif
menuconfig BSP_USING_PLIC
bool "Using PLIC device"
default y
default n
if BSP_USING_PLIC
source "$BSP_DIR/third_party_driver/plic/Kconfig"
endif
menuconfig BSP_USING_RTC
bool "Using RTC device"
default n
select RESOURCES_RTC
if BSP_USING_RTC
source "$BSP_DIR/third_party_driver/rtc/Kconfig"
endif
menuconfig BSP_USING_SPI
bool "Using SPI device"
default n
select RESOURCES_SPI
select BSP_USING_DMA
if BSP_USING_SPI
source "$BSP_DIR/third_party_driver/spi/Kconfig"
endif
menuconfig BSP_USING_SYSCLOCK
bool "Using SYSCLOCK device"
default y
@ -61,14 +44,6 @@ if BSP_USING_SYSCLOCK
source "$BSP_DIR/third_party_driver/sys_clock/Kconfig"
endif
menuconfig BSP_USING_HWTIMER
bool "Using HWTIMER device"
default n
select RESOURCES_HWTIMER
if BSP_USING_HWTIMER
source "$BSP_DIR/third_party_driver/timer/Kconfig"
endif
menuconfig BSP_USING_UART
bool "Using UART device"
default y
@ -76,11 +51,3 @@ select RESOURCES_SERIAL
if BSP_USING_UART
source "$BSP_DIR/third_party_driver/uart/Kconfig"
endif
menuconfig BSP_USING_WDT
bool "Using WATCHDOG device"
default y
select RESOURCES_WDT
if BSP_USING_WDT
source "$BSP_DIR/third_party_driver/watchdog/Kconfig"
endif

View File

@ -1,13 +1,5 @@
SRC_FILES := sleep.c
ifeq ($(CONFIG_BSP_USING_AUDIO),y)
SRC_DIR += audio
endif
ifeq ($(CONFIG_BSP_USING_CAMERA),y)
SRC_DIR += camera
endif
ifeq ($(CONFIG_BSP_USING_DMA),y)
SRC_DIR += dma
endif
@ -24,44 +16,16 @@ ifeq ($(CONFIG_BSP_USING_TOUCH),y)
SRC_DIR += touch
endif
ifeq ($(CONFIG_BSP_USING_I2S),y)
SRC_DIR += i2s
endif
ifeq ($(CONFIG_BSP_USING_PLIC),y)
SRC_DIR += plic
endif
ifeq ($(CONFIG_BSP_USING_RTC),y)
SRC_DIR += rtc
endif
ifeq ($(CONFIG_BSP_USING_SECURITY),y)
SRC_DIR += security
endif
ifeq ($(CONFIG_BSP_USING_SPI),y)
SRC_DIR += spi
endif
ifeq ($(CONFIG_BSP_USING_SYSCLOCK),y)
SRC_DIR += sys_clock
endif
ifeq ($(CONFIG_BSP_USING_HWTIMER),y)
SRC_DIR += timer
endif
ifeq ($(CONFIG_BSP_USING_UART),y)
SRC_DIR += uart
endif
ifeq ($(CONFIG_BSP_USING_VIDEO),y)
SRC_DIR += video
endif
ifeq ($(CONFIG_BSP_USING_WDT),y)
SRC_DIR += watchdog
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,11 +0,0 @@
if BSP_USING_RTC
config RTC_BUS_NAME
string "rtc bus name"
default "rtc"
config RTC_DRV_NAME
string "rtc bus driver name"
default "rtc_drv"
config RTC_DEVICE_NAME
string "rtc bus device name"
default "rtc_dev"
endif

View File

@ -1,3 +0,0 @@
SRC_FILES := connect_rtc.c hardware_rtc.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,184 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_rtc.c
* @brief support xidatong-riscv64-board rtc function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-07-25
*/
#include <stdint.h>
#include <time.h>
#include <stdlib.h>
#include "sysctl.h"
#include "connect_rtc.h"
#include "hardware_rtc.h"
static int GetWeekDay(int year, int month, int day)
{
/* Magic method to get weekday */
int weekday = (day += month < 3 ? year-- : year - 2,
23 * month / 9 + day + 4 + year / 4 - year / 100 + year / 400) % 7;
return weekday;
}
static uint32 RtcConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
struct RtcDriver *rtc_drv = (struct RtcDriver *)drv;
struct RtcDrvConfigureParam *drv_param = (struct RtcDrvConfigureParam *)configure_info->private_data;
int cmd = drv_param->rtc_operation_cmd;
time_t *time = drv_param->time;
switch (cmd)
{
case OPER_RTC_GET_TIME:
{
struct tm ct;
int year,month,day,hour,minute,second;
memset(&ct,0,sizeof(struct tm));
rtc_timer_get(&year, &month, &day, &hour, &minute, &second);
ct.tm_year = year - 1900;
ct.tm_mon = month - 1;
ct.tm_mday = day;
ct.tm_wday = GetWeekDay(year, month, day);
ct.tm_hour = hour;
ct.tm_min = minute;
ct.tm_sec = second;
*time = mktime(&ct);
}
break;
case OPER_RTC_SET_TIME:
{
struct tm *ct;
struct tm tm_new;
x_base lock;
lock = CriticalAreaLock();
ct = localtime(time);
memcpy(&tm_new, ct, sizeof(struct tm));
CriticalAreaUnLock(lock);
sysctl_reset(SYSCTL_RESET_RTC);
sysctl_clock_enable(SYSCTL_CLOCK_RTC);
rtc_protect_set(0);
rtc_timer_set_clock_frequency(SysctlClockGetFreq(SYSCTL_CLOCK_IN0));
rtc_timer_set_clock_count_value(1);
rtc_timer_set_mode(RTC_TIMER_RUNNING);
if (rtc_timer_set(tm_new.tm_year+1900,tm_new.tm_mon+1,tm_new.tm_mday,
tm_new.tm_hour,tm_new.tm_min,tm_new.tm_sec)==-1)
return ERROR;
}
break;
}
return EOK;
}
/*manage the rtc device operations*/
static const struct RtcDevDone dev_done =
{
.open = NONE,
.close = NONE,
.write = NONE,
.read = NONE,
};
static int BoardRtcBusInit(struct RtcBus *rtc_bus, struct RtcDriver *rtc_driver)
{
x_err_t ret = EOK;
/*Init the rtc bus */
ret = RtcBusInit(rtc_bus, RTC_BUS_NAME);
if (EOK != ret) {
KPrintf("HwRtcInit RtcBusInit error %d\n", ret);
return ERROR;
}
/*Init the rtc driver*/
ret = RtcDriverInit(rtc_driver, RTC_DRV_NAME);
if (EOK != ret) {
KPrintf("HwRtcInit RtcDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the rtc driver to the rtc bus*/
ret = RtcDriverAttachToBus(RTC_DRV_NAME, RTC_BUS_NAME);
if (EOK != ret) {
KPrintf("HwRtcInit RtcDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the rtc device to the rtc bus*/
static int BoardRtcDevBend(void)
{
x_err_t ret = EOK;
static struct RtcHardwareDevice rtc_device;
memset(&rtc_device, 0, sizeof(struct RtcHardwareDevice));
rtc_device.dev_done = &(dev_done);
ret = RtcDeviceRegister(&rtc_device, NONE, RTC_DEVICE_NAME);
if (EOK != ret) {
KPrintf("HwRtcInit RtcDeviceInit device %s error %d\n", RTC_DEVICE_NAME, ret);
return ERROR;
}
ret = RtcDeviceAttachToBus(RTC_DEVICE_NAME, RTC_BUS_NAME);
if (EOK != ret) {
KPrintf("HwRtcInit RtcDeviceAttachToBus device %s error %d\n", RTC_DEVICE_NAME, ret);
return ERROR;
}
return ret;
}
int HwRtcInit(void)
{
x_err_t ret = EOK;
static struct RtcBus rtc_bus;
memset(&rtc_bus, 0, sizeof(struct RtcBus));
static struct RtcDriver rtc_driver;
memset(&rtc_driver, 0, sizeof(struct RtcDriver));
rtc_driver.configure = &(RtcConfigure);
ret = BoardRtcBusInit(&rtc_bus, &rtc_driver);
if (EOK != ret) {
KPrintf("HwRtcInit error ret %u\n", ret);
return ERROR;
}
ret = BoardRtcDevBend();
if (EOK != ret) {
KPrintf("HwRtcInit error ret %u\n", ret);
return ERROR;
}
rtc_init();
return ret;
}

View File

@ -1,597 +0,0 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file hardware_rtc.c
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-07-25
*/
#include <stdint.h>
#include <time.h>
#include <stdlib.h>
#include "encoding.h"
#include "sysctl.h"
#include "hardware_rtc.h"
volatile rtc_t *const rtc = (volatile rtc_t *)RTC_BASE_ADDR;
struct tm rtc_date_time;
void rtc_timer_set_mode(rtc_timer_mode_t timer_mode)
{
rtc_register_ctrl_t register_ctrl = rtc->register_ctrl;
switch (timer_mode)
{
case RTC_TIMER_PAUSE:
register_ctrl.read_enable = 0;
register_ctrl.write_enable = 0;
break;
case RTC_TIMER_RUNNING:
register_ctrl.read_enable = 1;
register_ctrl.write_enable = 0;
break;
case RTC_TIMER_SETTING:
register_ctrl.read_enable = 0;
register_ctrl.write_enable = 1;
break;
default:
register_ctrl.read_enable = 0;
register_ctrl.write_enable = 0;
break;
}
rtc->register_ctrl = register_ctrl;
}
rtc_timer_mode_t rtc_timer_get_mode(void)
{
rtc_register_ctrl_t register_ctrl = rtc->register_ctrl;
rtc_timer_mode_t timer_mode = RTC_TIMER_PAUSE;
if ((!register_ctrl.read_enable) && (!register_ctrl.write_enable))
{
/* RTC_TIMER_PAUSE */
timer_mode = RTC_TIMER_PAUSE;
}
else if ((register_ctrl.read_enable) && (!register_ctrl.write_enable))
{
/* RTC_TIMER_RUNNING */
timer_mode = RTC_TIMER_RUNNING;
}
else if ((!register_ctrl.read_enable) && (register_ctrl.write_enable)) {
/* RTC_TIMER_SETTING */
timer_mode = RTC_TIMER_SETTING;
}
else
{
/* Something is error, reset timer mode */
rtc_timer_set_mode(timer_mode);
}
return timer_mode;
}
static inline int rtc_in_range(int value, int min, int max)
{
return ((value >= min) && (value <= max));
}
int rtc_timer_set_tm(const struct tm *tm)
{
rtc_date_t timer_date;
rtc_time_t timer_time;
rtc_extended_t timer_extended;
if (tm)
{
/*
* Range of tm->tm_sec could be [0,61]
*
* Range of tm->tm_sec allows for a positive leap second. Two
* leap seconds in the same minute are not allowed (the C90
* range 0..61 was a defect)
*/
if (rtc_in_range(tm->tm_sec, 0, 59))
timer_time.second = tm->tm_sec;
else
return -1;
/* Range of tm->tm_min could be [0,59] */
if (rtc_in_range(tm->tm_min, 0, 59))
timer_time.minute = tm->tm_min;
else
return -1;
/* Range of tm->tm_hour could be [0, 23] */
if (rtc_in_range(tm->tm_hour, 0, 23))
timer_time.hour = tm->tm_hour;
else
return -1;
/* Range of tm->tm_mday could be [1, 31] */
if (rtc_in_range(tm->tm_mday, 1, 31))
timer_date.day = tm->tm_mday;
else
return -1;
/*
* Range of tm->tm_mon could be [0, 11]
* But in this RTC, date.month should be [1, 12]
*/
if (rtc_in_range(tm->tm_mon, 0, 11))
timer_date.month = tm->tm_mon + 1;
else
return -1;
/*
* Range of tm->tm_year is the years since 1900
* But in this RTC, year is split into year and century
* In this RTC, century range is [0,31], year range is [0,99]
*/
int human_year = tm->tm_year + 1900;
int rtc_year = human_year % 100;
int rtc_century = human_year / 100;
if (rtc_in_range(rtc_year, 0, 99) &&
rtc_in_range(rtc_century, 0, 31))
{
timer_date.year = rtc_year;
timer_extended.century = rtc_century;
}
else
return -1;
/* Range of tm->tm_wday could be [0, 6] */
if (rtc_in_range(tm->tm_wday, 0, 6))
timer_date.week = tm->tm_wday;
else
return -1;
/* Set RTC mode to timer setting mode */
rtc_timer_set_mode(RTC_TIMER_SETTING);
/* Write value to RTC */
rtc->date = timer_date;
rtc->time = timer_time;
rtc->extended = timer_extended;
/* Get CPU current freq */
unsigned long freq = SysctlClockGetFreq(SYSCTL_CLOCK_CPU);
/* Set threshold to 1/26000000 s */
freq = freq / 26000000;
/* Get current CPU cycle */
unsigned long start_cycle = read_cycle();
/* Wait for 1/26000000 s to sync data */
while (read_cycle() - start_cycle < freq)
continue;
/* Set RTC mode to timer running mode */
rtc_timer_set_mode(RTC_TIMER_RUNNING);
}
return 0;
}
int rtc_timer_set_alarm_tm(const struct tm *tm)
{
rtc_alarm_date_t alarm_date;
rtc_alarm_time_t alarm_time;
if (tm) {
/*
* Range of tm->tm_sec could be [0,61]
*
* Range of tm->tm_sec allows for a positive leap second. Two
* leap seconds in the same minute are not allowed (the C90
* range 0..61 was a defect)
*/
if (rtc_in_range(tm->tm_sec, 0, 59))
alarm_time.second = tm->tm_sec;
else
return -1;
/* Range of tm->tm_min could be [0,59] */
if (rtc_in_range(tm->tm_min, 0, 59))
alarm_time.minute = tm->tm_min;
else
return -1;
/* Range of tm->tm_hour could be [0, 23] */
if (rtc_in_range(tm->tm_hour, 0, 23))
alarm_time.hour = tm->tm_hour;
else
return -1;
/* Range of tm->tm_mday could be [1, 31] */
if (rtc_in_range(tm->tm_mday, 1, 31))
alarm_date.day = tm->tm_mday;
else
return -1;
/*
* Range of tm->tm_mon could be [0, 11]
* But in this RTC, date.month should be [1, 12]
*/
if (rtc_in_range(tm->tm_mon, 0, 11))
alarm_date.month = tm->tm_mon + 1;
else
return -1;
/*
* Range of tm->tm_year is the years since 1900
* But in this RTC, year is split into year and century
* In this RTC, century range is [0,31], year range is [0,99]
*/
int human_year = tm->tm_year + 1900;
int rtc_year = human_year % 100;
int rtc_century = human_year / 100;
if (rtc_in_range(rtc_year, 0, 99) &&
rtc_in_range(rtc_century, 0, 31))
{
alarm_date.year = rtc_year;
} else
return -1;
/* Range of tm->tm_wday could be [0, 6] */
if (rtc_in_range(tm->tm_wday, 0, 6))
alarm_date.week = tm->tm_wday;
else
return -1;
/* Write value to RTC */
rtc->alarm_date = alarm_date;
rtc->alarm_time = alarm_time;
}
return 0;
}
static int rtc_year_is_leap(int year)
{
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
static int rtc_get_yday(int year, int month, int day)
{
static const int days[2][13] =
{
{0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
{0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
};
int leap = rtc_year_is_leap(year);
return days[leap][month] + day;
}
static int rtc_get_wday(int year, int month, int day)
{
/* Magic method to get weekday */
int weekday = (day += month < 3 ? year-- : year - 2, 23 * month / 9 + day + 4 + year / 4 - year / 100 + year / 400) % 7;
return weekday;
}
struct tm *rtc_timer_get_tm(void)
{
if (rtc_timer_get_mode() != RTC_TIMER_RUNNING)
return NULL;
rtc_date_t timer_date = rtc->date;
rtc_time_t timer_time = rtc->time;
rtc_extended_t timer_extended = rtc->extended;
struct tm *tm = &rtc_date_time;
tm->tm_sec = timer_time.second % 60;
tm->tm_min = timer_time.minute % 60;
tm->tm_hour = timer_time.hour % 24;
tm->tm_mday = (timer_date.day - 1) % 31 + 1;
tm->tm_mon = (timer_date.month - 1)% 12;
tm->tm_year = (timer_date.year % 100) + (timer_extended.century * 100) - 1900;
tm->tm_wday = timer_date.week;
tm->tm_yday = rtc_get_yday(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
tm->tm_isdst = -1;
return tm;
}
struct tm *rtc_timer_get_alarm_tm(void)
{
if (rtc_timer_get_mode() != RTC_TIMER_RUNNING)
return NULL;
rtc_alarm_date_t alarm_date = rtc->alarm_date;
rtc_alarm_time_t alarm_time = rtc->alarm_time;
rtc_extended_t timer_extended = rtc->extended;
struct tm *tm = &rtc_date_time;
tm->tm_sec = alarm_time.second % 60;
tm->tm_min = alarm_time.minute % 60;
tm->tm_hour = alarm_time.hour % 24;
tm->tm_mday = alarm_date.day % 31;
tm->tm_mon = (alarm_date.month % 12) - 1;
/* Alarm and Timer use same timer_extended.century */
tm->tm_year = (alarm_date.year % 100) + (timer_extended.century * 100) - 1900;
tm->tm_wday = alarm_date.week;
tm->tm_yday = rtc_get_yday(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
tm->tm_isdst = -1;
return tm;
}
int rtc_timer_set(int year, int month, int day, int hour, int minute, int second)
{
struct tm date_time =
{
.tm_sec = second,
.tm_min = minute,
.tm_hour = hour,
.tm_mday = day,
.tm_mon = month - 1,
.tm_year = year - 1900,
.tm_wday = rtc_get_wday(year, month, day),
.tm_yday = rtc_get_yday(year, month, day),
.tm_isdst = -1,
};
return rtc_timer_set_tm(&date_time);
}
int rtc_timer_get(int *year, int *month, int *day, int *hour, int *minute, int *second)
{
struct tm *tm = rtc_timer_get_tm();
if (tm)
{
if (year)
*year = tm->tm_year + 1900;
if (month)
*month = tm->tm_mon + 1;
if (day)
*day = tm->tm_mday;
if (hour)
*hour = tm->tm_hour;
if (minute)
*minute = tm->tm_min;
if (second)
*second = tm->tm_sec;
} else
return -1;
return 0;
}
int rtc_timer_set_alarm(int year, int month, int day, int hour, int minute, int second)
{
struct tm date_time = {
.tm_sec = second,
.tm_min = minute,
.tm_hour = hour,
.tm_mday = day,
.tm_mon = month - 1,
.tm_year = year - 1900,
.tm_wday = rtc_get_wday(year, month, day),
.tm_yday = rtc_get_yday(year, month, day),
.tm_isdst = -1,
};
return rtc_timer_set_alarm_tm(&date_time);
}
int rtc_timer_get_alarm(int *year, int *month, int *day, int *hour, int *minute, int *second)
{
struct tm *tm = rtc_timer_get_alarm_tm();
if (tm) {
if (year)
*year = tm->tm_year + 1900;
if (month)
*month = tm->tm_mon + 1;
if (day)
*day = tm->tm_mday;
if (hour)
*hour = tm->tm_hour;
if (minute)
*minute = tm->tm_min;
if (second)
*second = tm->tm_sec;
} else
return -1;
return 0;
}
int rtc_timer_set_clock_frequency(unsigned int frequency)
{
rtc_initial_count_t initial_count;
initial_count.count = frequency;
rtc_timer_set_mode(RTC_TIMER_SETTING);
rtc->initial_count = initial_count;
rtc_timer_set_mode(RTC_TIMER_RUNNING);
return 0;
}
unsigned int rtc_timer_get_clock_frequency(void)
{
return rtc->initial_count.count;
}
int rtc_timer_set_clock_count_value(unsigned int count)
{
rtc_current_count_t current_count;
current_count.count = count;
rtc_timer_set_mode(RTC_TIMER_SETTING);
rtc->current_count = current_count;
rtc_timer_set_mode(RTC_TIMER_RUNNING);
return 0;
}
unsigned int rtc_timer_get_clock_count_value(void)
{
return rtc->current_count.count;
}
int rtc_tick_interrupt_set(int enable)
{
rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl;
interrupt_ctrl.tick_enable = enable;
rtc_timer_set_mode(RTC_TIMER_SETTING);
rtc->interrupt_ctrl = interrupt_ctrl;
rtc_timer_set_mode(RTC_TIMER_RUNNING);
return 0;
}
int rtc_tick_interrupt_get(void)
{
rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl;
return interrupt_ctrl.tick_enable;
}
int rtc_tick_interrupt_mode_set(rtc_tick_interrupt_mode_t mode)
{
rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl;
interrupt_ctrl.tick_int_mode = mode;
rtc_timer_set_mode(RTC_TIMER_SETTING);
rtc->interrupt_ctrl = interrupt_ctrl;
rtc_timer_set_mode(RTC_TIMER_RUNNING);
return 0;
}
rtc_tick_interrupt_mode_t rtc_tick_interrupt_mode_get(void)
{
rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl;
return interrupt_ctrl.tick_int_mode;
}
int rtc_alarm_interrupt_set(int enable)
{
rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl;
interrupt_ctrl.alarm_enable = enable;
rtc->interrupt_ctrl = interrupt_ctrl;
return 0;
}
int rtc_alarm_interrupt_get(void)
{
rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl;
return interrupt_ctrl.alarm_enable;
}
int rtc_alarm_interrupt_mask_set(rtc_mask_t mask)
{
rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl;
interrupt_ctrl.alarm_compare_mask = *(uint8_t *)&mask;
rtc->interrupt_ctrl = interrupt_ctrl;
return 0;
}
rtc_mask_t rtc_alarm_interrupt_mask_get(void)
{
rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl;
uint8_t compare_mask = interrupt_ctrl.alarm_compare_mask;
return *(rtc_mask_t *)&compare_mask;
}
int rtc_protect_set(int enable)
{
rtc_register_ctrl_t register_ctrl = rtc->register_ctrl;
rtc_mask_t mask =
{
.second = 1,
/* Second mask */
.minute = 1,
/* Minute mask */
.hour = 1,
/* Hour mask */
.week = 1,
/* Week mask */
.day = 1,
/* Day mask */
.month = 1,
/* Month mask */
.year = 1,
};
rtc_mask_t unmask =
{
.second = 0,
/* Second mask */
.minute = 0,
/* Minute mask */
.hour = 0,
/* Hour mask */
.week = 0,
/* Week mask */
.day = 0,
/* Day mask */
.month = 0,
/* Month mask */
.year = 0,
};
if (enable)
{
/* Turn RTC in protect mode, no one can write time */
register_ctrl.TimerMask = *(uint8_t *)&unmask;
register_ctrl.alarm_mask = *(uint8_t *)&unmask;
register_ctrl.initial_count_mask = 0;
register_ctrl.interrupt_register_mask = 0;
}
else
{
/* Turn RTC in unprotect mode, everyone can write time */
register_ctrl.TimerMask = *(uint8_t *)&mask;
register_ctrl.alarm_mask = *(uint8_t *)&mask;
register_ctrl.initial_count_mask = 1;
register_ctrl.interrupt_register_mask = 1;
}
rtc_timer_set_mode(RTC_TIMER_SETTING);
rtc->register_ctrl = register_ctrl;
rtc_timer_set_mode(RTC_TIMER_RUNNING);
return 0;
}
int rtc_init(void)
{
/* Reset RTC */
sysctl_reset(SYSCTL_RESET_RTC);
/* Enable RTC */
sysctl_clock_enable(SYSCTL_CLOCK_RTC);
/* Unprotect RTC */
rtc_protect_set(0);
/* Set RTC clock frequency */
rtc_timer_set_clock_frequency(
SysctlClockGetFreq(SYSCTL_CLOCK_IN0)
);
rtc_timer_set_clock_count_value(1);
/* Set RTC mode to timer running mode */
rtc_timer_set_mode(RTC_TIMER_RUNNING);
return 0;
}

View File

@ -1,34 +0,0 @@
config BSP_USING_SPI1
bool "Using spi1 "
default y
if BSP_USING_SPI1
config SPI_BUS_NAME_1
string "spi bus 1 name"
default "spi1"
config SPI_1_DRV_NAME
string "spi bus 1 driver name"
default "spi1_drv"
config BSP_SPI1_CLK_PIN
int "spi1 clk pin number"
default 9
config BSP_SPI1_D0_PIN
int "spi1 MOSI d0 pin number"
default 11
config BSP_SPI1_D1_PIN
int "spi1 MISO d1 pin number"
default 10
menuconfig BSP_SPI1_USING_SS0
bool "SPI1 Enable SS0"
default y
if BSP_SPI1_USING_SS0
config SPI_1_DEVICE_NAME_0
string "spi bus 1 device 0 name"
default "spi1_dev0"
config BSP_SPI1_SS0_PIN
int "spi1 ss0 pin number"
default 12
endif
endif

View File

@ -1,6 +0,0 @@
SRC_FILES := connect_spi.c hardware_spi.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,474 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-18 ZYH first version
*/
/**
* @file connect_spi.c
* @brief support xidatong-riscv64-board spi function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-07-25
*/
/*************************************************
File name: connect_spi.c
Description: support xidatong-riscv64-board spi configure and spi bus register function
Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_spi.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2022-07-25
Author: AIIT XUOS Lab
Modification:
1. support xidatong-riscv64-board spi configure, write and read
2. support xidatong-riscv64-board spi bus device and driver register
*************************************************/
#include <dmac.h>
#include <sysctl.h>
#include <gpiohs.h>
#include <string.h>
#include "connect_spi.h"
#include "hardware_spi.h"
#include <drv_io_config.h>
#include "utils.h"
#ifdef BSP_SPI1_USING_SS0
#define SPI_DEVICE_SLAVE_ID_0 0
#endif
#ifdef BSP_SPI1_USING_SS1
#define SPI_DEVICE_SLAVE_ID_1 1
#endif
#ifdef BSP_SPI1_USING_SS2
#define SPI_DEVICE_SLAVE_ID_2 2
#endif
#ifdef BSP_SPI1_USING_SS3
#define SPI_DEVICE_SLAVE_ID_3 3
#endif
static volatile spi_t *const spi_instance[4] =
{
(volatile spi_t *)SPI0_BASE_ADDR,
(volatile spi_t *)SPI1_BASE_ADDR,
(volatile spi_t *)SPI_SLAVE_BASE_ADDR,
(volatile spi_t *)SPI3_BASE_ADDR
};
void __spi_set_tmod(uint8_t spi_num, uint32_t tmod)
{
CHECK(spi_num < SPI_DEVICE_MAX);
volatile spi_t *spi_handle = spi[spi_num];
uint8_t tmod_offset = 0;
switch (spi_num)
{
case 0:
case 1:
case 2:
tmod_offset = 8;
break;
case 3:
default:
tmod_offset = 10;
break;
}
set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset);
}
/*Init the spi sdk intetface */
static uint32 SpiSdkInit(struct SpiDriver *spi_drv)
{
NULL_PARAM_CHECK(spi_drv);
uint8 cs_gpio_pin, cs_select_id;
uint32 max_frequency;
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data);
cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
cs_select_id = dev_param->spi_slave_param->spi_cs_select_id;
gpiohs_set_drive_mode(cs_select_id, GPIO_DM_OUTPUT);//Set the cs pin as output
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH);//set the cs gpio high
spi_init(dev_param->spi_dma_param->spi_master_id,
dev_param->spi_master_param->spi_work_mode & SPI_MODE_3,
dev_param->spi_master_param->spi_frame_format,
dev_param->spi_master_param->spi_data_bit_width,
dev_param->spi_master_param->spi_data_endian);
max_frequency = (dev_param->spi_master_param->spi_maxfrequency < SPI_MAX_CLOCK) ? dev_param->spi_master_param->spi_maxfrequency : SPI_MAX_CLOCK;
uint32 real_freq = spi_set_clk_rate(dev_param->spi_dma_param->spi_master_id, max_frequency);
return EOK;
}
static uint32 SpiSdkCfg(struct SpiDriver *spi_drv, struct SpiMasterParam *spi_param)
{
NULL_PARAM_CHECK(spi_drv);
NULL_PARAM_CHECK(spi_param);
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data);
dev_param->spi_master_param = spi_param;
dev_param->spi_master_param->spi_work_mode = dev_param->spi_master_param->spi_work_mode & SPI_MODE_MASK;
dev_param->spi_master_param->spi_frame_format = SPI_FF_STANDARD;
return EOK;
}
/*Configure the spi device param, make sure struct (configure_info->private_data) = (SpiMasterParam)*/
static uint32 SpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
struct SpiDriver *spi_drv = (struct SpiDriver *)drv;
struct SpiMasterParam *spi_param;
switch (configure_info->configure_cmd)
{
case OPE_INT:
ret = SpiSdkInit(spi_drv);
break;
case OPE_CFG:
spi_param = (struct SpiMasterParam *)configure_info->private_data;
ret = SpiSdkCfg(spi_drv, spi_param);
break;
default:
break;
}
return ret;
}
static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
{
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
uint8 device_id = dev_param->spi_slave_param->spi_slave_id;
uint8 device_master_id = dev_param->spi_dma_param->spi_master_id;
uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
while (NONE != spi_datacfg) {
uint32_t * tx_buff = NONE;
int i;
x_ubase dummy = 0xFFFFFFFFU;
__spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV);
if (spi_datacfg->spi_chip_select) {
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW);
}
if (spi_datacfg->length) {
spi_instance[device_master_id]->dmacr = 0x3;
spi_instance[device_master_id]->ssienr = 0x01;
sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2);
sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id* 2);
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
if (!spi_datacfg->tx_buff) {
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
} else {
tx_buff = x_malloc(spi_datacfg->length * 4);
if (!tx_buff) {
goto transfer_done;
}
for (i = 0; i < spi_datacfg->length; i++) {
tx_buff[i] = ((uint8_t *)spi_datacfg->tx_buff)[i];
}
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, tx_buff, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
}
spi_instance[device_master_id]->ser = 1U << dev_param->spi_slave_param->spi_cs_select_id;
dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel);
dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel);
spi_instance[device_master_id]->ser = 0x00;
spi_instance[device_master_id]->ssienr = 0x00;
transfer_done:
if (tx_buff) {
x_free(tx_buff);
}
}
if (spi_datacfg->spi_cs_release) {
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH);
}
spi_datacfg = spi_datacfg->next;
}
return EOK;
}
static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
{
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
uint32 spi_read_length = 0;
uint8 device_id = dev_param->spi_slave_param->spi_slave_id;
uint8 device_master_id = dev_param->spi_dma_param->spi_master_id;
uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
while (NONE != spi_datacfg) {
uint32_t * rx_buff = NONE;
int i;
x_ubase dummy = 0xFFFFFFFFU;
__spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV);
if (spi_datacfg->spi_chip_select) {
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW);
}
if (spi_datacfg->length) {
spi_instance[device_master_id]->dmacr = 0x3;
spi_instance[device_master_id]->ssienr = 0x01;
sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2);
sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id* 2);
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
if (!spi_datacfg->rx_buff) {
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
} else {
rx_buff = x_calloc(spi_datacfg->length * 4, 1);
if (!rx_buff) {
goto transfer_done;
}
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
}
spi_instance[device_master_id]->ser = 1U << dev_param->spi_slave_param->spi_cs_select_id;
dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel);
dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel);
spi_instance[device_master_id]->ser = 0x00;
spi_instance[device_master_id]->ssienr = 0x00;
if (spi_datacfg->rx_buff) {
for (i = 0; i < spi_datacfg->length; i++) {
((uint8_t *)spi_datacfg->rx_buff)[i] = (uint8_t)rx_buff[i];
}
}
transfer_done:
if (rx_buff) {
x_free(rx_buff);
}
}
if (spi_datacfg->spi_cs_release) {
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH);
}
spi_read_length += spi_datacfg->length;
spi_datacfg = spi_datacfg->next;
}
return spi_read_length;
}
/*manage the spi device operations*/
static const struct SpiDevDone spi_dev_done =
{
.dev_open = NONE,
.dev_close = NONE,
.dev_write = SpiWriteData,
.dev_read = SpiReadData,
};
static int BoardSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver)
{
x_err_t ret = EOK;
/*Init the spi bus */
ret = SpiBusInit(spi_bus, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiBusInit error %d\n", ret);
return ERROR;
}
/*Init the spi driver*/
ret = SpiDriverInit(spi_driver, SPI_1_DRV_NAME);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the spi driver to the spi bus*/
ret = SpiDriverAttachToBus(SPI_1_DRV_NAME, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the spi device to the spi bus*/
static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam)
{
x_err_t ret = EOK;
#ifdef BSP_SPI1_USING_SS0
static struct SpiHardwareDevice spi_device0;
memset(&spi_device0, 0, sizeof(struct SpiHardwareDevice));
static struct SpiSlaveParam spi_slaveparam0;
memset(&spi_slaveparam0, 0, sizeof(struct SpiSlaveParam));
spi_slaveparam0.spi_slave_id = SPI_DEVICE_SLAVE_ID_0;
spi_slaveparam0.spi_cs_gpio_pin = SPI1_CS0_PIN;
spi_slaveparam0.spi_cs_select_id = SPI_CHIP_SELECT_0;
spi_device0.spi_param.spi_dma_param = spi_initparam;
spi_device0.spi_param.spi_slave_param = &spi_slaveparam0;
spi_device0.spi_dev_done = &(spi_dev_done);
ret = SpiDeviceRegister(&spi_device0, (void *)(&spi_device0.spi_param), SPI_1_DEVICE_NAME_0);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_0, ret);
return ERROR;
}
ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_0, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_0, ret);
return ERROR;
}
#endif
#ifdef BSP_SPI1_USING_SS1
static struct SpiHardwareDevice spi_device1;
memset(&spi_device1, 0, sizeof(struct SpiHardwareDevice));
static struct SpiSlaveParam spi_slaveparam1;
memset(&spi_slaveparam1, 0, sizeof(struct SpiSlaveParam));
spi_slaveparam1.spi_slave_id = SPI_DEVICE_SLAVE_ID_1;
spi_slaveparam1.spi_cs_gpio_pin = SPI1_CS1_PIN;
spi_slaveparam1.spi_cs_select_id = SPI_CHIP_SELECT_1;
spi_device1.spi_param.spi_dma_param = spi_initparam;
spi_device1.spi_param.spi_slave_param = &spi_slaveparam1;
spi_device1.spi_dev_done = &(spi_dev_done);
ret = SpiDeviceRegister(&spi_device1, (void *)(&spi_device1.spi_param), SPI_1_DEVICE_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_1, ret);
return ERROR;
}
ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_1, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_1, ret);
return ERROR;
}
#endif
#ifdef BSP_SPI1_USING_SS2
static struct SpiHardwareDevice spi_device2;
memset(&spi_device2, 0, sizeof(struct SpiHardwareDevice));
spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_2] = SPI_DEVICE_SLAVE_ID_2;
spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_2] = SPI1_CS2_PIN;
spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_2] = SPI_CHIP_SELECT_2;
spi_device2.spi_dev_done = &(spi_dev_done);
ret = SpiDeviceRegister(&spi_device2, (void *)(&spi_device2.spi_param), SPI_1_DEVICE_NAME_2);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_2, ret);
return ERROR;
}
ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_2, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_2, ret);
return ERROR;
}
#endif
#ifdef BSP_SPI1_USING_SS3
static struct SpiHardwareDevice spi_device3;
memset(&spi_device3, 0, sizeof(struct SpiHardwareDevice));
spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_3] = SPI_DEVICE_SLAVE_ID_3;
spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_3] = SPI1_CS3_PIN;
spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_3] = SPI_CHIP_SELECT_3;
spi_device3.spi_dev_done = &(spi_dev_done);
ret = SpiDeviceRegister(&spi_device3, (void *)(&spi_device3.spi_param), SPI_1_DEVICE_NAME_3);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_3, ret);
return ERROR;
}
ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_3, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_3, ret);
return ERROR;
}
#endif
return ret;
}
/*RISC-V 64 BOARD SPI INIT*/
int HwSpiInit(void)
{
x_err_t ret = EOK;
static struct SpiDmaParam spi_initparam;
memset(&spi_initparam, 0, sizeof(struct SpiDmaParam));
#ifdef BSP_USING_SPI1
static struct SpiBus spi_bus;
memset(&spi_bus, 0, sizeof(struct SpiBus));
static struct SpiDriver spi_driver;
memset(&spi_driver, 0, sizeof(struct SpiDriver));
spi_initparam.spi_master_id = SPI_DEVICE_1;
spi_initparam.spi_dmac_txchannel = DMAC_CHANNEL1;
spi_initparam.spi_dmac_rxchannel = DMAC_CHANNEL2;
spi_driver.configure = &(SpiDrvConfigure);
ret = BoardSpiBusInit(&spi_bus, &spi_driver);
if (EOK != ret) {
KPrintf("Board_Spi_Init error ret %u\n", ret);
return ERROR;
}
ret = BoardSpiDevBend(&spi_initparam);
if (EOK != ret) {
KPrintf("Board_Spi_Init error ret %u\n", ret);
return ERROR;
}
#endif
return ret;
}

View File

@ -1,19 +0,0 @@
if BSP_USING_HWTIMER
config HWTIMER_BUS_NAME_1
string "hwtimer bus name"
default "hwtim1"
menuconfig ENABLE_TIM1
bool "enable TIM1"
default y
if ENABLE_TIM1
config HWTIMER_1_DEVICE_NAME_1
string "TIM1 dev name"
default "hwtim1_dev1"
config HWTIMER_DRIVER_NAME_1
string "TIM1 drv name"
default "hwtim1_drv"
endif
endif

View File

@ -1,3 +0,0 @@
SRC_FILES := hardware_hwtimer.c connect_hwtimer.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,155 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_hwtimer.c
* @brief support xidatong-riscv64-board hwtimer function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-07-25
*/
#include <board.h>
#include <xizi.h>
#include <stdio.h>
#include <syslog.h>
#include <plic.h>
#include <sysctl.h>
#include <fpioa.h>
#include "connect_hwtimer.h"
static struct HwtimerCallBackInfo *ptim2_cb_info = NULL;
int timer_callback(void *ctx)
{
if (ptim2_cb_info) {
if (ptim2_cb_info->timeout_callback) {
ptim2_cb_info->timeout_callback(ptim2_cb_info->param);
}
}
return 0;
}
uint32 HwtimerOpen(void *dev)
{
struct HwtimerHardwareDevice *hwtimer_dev = dev;
ptim2_cb_info = &hwtimer_dev->hwtimer_param.cb_info;
plic_init();
sysctl_enable_irq();
timer_init(TIMER_DEVICE_1);
size_t real_time = timer_set_interval(TIMER_DEVICE_1, TIMER_CHANNEL_1, hwtimer_dev->hwtimer_param.period_millisecond *1000);
KPrintf("timer_set_interval -- real_time : %ld\n", real_time);
timer_irq_register(TIMER_DEVICE_1, TIMER_CHANNEL_1, !hwtimer_dev->hwtimer_param.repeat, 1, timer_callback, NULL);
timer_set_enable(TIMER_DEVICE_1, TIMER_CHANNEL_1, 1);
return EOK;
}
uint32 HwtimerClose(void *dev)
{
timer_set_enable(TIMER_DEVICE_1, TIMER_CHANNEL_1, 0);
return EOK;
}
/*manage the hwtimer device operations*/
static const struct HwtimerDevDone dev_done =
{
.open = HwtimerOpen,
.close = HwtimerClose,
.write = NONE,
.read = NONE,
};
/*Init hwtimer bus*/
static int BoardHwtimerBusInit(struct HwtimerBus *hwtimer_bus, struct HwtimerDriver *hwtimer_driver)
{
x_err_t ret = EOK;
/*Init the hwtimer bus */
ret = HwtimerBusInit(hwtimer_bus, HWTIMER_BUS_NAME_1);
if (EOK != ret) {
KPrintf("board_hwtimer_init HwtimerBusInit error %d\n", ret);
return ERROR;
}
/*Init the hwtimer driver*/
hwtimer_driver->configure = NONE;
ret = HwtimerDriverInit(hwtimer_driver, HWTIMER_DRIVER_NAME_1);
if (EOK != ret) {
KPrintf("board_hwtimer_init HwtimerDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the hwtimer driver to the hwtimer bus*/
ret = HwtimerDriverAttachToBus(HWTIMER_DRIVER_NAME_1, HWTIMER_BUS_NAME_1);
if (EOK != ret) {
KPrintf("board_hwtimer_init USEDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the hwtimer device to the hwtimer bus*/
static int BoardHwtimerDevBend(void)
{
x_err_t ret = EOK;
static struct HwtimerHardwareDevice hwtimer_device_0;
memset(&hwtimer_device_0, 0, sizeof(struct HwtimerHardwareDevice));
hwtimer_device_0.dev_done = &dev_done;
ret = HwtimerDeviceRegister(&hwtimer_device_0, NONE, HWTIMER_1_DEVICE_NAME_1);
if (EOK != ret) {
KPrintf("board_hwtimer_init HWTIMERDeviceInit device %s error %d\n", HWTIMER_1_DEVICE_NAME_1, ret);
return ERROR;
}
ret = HwtimerDeviceAttachToBus(HWTIMER_1_DEVICE_NAME_1, HWTIMER_BUS_NAME_1);
if (EOK != ret) {
KPrintf("board_hwtimer_init HwtimerDeviceAttachToBus device %s error %d\n", HWTIMER_1_DEVICE_NAME_1, ret);
return ERROR;
}
return ret;
}
/*K210 BOARD HWTIMER INIT*/
int HwTimerInit(void)
{
x_err_t ret = EOK;
static struct HwtimerBus hwtimer_bus;
memset(&hwtimer_bus, 0, sizeof(struct HwtimerBus));
static struct HwtimerDriver hwtimer_driver;
memset(&hwtimer_driver, 0, sizeof(struct HwtimerDriver));
ret = BoardHwtimerBusInit(&hwtimer_bus, &hwtimer_driver);
if (EOK != ret) {
KPrintf("board_hwtimer_Init error ret %u\n", ret);
return ERROR;
}
ret = BoardHwtimerDevBend();
if (EOK != ret) {
KPrintf("board_hwtimer_Init error ret %u\n", ret);
return ERROR;
}
return ret;
}

View File

@ -1,406 +0,0 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file hardware_hwtimer.c
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-07-25
*/
#include <syslog.h>
#include "hardware_hwtimer.h"
#include "sysctl.h"
#include "stddef.h"
#include "utils.h"
#include "plic.h"
#include "io.h"
#include "xs_isr.h"
/**
* @brief Private definitions for the timer instance
*/
typedef struct timer_instance
{
timer_callback_t callback;
void *ctx;
bool single_shot;
} timer_instance_t;
typedef void(*irq_manager_callback_t)(int irq, void* arg);
volatile timer_instance_t timer_instance[TIMER_DEVICE_MAX][TIMER_CHANNEL_MAX];
volatile kendryte_timer_t *const timer[3] =
{
(volatile kendryte_timer_t *)TIMER0_BASE_ADDR,
(volatile kendryte_timer_t *)TIMER1_BASE_ADDR,
(volatile kendryte_timer_t *)TIMER2_BASE_ADDR
};
void timer_init(timer_device_number_t timer_number)
{
for(size_t i = 0; i < TIMER_CHANNEL_MAX; i++)
timer_instance[timer_number][i] = (const timer_instance_t) {
.callback = NULL,
.ctx = NULL,
.single_shot = 0,
};
sysctl_clock_enable(SYSCTL_CLOCK_TIMER0 + timer_number);
}
void timer_set_clock_div(timer_device_number_t timer_number, uint32_t div)
{
sysctl_clock_set_threshold(timer_number == 0 ? SYSCTL_THRESHOLD_TIMER0 :
timer_number == 1 ? SYSCTL_THRESHOLD_TIMER1 :
SYSCTL_THRESHOLD_TIMER2, div);
}
void timer_enable(timer_device_number_t timer_number, timer_channel_number_t channel)
{
timer[timer_number]->channel[channel].control |= TIMER_CR_ENABLE;
}
void timer_disable(timer_device_number_t timer_number, timer_channel_number_t channel)
{
timer[timer_number]->channel[channel].control &= (~TIMER_CR_ENABLE);
}
void timer_enable_pwm(timer_device_number_t timer_number, timer_channel_number_t channel)
{
timer[timer_number]->channel[channel].control |= TIMER_CR_PWM_ENABLE;
}
void timer_disable_pwm(timer_device_number_t timer_number, timer_channel_number_t channel)
{
timer[timer_number]->channel[channel].control &= (~TIMER_CR_PWM_ENABLE);
}
void timer_enable_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel)
{
timer[timer_number]->channel[channel].control &= (~TIMER_CR_INTERRUPT_MASK);
}
void timer_disable_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel)
{
timer[timer_number]->channel[channel].control |= TIMER_CR_INTERRUPT_MASK;
}
void timer_set_mode(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t mode)
{
timer[timer_number]->channel[channel].control &= (~TIMER_CR_MODE_MASK);
timer[timer_number]->channel[channel].control |= mode;
}
void timer_set_reload(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t count)
{
timer[timer_number]->channel[channel].load_count = count;
}
void timer_set_reload2(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t count)
{
timer[timer_number]->load_count2[channel] = count;
}
uint32_t timer_get_count(timer_device_number_t timer_number, timer_channel_number_t channel)
{
return timer[timer_number]->channel[channel].current_value;
}
uint32_t timer_get_reload(timer_device_number_t timer_number, timer_channel_number_t channel)
{
return timer[timer_number]->channel[channel].load_count;
}
uint32_t timer_get_reload2(timer_device_number_t timer_number, timer_channel_number_t channel)
{
return timer[timer_number]->load_count2[channel];
}
uint32_t timer_get_interrupt_status(timer_device_number_t timer_number)
{
return timer[timer_number]->intr_stat;
}
uint32_t timer_get_raw_interrupt_status(timer_device_number_t timer_number)
{
return timer[timer_number]->raw_intr_stat;
}
uint32_t timer_channel_get_interrupt_status(timer_device_number_t timer_number, timer_channel_number_t channel)
{
return timer[timer_number]->channel[channel].intr_stat;
}
void timer_clear_interrupt(timer_device_number_t timer_number)
{
timer[timer_number]->eoi = timer[timer_number]->eoi;
}
void timer_channel_clear_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel)
{
timer[timer_number]->channel[channel].eoi = timer[timer_number]->channel[channel].eoi;
}
void timer_set_enable(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t enable)
{
if (enable)
timer[timer_number]->channel[channel].control = TIMER_CR_USER_MODE | TIMER_CR_ENABLE;
else
timer[timer_number]->channel[channel].control = TIMER_CR_INTERRUPT_MASK;
}
size_t timer_set_interval(timer_device_number_t timer_number, timer_channel_number_t channel, size_t useconds)
{
uint32_t clk_freq = SysctlClockGetFreq(SYSCTL_CLOCK_TIMER0 + timer_number);
double min_step = 1e6 / clk_freq;
size_t value = (size_t)(useconds / min_step);
configASSERT(value > 0 && value < UINT32_MAX);
timer[timer_number]->channel[channel].load_count = (uint32_t)value;
return (size_t)(min_step * value);
}
typedef void(*timer_ontick)();
timer_ontick time_irq[3][4] = { NULL };
static int timer_isr(void *parm)
{
uint32_t timer_number;
for (timer_number = 0; timer_number < 3; timer_number++)
{
if (parm == timer[timer_number])
break;
}
uint32_t channel = timer[timer_number]->intr_stat;
size_t i = 0;
for (i = 0; i < 4; i++)
{
if (channel & 1)
{
if (time_irq[timer_number][i])
(time_irq[timer_number][i])();
break;
}
channel >>= 1;
}
readl(&timer[timer_number]->eoi);
return 0;
}
void timer_set_irq(timer_device_number_t timer_number, timer_channel_number_t channel, void(*func)(), uint32_t priority)
{
time_irq[timer_number][channel] = func;
if (channel < 2)
{
plic_set_priority(IRQN_TIMER0A_INTERRUPT + timer_number * 2, priority);
plic_irq_register(IRQN_TIMER0A_INTERRUPT + timer_number * 2, timer_isr, (void *)timer[timer_number]);
plic_irq_enable(IRQN_TIMER0A_INTERRUPT + timer_number * 2);
}
else
{
plic_set_priority(IRQN_TIMER0B_INTERRUPT + timer_number * 2, priority);
plic_irq_register(IRQN_TIMER0B_INTERRUPT + timer_number * 2, timer_isr, (void *)timer[timer_number]);
plic_irq_enable(IRQN_TIMER0B_INTERRUPT + timer_number * 2);
}
}
/**
* @brief Get the timer irqn by device and channel object
*
* @note Internal function, not public
* @param device The device
* @param channel The channel
* @return plic_irq_t IRQ number
*/
static plic_irq_t get_timer_irqn_by_device_and_channel(timer_device_number_t device, timer_channel_number_t channel)
{
if (device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX) {
/*
* Select timer interrupt part
* Hierarchy of Timer interrupt to PLIC
* +---------+ +-----------+
* | 0+----+ | |
* | | +--+0A |
* | 1+----+ | |
* | TIMER0 | | |
* | 2+----+ | |
* | | +--+0B |
* | 3+----+ | |
* +---------+ | |
* | |
* +---------+ | |
* | 0+----+ | |
* | | +--+1A |
* | 1+----+ | |
* | TIMER1 | | PLIC |
* | 2+----+ | |
* | | +--+1B |
* | 3+----+ | |
* +---------+ | |
* | |
* +---------+ | |
* | 0+----+ | |
* | | +--+2A |
* | 1+----+ | |
* | TIMER2 | | |
* | 2+----+ | |
* | | +--+2B |
* | 3+----+ | |
* +---------+ +-----------+
*
*/
if (channel < 2) {
/* It is part A interrupt, offset + 0 */
return IRQN_TIMER0A_INTERRUPT + device * 2;
}
else {
/* It is part B interrupt, offset + 1 */
return IRQN_TIMER0B_INTERRUPT + device * 2;
}
}
return IRQN_NO_INTERRUPT;
}
/**
* @brief Process user callback function
*
* @note Internal function, not public
* @param device The timer device
* @param ctx The context
* @return int The callback result
*/
static int timer_interrupt_handler(timer_device_number_t device, void *ctx)
{
uint32_t channel_int_stat = timer[device]->intr_stat;
for (size_t i = 0; i < TIMER_CHANNEL_MAX; i++)
{
/* Check every bit for interrupt status */
if (channel_int_stat & 1)
{
if (timer_instance[device][i].callback) {
/* Process user callback function */
timer_instance[device][i].callback(timer_instance[device][i].ctx);
/* Check if this timer is a single shot timer */
if (timer_instance[device][i].single_shot) {
/* Single shot timer, disable it */
timer_set_enable(device, i, 0);
}
}
/* Clear timer interrupt flag for specific channel */
readl(&timer[device]->channel[i].eoi);
}
channel_int_stat >>= 1;
}
/*
* NOTE:
* Don't read timer[device]->eoi here, or you will lost some interrupt
* readl(&timer[device]->eoi);
*/
return 0;
}
/**
* @brief Callback function bus for timer interrupt
*
* @note Internal function, not public
* @param ctx The context
* @return int The callback result
*/
static void timer0_interrupt_callback(int irq, void *ctx)
{
timer_interrupt_handler(TIMER_DEVICE_0, ctx);
}
/**
* @brief Callback function bus for timer interrupt
*
* @note Internal function, not public
* @param ctx The context
* @return int The callback result
*/
static void timer1_interrupt_callback(int irq, void *ctx)
{
timer_interrupt_handler(TIMER_DEVICE_1, ctx);
}
/**
* @brief Callback function bus for timer interrupt
*
* @note Internal function, not public
* @param ctx The context
* @return int The callback result
*/
static void timer2_interrupt_callback(int irq, void *ctx)
{
timer_interrupt_handler(TIMER_DEVICE_2, ctx);
}
int timer_irq_register(timer_device_number_t device, timer_channel_number_t channel, int is_single_shot, uint32_t priority, timer_callback_t callback, void *ctx)
{
if (device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX) {
plic_irq_t irq_number = get_timer_irqn_by_device_and_channel(device, channel);
irq_manager_callback_t plic_irq_callback[TIMER_DEVICE_MAX] = {
timer0_interrupt_callback,
timer1_interrupt_callback,
timer2_interrupt_callback,
};
timer_instance[device][channel] = (const timer_instance_t) {
.callback = callback,
.ctx = ctx,
.single_shot = is_single_shot,
};
// plic_set_priority(irq_number, priority);
// plic_irq_register(irq_number, plic_irq_callback[device], (void *)&timer_instance[device]);
// plic_irq_enable(irq_number);
isrManager.done->registerIrq(irq_number, plic_irq_callback[device], NULL);
isrManager.done->enableIrq(irq_number);
return 0;
}
return -1;
}
int timer_irq_unregister(timer_device_number_t device, timer_channel_number_t channel)
{
if (device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX) {
timer_instance[device][channel] = (const timer_instance_t) {
.callback = NULL,
.ctx = NULL,
.single_shot = 0,
};
/* Combine 0 and 1 to A interrupt, 2 and 3 to B interrupt */
if ((!(timer_instance[device][TIMER_CHANNEL_0].callback ||
timer_instance[device][TIMER_CHANNEL_1].callback)) ||
(!(timer_instance[device][TIMER_CHANNEL_2].callback ||
timer_instance[device][TIMER_CHANNEL_3].callback))) {
plic_irq_t irq_number = get_timer_irqn_by_device_and_channel(device, channel);
plic_irq_unregister(irq_number);
}
return 0;
}
return -1;
}

View File

@ -1,34 +0,0 @@
menuconfig BSP_USING_WDT0
bool "Using watchdog 0 "
default n
if BSP_USING_WDT0
config WDT_BUS_NAME_0
string "watchdog bus 0 name"
default "wdt0"
config WDT_DRIVER_NAME_0
string "watchdog driver 0 name"
default "wdt0_drv"
config WDT_0_DEVICE_NAME_0
string "watchdog device 0 name"
default "wdt0_dev0"
endif
menuconfig BSP_USING_WDT1
bool "Using watchdog 1 "
default n
if BSP_USING_WDT1
config WDT_BUS_NAME_1
string "watchdog bus 1 name"
default "wdt1"
config WDT_DRIVER_NAME_1
string "watchdog driver 1 name"
default "wdt1_drv"
config WDT_1_DEVICE_NAME_1
string "watchdog device 1 name"
default "wdt1_dev1"
endif

View File

@ -1,6 +0,0 @@
SRC_FILES := wdt.c connect_wdt.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,183 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_wdt.c
* @brief support kd233-board watchdog function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-07-25
*/
#include "wdt.h"
#include "connect_wdt.h"
static uint32 WdtOpen(void *dev)
{
NULL_PARAM_CHECK(dev);
wdt_device_number_t id;
struct WdtHardwareDevice *wdt = (struct WdtHardwareDevice *)dev;
id = *(wdt_device_number_t *)wdt->private_data;
wdt_init(id, 4095, NONE, NONE);
return EOK;
}
static uint32 WdtConfigure(void *drv, struct BusConfigureInfo *args)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(args);
struct WdtDriver *wdt = (struct WdtDriver *)drv;
wdt_device_number_t id = *(wdt_device_number_t *)wdt->private_data;
switch (args->configure_cmd)
{
case OPER_WDT_SET_TIMEOUT:
if (wdt_init(id, (uint64_t)*(int *)args->private_data, NONE, NONE) == 0)
{
return ERROR;
}
break;
case OPER_WDT_KEEPALIVE:
wdt_feed(id);
break;
default:
return ERROR;
}
return EOK;
}
static const struct WdtDevDone dev_done =
{
WdtOpen,
NONE,
NONE,
NONE,
};
/**
* @description: Watchdog function
* @return success: EOK, failure: other
*/
int StartWatchdog(void)
{
//add feed watchdog task function
return EOK;
}
int HwWdtInit(void)
{
wdt_device_number_t id;
x_err_t ret = EOK;
#ifdef BSP_USING_WDT0
{
static struct WdtBus wdt0;
ret = WdtBusInit(&wdt0, WDT_BUS_NAME_0);
if(ret != EOK)
{
KPrintf("Watchdog bus init error %d\n", ret);
return ERROR;
}
static struct WdtDriver drv0;
drv0.configure = WdtConfigure;
id = WDT_DEVICE_0;
drv0.private_data = &id;
ret = WdtDriverInit(&drv0, WDT_DRIVER_NAME_0);
if(ret != EOK)
{
KPrintf("Watchdog driver init error %d\n", ret);
return ERROR;
}
ret = WdtDriverAttachToBus(WDT_DRIVER_NAME_0, WDT_BUS_NAME_0);
if(ret != EOK)
{
KPrintf("Watchdog driver attach error %d\n", ret);
return ERROR;
}
static struct WdtHardwareDevice dev0;
dev0.dev_done = &dev_done;
dev0.private_data = &id;
ret = WdtDeviceRegister(&dev0, WDT_0_DEVICE_NAME_0);
if(ret != EOK)
{
KPrintf("Watchdog device register error %d\n", ret);
return ERROR;
}
ret = WdtDeviceAttachToBus(WDT_0_DEVICE_NAME_0, WDT_BUS_NAME_0);
if(ret != EOK)
{
KPrintf("Watchdog device register error %d\n", ret);
return ERROR;
}
}
#endif
#ifdef BSP_USING_WDT1
{
static struct WdtBus wdt1;
ret = WdtBusInit(&wdt1, WDT_BUS_NAME_1);
if(ret != EOK)
{
KPrintf("Watchdog bus init error %d\n", ret);
return ERROR;
}
static struct WdtDriver drv1;
drv1.configure = WdtConfigure;
id = WDT_DEVICE_1;
drv1.private_data = &id;
ret = WdtDriverInit(&drv1, WDT_DRIVER_NAME_1);
if(ret != EOK)
{
KPrintf("Watchdog driver init error %d\n", ret);
return ERROR;
}
ret = WdtDriverAttachToBus(WDT_DRIVER_NAME_1, WDT_BUS_NAME_1);
if(ret != EOK)
{
KPrintf("Watchdog driver attach error %d\n", ret);
return ERROR;
}
static struct WdtHardwareDevice dev1;
dev1.dev_done = &dev_done;
dev1.private_data = &id;
ret = WdtDeviceRegister(&dev1, WDT_1_DEVICE_NAME_1);
if(ret != EOK)
{
KPrintf("Watchdog device register error %d\n", ret);
return ERROR;
}
ret = WdtDeviceAttachToBus(WDT_1_DEVICE_NAME_1, WDT_BUS_NAME_1);
if(ret != EOK)
{
KPrintf("Watchdog device register error %d\n", ret);
return ERROR;
}
}
#endif
return ret;
}

View File

@ -1,125 +0,0 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file wdt.c
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-07-25
*/
#include "wdt.h"
#include "platform.h"
#include "stddef.h"
#include "utils.h"
#include "sysctl.h"
#include "plic.h"
#include "math.h"
volatile wdt_t *const wdt[2] =
{
(volatile wdt_t *)WDT0_BASE_ADDR,
(volatile wdt_t *)WDT1_BASE_ADDR
};
static void wdt_enable(wdt_device_number_t id)
{
wdt[id]->crr = WDT_CRR_MASK;
wdt[id]->cr |= WDT_CR_ENABLE;
}
static void wdt_disable(wdt_device_number_t id)
{
wdt[id]->crr = WDT_CRR_MASK;
wdt[id]->cr &= (~WDT_CR_ENABLE);
}
static void wdt_set_timeout(wdt_device_number_t id, uint8_t timeout)
{
wdt[id]->torr = WDT_TORR_TOP(timeout);
}
static void wdt_response_mode(wdt_device_number_t id, uint8_t mode)
{
wdt[id]->cr &= (~WDT_CR_RMOD_MASK);
wdt[id]->cr |= mode;
}
static uint64_t wdt_get_pclk(wdt_device_number_t id)
{
return id ? SysctlClockGetFreq(SYSCTL_CLOCK_WDT1) : SysctlClockGetFreq(SYSCTL_CLOCK_WDT0);
}
static uint8_t wdt_get_top(wdt_device_number_t id, uint64_t timeout_ms)
{
uint64_t wdt_clk = wdt_get_pclk(id);
uint64_t ret = (timeout_ms * wdt_clk / 1000) >> 16;
if (ret)
ret = (uint32_t)log2(ret);
if (ret > 0xf)
ret = 0xf;
return (uint8_t)ret;
}
void wdt_feed(wdt_device_number_t id)
{
wdt[id]->crr = WDT_CRR_MASK;
}
void wdt_clear_interrupt(wdt_device_number_t id)
{
wdt[id]->eoi = wdt[id]->eoi;
}
void wdt_start(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq)
{
sysctl_reset(id ? SYSCTL_RESET_WDT1 : SYSCTL_RESET_WDT0);
sysctl_clock_set_threshold(id ? SYSCTL_THRESHOLD_WDT1 : SYSCTL_THRESHOLD_WDT0, 0);
sysctl_clock_enable(id ? SYSCTL_CLOCK_WDT1 : SYSCTL_CLOCK_WDT0);
plic_set_priority(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, 1);
plic_irq_enable(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT);
plic_irq_register(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, on_irq, NULL);
wdt_response_mode(id, WDT_CR_RMOD_INTERRUPT);
uint8_t m_top = wdt_get_top(id, time_out_ms);
wdt_set_timeout(id, m_top);
wdt_enable(id);
}
uint32_t wdt_init(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq, void *ctx)
{
sysctl_reset(id ? SYSCTL_RESET_WDT1 : SYSCTL_RESET_WDT0);
sysctl_clock_set_threshold(id ? SYSCTL_THRESHOLD_WDT1 : SYSCTL_THRESHOLD_WDT0, 0);
sysctl_clock_enable(id ? SYSCTL_CLOCK_WDT1 : SYSCTL_CLOCK_WDT0);
plic_set_priority(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, 1);
plic_irq_enable(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT);
plic_irq_register(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, on_irq, ctx);
wdt_response_mode(id, WDT_CR_RMOD_INTERRUPT);
uint8_t m_top = wdt_get_top(id, time_out_ms);
wdt_set_timeout(id, m_top);
wdt_enable(id);
return (1UL << (m_top + 16 + 1)) * 1000UL / wdt_get_pclk(id);
}
void wdt_stop(wdt_device_number_t id)
{
wdt_disable(id);
}