First commit XiUOS

This commit is contained in:
xuetest
2021-04-28 17:49:18 +08:00
commit 6001051eb7
1331 changed files with 433955 additions and 0 deletions
+148
View File
@@ -0,0 +1,148 @@
menuconfig RESOURCES_SERIAL
bool "Using SERIAL bus drivers"
select KERNEL_WORKQUEUE
default y
if RESOURCES_SERIAL
config SERIAL_USING_DMA
bool "Enable SERIAL DMA mode"
default y
config SERIAL_RB_BUFSZ
int "Set SERIAL RX buffer size"
default 128
endif
if BSP_USING_CAN
config RESOURCES_CAN
bool "Using CAN bus drivers"
default y
endif
if BSP_USING_I2C
config RESOURCES_I2C
bool "Using I2C bus drivers"
default n
endif
if BSP_USING_LCD
config RESOURCES_LCD
bool "Using LCD bus drivers"
default n
endif
if BSP_USING_GPIO
config RESOURCES_PIN
bool "Using generic GPIO PIN bus drivers"
default n
endif
if BSP_USING_RTC
menuconfig RESOURCES_RTC
bool "Using RTC bus drivers"
default n
if RESOURCES_RTC
config USING_SOFT_RTC
bool "Using SOFT RTC"
default n
if USING_SOFT_RTC
config SOFT_RTC_BUS_NAME
string "soft rtc bus name"
default "srtc"
config SOFT_RTC_DRV_NAME
string "soft rtc bus driver name"
default "srtc_drv"
endif
endif
endif
if BSP_USING_SDIO
config RESOURCES_SDIO
bool "Using SD/MMC card bus drivers"
default n
endif
if BSP_USING_SPI
menuconfig RESOURCES_SPI
bool "Using SPI bus drivers"
default n
if RESOURCES_SPI
menuconfig RESOURCES_SPI_SD
bool "Using SD/TF card driver with spi"
default n
if RESOURCES_SPI_SD
config SPI_SD_NAME
string "spi sd card 0 name"
default "sd0"
endif
menuconfig RESOURCES_SPI_SFUD
bool "Using Serial Flash Universal Driver Lib"
default n
if RESOURCES_SPI_SFUD
config SFUD_USING_SFDP
bool "Using auto probe flash JEDEC SFDP parameter"
default y
config SFUD_USING_FLASH_INFO_TABLE
bool "Using defined supported flash chip information table"
default n
config SFUD_DEBUG_LOG
bool "Support SFUD debug log"
default y
endif
endif
endif
if BSP_USING_HWTIMER
config RESOURCES_HWTIMER
bool "Using hardware timer bus drivers"
default n
endif
if BSP_USING_TOUCH
config RESOURCES_TOUCH
bool "Using touch bus drivers"
default n
endif
if BSP_USING_USB
menuconfig RESOURCES_USB
bool "Using USB bus drivers"
default n
if RESOURCES_USB
config RESOURCES_USB_HOST
bool "Using USB host function"
default y
if RESOURCES_USB_HOST
config UDISK_MOUNTPOINT
string "Udisk mount dir"
default "/"
endif
config USBH_MSTORAGE
bool "usb use mass storage device"
default y
select FS_VFS
config RESOURCES_USB_DEVICE
bool "Using USB device function"
default y
if RESOURCES_USB_DEVICE
config USBD_THREAD_STACK_SZ
int "usb thread stack size"
default 4096
endif
endif
endif
if BSP_USING_WDT
config RESOURCES_WDT
bool "Using Watch Dog bus drivers"
default n
endif
+56
View File
@@ -0,0 +1,56 @@
SRC_DIR :=
SRC_FILES += bus.c
ifeq ($(CONFIG_KERNEL_DEVICE),y)
SRC_FILES += device.c
endif
ifeq ($(CONFIG_RESOURCES_CAN),y)
SRC_DIR += can
endif
ifeq ($(CONFIG_RESOURCES_I2C),y)
SRC_DIR += i2c
endif
ifeq ($(CONFIG_RESOURCES_LCD),y)
SRC_DIR += lcd
endif
ifeq ($(CONFIG_RESOURCES_PIN),y)
SRC_DIR += pin
endif
ifeq ($(CONFIG_RESOURCES_RTC),y)
SRC_DIR += rtc
endif
ifeq ($(CONFIG_RESOURCES_SDIO),y)
SRC_DIR += sdio
endif
ifeq ($(CONFIG_RESOURCES_SERIAL),y)
SRC_DIR += serial
endif
ifeq ($(CONFIG_RESOURCES_SPI),y)
SRC_DIR += spi
endif
ifeq ($(CONFIG_RESOURCES_HWTIMER),y)
SRC_DIR += timer
endif
ifeq ($(CONFIG_RESOURCES_TOUCH),y)
SRC_DIR += touch
endif
ifeq ($(CONFIG_RESOURCES_USB),y)
SRC_DIR += usb
endif
ifeq ($(CONFIG_RESOURCES_WDT),y)
SRC_DIR += watchdog
endif
include $(KERNEL_ROOT)/compiler.mk
+433
View File
@@ -0,0 +1,433 @@
/*
* 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 bus.c
* @brief 1、support bus driver framework2、provide bus API。
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus.h>
#include <stdlib.h>
DoubleLinklistType bus_linklist;
/*Create the bus linklist*/
static void BusLinkInit(struct Bus *bus)
{
static uint8 bus_link_flag = RET_FALSE;
if(!bus_link_flag) {
InitDoubleLinkList(&bus_linklist);
bus_link_flag = RET_TRUE;
bus->bus_link_flag = RET_TRUE;
}
/*Create the driver of the bus linklist*/
if(!bus->bus_drvlink_flag) {
InitDoubleLinkList(&bus->bus_drvlink);
bus->bus_drvlink_flag = RET_TRUE;
}
/*Create the hardware device of the bus linklist*/
if(!bus->bus_devlink_flag) {
InitDoubleLinkList(&bus->bus_devlink);
bus->bus_devlink_flag = RET_TRUE;
}
}
static int BusMatchDrvDev(struct Driver *driver, struct HardwareDev *device)
{
NULL_PARAM_CHECK(driver);
NULL_PARAM_CHECK(device);
if(!strncmp(driver->owner_bus->bus_name, device->owner_bus->bus_name, NAME_NUM_MAX)) {
KPrintf("BusMatchDrvDev match successfully, bus name %s\n", driver->owner_bus->bus_name);
driver->private_data = device->private_data;//driver get the device param
device->owner_bus->owner_driver = driver;
driver->owner_bus->owner_haldev = device;
return EOK;
}
return ERROR;
}
/**
* @Description: support to obtain bus for a certain dev if necessary, then configure and init its drv
* @param bus - bus pointer
* @param dev - dev pointer
* @param drv_name - drv name
* @param configure_info - BusConfigureInfo pointer
* @return successfulEOKfailedERROR
*/
int DeviceObtainBus(struct Bus *bus, struct HardwareDev *dev, const char *drv_name, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(bus);
NULL_PARAM_CHECK(dev);
int32 ret = EOK;
ret = KMutexObtain(bus->bus_lock, WAITING_FOREVER);
if(EOK != ret) {
KPrintf("DevObtainBus bus_lock error %d!\n", ret);
return ret;
}
if(bus->owner_haldev != dev) {
struct Driver *drv = BusFindDriver(bus, drv_name);
configure_info->configure_cmd = OPE_CFG;
drv->configure(drv, configure_info);
configure_info->configure_cmd = OPE_INT;
drv->configure(drv, configure_info);
bus->owner_haldev = dev;
}
return ret;
}
/**
* @Description: support to register bus pointer with linklist
* @param bus - bus pointer
* @return successfulEOKfailedNONE
*/
int BusRegister(struct Bus *bus)
{
x_err_t ret = EOK;
NULL_PARAM_CHECK(bus);
bus->match = BusMatchDrvDev;
BusLinkInit(bus);
bus->bus_lock = KMutexCreate();
DoubleLinkListInsertNodeAfter(&bus_linklist, &(bus->bus_link));
return ret;
}
/**
* @Description: support to release bus pointer in linklist
* @param bus - bus pointer
* @return successfulEOKfailedNONE
*/
int BusRelease(struct Bus *bus)
{
NULL_PARAM_CHECK(bus);
KMutexAbandon(bus->bus_lock);
bus->bus_cnt = 0;
bus->driver_cnt = 0;
bus->haldev_cnt = 0;
bus->bus_link_flag = RET_FALSE;
bus->bus_drvlink_flag = RET_FALSE;
bus->bus_devlink_flag = RET_FALSE;
return EOK;
}
/**
* @Description: support to unregister bus pointer and delete its linklist node
* @param bus - bus pointer
* @return successfulEOKfailedNONE
*/
int BusUnregister(struct Bus *bus)
{
NULL_PARAM_CHECK(bus);
bus->bus_cnt--;
DoubleLinkListRmNode(&(bus->bus_link));
return EOK;
}
/**
* @Description: support to register driver pointer to bus pointer
* @param bus - bus pointer
* @param driver - driver pointer
* @return successfulEOKfailedNONE
*/
int DriverRegisterToBus(struct Bus *bus, struct Driver *driver)
{
NULL_PARAM_CHECK(bus);
NULL_PARAM_CHECK(driver);
driver->owner_bus = bus;
bus->driver_cnt++;
DoubleLinkListInsertNodeAfter(&bus->bus_drvlink, &(driver->driver_link));
return EOK;
}
/**
* @Description: support to register dev pointer to bus pointer
* @param bus - bus pointer
* @param device - device pointer
* @return successfulEOKfailedNONE
*/
int DeviceRegisterToBus(struct Bus *bus, struct HardwareDev *device)
{
NULL_PARAM_CHECK(bus);
NULL_PARAM_CHECK(device);
device->owner_bus = bus;
bus->haldev_cnt++;
DoubleLinkListInsertNodeAfter(&bus->bus_devlink, &(device->dev_link));
return EOK;
}
/**
* @Description: support to delete driver pointer from bus pointer
* @param bus - bus pointer
* @param driver - driver pointer
* @return successfulEOKfailedNONE
*/
int DriverDeleteFromBus(struct Bus *bus, struct Driver *driver)
{
NULL_PARAM_CHECK(bus);
NULL_PARAM_CHECK(driver);
bus->driver_cnt--;
DoubleLinkListRmNode(&(driver->driver_link));
free(driver);
return EOK;
}
/**
* @Description: support to delete dev pointer from bus pointer
* @param bus - bus pointer
* @param device - device pointer
* @return successfulEOKfailedNONE
*/
int DeviceDeleteFromBus(struct Bus *bus, struct HardwareDev *device)
{
NULL_PARAM_CHECK(bus);
NULL_PARAM_CHECK(device);
bus->haldev_cnt--;
DoubleLinkListRmNode(&(device->dev_link));
free(device);
return EOK;
}
/**
* @Description: support to find bus pointer by bus name
* @param bus_name - bus name
* @return successfulbus pointerfailedNONE
*/
BusType BusFind(const char *bus_name)
{
struct Bus *bus = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &bus_linklist;
for (node = head->node_next; node != head; node = node->node_next)
{
bus = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Bus, bus_link);
if(!strcmp(bus->bus_name, bus_name)) {
return bus;
}
}
KPrintf("BusFind cannot find the %s bus.return NULL\n", bus_name);
return NONE;
}
/**
* @Description: support to find driver pointer of certain bus by driver name
* @param bus - bus pointer
* @param driver_name - driver name
* @return successfulEOKfailedNONE
*/
DriverType BusFindDriver(struct Bus *bus, const char *driver_name)
{
NULL_PARAM_CHECK(bus);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &bus->bus_drvlink;
for (node = head->node_next; node != head; node = node->node_next)
{
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if(!strcmp(driver->drv_name, driver_name)) {
return driver;
}
}
KPrintf("BusFindDriver cannot find the %s driver.return NULL\n", driver_name);
return NONE;
}
/**
* @Description: support to find device pointer of certain bus by device name
* @param bus - bus pointer
* @param device_name - device name
* @return successfulEOKfailedNONE
*/
HardwareDevType BusFindDevice(struct Bus *bus, const char *device_name)
{
NULL_PARAM_CHECK(bus);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &bus->bus_devlink;
for (node = head->node_next; node != head; node = node->node_next)
{
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if(!strcmp(device->dev_name, device_name)) {
return device;
}
}
KPrintf("BusFindDevice cannot find the %s device.return NULL\n", device_name);
return NONE;
}
/**
* @Description: support to set dev receive function callback
* @param dev - dev pointer
* @param dev_recv_callback - callback function
* @return successfulEOKfailedERROR
*/
uint32 BusDevRecvCallback(struct HardwareDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length))
{
NULL_PARAM_CHECK(dev );
dev->dev_recv_callback = dev_recv_callback;
return EOK;
}
/**
* @Description: support to open dev
* @param dev - dev pointer
* @return successfulEOKfailedERROR
*/
uint32 BusDevOpen(struct HardwareDev *dev)
{
NULL_PARAM_CHECK(dev);
x_err_t ret = EOK;
if (dev->dev_done->open) {
ret = dev->dev_done->open(dev);
if(ret) {
KPrintf("BusDevOpen error ret %u\n", ret);
return ERROR;
}
}
return ret;
}
/**
* @Description: support to close dev
* @param dev - dev pointer
* @return successfulEOKfailedERROR
*/
uint32 BusDevClose(struct HardwareDev *dev)
{
NULL_PARAM_CHECK(dev);
x_err_t ret = EOK;
if (dev->dev_done->close) {
ret = dev->dev_done->close(dev);
if(ret) {
KPrintf("BusDevClose error ret %u\n", ret);
return ERROR;
}
}
return ret;
}
/**
* @Description: support to write data to dev
* @param dev - dev pointer
* @param write_param - BusBlockWriteParam
* @return successfulEOKfailedNONE
*/
uint32 BusDevWriteData(struct HardwareDev *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
if (dev->dev_done->write) {
return dev->dev_done->write(dev, write_param);
}
return EOK;
}
/**
* @Description: support to read data from dev
* @param dev - dev pointer
* @param read_param - BusBlockReadParam
* @return successfulEOKfailedNONE
*/
uint32 BusDevReadData(struct HardwareDev *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
if (dev->dev_done->read) {
return dev->dev_done->read(dev, read_param);
}
return EOK;
}
/**
* @Description: support to configure drv, include OPE_CFG and OPE_INT
* @param drv - drv pointer
* @param configure_info - BusConfigureInfo
* @return successfulEOKfailedNONE
*/
uint32 BusDrvConfigure(struct Driver *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
if (drv->configure) {
ret = drv->configure(drv, configure_info);
if(ret) {
KPrintf("BusDrvCfg error, ret %u\n", ret);
return ERROR;
}
}
return ret;
}
+5
View File
@@ -0,0 +1,5 @@
SRC_FILES += dev_can.c drv_can.c bus_can.c
include $(KERNEL_ROOT)/compiler.mk
+122
View File
@@ -0,0 +1,122 @@
/*
* 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 bus_can.c
* @brief register can bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_can.h>
#include <dev_can.h>
/*Register the CAN BUS*/
int CanBusInit(struct CanBus *can_bus, const char *bus_name)
{
NULL_PARAM_CHECK(can_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != can_bus->bus.bus_state) {
strncpy(can_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
can_bus->bus.bus_type = TYPE_CAN_BUS;
can_bus->bus.bus_state = BUS_INSTALL;
can_bus->bus.private_data = can_bus->private_data;
ret = BusRegister(&can_bus->bus);
if (EOK != ret) {
KPrintf("CanBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("CanBusInit BusRegister bus has been register state%u\n", can_bus->bus.bus_state);
}
return ret;
}
/*Register the CAN Driver*/
int CanDriverInit(struct CanDriver *can_driver, const char *driver_name)
{
NULL_PARAM_CHECK(can_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != can_driver->driver.driver_state) {
can_driver->driver.driver_type = TYPE_CAN_DRV;
can_driver->driver.driver_state = DRV_INSTALL;
strncpy(can_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
can_driver->driver.configure = can_driver->configure;
can_driver->driver.private_data = can_driver->private_data;
ret = CanDriverRegister(&can_driver->driver);
if (EOK != ret) {
KPrintf("CanDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("CanDriverInit DriverRegister driver has been register state%u\n", can_driver->driver.driver_state);
}
return ret;
}
/*Release the CAN device*/
int CanReleaseBus(struct CanBus *can_bus)
{
NULL_PARAM_CHECK(can_bus);
return BusRelease(&can_bus->bus);
}
/*Register the CAN Driver to the CAN BUS*/
int CanDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("CanDriverAttachToBus find can bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_CAN_BUS == bus->bus_type) {
driver = CanDriverFind(drv_name, TYPE_CAN_DRV);
if (NONE == driver) {
KPrintf("CanDriverAttachToBus find can driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_CAN_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("CanDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+120
View File
@@ -0,0 +1,120 @@
/*
* 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 dev_can.c
* @brief register can dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_can.h>
#include <dev_can.h>
static DoubleLinklistType candev_linklist;
/*Create the CAN device linklist*/
static void CanDeviceLinkInit()
{
InitDoubleLinkList(&candev_linklist);
}
/*Find the register CAN device*/
HardwareDevType CanDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &candev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("CanDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
/*Register the CAN device*/
int CanDeviceRegister(struct CanHardwareDevice *can_device, void *can_param, const char *device_name)
{
NULL_PARAM_CHECK(can_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (dev_link_flag) {
CanDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != can_device->haldev.dev_state) {
strncpy(can_device->haldev.dev_name, device_name, NAME_NUM_MAX);
can_device->haldev.dev_type = TYPE_CAN_DEV;
can_device->haldev.dev_state = DEV_INSTALL;
can_device->haldev.dev_done = (struct HalDevDone *)can_device->dev_done;
can_device->haldev.private_data = can_param;
DoubleLinkListInsertNodeAfter(&candev_linklist, &(can_device->haldev.dev_link));
} else {
KPrintf("CanDeviceRegister device has been register state%u\n", can_device->haldev.dev_state);
}
return ret;
}
/*Register the CAN Device to the CAN BUS*/
int CanDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("CanDeviceAttachToBus find can bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_CAN_BUS == bus->bus_type) {
device = CanDeviceFind(dev_name, TYPE_CAN_DEV);
if (NONE == device) {
KPrintf("CanDeviceAttachToBus find can device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_CAN_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("CanDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+69
View File
@@ -0,0 +1,69 @@
/*
* 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 drv_can.c
* @brief register can drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_can.h>
#include <dev_can.h>
static DoubleLinklistType candrv_linklist;
/*Create the driver linklist*/
static void CanDrvLinkInit()
{
InitDoubleLinkList(&candrv_linklist);
}
/*Find the regiter driver*/
DriverType CanDriverFind(const char *drv_name, enum DriverType drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &candrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("CanDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
/*Register the Driver, manage with the double linklist*/
int CanDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
CanDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&candrv_linklist, &(driver->driver_link));
return ret;
}
+5
View File
@@ -0,0 +1,5 @@
SRC_FILES += dev_i2c.c drv_i2c.c bus_i2c.c
include $(KERNEL_ROOT)/compiler.mk
+121
View File
@@ -0,0 +1,121 @@
/*
* 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 bus_i2c.c
* @brief register i2c bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_i2c.h>
#include <dev_i2c.h>
/*Register the I2C BUS*/
int I2cBusInit(struct I2cBus *i2c_bus, const char *bus_name)
{
NULL_PARAM_CHECK(i2c_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != i2c_bus->bus.bus_state) {
strncpy(i2c_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
i2c_bus->bus.bus_type = TYPE_I2C_BUS;
i2c_bus->bus.bus_state = BUS_INSTALL;
i2c_bus->bus.private_data = i2c_bus->private_data;
ret = BusRegister(&i2c_bus->bus);
if (EOK != ret) {
KPrintf("I2cBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("I2cBusInit BusRegister bus has been register state%u\n", i2c_bus->bus.bus_state);
}
return ret;
}
/*Register the I2C Driver*/
int I2cDriverInit(struct I2cDriver *i2c_driver, const char *driver_name)
{
NULL_PARAM_CHECK(i2c_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != i2c_driver->driver.driver_state) {
i2c_driver->driver.driver_type = TYPE_I2C_DRV;
i2c_driver->driver.driver_state = DRV_INSTALL;
strncpy(i2c_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
i2c_driver->driver.private_data = i2c_driver->private_data;
ret = I2cDriverRegister(&i2c_driver->driver);
if (EOK != ret) {
KPrintf("I2cDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("I2cDriverInit DriverRegister driver has been register state%u\n", i2c_driver->driver.driver_state);
}
return ret;
}
/*Release the I2C device*/
int I2cReleaseBus(struct I2cBus *i2c_bus)
{
NULL_PARAM_CHECK(i2c_bus);
return BusRelease(&i2c_bus->bus);
}
/*Register the I2C Driver to the I2C BUS*/
int I2cDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("I2cDriverAttachToBus find i2c bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_I2C_BUS == bus->bus_type) {
driver = I2cDriverFind(drv_name, TYPE_I2C_DRV);
if (NONE == driver) {
KPrintf("I2cDriverAttachToBus find i2c driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_I2C_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("I2cDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+162
View File
@@ -0,0 +1,162 @@
/*
* 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 dev_i2c.c
* @brief register i2c dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_i2c.h>
#include <dev_i2c.h>
static DoubleLinklistType i2cdev_linklist;
/*Create the I2C device linklist*/
static void I2cDeviceLinkInit()
{
InitDoubleLinkList(&i2cdev_linklist);
}
static uint32 I2cDeviceWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
struct I2cHardwareDevice *i2c_dev = (struct I2cHardwareDevice *)dev;
struct I2cDataStandard i2c_msg;
i2c_msg.addr = I2C_SLAVE_ADDR;
i2c_msg.flags = I2C_WR;
i2c_msg.buf = NONE;
i2c_msg.len = 0;
i2c_msg.retries = 1;
i2c_msg.next = NONE;
return i2c_dev->i2c_dev_done->write(i2c_dev, &i2c_msg);
}
static uint32 I2cDeviceRead(void *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(read_param);
struct I2cHardwareDevice *i2c_dev = (struct I2cHardwareDevice *)dev;
struct I2cDataStandard i2c_msg;
i2c_msg.addr = I2C_SLAVE_ADDR;
i2c_msg.flags = I2C_RD;
i2c_msg.buf = read_param->buffer;
i2c_msg.len = read_param->size;
i2c_msg.retries = 1;
i2c_msg.next = NONE;
return i2c_dev->i2c_dev_done->read(i2c_dev, &i2c_msg);
}
static const struct HalDevDone dev_done =
{
.open = NONE,
.close = NONE,
.write = I2cDeviceWrite,
.read = I2cDeviceRead,
};
/*Find the register I2C device*/
HardwareDevType I2cDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &i2cdev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("I2cDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
/*Register the I2C device*/
int I2cDeviceRegister(struct I2cHardwareDevice *i2c_device, void *i2c_param, const char *device_name)
{
NULL_PARAM_CHECK(i2c_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (dev_link_flag) {
I2cDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != i2c_device->haldev.dev_state) {
strncpy(i2c_device->haldev.dev_name, device_name, NAME_NUM_MAX);
i2c_device->haldev.dev_type = TYPE_I2C_DEV;
i2c_device->haldev.dev_state = DEV_INSTALL;
i2c_device->haldev.dev_done = &dev_done;
i2c_device->haldev.private_data = i2c_param;
DoubleLinkListInsertNodeAfter(&i2cdev_linklist, &(i2c_device->haldev.dev_link));
} else {
KPrintf("I2cDeviceRegister device has been register state%u\n", i2c_device->haldev.dev_state);
}
return ret;
}
/*Register the I2C Device to the I2C BUS*/
int I2cDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("I2cDeviceAttachToBus find i2c bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_I2C_BUS == bus->bus_type) {
device = I2cDeviceFind(dev_name, TYPE_I2C_DEV);
if (NONE == device) {
KPrintf("I2cDeviceAttachToBus find i2c device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_I2C_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("I2cDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+69
View File
@@ -0,0 +1,69 @@
/*
* 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 drv_i2c.c
* @brief register i2c drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_i2c.h>
#include <dev_i2c.h>
static DoubleLinklistType i2cdrv_linklist;
/*Create the driver linklist*/
static void I2cDrvLinkInit()
{
InitDoubleLinkList(&i2cdrv_linklist);
}
/*Find the regiter driver*/
DriverType I2cDriverFind(const char *drv_name, enum DriverType drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &i2cdrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("I2cDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
/*Register the Driver, manage with the double linklist*/
int I2cDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
I2cDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&i2cdrv_linklist, &(driver->driver_link));
return ret;
}
+267
View File
@@ -0,0 +1,267 @@
/*
* 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 bus.h
* @brief define bus driver framework function and common API
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_H
#define BUS_H
#include <xiuos.h>
#ifdef __cplusplus
extern "C" {
#endif
#define OPE_INT 0x0000
#define OPE_CFG 0x0001
#define OPER_WDT_SET_TIMEOUT 0x0002
#define OPER_WDT_KEEPALIVE 0x0003
typedef struct Bus *BusType;
typedef struct HardwareDev *HardwareDevType;
typedef struct Driver *DriverType;
/* need to add new bus type in ../tool/shell/letter-shell/cmd.c, ensure ShowBus cmd supported*/
enum BusType
{
TYPE_I2C_BUS = 0,
TYPE_SPI_BUS,
TYPE_HWTIMER_BUS,
TYPE_USB_BUS,
TYPE_CAN_BUS,
TYPE_WDT_BUS,
TYPE_SDIO_BUS,
TYPE_TOUCH_BUS,
TYPE_LCD_BUS,
TYPE_PIN_BUS,
TYPE_RTC_BUS,
TYPE_SERIAL_BUS,
TYPE_BUS_END,
};
enum BusState
{
BUS_INIT = 0,
BUS_INSTALL,
BUS_UNINSTALL,
};
enum DevType
{
TYPE_I2C_DEV = 0,
TYPE_SPI_DEV,
TYPE_HWTIMER_DEV,
TYPE_USB_DEV,
TYPE_CAN_DEV,
TYPE_WDT_DEV,
TYPE_SDIO_DEV,
TYPE_TOUCH_DEV,
TYPE_LCD_DEV,
TYPE_PIN_DEV,
TYPE_RTC_DEV,
TYPE_SERIAL_DEV,
TYPE_DEV_END,
};
enum DevState
{
DEV_INIT = 0,
DEV_INSTALL,
DEV_UNINSTALL,
};
enum DriverType
{
TYPE_I2C_DRV = 0,
TYPE_SPI_DRV,
TYPE_HWTIMER_DRV,
TYPE_USB_DRV,
TYPE_CAN_DRV,
TYPE_WDT_DRV,
TYPE_SDIO_DRV,
TYPE_TOUCH_DRV,
TYPE_LCD_DRV,
TYPE_PIN_DRV,
TYPE_RTC_DRV,
TYPE_SERIAL_DRV,
TYPE_DRV_END,
};
enum DriverState
{
DRV_INIT = 0,
DRV_INSTALL,
DRV_UNINSTALL,
};
struct BusConfigureInfo
{
int configure_cmd;
void *private_data;
};
struct BusBlockReadParam
{
x_OffPos pos;
void* buffer;
x_size_t size;
x_size_t read_length;
};
struct BusBlockWriteParam
{
x_OffPos pos;
const void* buffer;
x_size_t size;
};
struct HalDevBlockParam
{
uint32 cmd;
struct DeviceBlockArrange dev_block;
struct DeviceBlockAddr *dev_addr;
};
struct HalDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct HardwareDev
{
int8 dev_name[NAME_NUM_MAX];
enum DevType dev_type;
enum DevState dev_state;
const struct HalDevDone *dev_done;
int (*dev_recv_callback) (void *dev, x_size_t length);
int (*dev_block_control) (struct HardwareDev *dev, struct HalDevBlockParam *block_param);
struct Bus *owner_bus;
void *private_data;
int32 dev_sem;
DoubleLinklistType dev_link;
};
struct Driver
{
int8 drv_name[NAME_NUM_MAX];
enum DriverType driver_type;
enum DriverState driver_state;
uint32 (*configure)(void *drv, struct BusConfigureInfo *configure_info);
struct Bus *owner_bus;
void *private_data;
DoubleLinklistType driver_link;
};
struct Bus
{
int8 bus_name[NAME_NUM_MAX];
enum BusType bus_type;
enum BusState bus_state;
int32 (*match)(struct Driver *driver, struct HardwareDev *device);
int bus_lock;
struct HardwareDev *owner_haldev;
struct Driver *owner_driver;
void *private_data;
/*manage the drv of the bus*/
uint8 driver_cnt;
uint8 bus_drvlink_flag;
DoubleLinklistType bus_drvlink;
/*manage the dev of the bus*/
uint8 haldev_cnt;
uint8 bus_devlink_flag;
DoubleLinklistType bus_devlink;
uint8 bus_cnt;
uint8 bus_link_flag;
DoubleLinklistType bus_link;
};
/*Register the BUS,manage with the double linklist*/
int BusRegister(struct Bus *bus);
/*Release the BUS framework*/
int BusRelease(struct Bus *bus);
/*Unregister a certain kind of BUS*/
int BusUnregister(struct Bus *bus);
/*Register the driver to the bus*/
int DriverRegisterToBus(struct Bus *bus, struct Driver *driver);
/*Register the device to the bus*/
int DeviceRegisterToBus(struct Bus *bus, struct HardwareDev *device);
/*Delete the driver from the bus*/
int DriverDeleteFromBus(struct Bus *bus, struct Driver *driver);
/*Delete the device from the bus*/
int DeviceDeleteFromBus(struct Bus *bus, struct HardwareDev *device);
/*Find the bus with bus name*/
BusType BusFind(const char *bus_name);
/*Find the driver of cetain bus*/
DriverType BusFindDriver(struct Bus *bus, const char *driver_name);
/*Find the device of certain bus*/
HardwareDevType BusFindDevice(struct Bus *bus, const char *device_name);
/*Dev receive data callback function*/
uint32 BusDevRecvCallback(struct HardwareDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length));
/*Open the device of the bus*/
uint32 BusDevOpen(struct HardwareDev *dev);
/*Close the device of the bus*/
uint32 BusDevClose(struct HardwareDev *dev);
/*Write data to the device*/
uint32 BusDevWriteData(struct HardwareDev *dev, struct BusBlockWriteParam *write_param);
/*Read data from the device*/
uint32 BusDevReadData(struct HardwareDev *dev, struct BusBlockReadParam *read_param);
/*Configure the driver of the bus*/
uint32 BusDrvConfigure(struct Driver *drv, struct BusConfigureInfo *configure_info);
/*Obtain the bus using a certain dev*/
int DeviceObtainBus(struct Bus *bus, struct HardwareDev *dev, const char *drv_name, struct BusConfigureInfo *configure_info);
#ifdef __cplusplus
}
#endif
#endif
+67
View File
@@ -0,0 +1,67 @@
/*
* 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 bus_can.h
* @brief define can bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_CAN_H
#define BUS_CAN_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct CanDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
void *private_data;
};
struct CanBus
{
struct Bus bus;
void *private_data;
};
/*Register the CAN bus*/
int CanBusInit(struct CanBus *can_bus, const char *bus_name);
/*Register the CAN driver*/
int CanDriverInit(struct CanDriver *can_driver, const char *driver_name);
/*Release the CAN device*/
int CanReleaseBus(struct CanBus *can_bus);
/*Register the CAN driver to the CAN bus*/
int CanDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int CanDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType CanDriverFind(const char *drv_name, enum DriverType drv_type);
#ifdef __cplusplus
}
#endif
#endif
+65
View File
@@ -0,0 +1,65 @@
/*
* 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 bus_hwtimer.h
* @brief define hwtimer bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_HWTIMER_H
#define BUS_HWTIMER_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct HwtimerDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
};
struct HwtimerBus
{
struct Bus bus;
void *private_data;
};
/*Register the hwtimer bus*/
int HwtimerBusInit(struct HwtimerBus *hwtimer_bus, const char *bus_name);
/*Register the hwtimer driver*/
int HwtimerDriverInit(struct HwtimerDriver *hwtimer_driver, const char *driver_name);
/*Release the hwtimer device*/
int HwtimerReleaseBus(struct HwtimerBus *hwtimer_bus);
/*Register the hwtimer driver to the hwtimer bus*/
int HwtimerDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int HwtimerDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType HwtimerDriverFind(const char *drv_name);
#ifdef __cplusplus
}
#endif
#endif
+90
View File
@@ -0,0 +1,90 @@
/*
* 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 bus_i2c.h
* @brief define i2c bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_I2C_H
#define BUS_I2C_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct I2cHalDrvDone
{
void *data;
void (*SetSdaState) (void *data, uint8 sda_state);
void (*SetSclState) (void *data, uint8 scl_state);
uint8 (*GetSdaState) (void *data);
uint8 (*GetSclState) (void *data);
#ifdef ARCH_RISCV
int (*udelay)(uint64 us);
#endif
#ifdef ARCH_ARM
int (*udelay)(uint32 us);
#endif
uint32 delay_us;
uint32 timeout;
};
typedef struct
{
uint8 i2c_sda_pin;
uint8 i2c_scl_pin;
}I2cBusParam;
struct I2cDriver
{
struct Driver driver;
void *private_data;
};
struct I2cBus
{
struct Bus bus;
void *private_data;
};
/*Register the I2C bus*/
int I2cBusInit(struct I2cBus *i2c_bus, const char *bus_name);
/*Register the I2C driver*/
int I2cDriverInit(struct I2cDriver *i2c_driver, const char *driver_name);
/*Release the I2C device*/
int I2cReleaseBus(struct I2cBus *i2c_bus);
/*Register the I2C driver to the I2C bus*/
int I2cDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int I2cDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType I2cDriverFind(const char *drv_name, enum DriverType drv_type);
#ifdef __cplusplus
}
#endif
#endif
+65
View File
@@ -0,0 +1,65 @@
/*
* 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 bus_lcd.h
* @brief define lcd bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_LCD_H
#define BUS_LCD_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct LcdDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
};
struct LcdBus
{
struct Bus bus;
void *private_data;
};
/*Register the lcd bus*/
int LcdBusInit(struct LcdBus *lcd_bus , const char *bus_name);
/*Register the lcd driver*/
int LcdDriverInit(struct LcdDriver *lcd_driver, const char *driver_name);
/*Release the lcd device*/
int LcdReleaseBus(struct LcdBus *lcd_bus );
/*Register the lcd driver to the lcd bus*/
int LcdDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int LcdDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType LcdDriverFind(const char *drv_name, enum DriverType drv_type);
#ifdef __cplusplus
}
#endif
#endif
+68
View File
@@ -0,0 +1,68 @@
/*
* 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 bus_pin.h
* @brief define pin bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_PIN_H
#define BUS_PIN_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct PinDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *ConfigureInfo);
};
struct PinBus
{
struct Bus bus;
void *private_data;
};
/*Register the Pin bus*/
int PinBusInit(struct PinBus *pin_bus, const char *bus_name);
/*Register the Pin driver*/
int PinDriverInit(struct PinDriver *pin_driver, const char *driver_name, void *data);
/*Release the Pin device*/
int PinReleaseBus(struct PinBus *pin_bus);
/*Register the Pin driver to the Pin bus*/
int PinDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int PinDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType PinDriverFind(const char *drv_name, enum DriverType drv_type);
/*Get the initialized Pin bus*/
BusType PinBusInitGet(void);
#ifdef __cplusplus
}
#endif
#endif
+98
View File
@@ -0,0 +1,98 @@
/*
* 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 bus_rtc.h
* @brief define rtc bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_RTC_H
#define BUS_RTC_H
#include <bus.h>
#include <time.h>
#ifdef __cplusplus
extern "C" {
#endif
struct RtcDateParam
{
uint32 year;
uint32 month;
uint32 day;
};
struct RtcTimeParam
{
uint32 hour;
uint32 minute;
uint32 second;
};
struct RtcSetParam
{
int rtc_set_cmd;
time_t *time;
struct RtcDateParam date_param;
struct RtcTimeParam time_param;
};
struct RtcDrvConfigureParam
{
int rtc_operation_cmd;
time_t *time;
};
struct RtcDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
};
struct RtcBus
{
struct Bus bus;
void *private_data;
};
/*Register the rtc bus*/
int RtcBusInit(struct RtcBus *rtc_bus, const char *bus_name);
/*Register the rtc driver*/
int RtcDriverInit(struct RtcDriver *rtc_driver, const char *driver_name);
/*Release the rtc device*/
int RtcReleaseBus(struct RtcBus *rtc_bus);
/*Register the rtc driver to the rtc bus*/
int RtcDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int RtcDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType RtcDriverFind(const char *drv_name, enum DriverType drv_type);
/*Set Rtc time and date*/
int RtcDrvSetFunction(char *driver_name, struct RtcSetParam *rtc_set_param);
#ifdef __cplusplus
}
#endif
#endif
+64
View File
@@ -0,0 +1,64 @@
/*
* 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 bus_sdio.h
* @brief define sdio bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_SDIO_H
#define BUS_SDIO_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct SdioDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
};
struct SdioBus
{
struct Bus bus;
void *private_data;
};
/*Register the sdio bus*/
int SdioBusInit(struct SdioBus *sdio_bus, const char *bus_name);
/*Register the sdio driver*/
int SdioDriverInit(struct SdioDriver *sdio_driver, const char *driver_name);
/*Release the sdio device*/
int SdioReleaseBus(struct SdioBus *sdio_bus);
/*Register the sdio driver to the sdio bus*/
int SdioDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int SdioDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType SdioDriverFind(const char *drv_name);
#ifdef __cplusplus
}
#endif
#endif
+112
View File
@@ -0,0 +1,112 @@
/*
* 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 bus_serial.h
* @brief define serial bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_SERIAL_H
#define BUS_SERIAL_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
enum ExtSerialPortConfigure
{
PORT_CFG_INIT = 0,
PORT_CFG_PARITY_CHECK,
PORT_CFG_DISABLE,
PORT_CFG_DIV,
};
struct SerialDataCfg
{
uint32 serial_baud_rate;
uint8 serial_data_bits;
uint8 serial_stop_bits;
uint8 serial_parity_mode;
uint8 serial_bit_order;
uint8 serial_invert_mode;
uint16 serial_buffer_size;
uint8 ext_uart_no;
enum ExtSerialPortConfigure port_configure;
};
struct SerialHwCfg
{
uint32 serial_register_base;
uint32 serial_irq_interrupt;
void *private_data;
};
struct SerialCfgParam
{
struct SerialDataCfg data_cfg;
struct SerialHwCfg hw_cfg;
};
struct SerialDriver;
struct SerialDrvDone
{
uint32 (*init) (struct SerialDriver *serial_drv, struct BusConfigureInfo *configure_info);
uint32 (*configure) (struct SerialDriver *serial_drv, int serial_operation_cmd);
};
struct SerialDriver
{
struct Driver driver;
const struct SerialDrvDone *drv_done;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
void *private_data;
};
struct SerialBus
{
struct Bus bus;
void *private_data;
};
/*Register the serial bus*/
int SerialBusInit(struct SerialBus *serial_bus, const char *bus_name);
/*Register the serial driver*/
int SerialDriverInit(struct SerialDriver *serial_driver, const char *driver_name);
/*Release the serial bus*/
int SerialReleaseBus(struct SerialBus *serial_bus);
/*Register the serial driver to the serial bus*/
int SerialDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int SerialDriverRegister(struct Driver *driver);
/*Find the regiter driver*/
DriverType SerialDriverFind(const char *drv_name, enum DriverType drv_type);
#ifdef __cplusplus
}
#endif
#endif
+66
View File
@@ -0,0 +1,66 @@
/*
* 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 bus_spi.h
* @brief define spi bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_SPI_H
#define BUS_SPI_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct SpiDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
};
struct SpiBus
{
struct Bus bus;
void *private_data;
};
/*Register the spi bus*/
int SpiBusInit(struct SpiBus *spi_bus, const char *bus_name);
/*Register the spi driver*/
int SpiDriverInit(struct SpiDriver *spi_driver, const char *driver_name);
/*Release the spi device*/
int SpiReleaseBus(struct SpiBus *spi_bus);
/*Register the spi driver to the spi bus*/
int SpiDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int SpiDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType SpiDriverFind(const char *drv_name, enum DriverType drv_type);
#ifdef __cplusplus
}
#endif
#endif
+65
View File
@@ -0,0 +1,65 @@
/*
* 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 bus_touch.h
* @brief define touch bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_TOUCH_H
#define BUS_TOUCH_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct TouchDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
};
struct TouchBus
{
struct Bus bus;
void *private_data;
};
/*Register the touch bus*/
int TouchBusInit(struct TouchBus *touch_bus, const char *bus_name);
/*Register the touch driver*/
int TouchDriverInit(struct TouchDriver *touch_driver, const char *driver_name);
/*Release the touch device*/
int TouchReleaseBus(struct TouchBus *touch_bus);
/*Register the touch driver to the touch bus*/
int TouchDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int TouchDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType TouchDriverFind(const char *drv_name, enum DriverType drv_type);
#ifdef __cplusplus
}
#endif
#endif
+68
View File
@@ -0,0 +1,68 @@
/*
* 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 bus_usb.h
* @brief define usb bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_USB_H
#define BUS_USB_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct UsbDriver
{
struct Driver driver;
uint32 (*configure)(void *drv, struct BusConfigureInfo *configure_info);
void *private_data;
};
struct UsbBus
{
struct Bus bus;
void *private_data;
};
/*Register the USB bus*/
int UsbBusInit(struct UsbBus *usb_bus, const char *bus_name);
/*Register the USB driver*/
int UsbDriverInit(struct UsbDriver *usb_driver, const char *driver_name);
/*Release the USB device*/
int UsbReleaseBus(struct UsbBus *usb_bus);
/*Register the USB driver to the USB bus*/
int UsbDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int UsbDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType UsbDriverFind(const char *drv_name, enum DriverType drv_type);
#ifdef __cplusplus
}
#endif
#endif
+66
View File
@@ -0,0 +1,66 @@
/*
* 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 bus_wdt.h
* @brief define wdt bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef BUS_WDT_H
#define BUS_WDT_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct WdtDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *ConfigureInfo);
void *private_data;
};
struct WdtBus
{
struct Bus bus;
void *private_data;
};
/*Register the wdt bus*/
int WdtBusInit(struct WdtBus *wdt_bus, const char *bus_name);
/*Register the wdt driver*/
int WdtDriverInit(struct WdtDriver *wdt_driver, const char *driver_name);
/*Release the wdt device*/
int WdtReleaseBus(struct WdtBus *wdt_bus);
/*Register the wdt driver to the wdt bus*/
int WdtDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int WdtDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType WdtDriverFind(const char *drv_name);
#ifdef __cplusplus
}
#endif
#endif
+79
View File
@@ -0,0 +1,79 @@
/*
* 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 dev_can.h
* @brief define can dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_CAN_H
#define DEV_CAN_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct CanDriverConfigure
{
uint8 tsjw;
uint8 tbs2 ;
uint8 tbs1;
uint8 mode;
uint16 brp;
};
struct CanSendConfigure
{
uint32 stdid;
uint32 exdid;
uint8 ide;
uint8 rtr;
uint8 data_lenth;
uint8 *data;
};
struct CanDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev,struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct CanHardwareDevice
{
struct HardwareDev haldev;
const struct CanDevDone *dev_done;
void *private_data;
};
/*Register the CAN device*/
int CanDeviceRegister(struct CanHardwareDevice *can_device, void *can_param, const char *device_name);
/*Register the CAN device to the CAN bus*/
int CanDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register CAN device*/
HardwareDevType CanDeviceFind(const char *dev_name, enum DevType dev_type);
#ifdef __cplusplus
}
#endif
#endif
+74
View File
@@ -0,0 +1,74 @@
/*
* 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 dev_hwtimer.h
* @brief define hwtimer dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_HWTIMER_H
#define DEV_HWTIMER_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct HwtimerCallBackInfo
{
void (*TimeoutCb) (void* param);
void *param;
};
struct HwtimerDeviceParam
{
uint32 period_millisecond;
uint32 repeat;
struct HwtimerCallBackInfo cb_info;
};
struct HwtimerDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev,struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct HwtimerHardwareDevice
{
struct HardwareDev haldev;
struct HwtimerDeviceParam hwtimer_param;
const struct HwtimerDevDone *dev_done;
void *private_data;
};
/*Register the hwtimer device*/
int HwtimerDeviceRegister(struct HwtimerHardwareDevice *hwtimer_device, void *hwtimer_param, const char *device_name);
/*Register the hwtimer device to the hwtimer bus*/
int HwtimerDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register hwtimer device*/
HardwareDevType HwtimerDeviceFind(const char *dev_name);
#ifdef __cplusplus
}
#endif
#endif
+80
View File
@@ -0,0 +1,80 @@
/*
* 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 dev_i2c.h
* @brief define i2c dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_I2C_H
#define DEV_I2C_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
#define I2C_SLAVE_ADDR 0x44
#define I2C_WR 0x0000
#define I2C_RD (1u << 0)
#define I2C_ADDR_10BIT (1u << 2)
#define I2C_NO_START (1u << 4)
#define I2C_IGNORE_NACK (1u << 5)
#define I2C_NO_READ_ACK (1u << 6)
struct I2cDataStandard
{
uint16 addr;
uint16 flags;
uint16 len;
uint16 retries;
uint8 *buf;
struct I2cDataStandard *next;
};
struct I2cHardwareDevice;
struct I2cDevDone
{
uint32 (*open) (struct I2cHardwareDevice *i2c_device);
uint32 (*close) (struct I2cHardwareDevice *i2c_device);
uint32 (*write) (struct I2cHardwareDevice *i2c_device, struct I2cDataStandard *msg);
uint32 (*read) (struct I2cHardwareDevice *i2c_device, struct I2cDataStandard *msg);
};
struct I2cHardwareDevice
{
struct HardwareDev haldev;
const struct I2cDevDone *i2c_dev_done;
void *private_data;
};
/*Register the I2C device*/
int I2cDeviceRegister(struct I2cHardwareDevice *i2c_device, void *i2c_param, const char *device_name);
/*Register the I2C device to the I2C bus*/
int I2cDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register I2C device*/
HardwareDevType I2cDeviceFind(const char *dev_name, enum DevType dev_type);
#ifdef __cplusplus
}
#endif
#endif
+97
View File
@@ -0,0 +1,97 @@
/*
* 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 dev_lcd.h
* @brief define lcd dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_LCD_H
#define DEV_LCD_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
/*set the pen color*/
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0xF81F
#define GRED 0xFFE0
#define GBLUE 0x07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0xBC40
#define BRRED 0xFC07
#define GRAY 0x8430
#define DARKBLUE 0x01CF//Navy blue
#define LIGHTBLUE 0x7D7C//Light blue
#define GRAYBLUE 0x5458//Gray blue
#define LIGHTGREEN 0x841F
#define LGRAY 0xC618
#define LGRAYBLUE 0xA651
#define LBBLUE 0x2B12
typedef struct
{
uint16 x_pos;
uint16 y_pos;
uint16 width;
uint16 height;
uint8 font_size;
uint8 *addr;
uint16 font_color;
uint16 back_color;
}LcdStringParam;
struct LcdDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct LcdHardwareDevice
{
struct HardwareDev haldev;
const struct LcdDevDone *dev_done;
void *private_data;
};
/*Register the lcd device*/
int LcdDeviceRegister(struct LcdHardwareDevice *lcd_device, void *lcd_param, const char *device_name);
/*Register the lcd device to the lcd bus*/
int LcdDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register lcd device*/
HardwareDevType LcdDeviceFind(const char *dev_name, enum DevType dev_type);
#ifdef __cplusplus
}
#endif
#endif
+111
View File
@@ -0,0 +1,111 @@
/*
* 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 dev_pin.h
* @brief define pin dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_PIN_H
#define DEV_PIN_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
#define GPIO_LOW 0x00
#define GPIO_HIGH 0x01
#define GPIO_CFG_OUTPUT 0x00
#define GPIO_CFG_INPUT 0x01
#define GPIO_CFG_INPUT_PULLUP 0x02
#define GPIO_CFG_INPUT_PULLDOWN 0x03
#define GPIO_CFG_OUTPUT_OD 0x04
#define GPIO_IRQ_EDGE_RISING 0x00
#define GPIO_IRQ_EDGE_FALLING 0x01
#define GPIO_IRQ_EDGE_BOTH 0x02
#define GPIO_IRQ_LEVEL_HIGH 0x03
#define GPIO_IRQ_LEVEL_LOW 0x04
#define GPIO_CONFIG_MODE 0xffffffff
#define GPIO_IRQ_REGISTER 0xfffffffe
#define GPIO_IRQ_FREE 0xfffffffd
#define GPIO_IRQ_DISABLE 0xfffffffc
#define GPIO_IRQ_ENABLE 0xfffffffb
struct PinDevIrq
{
int irq_mode;//< RISING/FALLING/HIGH/LOW
void (*hdr) (void *args);//< callback function
void *args;//< the params of callback function
};
struct PinParam
{
int cmd;//< cmd:GPIO_CONFIG_MODE/GPIO_IRQ_REGISTER/GPIO_IRQ_FREE/GPIO_IRQ_DISABLE/GPIO_IRQ_ENABLE
x_base pin;//< pin number
int mode;//< pin mode: input/output
struct PinDevIrq irq_set;//< pin irq set
uint64 arg;
};
struct PinStat
{
x_base pin;//< pin number
uint16 val;//< pin level
};
struct PinIrqHdr
{
int16 pin;
uint16 mode;
void (*hdr) (void *args);
void *args;
};
struct PinDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct PinHardwareDevice
{
struct HardwareDev haldev;
const struct PinDevDone *dev_done;
void *private_data;
};
/*Register the Pin device*/
int PinDeviceRegister(struct PinHardwareDevice *pin_device, void *pin_param, const char *device_name);
/*Register the Pin Device to the Pin bus*/
int PinDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register Pin device*/
HardwareDevType PinDeviceFind(const char *dev_name, enum DevType dev_type);
#ifdef __cplusplus
}
#endif
#endif
+60
View File
@@ -0,0 +1,60 @@
/*
* 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 dev_rtc.h
* @brief define rtc dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_RTC_H
#define DEV_RTC_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct RtcDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *datacfg);
uint32 (*read) (void *dev, struct BusBlockReadParam *datacfg);
};
struct RtcHardwareDevice
{
struct HardwareDev haldev;
const struct RtcDevDone *dev_done;
void *private_data;
};
/*Register the rtc device*/
int RtcDeviceRegister(struct RtcHardwareDevice *rtc_device, void *rtc_param, const char *device_name);
/*Register the rtc device to the rtc bus*/
int RtcDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register rtc device*/
HardwareDevType RtcDeviceFind(const char *dev_name, enum DevType dev_type);
#ifdef __cplusplus
}
#endif
#endif
+60
View File
@@ -0,0 +1,60 @@
/*
* 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 dev_sdio.h
* @brief define sdio dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_SDIO_H
#define DEV_SDIO_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct SdioDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct SdioHardwareDevice
{
struct HardwareDev haldev;
struct SdioDevDone *dev_done;
void *private_data;
};
/*Register the sdio device*/
int SdioDeviceRegister(struct SdioHardwareDevice *sdio_device, const char *device_name);
/*Register the sdio device to the sdio bus*/
int SdioDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register sdio device*/
HardwareDevType SdioDeviceFind(const char *dev_name);
#ifdef __cplusplus
}
#endif
#endif
+157
View File
@@ -0,0 +1,157 @@
/*
* 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 dev_serial.h
* @brief define serial dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_SERIAL_H
#define DEV_SERIAL_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
#define BAUD_RATE_2400 2400
#define BAUD_RATE_4800 4800
#define BAUD_RATE_9600 9600
#define BAUD_RATE_19200 19200
#define BAUD_RATE_38400 38400
#define BAUD_RATE_57600 57600
#define BAUD_RATE_115200 115200
#define BAUD_RATE_230400 230400
#define BAUD_RATE_460800 460800
#define BAUD_RATE_921600 921600
#define BAUD_RATE_2000000 2000000
#define BAUD_RATE_3000000 3000000
#define DATA_BITS_5 5
#define DATA_BITS_6 6
#define DATA_BITS_7 7
#define DATA_BITS_8 8
#define DATA_BITS_9 9
#define STOP_BITS_1 1
#define STOP_BITS_2 2
#define STOP_BITS_3 3
#define STOP_BITS_4 4
#define PARITY_NONE 1
#define PARITY_ODD 2
#define PARITY_EVEN 3
#define BIT_ORDER_LSB 1
#define BIT_ORDER_MSB 2
#define NRZ_NORMAL 1
#define NRZ_INVERTED 2
#ifndef SERIAL_RB_BUFSZ
#define SERIAL_RB_BUFSZ 128
#endif
#define SERIAL_EVENT_RX_IND 0x01
#define SERIAL_event_id_tX_DONE 0x02
#define SERIAL_EVENT_RX_DMADONE 0x03
#define SERIAL_event_id_tX_DMADONE 0x04
#define SERIAL_EVENT_RX_TIMEOUT 0x05
#define SERIAL_DMA_RX 0x01
#define SERIAL_DMA_TX 0x02
struct SerialTx
{
int32 serial_txfifo_sem;
x_bool serial_dma_enable;
queue serial_dma_queue;
};
struct SerialRx
{
uint8 *serial_rx_buffer;
uint16 serial_send_num;
uint16 serial_recv_num;
x_bool serial_rx_full;
x_bool serial_dma_enable;
};
struct SerialDataTransferParam
{
struct SerialTx *serial_tx;
struct SerialRx *serial_rx;
};
struct SerialDevParam
{
uint8 ext_uart_no;
uint16 serial_work_mode;
uint16 serial_set_mode;
uint16 serial_stream_mode;
};
struct SerialHardwareDevice;
struct SerialHwDevDone
{
int (*put_char) (struct SerialHardwareDevice *serial_dev, char c);
int (*get_char) (struct SerialHardwareDevice *serial_dev);
int (*dmatransfer) (struct SerialHardwareDevice *serial_dev, uint8 *buf, x_size_t size, int direction);
};
struct SerialDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *datacfg);
uint32 (*read) (void *dev, struct BusBlockReadParam *datacfg);
};
struct SerialHardwareDevice
{
struct HardwareDev haldev;
struct SerialHwDevDone *hwdev_done;
struct SerialDataTransferParam serial_fifo;
uint32 ext_serial_mode;
const struct SerialDevDone *dev_done;
void *private_data;
};
/*Register the serial device*/
int SerialDeviceRegister(struct SerialHardwareDevice *serial_device, void *serial_param, const char *device_name);
/*Register the serial device to the serial bus*/
int SerialDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register serial device*/
HardwareDevType SerialDeviceFind(const char *dev_name, enum DevType dev_type);
/*Set serial isr function*/
void SerialSetIsr(struct SerialHardwareDevice *serial_dev, int event);
#ifdef __cplusplus
}
#endif
#endif
+139
View File
@@ -0,0 +1,139 @@
/*
* 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 dev_spi.h
* @brief define spi dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_SPI_H
#define DEV_SPI_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SPI_MAX_CLOCK 40000000
#define spi_device_max_num 4
#define SPI_LINE_CPHA (1<<0)
#define SPI_LINE_CPOL (1<<1)
#define SPI_LSB (0<<2)
#define SPI_MSB (1<<2)
#define SPI_MASTER (0<<3)
#define DEV_SPI_SLAVE (1<<3)
#define SPI_MODE_0 (0 | 0)
#define SPI_MODE_1 (0 | SPI_LINE_CPHA)
#define SPI_MODE_2 (SPI_LINE_CPOL | 0)
#define SPI_MODE_3 (SPI_LINE_CPOL | SPI_LINE_CPHA)
#define SPI_MODE_MASK (SPI_LINE_CPHA | SPI_LINE_CPOL | SPI_MSB)
#define SPI_CS_HIGH (1<<4)
#define SPI_NO_CS (1<<5)
#define SPI_3WIRE (1<<6)
#define SPI_READY (1<<7)
struct SpiDataStandard
{
uint8 spi_chip_select;
uint8 spi_cs_release;
const uint8 *tx_buff;
uint32 tx_len;
const uint8 *rx_buff;
uint32 rx_len;
uint32 length;
struct SpiDataStandard *next;
};
struct SpiMasterParam
{
uint8 spi_work_mode;//CPOL CPHA
uint8 spi_frame_format;//frame format
uint8 spi_data_bit_width;//bit width
uint8 spi_data_endian;//little endian0big endian1
uint32 spi_maxfrequency;//work frequency
};
struct SpiDmaParam
{
uint8 spi_master_id;
uint8 spi_dmac_txchannel;
uint8 spi_dmac_rxchannel;
};
struct SpiSlaveParam
{
uint8 spi_slave_id;
uint8 spi_cs_gpio_pin;
uint8 spi_cs_select_id;
};
typedef struct
{
struct SpiDmaParam *spi_dma_param;
struct SpiSlaveParam *spi_slave_param;
struct SpiMasterParam *spi_master_param;
}SpiDeviceParam;
struct SpiHardwareDevice;
struct SpiDevDone
{
uint32 (*open) (struct SpiHardwareDevice *dev);
uint32 (*close) (struct SpiHardwareDevice *dev);
uint32 (*write) (struct SpiHardwareDevice *dev, struct SpiDataStandard *msg);
uint32 (*read) (struct SpiHardwareDevice *dev, struct SpiDataStandard *msg);
};
struct SpiHardwareDevice
{
struct HardwareDev haldev;
SpiDeviceParam spi_param;
x_bool spi_dev_flag;
const struct SpiDevDone *spi_dev_done;
void *private_data;
};
/*Register the spi device*/
int SpiDeviceRegister(struct SpiHardwareDevice *spi_device, void *spi_param, const char *device_name);
/*Register the spi device to the spi bus*/
int SpiDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register spi device*/
HardwareDevType SpiDeviceFind(const char *dev_name, enum DevType dev_type);
/*Configure the cs pin of spi dev*/
int SpiDevConfigureCs(struct HardwareDev *dev, uint8 spi_chip_select, uint8 spi_cs_release);
#ifdef __cplusplus
}
#endif
#endif
+66
View File
@@ -0,0 +1,66 @@
/*
* 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 dev_touch.h
* @brief define touch dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_TOUCH_H
#define DEV_TOUCH_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct TouchDataStandard
{
uint16 x;
uint16 y;
};
struct TouchDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev,struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct TouchHardwareDevice
{
struct HardwareDev haldev;
const struct TouchDevDone *dev_done;
void *private_data;
};
/*Register the touch device*/
int TouchDeviceRegister(struct TouchHardwareDevice *touch_device, void *touch_param, const char *device_name);
/*Register the touch device to the touch bus*/
int TouchDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register touch device*/
HardwareDevType TouchDeviceFind(const char *dev_name, enum DevType dev_type);
#ifdef __cplusplus
}
#endif
#endif
+62
View File
@@ -0,0 +1,62 @@
/*
* 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 dev_usb.h
* @brief define usb dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_USB_H
#define DEV_USB_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
#define UDISK_USB_BUS_NAME USB_BUS_NAME
#define UDISK_USB_DEVICE_NAME USB_DEVICE_NAME
struct UsbDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct UsbHardwareDevice
{
struct HardwareDev haldev;
const struct UsbDevDone *dev_done;
void *private_data;
};
/*Register the USB device*/
int USBDeviceRegister(struct UsbHardwareDevice *usb_device, void *usb_param, const char *device_name);
/*Register the USB device to the USB bus*/
int USBDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register USB device*/
HardwareDevType USBDeviceFind(const char *dev_name, enum DevType dev_type);
#ifdef __cplusplus
}
#endif
#endif
+60
View File
@@ -0,0 +1,60 @@
/*
* 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 dev_wdt.h
* @brief define wdt dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEV_WDT_H
#define DEV_WDT_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct WdtDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct WdtHardwareDevice
{
struct HardwareDev haldev;
const struct WdtDevDone *dev_done;
void *private_data;
};
/*Register the wdt device*/
int WdtDeviceRegister(struct WdtHardwareDevice *wdt_device, const char *device_name);
/*Register the wdt device to the wdt bus*/
int WdtDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register wdt device*/
HardwareDevType WdtDeviceFind(const char *dev_name);
#ifdef __cplusplus
}
#endif
#endif
+97
View File
@@ -0,0 +1,97 @@
/*
* 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 device.h
* @brief support to include RESOURCES of all drivers
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef DEVICE_H
#define DEVICE_H
#include <xiuos.h>
#include <xs_avltree.h>
#include <xs_circular_area.h>
#include <xs_dataqueue.h>
#include <xs_workqueue.h>
#include <xs_waitqueue.h>
#ifdef RESOURCES_RTC
#include <bus_rtc.h>
#include <dev_rtc.h>
#endif
#ifdef RESOURCES_SPI
#include <bus_spi.h>
#include <dev_spi.h>
#endif
#ifdef RESOURCES_TOUCH
#include <bus_touch.h>
#include <dev_touch.h>
#endif
#ifdef RESOURCES_LCD
#include <bus_lcd.h>
#include <dev_lcd.h>
#endif
#ifdef RESOURCES_USB
#include <bus_usb.h>
#include <dev_usb.h>
#ifdef RESOURCES_USB_HOST
#include <usb_host.h>
#endif
#endif
#ifdef RESOURCES_SERIAL
#include <bus_serial.h>
#include <dev_serial.h>
HardwareDevType InstallConsole(const char *bus_name, const char *drv_name, const char *dev_name);
HardwareDevType ObtainConsole(void);
#endif
#ifdef RESOURCES_I2C
#include <bus_i2c.h>
#include <dev_i2c.h>
#endif
#ifdef RESOURCES_WDT
#include <bus_wdt.h>
#include <dev_wdt.h>
#endif
#ifdef RESOURCES_SDIO
#include <bus_sdio.h>
#include <dev_sdio.h>
#endif
#ifdef RESOURCES_PIN
#include <bus_pin.h>
#include <dev_pin.h>
#endif
#ifdef RESOURCES_CAN
#include <bus_can.h>
#include <dev_can.h>
#endif
#ifdef RESOURCES_HWTIMER
#include <bus_hwtimer.h>
#include <dev_hwtimer.h>
#endif
#endif
+40
View File
@@ -0,0 +1,40 @@
/*
* 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 flash_spi.h
* @brief define spi-flash dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef FLASH_SPI_H
#define FLASH_SPI_H
#include <sfud_port.h>
#ifdef __cplusplus
extern "C" {
#endif
SpiFlashDeviceType SpiFlashInit(char *bus_name, char *dev_name, char *drv_name, char *flash_name);
uint32 SpiFlashRelease(SpiFlashDeviceType spi_flash_dev);
sfud_flash_t SpiFlashFind(char *flash_name);
#ifdef __cplusplus
}
#endif
#endif
+155
View File
@@ -0,0 +1,155 @@
/*
* 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 sd_spi.h
* @brief define spi-sd dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef SD_SPI_H
#define SD_SPI_H
#include <bus_spi.h>
#include <dev_spi.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SPI_SD_FREQUENCY 400000
#define SPI_SD_TIMEOUT_NUM 100
#define SD_CMD_RESPONE_LENGTH 5
#define SD_CMD_CSD_LENGTH 16
#define SD_BLOCK_LENGTH 512
#define SD_TIMEOUT(cnt, time) \
do \
{ \
cnt++; \
if(cnt >= time) \
{ \
KPrintf("SD_TMEOUT %s %d\n", __FUNCTION__, __LINE__); \
return ETIMEOUT; \
} \
}while(0)
typedef struct SpiSdDevice *SpiSdDeviceType;
typedef enum
{
SD_CMD_0 = 0,
SD_CMD_1,
SD_CMD_8 = 8,
SD_CMD_9,
SD_CMD_12 = 12,
SD_CMD_16 = 16,
SD_CMD_17,
SD_CMD_18,
SD_ACMD_23 = 23,
SD_CMD_24,
SD_CMD_25,
SD_ACMD_41 = 41,
SD_CMD_55 = 55,
SD_CMD_58 = 58,
}SdCmd;
typedef enum
{
SD_Respone_1 = 1,
SD_Respone_1b,
SD_Respone_2,
SD_Respone_3,
SD_Respone_7,
}SdRespone;
struct SdCmdParam
{
SdCmd sd_cmd_type;
uint8 sd_cmd_crc;
uint32 sd_cmd_args;
SdRespone sd_respone_type;
uint8 sd_respone_data[SD_CMD_RESPONE_LENGTH];
};
struct SdRespone1
{
uint8 sd_respone_r1;
};
struct SdRespone2
{
uint16 sd_respone_r2;
};
typedef enum
{
SD_TYPE_UNKNOW = 0,
SD_TYPE_MMC,
SD_TYPE_V1,
SD_TYPE_V2,
SD_TYPE_SDHC,
SD_TYPE_SDXC,
}SdType;
struct BlockDevParam
{
uint32 sector_num;
uint32 sector_bytes;
uint32 block_size;
};
struct CSDRegData
{
uint8 sd_csd_data[SD_CMD_CSD_LENGTH];
uint8 sd_csd_structure;
uint32 sd_csd_csize;
uint8 sd_csd_csize_multi;
uint8 sd_csd_readbl_len;
uint8 sd_csd_transpeed;
uint8 sd_csd_sectorsize;
uint32 sd_csd_capacity;
};
struct SdDevParam
{
SdType sd_type;
uint32 sd_spi_maxfreq;
struct BlockDevParam block_param;
struct CSDRegData csd_data;
};
struct SdDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct SpiSdDevice
{
struct SpiHardwareDevice *spi_dev;
struct SdDevParam sd_param;
struct SpiHardwareDevice sd_dev;
};
SpiSdDeviceType SpiSdInit(struct Bus *bus, const char *dev_name, const char *drv_name, const char *sd_name);
#ifdef __cplusplus
}
#endif
#endif
+574
View File
@@ -0,0 +1,574 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-10-01 Yi Qiu first version
* 2013-04-26 aozima add DEVICEQUALIFIER support.
* 2017-11-15 ZYH fix ep0 transform error
*/
/**
* @file usb_common.h
* @brief define usb function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: usb_common.h
Description: define usb function and common struct
Others: take RT-Thread v4.0.2/components/drivers/include/drivers/usb_common.h for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. define usb common configure, function and struct
2. support bus driver framework
*************************************************/
#ifndef USB_COMMON_H
#define USB_COMMON_H
#include <xiuos.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SYS_DEBUG_USB 0x00
#define USB_DYNAMIC 0x00
#define USB_CLASS_DEVICE 0x00
#define USB_CLASS_AUDIO 0x01
#define USB_CLASS_CDC 0x02
#define USB_CLASS_HID 0x03
#define USB_CLASS_PHYSICAL 0x05
#define USB_CLASS_IMAGE 0x06
#define USB_CLASS_PRINTER 0x07
#define USB_CLASS_MASS_STORAGE 0x08
#define USB_CLASS_HUB 0x09
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_SMART_CARD 0x0b
#define USB_CLASS_SECURITY 0x0d
#define USB_CLASS_VIDEO 0x0e
#define USB_CLASS_HEALTHCARE 0x0f
#define USB_CLASS_DIAG_DEVICE 0xdc
#define USB_CLASS_WIRELESS 0xe0
#define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPECIFIC 0xfe
#define USB_CLASS_VEND_SPECIFIC 0xff
#define USB_DESC_TYPE_DEVICE 0x01
#define USB_DESC_TYPE_CONFIGURATION 0x02
#define USB_DESC_TYPE_STRING 0x03
#define USB_DESC_TYPE_INTERFACE 0x04
#define USB_DESC_TYPE_ENDPOINT 0x05
#define USB_DESC_TYPE_DEVICEQUALIFIER 0x06
#define USB_DESC_TYPE_OTHERSPEED 0x07
#define USB_DESC_TYPE_IAD 0x0b
#define USB_DESC_TYPE_HID 0x21
#define USB_DESC_TYPE_REPORT 0x22
#define USB_DESC_TYPE_PHYSICAL 0x23
#define USB_DESC_TYPE_HUB 0x29
#define USB_DESC_LENGTH_DEVICE 0x12
#define USB_DESC_LENGTH_CONFIG 0x9
#define USB_DESC_LENGTH_IAD 0x8
#define USB_DESC_LENGTH_STRING 0x4
#define USB_DESC_LENGTH_INTERFACE 0x9
#define USB_DESC_LENGTH_ENDPOINT 0x7
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_MASK 0x60
#define USB_REQ_TYPE_DIR_OUT 0x00
#define USB_REQ_TYPE_DIR_IN 0x80
#define USB_REQ_TYPE_DEVICE 0x00
#define USB_REQ_TYPE_INTERFACE 0x01
#define USB_REQ_TYPE_ENDPOINT 0x02
#define USB_REQ_TYPE_OTHER 0x03
#define USB_REQ_TYPE_RECIPIENT_MASK 0x1f
#define USB_FEATURE_ENDPOINT_HALT 0x00
#define USB_FEATURE_DEV_REMOTE_WAKEUP 0x01
#define USB_FEATURE_TEST_MODE 0x02
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_REQ_SET_ENCRYPTION 0x0D
#define USB_REQ_GET_ENCRYPTION 0x0E
#define USB_REQ_RPIPE_ABORT 0x0E
#define USB_REQ_SET_HANDSHAKE 0x0F
#define USB_REQ_RPIPE_RESET 0x0F
#define USB_REQ_GET_HANDSHAKE 0x10
#define USB_REQ_SET_CONNECTION 0x11
#define USB_REQ_SET_SECURITY_DATA 0x12
#define USB_REQ_GET_SECURITY_DATA 0x13
#define USB_REQ_SET_WUSB_DATA 0x14
#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
#define USB_REQ_LOOPBACK_DATA_READ 0x16
#define USB_REQ_SET_INTERFACE_DS 0x17
#define USB_STRING_LANGID_INDEX 0x00
#define USB_STRING_MANU_INDEX 0x01
#define USB_STRING_PRODUCT_INDEX 0x02
#define USB_STRING_SERIAL_INDEX 0x03
#define USB_STRING_CONFIG_INDEX 0x04
#define USB_STRING_INTERFACE_INDEX 0x05
#define USB_STRING_OS_INDEX 0x06
#define USB_STRING_MAX USB_STRING_OS_INDEX
#define USB_STRING_OS "MSFT100A"
#define USB_PID_OUT 0x01
#define USB_PID_ACK 0x02
#define USB_PID_DATA0 0x03
#define USB_PID_SOF 0x05
#define USB_PID_IN 0x09
#define USB_PID_NACK 0x0A
#define USB_PID_DATA1 0x0B
#define USB_PID_PRE 0x0C
#define USB_PID_SETUP 0x0D
#define USB_PID_STALL 0x0E
#define USB_EP_DESC_OUT 0x00
#define USB_EP_DESC_IN 0x80
#define USB_EP_DESC_NUM_MASK 0x0f
#define USB_EP_ATTR_CONTROL 0x00
#define USB_EP_ATTR_ISOC 0x01
#define USB_EP_ATTR_BULK 0x02
#define USB_EP_ATTR_INT 0x03
#define USB_EP_ATTR_TYPE_MASK 0x03
#define USB_EPNO_MASK 0x7f
#define USB_DIR_OUT 0x00
#define USB_DIR_IN 0x80
#define USB_DIR_INOUT 0x40
#define USB_DIR_MASK 0x80
#define ID_UNASSIGNED 0
#define ID_ASSIGNED 1
#define RH_GET_PORT_STATUS 0
#define RH_SET_PORT_STATUS 1
#define RH_CLEAR_PORT_FEATURE 2
#define RH_SET_PORT_FEATURE 3
#define USB_BUS_POWERED 0
#define USB_SELF_POWERED 1
#define USB_REMOTE_WAKEUP 1
#define USB_EP_HALT 0
#define PORT_FEAT_CONNECTION 0
#define PORT_FEAT_ENABLE 1
#define PORT_FEAT_SUSPEND 2
#define PORT_FEAT_OVER_CURRENT 3
#define PORT_FEAT_RESET 4
#define PORT_FEAT_POWER 8
#define PORT_FEAT_LOWSPEED 9
#define PORT_FEAT_HIGHSPEED 10
#define PORT_FEAT_C_CONNECTION 16
#define PORT_FEAT_C_ENABLE 17
#define PORT_FEAT_C_SUSPEND 18
#define PORT_FEAT_C_OVER_CURRENT 19
#define PORT_FEAT_C_RESET 20
#define PORT_CCS 0x00000001UL
#define PORT_PES 0x00000002UL
#define PORT_PSS 0x00000004UL
#define PORT_POCI 0x00000008UL
#define PORT_PRS 0x00000010UL
#define PORT_PPS 0x00000100UL
#define PORT_LSDA 0x00000200UL
#define PORT_CCSC 0x00010000UL
#define PORT_PESC 0x00020000UL
#define PORT_PSSC 0x00040000UL
#define PORT_POCIC 0x00080000UL
#define PORT_PRSC 0x00100000UL
#define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002
#define USB_EP_ATTR(attr) (attr & USB_EP_ATTR_TYPE_MASK)
#define USB_EP_DESC_NUM(addr) (addr & USB_EP_DESC_NUM_MASK)
#define USB_EP_DIR(addr) ((addr & USB_DIR_MASK)>>7)
#define HID_REPORT_ID_KEYBOARD1 1
#define HID_REPORT_ID_KEYBOARD2 2
#define HID_REPORT_ID_KEYBOARD3 3
#define HID_REPORT_ID_KEYBOARD4 7
#define HID_REPORT_ID_MEDIA 4
#define HID_REPORT_ID_GENERAL 5
#define HID_REPORT_ID_MOUSE 6
#ifndef USB_TIMEOUT_BASIC
#define USB_TIMEOUT_BASIC (TICK_PER_SECOND)
#endif
#ifndef USB_TIMEOUT_LONG
#define USB_TIMEOUT_LONG (TICK_PER_SECOND * 5)
#endif
#ifndef USB_DEBOUNCE_TIME
#define USB_DEBOUNCE_TIME (TICK_PER_SECOND / 5)
#endif
#define uswap_32(x) \
((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
#define Uswap8(x) \
(((uint16)(*((uint8 *)(x)))) + \
(((uint16)(*(((uint8 *)(x)) + 1))) << 8))
typedef void (*FuncCallback) (void *context);
typedef enum
{
USB_STATE_NOTATTACHED = 0,
USB_STATE_ATTACHED,
USB_STATE_POWERED,
USB_STATE_RECONNECTING,
USB_STATE_UNAUTHENTICATED,
USB_STATE_DEFAULT,
USB_STATE_ADDRESS,
USB_STATE_CONFIGURED,
USB_STATE_SUSPENDED
}UdeviceStatePointer;
typedef enum
{
STAGE_IDLE,
STAGE_SETUP,
STAGE_STATUS_IN,
STAGE_STATUS_OUT,
STAGE_DIN,
STAGE_DOUT
} Uep0StagePointer;
#pragma pack(1)
struct UsbDescriptor
{
uint8 bLength;
uint8 type;
};
typedef struct UsbDescriptor* UdescPointer;
struct UdeviceDescriptor
{
uint8 bLength;
uint8 type;
uint16 bcdUSB;
uint8 bDeviceClass;
uint8 bDeviceSubClass;
uint8 bDeviceProtocol;
uint8 bMaxPacketSize0;
uint16 idVendor;
uint16 idProduct;
uint16 bcdDevice;
uint8 iManufacturer;
uint8 iProduct;
uint8 iSerialNumber;
uint8 bNumConfigurations;
};
typedef struct UdeviceDescriptor* UdevDescPointer;
struct UconfigDescriptor
{
uint8 bLength;
uint8 type;
uint16 wTotalLength;
uint8 bNumInterfaces;
uint8 bConfigurationValue;
uint8 iConfiguration;
uint8 bmAttributes;
uint8 MaxPower;
uint8 data[256];
};
typedef struct UconfigDescriptor* UcfgDescPointer;
struct UinterfaceDescriptor
{
uint8 bLength;
uint8 type;
uint8 bInterfaceNumber;
uint8 bAlternateSetting;
uint8 bNumEndpoints;
uint8 bInterfaceClass;
uint8 bInterfaceSubClass;
uint8 bInterfaceProtocol;
uint8 iInterface;
};
typedef struct UinterfaceDescriptor* UintfDescPointer;
struct UiadDescriptor
{
uint8 bLength;
uint8 bDescriptorType;
uint8 bFirstInterface;
uint8 bInterfaceCount;
uint8 bFunctionClass;
uint8 bFunctionSubClass;
uint8 bFunctionProtocol;
uint8 iFunction;
};
typedef struct UiadDescriptor* UiadDescPointer;
struct UendpointDescriptor
{
uint8 bLength;
uint8 type;
uint8 bEndpointAddress;
uint8 bmAttributes;
uint16 wMaxPacketSize;
uint8 bInterval;
};
typedef struct UendpointDescriptor* UepDescPointer;
struct UstringDescriptor
{
uint8 bLength;
uint8 type;
uint8 String[64];
};
typedef struct UstringDescriptor* UstrDescPointer;
struct UhubDescriptor
{
uint8 length;
uint8 type;
uint8 NumPorts;
uint16 characteristics;
uint8 PwronToGood;
uint8 current;
uint8 removable[8];
uint8 PwrCtl[8];
};
typedef struct UhubDescriptor* UhubDescPointer;
struct UsbQualifierDescriptor
{
uint8 bLength;
uint8 bDescriptorType;
uint16 bcdUSB;
uint8 bDeviceClass;
uint8 bDeviceSubClass;
uint8 bDeviceProtocol;
uint8 bMaxPacketSize0;
uint8 bNumConfigurations;
uint8 bRESERVED;
} __attribute__ ((packed));
struct UsbOsHeaderCompIdDescriptor
{
uint32 dwLength;
uint16 bcdVersion;
uint16 wIndex;
uint8 bCount;
uint8 reserved[7];
};
typedef struct UsbOsHeaderCompIdDescriptor * UsbOsHeaderDescPointer;
struct UsbOsFunctionCompIdDescriptor
{
DoubleLinklistType list;
uint8 bFirstInterfaceNumber;
uint8 reserved1;
uint8 compatibleID[8];
uint8 subCompatibleID[8];
uint8 reserved2[6];
};
typedef struct UsbOsFunctionCompIdDescriptor * UsbOsFuncCompIdDescPointer;
struct UsbOsCompIdDescriptor
{
struct UsbOsHeaderCompIdDescriptor HeadDesc;
DoubleLinklistType FuncDesc;
};
typedef struct UsbOsCompIdDescriptor * UsbOsCompIdDescPointer;
struct UsbOsPropertyHeader
{
uint32 dwLength;
uint16 bcdVersion;
uint16 wIndex;
uint16 wCount;
};
typedef struct UsbOsPropertyHeader * UsbOsPropertyHeaderPointer;
struct UsbOsProerty
{
uint32 dwSize;
uint32 dwPropertyDataType;
uint16 wPropertyNameLength;
const char * bPropertyName;
uint32 dwPropertyDataLength;
const char * bPropertyData;
};
typedef struct UsbOsProerty * UsbOsProertyPointer;
#define USB_OS_PROERTY_TYPE_REG_SZ 0x01UL
#define USB_OS_PROERTY_TYPE_REG_EXPAND_SZ 0x02UL
#define USB_OS_PROERTY_TYPE_REG_BINARY 0x03UL
#define USB_OS_PROERTY_TYPE_REG_DWORD_LITTLE_ENDIAN 0x04UL
#define USB_OS_PROERTY_TYPE_REG_DWORD_BIG_ENDIAN 0x05UL
#define USB_OS_PROERTY_TYPE_REG_LINK 0x06UL
#define USB_OS_PROERTY_TYPE_REG_MULTI_SZ 0x07UL
#define USB_OS_PROERTY_DESC(PropertyDataType,PropertyName,PropertyData) \
{\
.dwSize = sizeof(struct UsbOsProerty)-sizeof(const char *)*2\
+sizeof(PropertyName)*2+sizeof(PropertyData)*2,\
.dwPropertyDataType = PropertyDataType,\
.wPropertyNameLength = sizeof(PropertyName)*2,\
.bPropertyName = PropertyName,\
.dwPropertyDataLength = sizeof(PropertyData)*2,\
.bPropertyData = PropertyData\
}
#ifndef HID_SUB_DESCRIPTOR_MAX
#define HID_SUB_DESCRIPTOR_MAX 1
#endif
struct UhidDescriptor
{
uint8 bLength;
uint8 type;
uint16 bcdHID;
uint8 bCountryCode;
uint8 bNumDescriptors;
struct HidDescriptorList
{
uint8 type;
uint16 wLength;
}Descriptor[HID_SUB_DESCRIPTOR_MAX];
};
typedef struct UhidDescriptor* UhidDescPointer;
struct HidReport
{
uint8 ReportId;
uint8 report[63];
uint8 size;
};
typedef struct HidReport* HidReportPointer;
extern void HIDReportReceived(HidReportPointer report);
struct urequest
{
uint8 RequestType;
uint8 bRequest;
uint16 wValue;
uint16 wIndex;
uint16 wLength;
};
typedef struct urequest* UreqPointer;
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#define USBREQ_GET_MAX_LUN 0xfe
#define USBREQ_MASS_STORAGE_RESET 0xff
#define SIZEOF_CSW 0x0d
#define SIZEOF_CBW 0x1f
#define SIZEOF_INQUIRY_CMD 0x24
#define SIZEOF_MODE_SENSE_6 0x4
#define SIZEOF_READ_CAPACITIES 0xc
#define SIZEOF_READ_CAPACITY 0x8
#define SIZEOF_REQUEST_SENSE 0x12
#define CBWFLAGS_DIR_M 0x80
#define CBWFLAGS_DIR_IN 0x80
#define CBWFLAGS_DIR_OUT 0x00
#define SCSI_TEST_UNIT_READY 0x00
#define SCSI_REQUEST_SENSE 0x03
#define SCSI_INQUIRY_CMD 0x12
#define SCSI_ALLOW_REMOVAL 0x1e
#define SCSI_MODE_SENSE_6 0x1a
#define SCSI_START_STOP 0x1b
#define SCSI_READ_CAPACITIES 0x23
#define SCSI_READ_CAPACITY 0x25
#define SCSI_READ_10 0x28
#define SCSI_WRITE_10 0x2a
#define SCSI_VERIFY_10 0x2f
#define CBW_SIGNATURE 0x43425355
#define CSW_SIGNATURE 0x53425355
#define CBW_TAG_VALUE 0x12345678
struct UstorageCbw
{
uint32 signature;
uint32 tag;
uint32 XferLen;
uint8 dflags;
uint8 lun;
uint8 CbLen;
uint8 cb[16];
};
typedef struct UstorageCbw* UstorageCbwPointer;
struct UstorageCsw
{
uint32 signature;
uint32 tag;
int32 DataReside;
uint8 status;
};
typedef struct UstorageCsw* UstorageCswPointer;
#pragma pack()
#ifndef USBD_THREAD_STACK_SZ
#define USBD_THREAD_STACK_SZ 512
#endif
#ifndef USBD_THREAD_PRIO
#define USBD_THREAD_PRIO 8
#endif
#ifdef __cplusplus
}
#endif
#endif
+283
View File
@@ -0,0 +1,283 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-3-12 Yi Qiu first version
*/
/**
* @file usb_host.h
* @brief define usb host function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: usb_host.h
Description: define usb host function and struct
Others: take RT-Thread v4.0.2/components/drivers/include/drivers/usb_host.h for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. define usb host configure, function and struct
2. support bus driver framework
*************************************************/
#ifndef USB_HOST_H
#define USB_HOST_H
#include <xiuos.h>
#include <usb_common.h>
#ifdef __cplusplus
extern "C" {
#endif
#define USB_MAX_DEVICE 0x20
#define USB_MAX_INTERFACE 0x08
#define USB_HUB_PORT_NUM 0x04
#define SIZEOF_USB_REQUEST 0x08
#define DEV_STATUS_IDLE 0x00
#define DEV_STATUS_BUSY 0x01
#define DEV_STATUS_ERROR 0x02
#define UPIPE_STATUS_OK 0x00
#define UPIPE_STATUS_STALL 0x01
#define UPIPE_STATUS_ERROR 0x02
#define USBH_PID_SETUP 0x00
#define USBH_PID_DATA 0x01
struct uhcd;
struct uhintf;
struct uhub;
struct upipe;
struct UclassDriver
{
DoubleLinklistType list;
int ClassCode;
int subclass_code;
x_err_t (*enable)(void* arg);
x_err_t (*disable)(void* arg);
void* UserData;
};
typedef struct UclassDriver* UcdPointer;
struct uprotocal
{
DoubleLinklistType list;
int ProId;
x_err_t (*init)(void* arg);
x_err_t (*callback)(void* arg);
};
typedef struct uprotocal* UprotocalPointer;
struct uinstance
{
struct UdeviceDescriptor DevDesc;
UcfgDescPointer CfgDesc;
struct uhcd *hcd;
struct upipe * PipeEp0Out;
struct upipe * PipeEp0In;
DoubleLinklistType pipe;
uint8 status;
uint8 type;
uint8 index;
uint8 address;
uint8 speed;
uint8 MaxPacketSize;
uint8 port;
struct uhub* parent_hub;
struct uhintf* intf[USB_MAX_INTERFACE];
};
typedef struct uinstance* UinstPointer;
struct uhintf
{
struct uinstance* device;
UintfDescPointer IntfDesc;
UcdPointer drv;
void *UserData;
};
struct upipe
{
DoubleLinklistType list;
uint8 pipe_index;
uint32 status;
struct UendpointDescriptor ep;
UinstPointer inst;
FuncCallback callback;
void* UserData;
};
typedef struct upipe* upipe_t;
struct uhub
{
struct UhubDescriptor HubDesc;
uint8 NumPorts;
uint32 PortStatus[USB_HUB_PORT_NUM];
struct uinstance* child[USB_HUB_PORT_NUM];
x_bool IsRoothub;
uint8 buffer[8];
struct uinstance* self;
struct uhcd *hcd;
};
typedef struct uhub* UhubPointer;
struct uhcd_ops
{
x_err_t (*reset_port) (uint8 port);
int (*pipe_xfer) (upipe_t pipe, uint8 token, void* buffer, int nbytes, int timeout);
x_err_t (*open_pipe) (upipe_t pipe);
x_err_t (*close_pipe) (upipe_t pipe);
};
typedef struct uhcd_ops* uhcd_ops_t;
struct uhcd
{
uhcd_ops_t ops;
uint8 NumPorts;
UhubPointer roothub;
};
typedef struct uhcd* UhcdPointer;
enum uhost_msg_type
{
USB_MSG_CONNECT_CHANGE,
USB_MSG_CALLBACK,
};
typedef enum uhost_msg_type uhost_msg_type;
struct UhostMsg
{
uhost_msg_type type;
union
{
struct uhub* hub;
struct
{
FuncCallback function;
void *context;
}cb;
}content;
};
typedef struct UhostMsg* uhost_msg_t;
/* usb host system interface */
x_err_t UsbHostInit(struct uhcd *hcd);
void UsbhHubInit(struct uhcd *hcd);
/* usb host core interface */
struct uinstance* UsbhAllocInstance(UhcdPointer uhcd);
x_err_t UsbhAttatchInstance(struct uinstance* device);
x_err_t UsbhDetachInstance(struct uinstance* device);
x_err_t UsbhGetDescriptor(struct uinstance* device, uint8 type, void* buffer, int nbytes);
x_err_t UsbhSetConfigure(struct uinstance* device, int config);
x_err_t UsbhSetAddress(struct uinstance* device);
x_err_t UsbhSetInterface(struct uinstance* device, int intf);
x_err_t UsbhClearFeature(struct uinstance* device, int endpoint, int feature);
x_err_t UsbhGetInterfaceDescriptor(UcfgDescPointer CfgDesc, int num, UintfDescPointer* IntfDesc);
x_err_t UsbhGetEndpointDescriptor(UintfDescPointer IntfDesc, int num, UepDescPointer* EpDesc);
/* usb class driver interface */
x_err_t UsbhClassDriverInit(void);
x_err_t UsbhClassDriverRegister(UcdPointer drv);
x_err_t UsbhClassDriverUnregister(UcdPointer drv);
x_err_t UsbhClassDriverEnable(UcdPointer drv, void* args);
x_err_t UsbhClassDriverDisable(UcdPointer drv, void* args);
UcdPointer UsbhClassDriverFind(int ClassCode, int subclass_code);
/* usb class driver implement */
UcdPointer UsbhClassDriverHub(void);
UcdPointer UsbhClassDriverStorage(void);
/* usb hub interface */
x_err_t UsbhHubGetDescriptor(struct uinstance* device, uint8 *buffer,
x_size_t size);
x_err_t UsbhHubGetStatus(struct uinstance* device, uint32* buffer);
x_err_t UsbhHubGetPortStatus(UhubPointer uhub, uint16 port,
uint32* buffer);
x_err_t UsbhHubClearPortFeature(UhubPointer uhub, uint16 port,
uint16 feature);
x_err_t UsbhHubSetPortFeature(UhubPointer uhub, uint16 port,
uint16 feature);
x_err_t UsbhHubResetPort(UhubPointer uhub, uint16 port);
x_err_t UsbhEventSignal(struct UhostMsg* msg);
void UsbhRootHubConnectHandler(struct uhcd *hcd, uint8 port, x_bool isHS);
void UsbhRootHubDisconnectHandler(struct uhcd *hcd, uint8 port);
/* usb host controller driver interface */
static __inline x_err_t usb_instance_add_pipe(UinstPointer inst, upipe_t pipe)
{
NULL_PARAM_CHECK(inst);
NULL_PARAM_CHECK(pipe);
DoubleLinkListInsertNodeBefore(&inst->pipe, &pipe->list);
return EOK;
}
static __inline upipe_t UsbInstanceFindPipe(UinstPointer inst,uint8 ep_address)
{
DoubleLinklistType * l;
for(l = inst->pipe.node_next;l != &inst->pipe;l = l->node_next)
{
if(SYS_DOUBLE_LINKLIST_ENTRY(l,struct upipe,list)->ep.bEndpointAddress == ep_address)
{
return SYS_DOUBLE_LINKLIST_ENTRY(l,struct upipe,list);
}
}
return NONE;
}
static __inline x_err_t UsbHcdAllocPipe(UhcdPointer hcd, upipe_t* pipe, UinstPointer inst, UepDescPointer ep)
{
*pipe = (upipe_t)x_malloc(sizeof(struct upipe));
if(*pipe == NONE)
{
return ERROR;
}
memset(*pipe,0,sizeof(struct upipe));
(*pipe)->inst = inst;
memcpy(&(*pipe)->ep,ep,sizeof(struct UendpointDescriptor));
return hcd->ops->open_pipe(*pipe);
}
static __inline void UsbPipeAddCallback(upipe_t pipe, FuncCallback callback)
{
pipe->callback = callback;
}
static __inline x_err_t UsbHcdFreePipe(UhcdPointer hcd, upipe_t pipe)
{
NULL_PARAM_CHECK(pipe);
hcd->ops->close_pipe(pipe);
x_free(pipe);
return EOK;
}
int UsbHcdPipeXfer(UhcdPointer hcd, upipe_t pipe, void* buffer, int nbytes, int timeout);
static __inline int UsbHcdSetupXfer(UhcdPointer hcd, upipe_t pipe, UreqPointer setup, int timeout)
{
return hcd->ops->pipe_xfer(pipe, USBH_PID_SETUP, (void *)setup, 8, timeout);
}
#ifdef __cplusplus
}
#endif
#endif
+5
View File
@@ -0,0 +1,5 @@
SRC_FILES += dev_lcd.c bus_lcd.c drv_lcd.c
include $(KERNEL_ROOT)/compiler.mk
+118
View File
@@ -0,0 +1,118 @@
/*
* 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 bus_lcd.c
* @brief register lcd bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_lcd.h>
#include <dev_lcd.h>
int LcdBusInit(struct LcdBus *lcd_bus, const char *bus_name)
{
NULL_PARAM_CHECK(lcd_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != lcd_bus->bus.bus_state) {
strncpy(lcd_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
lcd_bus->bus.bus_type = TYPE_LCD_BUS;
lcd_bus->bus.bus_state = BUS_INSTALL;
lcd_bus->bus.private_data = lcd_bus->private_data;
ret = BusRegister(&lcd_bus->bus);
if (EOK != ret) {
KPrintf("LCDBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("LCDBusInit BusRegister bus has been register state%u\n", lcd_bus->bus.bus_state);
}
return ret;
}
int LcdDriverInit(struct LcdDriver *lcd_driver, const char *driver_name)
{
NULL_PARAM_CHECK(lcd_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != lcd_driver->driver.driver_state) {
lcd_driver->driver.driver_type = TYPE_LCD_DRV;
lcd_driver->driver.driver_state = DRV_INSTALL;
strncpy(lcd_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
lcd_driver->driver.configure = lcd_driver->configure;
ret = LcdDriverRegister(&lcd_driver->driver);
if (EOK != ret) {
KPrintf("LcdDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("LcdDriverInit DriverRegister driver has been register state%u\n", lcd_driver->driver.driver_state);
}
return ret;
}
int LcdReleaseBus(struct LcdBus *lcd_bus)
{
NULL_PARAM_CHECK(lcd_bus);
return BusRelease(&lcd_bus->bus);
}
int LcdDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("LcdDriverAttachToBus find lcd bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_LCD_BUS == bus->bus_type) {
driver = LcdDriverFind(drv_name, TYPE_LCD_DRV);
if (NONE == driver) {
KPrintf("LcdDriverAttachToBus find lcd driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_LCD_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("LcdDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+115
View File
@@ -0,0 +1,115 @@
/*
* 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 dev_lcd.c
* @brief register lcd dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_lcd.h>
#include <dev_lcd.h>
static DoubleLinklistType lcddev_linklist;
/*Create the lcd device linklist*/
static void LcdDeviceLinkInit()
{
InitDoubleLinkList(&lcddev_linklist);
}
HardwareDevType LcdDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &lcddev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("LcdDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int LcdDeviceRegister(struct LcdHardwareDevice *lcd_device, void *lcd_param, const char *device_name)
{
NULL_PARAM_CHECK(lcd_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (!dev_link_flag) {
LcdDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != lcd_device->haldev.dev_state) {
strncpy(lcd_device->haldev.dev_name, device_name, NAME_NUM_MAX);
lcd_device->haldev.dev_type = TYPE_LCD_DEV;
lcd_device->haldev.dev_state = DEV_INSTALL;
lcd_device->haldev.dev_done = (struct HalDevDone *)lcd_device->dev_done;
lcd_device->haldev.private_data = lcd_param;
DoubleLinkListInsertNodeAfter(&lcddev_linklist, &(lcd_device->haldev.dev_link));
} else {
KPrintf("LcdDeviceRegister device has been register state%u\n", lcd_device->haldev.dev_state);
}
return ret;
}
int LcdDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("LcdDeviceAttachToBus find lcd bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_LCD_BUS == bus->bus_type) {
device = LcdDeviceFind(dev_name, TYPE_LCD_DEV);
if (NONE == device) {
KPrintf("LcdDeviceAttachToBus find lcd device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_LCD_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("LcdDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+67
View File
@@ -0,0 +1,67 @@
/*
* 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 drv_lcd.c
* @brief register lcd drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_lcd.h>
#include <dev_lcd.h>
static DoubleLinklistType lcddrv_linklist;
/*Create the driver linklist*/
static void LcdDrvLinkInit()
{
InitDoubleLinkList(&lcddrv_linklist);
}
DriverType LcdDriverFind(const char *drv_name, enum DriverType drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &lcddrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("LcdDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int LcdDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
LcdDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&lcddrv_linklist, &(driver->driver_link));
return ret;
}
+5
View File
@@ -0,0 +1,5 @@
SRC_FILES +=bus_pin.c dev_pin.c drv_pin.c
include $(KERNEL_ROOT)/compiler.mk
+143
View File
@@ -0,0 +1,143 @@
/*
* 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 bus_pin.c
* @brief register pin bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_pin.h>
#include <dev_pin.h>
int PinBusInit(struct PinBus *pin_bus, const char *bus_name)
{
NULL_PARAM_CHECK(pin_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != pin_bus->bus.bus_state) {
strncpy(pin_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
pin_bus->bus.bus_type = TYPE_PIN_BUS;
pin_bus->bus.bus_state = BUS_INSTALL;
pin_bus->bus.private_data = pin_bus->private_data;
ret = BusRegister(&pin_bus->bus);
if (EOK != ret) {
KPrintf("PinBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("PinBusInit BusRegister bus has been register state%u\n", pin_bus->bus.bus_state);
}
return ret;
}
int PinDriverInit(struct PinDriver *pin_driver, const char *driver_name, void *data)
{
NULL_PARAM_CHECK(pin_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != pin_driver->driver.driver_state) {
pin_driver->driver.driver_type = TYPE_PIN_DRV;
pin_driver->driver.driver_state = DRV_INSTALL;
strncpy(pin_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
pin_driver->driver.configure = pin_driver->configure;
pin_driver->driver.private_data = data;
ret = PinDriverRegister(&pin_driver->driver);
if (EOK != ret) {
KPrintf("PinDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("PinDriverInit DriverRegister driver has been register state%u\n", pin_driver->driver.driver_state);
}
return ret;
}
int PinReleaseBus(struct PinBus *pin_bus)
{
NULL_PARAM_CHECK(pin_bus);
return BusRelease(&pin_bus->bus);
}
int PinDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("PinDriverAttachToBus find spi bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_PIN_BUS == bus->bus_type) {
driver = PinDriverFind(drv_name, TYPE_PIN_DRV);
if (NONE == driver) {
KPrintf("PinDriverAttachToBus find spi driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_PIN_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("PinDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
BusType PinBusInitGet(void)
{
struct BusConfigureInfo configure_info;
BusType pin;
int ret = 0;
pin = BusFind(PIN_BUS_NAME);
if (!pin) {
KPrintf("find %s failed!\n", PIN_BUS_NAME);
return NONE;
}
pin->owner_driver = BusFindDriver(pin, PIN_DRIVER_NAME);
pin->owner_haldev = BusFindDevice(pin, PIN_DEVICE_NAME);
configure_info.configure_cmd = OPE_INT;
ret = BusDrvConfigure(pin->owner_driver, &configure_info);
if (ret != EOK) {
KPrintf("initialize %s failed!\n", PIN_BUS_NAME);
return NONE;
}
return pin;
}
+116
View File
@@ -0,0 +1,116 @@
/*
* 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 dev_pin.c
* @brief register pin dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_pin.h>
#include <dev_pin.h>
static DoubleLinklistType pindev_linklist;
/*Create the Pin device linklist*/
static void PinDeviceLinkInit()
{
InitDoubleLinkList(&pindev_linklist);
}
HardwareDevType PinDeviceFind(const char *dev_name, enum DevType DevType)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &pindev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (DevType == device->dev_type)) {
return device;
}
}
KPrintf("PinDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int PinDeviceRegister(struct PinHardwareDevice *pin_device, void *pin_param, const char *device_name)
{
NULL_PARAM_CHECK(pin_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool DevLinkFlag = RET_FALSE;
if (DevLinkFlag) {
PinDeviceLinkInit();
DevLinkFlag = RET_TRUE;
}
if (DEV_INSTALL != pin_device->haldev.dev_state) {
strncpy(pin_device->haldev.dev_name, device_name, NAME_NUM_MAX);
pin_device->haldev.dev_type = TYPE_PIN_DEV;
pin_device->haldev.dev_state = DEV_INSTALL;
pin_device->haldev.dev_done = (struct HalDevDone *)pin_device->dev_done;
pin_device->haldev.private_data = pin_param;
DoubleLinkListInsertNodeAfter(&pindev_linklist, &(pin_device->haldev.dev_link));
} else {
KPrintf("PinDeviceRegister device has been register state%u\n", pin_device->haldev.dev_state);
}
return ret;
}
int PinDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("PinDeviceAttachToBus find Pin bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_PIN_BUS == bus->bus_type) {
device = PinDeviceFind(dev_name, TYPE_PIN_DEV);
if (NONE == device) {
KPrintf("PinDeviceAttachToBus find Pin device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_PIN_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("PinDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+67
View File
@@ -0,0 +1,67 @@
/*
* 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 drv_pin.c
* @brief register pin drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_pin.h>
#include <dev_pin.h>
static DoubleLinklistType pindrv_linklist;
/*Create the driver linklist*/
static void PinDrvLinkInit()
{
InitDoubleLinkList(&pindrv_linklist);
}
DriverType PinDriverFind(const char *drv_name, enum DriverType DrvType)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &pindrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (DrvType == driver->driver_type)) {
return driver;
}
}
KPrintf("PinDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int PinDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool DriverLinkFlag = RET_FALSE;
if (!DriverLinkFlag) {
PinDrvLinkInit();
DriverLinkFlag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&pindrv_linklist, &(driver->driver_link));
return ret;
}
+5
View File
@@ -0,0 +1,5 @@
SRC_FILES += bus_rtc.c dev_rtc.c drv_rtc.c
include $(KERNEL_ROOT)/compiler.mk
+117
View File
@@ -0,0 +1,117 @@
/*
* 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 bus_rtc.c
* @brief register rtc bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_rtc.h>
#include <dev_rtc.h>
int RtcBusInit(struct RtcBus *rtc_bus, const char *bus_name)
{
NULL_PARAM_CHECK(rtc_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != rtc_bus->bus.bus_state) {
strncpy(rtc_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
rtc_bus->bus.bus_type = TYPE_RTC_BUS;
rtc_bus->bus.bus_state = BUS_INSTALL;
rtc_bus->bus.private_data = rtc_bus->private_data;
ret = BusRegister(&rtc_bus->bus);
if (EOK != ret) {
KPrintf("RtcBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("RtcBusInit BusRegister bus has been register state%u\n", rtc_bus->bus.bus_state);
}
return ret;
}
int RtcDriverInit(struct RtcDriver *rtc_driver, const char *driver_name)
{
NULL_PARAM_CHECK(rtc_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != rtc_driver->driver.driver_state) {
rtc_driver->driver.driver_type = TYPE_RTC_DRV;
rtc_driver->driver.driver_state = DRV_INSTALL;
strncpy(rtc_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
rtc_driver->driver.configure = rtc_driver->configure;
ret = RtcDriverRegister(&rtc_driver->driver);
if (EOK != ret) {
KPrintf("RtcDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("RtcDriverInit DriverRegister driver has been register state%u\n", rtc_driver->driver.driver_state);
}
return ret;
}
int RtcReleaseBus(struct RtcBus *rtc_bus)
{
NULL_PARAM_CHECK(rtc_bus);
return BusRelease(&rtc_bus->bus);
}
int RtcDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("RtcDriverAttachToBus find rtc bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_RTC_BUS == bus->bus_type) {
driver = RtcDriverFind(drv_name, TYPE_RTC_DRV);
if (NONE == driver) {
KPrintf("RtcDriverAttachToBus find rtc driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_RTC_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("RtcDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+115
View File
@@ -0,0 +1,115 @@
/*
* 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 dev_rtc.c
* @brief register rtc dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_rtc.h>
#include <dev_rtc.h>
static DoubleLinklistType rtcdev_linklist;
/*Create the rtc device linklist*/
static void RtcDeviceLinkInit()
{
InitDoubleLinkList(&rtcdev_linklist);
}
HardwareDevType RtcDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &rtcdev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("RtcDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int RtcDeviceRegister(struct RtcHardwareDevice *rtc_device, void *rtc_param, const char *device_name)
{
NULL_PARAM_CHECK(rtc_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (dev_link_flag) {
RtcDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != rtc_device->haldev.dev_state) {
strncpy(rtc_device->haldev.dev_name, device_name, NAME_NUM_MAX);
rtc_device->haldev.dev_type = TYPE_RTC_DEV;
rtc_device->haldev.dev_state = DEV_INSTALL;
rtc_device->haldev.dev_done = (struct HalDevDone *)rtc_device->dev_done;
rtc_device->haldev.private_data = rtc_param;
DoubleLinkListInsertNodeAfter(&rtcdev_linklist, &(rtc_device->haldev.dev_link));
} else {
KPrintf("RtcDeviceRegister device has been register state%u\n", rtc_device->haldev.dev_state);
}
return ret;
}
int RtcDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("RtcDeviceAttachToBus find rtc bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_RTC_BUS == bus->bus_type) {
device = RtcDeviceFind(dev_name, TYPE_RTC_DEV);
if (NONE == device) {
KPrintf("RtcDeviceAttachToBus find rtc device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_RTC_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("RtcDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+244
View File
@@ -0,0 +1,244 @@
/*
* 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 drv_rtc.c
* @brief register rtc drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_rtc.h>
#include <dev_rtc.h>
static DoubleLinklistType rtcdrv_linklist;
/*Create the driver linklist*/
static void RtcDrvLinkInit()
{
InitDoubleLinkList(&rtcdrv_linklist);
}
DriverType RtcDriverFind(const char *drv_name, enum DriverType drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &rtcdrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("RtcDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int RtcDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
RtcDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&rtcdrv_linklist, &(driver->driver_link));
return ret;
}
int RtcDrvSetFunction(char *driver_name, struct RtcSetParam *rtc_set_param)
{
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
time_t now;
struct tm *tm_now;
struct tm tm_tmp;
x_base lock;
struct Driver *driver;
struct BusConfigureInfo configure_info;
struct RtcDrvConfigureParam drv_param;
configure_info.private_data = &drv_param;
driver = RtcDriverFind(driver_name, TYPE_RTC_DRV);
if (NONE == driver) {
KPrintf("RtcDrvSetFunction find rtc driver %s error\n", driver_name);
return ERROR;
}
if (OPER_RTC_SET_TIME == rtc_set_param->rtc_set_cmd) {
now = time(NONE);
lock = CriticalAreaLock();
tm_now = localtime(&now);
memcpy(&tm_tmp, tm_now, sizeof(struct tm));
CriticalAreaUnLock(lock);
tm_tmp.tm_year = rtc_set_param->date_param.year - 1900;
tm_tmp.tm_mon = rtc_set_param->date_param.month - 1;
tm_tmp.tm_mday = rtc_set_param->date_param.day;
tm_tmp.tm_hour = rtc_set_param->time_param.hour;
tm_tmp.tm_min = rtc_set_param->time_param.minute;
tm_tmp.tm_sec = rtc_set_param->time_param.second;
now = mktime(&tm_tmp);
drv_param.rtc_operation_cmd = OPER_RTC_SET_TIME;
drv_param.time = &now;
ret = driver->configure(driver, &configure_info);
if (EOK != ret) {
KPrintf("RtcDrvSetFunction set time error %d\n", ret);
return ret;
}
} else if (OPER_RTC_GET_TIME == rtc_set_param->rtc_set_cmd) {
drv_param.rtc_operation_cmd = OPER_RTC_GET_TIME;
drv_param.time = rtc_set_param->time;
ret = driver->configure(driver, &configure_info);
if (EOK != ret) {
KPrintf("RtcDrvSetFunction set time error %d\n", ret);
return ret;
}
}
return EOK;
}
#ifdef USING_SOFT_RTC
static x_ticks_t SoftRtc_InitTick;
static time_t SoftRtc_InitTime;
static int SoftRtcInitTime(struct tm *time, struct RtcDateParam *date_param, struct RtcTimeParam *time_param)
{
NULL_PARAM_CHECK(time);
time->tm_year = date_param->year - 1900;
time->tm_mon = date_param->month - 1;
time->tm_mday = date_param->day;
time->tm_hour = time_param->hour;
time->tm_min = time_param->minute;
time->tm_sec = time_param->second;
return EOK;
}
static uint32 SoftRtcConfigure(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:
{
*time = SoftRtc_InitTime + (CurrentTicksGain() - SoftRtc_InitTick) / TICK_PER_SECOND;
break;
}
case OPER_RTC_SET_TIME:
{
SoftRtc_InitTime = *time - (CurrentTicksGain() - SoftRtc_InitTick) / TICK_PER_SECOND;
break;
}
}
return EOK;
}
static struct RtcDateParam date_param =
{
.year = 2021,
.month = 1,
.day = 1,
};
static struct RtcTimeParam time_param =
{
.hour = 0,
.minute = 0,
.second = 0,
};
static int SoftRtcBusInit(struct RtcBus *softrtc_bus, struct RtcDriver *softrtc_driver)
{
x_err_t ret = EOK;
/*Init the soft rtc bus */
ret = RtcBusInit(softrtc_bus, SOFT_RTC_BUS_NAME);
if(EOK != ret)
{
KPrintf("SoftRtcBusInit RtcBusInit error %d\n", ret);
return ERROR;
}
/*Init the soft rtc driver*/
ret = RtcDriverInit(softrtc_driver, SOFT_RTC_DRV_NAME);
if(EOK != ret)
{
KPrintf("SoftRtcBusInit RtcDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the soft rtc driver to the soft rtc bus*/
ret = RtcDriverAttachToBus(SOFT_RTC_DRV_NAME, SOFT_RTC_BUS_NAME);
if(EOK != ret)
{
KPrintf("SoftRtcBusInit RtcDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
int SoftRtcInit(void)
{
x_err_t ret = EOK;
struct tm time;
SoftRtcInitTime(&time, &date_param, &time_param);
static struct RtcBus softrtc_bus;
memset(&softrtc_bus, 0, sizeof(struct RtcBus));
static struct RtcDriver softrtc_driver;
memset(&softrtc_driver, 0, sizeof(struct RtcDriver));
softrtc_driver.configure = &(SoftRtcConfigure);
ret = SoftRtcBusInit(&softrtc_bus, &softrtc_driver);
if (EOK != ret) {
KPrintf("SoftRtcInit error ret %u\n", ret);
return ERROR;
}
SoftRtc_InitTick = CurrentTicksGain();
SoftRtc_InitTime = mktime(&time);
return ret;
}
#endif
+5
View File
@@ -0,0 +1,5 @@
SRC_FILES +=bus_sdio.c dev_sdio.c drv_sdio.c
include $(KERNEL_ROOT)/compiler.mk
+117
View File
@@ -0,0 +1,117 @@
/*
* 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 bus_sdio.c
* @brief register sdio bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_sdio.h>
#include <dev_sdio.h>
int SdioBusInit(struct SdioBus *sdio_bus, const char *bus_name)
{
NULL_PARAM_CHECK(sdio_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != sdio_bus->bus.bus_state) {
strncpy(sdio_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
sdio_bus->bus.bus_type = TYPE_SDIO_BUS;
sdio_bus->bus.bus_state = BUS_INSTALL;
sdio_bus->bus.private_data = sdio_bus->private_data;
ret = BusRegister(&sdio_bus->bus);
if (EOK != ret) {
KPrintf("SdioBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("SdioBusInit BusRegister bus has been register state%u\n", sdio_bus->bus.bus_state);
}
return ret;
}
int SdioDriverInit(struct SdioDriver *sdio_driver, const char *driver_name)
{
NULL_PARAM_CHECK(sdio_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != sdio_driver->driver.driver_state) {
sdio_driver->driver.driver_type = TYPE_SDIO_DRV;
sdio_driver->driver.driver_state = DRV_INSTALL;
strncpy(sdio_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
sdio_driver->driver.configure = sdio_driver->configure;
ret = SdioDriverRegister(&sdio_driver->driver);
if (EOK != ret) {
KPrintf("SdioDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("SdioDriverInit DriverRegister driver has been register state%u\n", sdio_driver->driver.driver_state);
}
return ret;
}
int SdioReleaseBus(struct SdioBus *sdio_bus)
{
NULL_PARAM_CHECK(sdio_bus);
return BusRelease(&sdio_bus->bus);
}
int SdioDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("SdioDriverAttachToBus find sdio bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_SDIO_BUS == bus->bus_type) {
driver = SdioDriverFind(drv_name);
if (NONE == driver) {
KPrintf("SdioDriverAttachToBus find sdio driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_SDIO_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("SdioDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+114
View File
@@ -0,0 +1,114 @@
/*
* 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 dev_sdio.c
* @brief register sdio dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_sdio.h>
#include <dev_sdio.h>
static DoubleLinklistType sdiodev_linklist;
/*Create the sdio device linklist*/
static void SdioDeviceLinkInit()
{
InitDoubleLinkList(&sdiodev_linklist);
}
HardwareDevType SdioDeviceFind(const char *dev_name)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &sdiodev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if (!strcmp(device->dev_name, dev_name)) {
return device;
}
}
KPrintf("SdioDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int SdioDeviceRegister(struct SdioHardwareDevice *sdio_device, const char *device_name)
{
NULL_PARAM_CHECK(sdio_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool DevLinkFlag = RET_FALSE;
if (DevLinkFlag) {
SdioDeviceLinkInit();
DevLinkFlag = RET_TRUE;
}
if (DEV_INSTALL != sdio_device->haldev.dev_state) {
strncpy(sdio_device->haldev.dev_name, device_name, NAME_NUM_MAX);
sdio_device->haldev.dev_type = TYPE_SDIO_DEV;
sdio_device->haldev.dev_state = DEV_INSTALL;
sdio_device->haldev.dev_done = (struct HalDevDone *)sdio_device->dev_done;
sdio_device->haldev.private_data = sdio_device->private_data;
DoubleLinkListInsertNodeAfter(&sdiodev_linklist, &(sdio_device->haldev.dev_link));
} else {
KPrintf("SdioDeviceRegister device has been register state%u\n", sdio_device->haldev.dev_state);
}
return ret;
}
int SdioDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("SdioDeviceAttachToBus find sdio bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_SDIO_BUS == bus->bus_type) {
device = SdioDeviceFind(dev_name);
if (NONE == device) {
KPrintf("SdioDeviceAttachToBus find sdio device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_SDIO_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("SdioDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+67
View File
@@ -0,0 +1,67 @@
/*
* 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 drv_sdio.c
* @brief register sdio drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_sdio.h>
#include <dev_sdio.h>
static DoubleLinklistType sdiodrv_linklist;
/*Create the driver linklist*/
static void SdioDrvLinkInit()
{
InitDoubleLinkList(&sdiodrv_linklist);
}
DriverType SdioDriverFind(const char *drv_name)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &sdiodrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if (!strcmp(driver->drv_name, drv_name)) {
return driver;
}
}
KPrintf("SdioDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int SdioDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool DriverLinkFlag = RET_FALSE;
if (!DriverLinkFlag) {
SdioDrvLinkInit();
DriverLinkFlag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&sdiodrv_linklist, &(driver->driver_link));
return ret;
}
+3
View File
@@ -0,0 +1,3 @@
SRC_FILES += bus_serial.c drv_serial.c dev_serial.c
include $(KERNEL_ROOT)/compiler.mk
+117
View File
@@ -0,0 +1,117 @@
/*
* 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 bus_serial.c
* @brief register serial bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_serial.h>
#include <dev_serial.h>
int SerialBusInit(struct SerialBus *serial_bus, const char *bus_name)
{
NULL_PARAM_CHECK(serial_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != serial_bus->bus.bus_state) {
strncpy(serial_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
serial_bus->bus.bus_type = TYPE_SERIAL_BUS;
serial_bus->bus.bus_state = BUS_INSTALL;
serial_bus->bus.private_data = serial_bus->private_data;
ret = BusRegister(&serial_bus->bus);
if (EOK != ret) {
KPrintf("serial BusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("SerialBusInit BusRegister bus has been register state%u\n", serial_bus->bus.bus_state);
}
return ret;
}
int SerialDriverInit(struct SerialDriver *serial_driver, const char *driver_name)
{
NULL_PARAM_CHECK(serial_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != serial_driver->driver.driver_state) {
serial_driver->driver.driver_type = TYPE_SERIAL_DRV;
serial_driver->driver.driver_state = DRV_INSTALL;
strncpy(serial_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
serial_driver->driver.configure = serial_driver->configure;
ret = SerialDriverRegister(&serial_driver->driver);
if (EOK != ret) {
KPrintf("SerialDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("SerialDriverInit DriverRegister driver has been register state%u\n", serial_driver->driver.driver_state);
}
return ret;
}
int SerialReleaseBus(struct SerialBus *serial_bus)
{
NULL_PARAM_CHECK(serial_bus);
return BusRelease(&serial_bus->bus);
}
int SerialDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("SerialDriverAttachToBus find serial bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_SERIAL_BUS == bus->bus_type) {
driver = SerialDriverFind(drv_name, TYPE_SERIAL_DRV);
if (NONE == driver) {
KPrintf("SerialDriverAttachToBus find serial driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_SERIAL_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("SerialDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+874
View File
@@ -0,0 +1,874 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-13 bernard first version
* 2012-05-15 lgnq modified according bernard's implementation.
* 2012-05-28 bernard code cleanup
* 2012-11-23 bernard fix compiler warning.
* 2013-02-20 bernard use RT_SERIAL_RB_BUFSZ to define
* the size of ring buffer.
* 2014-07-10 bernard rewrite serial framework
* 2014-12-31 bernard use open_flag for poll_tx stream mode.
* 2015-05-19 Quintin fix DMA tx mod tx_dma->activated flag !=RT_FALSE BUG
* in open function.
* 2015-11-10 bernard fix the poll rx issue when there is no data.
* 2016-05-10 armink add fifo mode to DMA rx when serial->config.bufsz != 0.
* 2017-01-19 aubr.cool prevent change serial rx bufsz when serial is opened.
* 2017-11-07 JasonJia fix data bits error issue when using tcsetattr.
* 2017-11-15 JasonJia fix poll rx issue when data is full.
* add TCFLSH and FIONREAD support.
* 2018-12-08 Ernest Chen add DMA choice
* 2020-09-14 WillianChan add a line feed to the carriage return character
* when using interrupt tx
*/
/**
* @file dev_serial.c
* @brief register serial dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
/*************************************************
File name: dev_serial.c
Description: support serial dev INT and DMA configure、transfer data
Others: take RT-Thread v4.0.2/components/driver/serial/serial.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-24
Author: AIIT XUOS Lab
Modification:
1. support serial dev register, configure, write and read
2. add bus driver framework support, include INT and DMA mode
*************************************************/
#include <bus_serial.h>
#include <dev_serial.h>
static DoubleLinklistType serialdev_linklist;
static int SerialWorkModeCheck(struct SerialDevParam *serial_dev_param)
{
if (SIGN_OPER_INT_TX & serial_dev_param->serial_set_mode) {
if (SIGN_OPER_INT_TX & serial_dev_param->serial_work_mode) {
return EOK;
} else {
KPrintf("SerialWorkModeCheck set mode 0x%x work mode error 0x%x\n",
serial_dev_param->serial_set_mode, serial_dev_param->serial_work_mode);
return ERROR;
}
} else if (SIGN_OPER_INT_RX & serial_dev_param->serial_set_mode) {
if (SIGN_OPER_INT_RX & serial_dev_param->serial_work_mode) {
return EOK;
} else {
KPrintf("SerialWorkModeCheck set mode 0x%x work mode error 0x%x\n",
serial_dev_param->serial_set_mode, serial_dev_param->serial_work_mode);
return ERROR;
}
} else if (SIGN_OPER_DMA_TX & serial_dev_param->serial_set_mode) {
if (SIGN_OPER_DMA_TX & serial_dev_param->serial_work_mode) {
return EOK;
} else {
KPrintf("SerialWorkModeCheck set mode 0x%x work mode error 0x%x\n",
serial_dev_param->serial_set_mode, serial_dev_param->serial_work_mode);
return ERROR;
}
} else if (SIGN_OPER_DMA_RX & serial_dev_param->serial_set_mode) {
if (SIGN_OPER_DMA_RX & serial_dev_param->serial_work_mode) {
return EOK;
} else {
KPrintf("SerialWorkModeCheck set mode 0x%x work mode error 0x%x\n",
serial_dev_param->serial_set_mode, serial_dev_param->serial_work_mode);
return ERROR;
}
} else {
serial_dev_param->serial_set_mode = serial_dev_param->serial_work_mode;
return EOK;
}
}
static inline int SerialDevIntWrite(struct SerialHardwareDevice *serial_dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(serial_dev);
NULL_PARAM_CHECK(write_param);
struct SerialHwDevDone *hwdev_done = serial_dev->hwdev_done;
const uint8 *write_data = (const uint8 *)write_param->buffer;
x_size_t write_length = write_param->size;
while (write_length)
{
if (EOK != hwdev_done->put_char(serial_dev, *(char *)write_data)) {
KSemaphoreObtain(serial_dev->serial_fifo.serial_tx->serial_txfifo_sem, WAITING_FOREVER);
continue;
}
KPrintf("SerialDevIntWrite data %d write_length %u\n", *(char *)write_data, write_length);
write_data++;
write_length--;
}
return EOK;
}
static inline int SerialDevIntRead(struct SerialHardwareDevice *serial_dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(serial_dev);
NULL_PARAM_CHECK(read_param);
struct SerialHwDevDone *hwdev_done = serial_dev->hwdev_done;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
uint8 *read_data = (uint8 *)read_param->buffer;
x_size_t read_length = read_param->size;
while (read_length)
{
uint8 get_char;
x_base lock;
lock = CriticalAreaLock();
if (serial_dev->serial_fifo.serial_rx->serial_recv_num == serial_dev->serial_fifo.serial_rx->serial_send_num) {
if (RET_FALSE == serial_dev->serial_fifo.serial_rx->serial_rx_full) {
CriticalAreaUnLock(lock);
break;
}
}
get_char = serial_dev->serial_fifo.serial_rx->serial_rx_buffer[serial_dev->serial_fifo.serial_rx->serial_recv_num];
serial_dev->serial_fifo.serial_rx->serial_recv_num += 1;
if (serial_dev->serial_fifo.serial_rx->serial_recv_num >= serial_cfg->data_cfg.serial_buffer_size) {
serial_dev->serial_fifo.serial_rx->serial_recv_num = 0;
}
if (RET_TRUE == serial_dev->serial_fifo.serial_rx->serial_rx_full) {
serial_dev->serial_fifo.serial_rx->serial_rx_full = RET_FALSE;
}
CriticalAreaUnLock(lock);
*read_data = get_char;
read_data++;
read_length--;
read_param->read_length++;
}
return EOK;
}
#ifdef SERIAL_USING_DMA
static inline int SerialDevDMAWrite(struct SerialHardwareDevice *serial_dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(serial_dev);
NULL_PARAM_CHECK(write_param);
x_err_t ret = EOK;
x_base lock;
struct SerialHwDevDone *hwdev_done = serial_dev->hwdev_done;
const uint8 *write_data = (const uint8 *)write_param->buffer;
x_size_t write_length = write_param->size;
ret = ((DataQueueDoneType*)serial_dev->serial_fifo.serial_tx->serial_dma_queue.done)->PushDataqueue((DataQueueType *)serial_dev->serial_fifo.serial_tx->serial_dma_queue.property, write_param->buffer, write_param->size, WAITING_FOREVER);
if (EOK != ret) {
KUpdateExstatus(ret);
return ERROR;
}
lock = CriticalAreaLock();
if (RET_FALSE == serial_dev->serial_fifo.serial_tx->serial_dma_enable) {
serial_dev->serial_fifo.serial_tx->serial_dma_enable = RET_TRUE;
CriticalAreaUnLock(lock);
hwdev_done->dmatransfer(serial_dev, (uint8 *)write_data, write_length, SERIAL_DMA_TX);
} else {
CriticalAreaUnLock(lock);
}
return EOK;
}
static x_size_t SerialGetRxFifoLength(struct SerialHardwareDevice *serial_dev)
{
NULL_PARAM_CHECK(serial_dev);
x_size_t length;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
if (serial_dev->serial_fifo.serial_rx->serial_recv_num == serial_dev->serial_fifo.serial_rx->serial_send_num) {
if (serial_dev->serial_fifo.serial_rx->serial_rx_full) {
length = serial_cfg->data_cfg.serial_buffer_size;
} else {
length = 0;
}
} else {
if (serial_dev->serial_fifo.serial_rx->serial_recv_num > serial_dev->serial_fifo.serial_rx->serial_send_num) {
length = serial_cfg->data_cfg.serial_buffer_size - serial_dev->serial_fifo.serial_rx->serial_recv_num + serial_dev->serial_fifo.serial_rx->serial_send_num;
} else {
length = serial_dev->serial_fifo.serial_rx->serial_send_num - serial_dev->serial_fifo.serial_rx->serial_recv_num;
}
}
}
static void SerialDmaRxSetRecvLength(struct SerialHardwareDevice *serial_dev, x_size_t length)
{
CHECK(length <= SerialGetRxFifoLength(serial_dev));
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
if ((serial_dev->serial_fifo.serial_rx->serial_rx_full) && (length)) {
serial_dev->serial_fifo.serial_rx->serial_rx_full = RET_FALSE;
}
serial_dev->serial_fifo.serial_rx->serial_recv_num += length;
if (serial_dev->serial_fifo.serial_rx->serial_recv_num >= serial_cfg->data_cfg.serial_buffer_size) {
serial_dev->serial_fifo.serial_rx->serial_recv_num %= serial_cfg->data_cfg.serial_buffer_size;
}
}
static void SerialDmaRxSetSendLength(struct SerialHardwareDevice *serial_dev, x_size_t length)
{
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
if (serial_dev->serial_fifo.serial_rx->serial_recv_num > serial_dev->serial_fifo.serial_rx->serial_send_num) {
serial_dev->serial_fifo.serial_rx->serial_send_num += length;
if (serial_dev->serial_fifo.serial_rx->serial_recv_num <= serial_dev->serial_fifo.serial_rx->serial_send_num) {
if (serial_dev->serial_fifo.serial_rx->serial_send_num >= serial_cfg->data_cfg.serial_buffer_size) {
serial_dev->serial_fifo.serial_rx->serial_send_num %= serial_cfg->data_cfg.serial_buffer_size;
}
serial_dev->serial_fifo.serial_rx->serial_rx_full = RET_TRUE;
}
} else {
serial_dev->serial_fifo.serial_rx->serial_send_num += length;
if (serial_dev->serial_fifo.serial_rx->serial_send_num >= serial_cfg->data_cfg.serial_buffer_size) {
serial_dev->serial_fifo.serial_rx->serial_send_num %= serial_cfg->data_cfg.serial_buffer_size;
if (serial_dev->serial_fifo.serial_rx->serial_send_num >= serial_dev->serial_fifo.serial_rx->serial_recv_num) {
serial_dev->serial_fifo.serial_rx->serial_rx_full = RET_TRUE;
}
}
}
if (RET_TRUE == serial_dev->serial_fifo.serial_rx->serial_rx_full) {
serial_dev->serial_fifo.serial_rx->serial_recv_num = serial_dev->serial_fifo.serial_rx->serial_send_num;
}
}
static inline int SerialDevDMARead(struct SerialHardwareDevice *serial_dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(serial_dev);
NULL_PARAM_CHECK(read_param);
x_err_t ret = EOK;
x_base lock;
struct SerialHwDevDone *hwdev_done = serial_dev->hwdev_done;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
uint8 *read_data = (uint8 *)read_param->buffer;
x_size_t read_length = read_param->size;
x_size_t read_dma_length;
x_size_t read_dma_size = SerialGetRxFifoLength(serial_dev);
if (serial_cfg->data_cfg.serial_buffer_size) {
if(read_length < (int)read_dma_size)
read_dma_length = read_length;
else
read_dma_length = read_dma_size;
if (serial_dev->serial_fifo.serial_rx->serial_recv_num + read_dma_length < serial_cfg->data_cfg.serial_buffer_size) {
memcpy(read_data,
serial_dev->serial_fifo.serial_rx->serial_rx_buffer + serial_dev->serial_fifo.serial_rx->serial_recv_num, read_dma_length);
} else {
memcpy(read_data, serial_dev->serial_fifo.serial_rx->serial_rx_buffer + serial_dev->serial_fifo.serial_rx->serial_recv_num,
serial_cfg->data_cfg.serial_buffer_size - serial_dev->serial_fifo.serial_rx->serial_recv_num);
memcpy(read_data + serial_cfg->data_cfg.serial_buffer_size - serial_dev->serial_fifo.serial_rx->serial_recv_num,
serial_dev->serial_fifo.serial_rx->serial_rx_buffer, read_dma_length + serial_dev->serial_fifo.serial_rx->serial_recv_num - serial_cfg->data_cfg.serial_buffer_size);
}
SerialDmaRxSetRecvLength(serial_dev, read_dma_length);
CriticalAreaUnLock(lock);
return EOK;
} else {
if (RET_FALSE == serial_dev->serial_fifo.serial_rx->serial_dma_enable) {
serial_dev->serial_fifo.serial_rx->serial_dma_enable = RET_TRUE;
hwdev_done->dmatransfer(serial_dev, read_data, read_length, SERIAL_DMA_RX);
} else {
ret = ERROR;
KUpdateExstatus(ret);
}
CriticalAreaUnLock(lock);
return ret;
}
}
#endif
static inline int SerialDevPollingWrite(struct SerialHardwareDevice *serial_dev, struct BusBlockWriteParam *write_param, uint16 serial_stream_mode)
{
NULL_PARAM_CHECK(serial_dev);
NULL_PARAM_CHECK(write_param);
struct SerialHwDevDone *hwdev_done = serial_dev->hwdev_done;
const uint8 *write_data = (const uint8 *)write_param->buffer;
x_size_t write_length = write_param->size;
while (write_length)
{
if ((*write_data == '\n') && (SIGN_OPER_STREAM == serial_stream_mode)) {
hwdev_done->put_char(serial_dev, '\r');
}
hwdev_done->put_char(serial_dev, *write_data);
++write_data;
--write_length;
}
return EOK;
}
static inline int SerialDevPollingRead(struct SerialHardwareDevice *serial_dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(serial_dev);
NULL_PARAM_CHECK(read_param);
struct SerialHwDevDone *hwdev_done = serial_dev->hwdev_done;
uint8 *read_data = (uint8 *)read_param->buffer;
x_size_t read_length = read_param->size;
uint8 get_char;
x_err_t ret = EOK;
while (read_length)
{
ret = hwdev_done->get_char(serial_dev);
if (-ERROR == ret) {
break;
}
*read_data = get_char;
read_data++;
read_length--;
if ('\n' == get_char) {
break;
}
}
return EOK;
}
static uint32 SerialDevOpen(void *dev)
{
NULL_PARAM_CHECK(dev);
int serial_operation_cmd;
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)dev;
struct Driver *drv = serial_dev->haldev.owner_bus->owner_driver;
struct SerialDriver *serial_drv = (struct SerialDriver *)drv;
struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
if (EOK != SerialWorkModeCheck(serial_dev_param)) {
KPrintf("SerialDevOpen error!\n");
return ERROR;
}
if (NONE == serial_dev->serial_fifo.serial_rx) {
if (SIGN_OPER_INT_RX & serial_dev_param->serial_set_mode) {
serial_dev->serial_fifo.serial_rx = (struct SerialRx *)malloc(sizeof(struct SerialRx));
if (NONE == serial_dev->serial_fifo.serial_rx) {
KPrintf("SerialDevOpen malloc serial_rx error\n");
free(serial_dev->serial_fifo.serial_rx);
return ERROR;
}
serial_dev->serial_fifo.serial_rx->serial_rx_buffer = (uint8 *)malloc(serial_cfg->data_cfg.serial_buffer_size);
if (NONE == serial_dev->serial_fifo.serial_rx->serial_rx_buffer) {
KPrintf("SerialDevOpen malloc serial_rx_buffer error\n");
free(serial_dev->serial_fifo.serial_rx->serial_rx_buffer);
free(serial_dev->serial_fifo.serial_rx);
return ERROR;
}
memset(serial_dev->serial_fifo.serial_rx->serial_rx_buffer, 0, serial_cfg->data_cfg.serial_buffer_size);
serial_dev->serial_fifo.serial_rx->serial_send_num = 0;
serial_dev->serial_fifo.serial_rx->serial_recv_num = 0;
serial_dev->serial_fifo.serial_rx->serial_rx_full = RET_FALSE;
serial_dev_param->serial_work_mode |= SIGN_OPER_INT_RX;
serial_operation_cmd = OPER_SET_INT;
serial_drv->drv_done->configure(serial_drv, serial_operation_cmd);
}
#ifdef SERIAL_USING_DMA
else if (SIGN_OPER_DMA_RX & serial_dev_param->serial_set_mode) {
if (0 == serial_cfg->data_cfg.serial_buffer_size) {
serial_dev->serial_fifo.serial_rx = (struct SerialRx *)malloc(sizeof(struct SerialRx));
if (NONE == serial_dev->serial_fifo.serial_rx) {
KPrintf("SerialDevOpen DMA buffer 0 malloc serial_rx error\n");
free(serial_dev->serial_fifo.serial_rx);
return ERROR;
}
serial_dev->serial_fifo.serial_rx->serial_dma_enable = RET_FALSE;
serial_dev_param->serial_work_mode |= SIGN_OPER_DMA_RX;
} else {
serial_dev->serial_fifo.serial_rx = (struct SerialRx *)malloc(sizeof(struct SerialRx));
if (NONE == serial_dev->serial_fifo.serial_rx) {
KPrintf("SerialDevOpen DMA malloc serial_rx error\n");
free(serial_dev->serial_fifo.serial_rx);
return ERROR;
}
serial_dev->serial_fifo.serial_rx->serial_rx_buffer = (uint8 *)malloc(serial_cfg->data_cfg.serial_buffer_size);
if (NONE == serial_dev->serial_fifo.serial_rx->serial_rx_buffer) {
KPrintf("SerialDevOpen DMA malloc serial_rx_buffer error\n");
free(serial_dev->serial_fifo.serial_rx->serial_rx_buffer);
free(serial_dev->serial_fifo.serial_rx);
return ERROR;
}
memset(serial_dev->serial_fifo.serial_rx->serial_rx_buffer, 0, serial_cfg->data_cfg.serial_buffer_size);
serial_dev->serial_fifo.serial_rx->serial_send_num = 0;
serial_dev->serial_fifo.serial_rx->serial_recv_num = 0;
serial_dev->serial_fifo.serial_rx->serial_rx_full = RET_FALSE;
serial_dev_param->serial_work_mode |= SIGN_OPER_DMA_RX;
int serial_dma_operation = OPER_CONFIG;
serial_drv->drv_done->configure(serial_drv, serial_dma_operation);
}
}
#endif
else {
serial_dev->serial_fifo.serial_rx = NONE;
}
} else {
if (SIGN_OPER_INT_RX & serial_dev_param->serial_set_mode) {
serial_dev_param->serial_work_mode |= SIGN_OPER_INT_RX;
}
#ifdef SERIAL_USING_DMA
else if (SIGN_OPER_DMA_RX & serial_dev_param->serial_set_mode) {
serial_dev_param->serial_work_mode |= SIGN_OPER_DMA_RX;
}
#endif
}
if (NONE == serial_dev->serial_fifo.serial_tx) {
if (SIGN_OPER_INT_TX & serial_dev_param->serial_set_mode) {
serial_dev->serial_fifo.serial_tx = (struct SerialTx *)malloc(sizeof(struct SerialTx));
if (NONE == serial_dev->serial_fifo.serial_tx) {
KPrintf("SerialDevOpen malloc serial_tx error\n");
free(serial_dev->serial_fifo.serial_tx);
return ERROR;
}
serial_dev->serial_fifo.serial_tx->serial_txfifo_sem = KSemaphoreCreate(0);
serial_dev_param->serial_work_mode |= SIGN_OPER_INT_TX;
serial_operation_cmd = OPER_SET_INT;
serial_drv->drv_done->configure(serial_drv, serial_operation_cmd);
}
#ifdef SERIAL_USING_DMA
else if (SIGN_OPER_DMA_TX & serial_dev_param->serial_set_mode) {
serial_dev->serial_fifo.serial_tx = (struct SerialTx *)malloc(sizeof(struct SerialTx));
if (NONE == serial_dev->serial_fifo.serial_tx) {
KPrintf("SerialDevOpen DMA malloc serial_tx error\n");
free(serial_dev->serial_fifo.serial_tx);
return ERROR;
}
serial_dev->serial_fifo.serial_tx->serial_dma_enable = RET_FALSE;
serial_dev->serial_fifo.serial_tx->serial_dma_queue.done = g_queue_done[DATA_QUEUE];
serial_dev->serial_fifo.serial_tx->serial_dma_queue.property = x_malloc(sizeof(DataQueueType));
((DataQueueDoneType*)serial_dev->serial_fifo.serial_tx->serial_dma_queue.done)->InitDataqueue((DataQueueType *)serial_dev->serial_fifo.serial_tx->serial_dma_queue.property, 8);
serial_dev_param->serial_work_mode |= SIGN_OPER_DMA_TX;
serial_operation_cmd = OPER_CONFIG;
serial_drv->drv_done->configure(serial_drv, serial_operation_cmd);
}
#endif
else {
serial_dev->serial_fifo.serial_tx = NONE;
}
} else {
if (SIGN_OPER_INT_TX & serial_dev_param->serial_set_mode) {
serial_dev_param->serial_work_mode |= SIGN_OPER_INT_TX;
}
#ifdef SERIAL_USING_DMA
else if (SIGN_OPER_DMA_TX & serial_dev_param->serial_set_mode) {
serial_dev_param->serial_work_mode |= SIGN_OPER_DMA_TX;
}
#endif
}
serial_dev->haldev.dev_sem = KSemaphoreCreate(0);
if (serial_dev->haldev.dev_sem < 0) {
KPrintf("SerialDevOpen create sem failed .\n");
if (serial_dev->serial_fifo.serial_rx->serial_rx_buffer) {
free(serial_dev->serial_fifo.serial_rx->serial_rx_buffer);
}
if (serial_dev->serial_fifo.serial_rx) {
free(serial_dev->serial_fifo.serial_rx);
}
if (serial_dev->serial_fifo.serial_tx) {
free(serial_dev->serial_fifo.serial_tx);
}
return ERROR;
}
return EOK;
}
static uint32 SerialDevClose(void *dev)
{
NULL_PARAM_CHECK(dev);
int serial_operation_cmd = OPER_CLR_INT;
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)dev;
struct Driver *drv = serial_dev->haldev.owner_bus->owner_driver;
struct SerialDriver *serial_drv = (struct SerialDriver *)drv;
struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
if (SIGN_OPER_INT_RX & serial_dev_param->serial_work_mode) {
NULL_PARAM_CHECK(serial_dev->serial_fifo.serial_rx->serial_rx_buffer);
NULL_PARAM_CHECK(serial_dev->serial_fifo.serial_rx);
free(serial_dev->serial_fifo.serial_rx->serial_rx_buffer);
free(serial_dev->serial_fifo.serial_rx);
serial_drv->drv_done->configure(serial_drv, serial_operation_cmd);
}
#ifdef SERIAL_USING_DMA
else if (SIGN_OPER_DMA_RX & serial_dev_param->serial_work_mode) {
if(0 == serial_cfg->data_cfg.serial_buffer_size)
{
NULL_PARAM_CHECK(serial_dev->serial_fifo.serial_rx);
free(serial_dev->serial_fifo.serial_rx);
} else {
NULL_PARAM_CHECK(serial_dev->serial_fifo.serial_rx->serial_rx_buffer);
NULL_PARAM_CHECK(serial_dev->serial_fifo.serial_rx);
free(serial_dev->serial_fifo.serial_rx->serial_rx_buffer);
free(serial_dev->serial_fifo.serial_rx);
}
serial_drv->drv_done->configure(serial_drv, serial_operation_cmd);
}
#endif
if (SIGN_OPER_INT_TX & serial_dev_param->serial_work_mode) {
NULL_PARAM_CHECK(serial_dev->serial_fifo.serial_tx);
free(serial_dev->serial_fifo.serial_tx);
serial_drv->drv_done->configure(serial_drv, serial_operation_cmd);
}
#ifdef SERIAL_USING_DMA
else if (SIGN_OPER_DMA_TX & serial_dev_param->serial_work_mode) {
NULL_PARAM_CHECK(serial_dev->serial_fifo.serial_tx);
free(serial_dev->serial_fifo.serial_tx);
serial_drv->drv_done->configure(serial_drv, serial_operation_cmd);
}
#endif
KSemaphoreDelete(serial_dev->haldev.dev_sem);
return EOK;
}
static uint32 SerialDevWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
x_err_t ret = EOK;
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)dev;
struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
if (serial_dev_param->serial_work_mode & SIGN_OPER_INT_TX) {
ret = SerialDevIntWrite(serial_dev, write_param);
if (EOK != ret) {
KPrintf("SerialDevIntWrite error %d\n", ret);
return ERROR;
}
}
#ifdef SERIAL_USING_DMA
else if (serial_dev_param->serial_work_mode & SIGN_OPER_DMA_TX) {
ret = SerialDevDMAWrite(serial_dev, write_param);
if (EOK != ret) {
KPrintf("SerialDevDMAWrite error %d\n", ret);
return ERROR;
}
}
#endif
else {
ret = SerialDevPollingWrite(serial_dev, write_param, serial_dev_param->serial_stream_mode);
if (EOK != ret) {
KPrintf("SerialDevPollingWrite error %d\n", ret);
return ERROR;
}
}
return EOK;
}
static uint32 SerialDevRead(void *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(read_param);
x_err_t ret = EOK;
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)dev;
struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
if (EOK == KSemaphoreObtain(serial_dev->haldev.dev_sem, WAITING_FOREVER)) {
if (serial_dev_param->serial_work_mode & SIGN_OPER_INT_RX) {
ret = SerialDevIntRead(serial_dev, read_param);
if (EOK != ret) {
KPrintf("SerialDevIntRead error %d\n", ret);
return ERROR;
}
}
#ifdef SERIAL_USING_DMA
else if (serial_dev_param->serial_work_mode & SIGN_OPER_DMA_RX) {
ret = SerialDevDMARead(serial_dev, read_param);
if (EOK != ret) {
KPrintf("SerialDevDMARead error %d\n", ret);
return ERROR;
}
}
#endif
else {
ret = SerialDevPollingRead(serial_dev, read_param);
if (EOK != ret) {
KPrintf("SerialDevPollingRead error %d\n", ret);
return ERROR;
}
}
}
return EOK;
}
void SerialSetIsr(struct SerialHardwareDevice *serial_dev, int event)
{
switch (event & 0xff)
{
case SERIAL_EVENT_RX_IND:
{
int get_char;
x_base lock;
struct SerialHwDevDone *hwdev_done = serial_dev->hwdev_done;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
while (1)
{
get_char = hwdev_done->get_char(serial_dev);
if (-ERROR == get_char) {
break;
}
lock = CriticalAreaLock();
serial_dev->serial_fifo.serial_rx->serial_rx_buffer[serial_dev->serial_fifo.serial_rx->serial_send_num] = (uint8)get_char;
serial_dev->serial_fifo.serial_rx->serial_send_num += 1;
if (serial_dev->serial_fifo.serial_rx->serial_send_num >= serial_cfg->data_cfg.serial_buffer_size) {
serial_dev->serial_fifo.serial_rx->serial_send_num = 0;
}
if (serial_dev->serial_fifo.serial_rx->serial_send_num == serial_dev->serial_fifo.serial_rx->serial_recv_num) {
serial_dev->serial_fifo.serial_rx->serial_recv_num += 1;
serial_dev->serial_fifo.serial_rx->serial_rx_full = RET_TRUE;
if (serial_dev->serial_fifo.serial_rx->serial_recv_num >= serial_cfg->data_cfg.serial_buffer_size) {
serial_dev->serial_fifo.serial_rx->serial_recv_num = 0;
}
}
CriticalAreaUnLock(lock);
}
x_size_t serial_rx_length;
lock = CriticalAreaLock();
if (serial_dev->serial_fifo.serial_rx->serial_recv_num > serial_dev->serial_fifo.serial_rx->serial_send_num) {
serial_rx_length = serial_cfg->data_cfg.serial_buffer_size - serial_dev->serial_fifo.serial_rx->serial_recv_num + serial_dev->serial_fifo.serial_rx->serial_send_num;
} else {
serial_rx_length = serial_dev->serial_fifo.serial_rx->serial_send_num - serial_dev->serial_fifo.serial_rx->serial_recv_num;
}
CriticalAreaUnLock(lock);
if (serial_rx_length) {
if (serial_dev->haldev.dev_recv_callback) {
serial_dev->haldev.dev_recv_callback((void *)serial_dev, serial_rx_length);
}
KSemaphoreAbandon(serial_dev->haldev.dev_sem);
}
break;
}
case SERIAL_event_id_tX_DONE:
{
KSemaphoreAbandon(serial_dev->serial_fifo.serial_tx->serial_txfifo_sem);
break;
}
#ifdef SERIAL_USING_DMA
case SERIAL_event_id_tX_DMADONE:
{
const void *data_ptr;
x_size_t DataSize;
const void *last_data_ptr;
struct SerialHwDevDone *hwdev_done = serial_dev->hwdev_done;
((DataQueueDoneType*)serial_dev->serial_fifo.serial_tx->serial_dma_queue.done)->PopDataqueue((DataQueueType *)serial_dev->serial_fifo.serial_tx->serial_dma_queue.property, &last_data_ptr, &DataSize, 0);
if (EOK == ((DataQueueDoneType*)serial_dev->serial_fifo.serial_tx->serial_dma_queue.done)->DataqueuePeak((DataQueueType *)serial_dev->serial_fifo.serial_tx->serial_dma_queue.property, &data_ptr, &DataSize)) {
serial_dev->serial_fifo.serial_tx->serial_dma_enable = RET_TRUE;
hwdev_done->dmatransfer(serial_dev, (uint8 *)data_ptr, DataSize, SERIAL_DMA_TX);
} else {
serial_dev->serial_fifo.serial_tx->serial_dma_enable = RET_FALSE;
}
break;
}
case SERIAL_EVENT_RX_DMADONE:
{
int length;
x_base lock;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
length = (event & (~0xff)) >> 8;
if (serial_cfg->data_cfg.serial_buffer_size) {
lock = CriticalAreaLock();
SerialDmaRxSetSendLength(serial_dev, length);
length = SerialGetRxFifoLength(serial_dev);
CriticalAreaUnLock(lock);
if (serial_dev->haldev.dev_recv_callback) {
serial_dev->haldev.dev_recv_callback((void *)serial_dev, length);
}
KSemaphoreAbandon(serial_dev->haldev.dev_sem);
} else {
serial_dev->serial_fifo.serial_rx->serial_dma_enable = RET_FALSE;
if (serial_dev->haldev.dev_recv_callback) {
serial_dev->haldev.dev_recv_callback((void *)serial_dev, length);
}
KSemaphoreAbandon(serial_dev->haldev.dev_sem);
}
break;
}
#endif
}
}
const struct SerialDevDone dev_done =
{
.open = SerialDevOpen,
.close = SerialDevClose,
.write = SerialDevWrite,
.read = SerialDevRead,
};
/*Create the serial device linklist*/
static void SerialDeviceLinkInit()
{
InitDoubleLinkList(&serialdev_linklist);
}
HardwareDevType SerialDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &serialdev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("SerialDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int SerialDeviceRegister(struct SerialHardwareDevice *serial_device, void *serial_param, const char *device_name)
{
NULL_PARAM_CHECK(serial_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (dev_link_flag) {
SerialDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != serial_device->haldev.dev_state) {
strncpy(serial_device->haldev.dev_name, device_name, NAME_NUM_MAX);
serial_device->haldev.dev_type = TYPE_SERIAL_DEV;
serial_device->haldev.dev_state = DEV_INSTALL;
if (serial_device->ext_serial_mode) {
serial_device->haldev.dev_done = (struct HalDevDone *)serial_device->dev_done;
} else {
serial_device->haldev.dev_done = (struct HalDevDone *)&dev_done;
}
serial_device->private_data = serial_param;
DoubleLinkListInsertNodeAfter(&serialdev_linklist, &(serial_device->haldev.dev_link));
} else {
KPrintf("SerialDeviceRegister device has been register state%u\n", serial_device->haldev.dev_state);
}
return ret;
}
int SerialDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("SerialDeviceAttachToBus find serial bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_SERIAL_BUS == bus->bus_type) {
device = SerialDeviceFind(dev_name, TYPE_SERIAL_DEV);
if (NONE == device) {
KPrintf("SerialDeviceAttachToBus find serial device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_SERIAL_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("SerialDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+68
View File
@@ -0,0 +1,68 @@
/*
* 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 drv_serial.c
* @brief register serial drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_serial.h>
#include <dev_serial.h>
static DoubleLinklistType serialdrv_linklist;
/*Create the driver linklist*/
static void SerialDrvLinkInit()
{
InitDoubleLinkList(&serialdrv_linklist);
}
DriverType SerialDriverFind(const char *drv_name, enum DriverType drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &serialdrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("SerialDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int SerialDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
SerialDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&serialdrv_linklist, &(driver->driver_link));
return ret;
}
+16
View File
@@ -0,0 +1,16 @@
SRC_FILES += dev_spi.c bus_spi.c drv_spi.c
SRC_DIR := third_party_spi
ifeq ($(CONFIG_RESOURCES_SPI_SD), y)
SRC_DIR += sd_card_spi
endif
ifeq ($(CONFIG_RESOURCES_SPI_SFUD),y)
SRC_FILES += flash_spi.c
endif
include $(KERNEL_ROOT)/compiler.mk
+117
View File
@@ -0,0 +1,117 @@
/*
* 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 bus_spi.c
* @brief register spi bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_spi.h>
#include <dev_spi.h>
int SpiBusInit(struct SpiBus *spi_bus, const char *bus_name)
{
NULL_PARAM_CHECK(spi_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != spi_bus->bus.bus_state) {
strncpy(spi_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
spi_bus->bus.bus_type = TYPE_SPI_BUS;
spi_bus->bus.bus_state = BUS_INSTALL;
spi_bus->bus.private_data = spi_bus->private_data;
ret = BusRegister(&spi_bus->bus);
if (EOK != ret) {
KPrintf("SpiBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("SpiBusInit BusRegister bus has been register state%u\n", spi_bus->bus.bus_state);
}
return ret;
}
int SpiDriverInit(struct SpiDriver *spi_driver, const char *driver_name)
{
NULL_PARAM_CHECK(spi_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != spi_driver->driver.driver_state) {
spi_driver->driver.driver_type = TYPE_SPI_DRV;
spi_driver->driver.driver_state = DRV_INSTALL;
strncpy(spi_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
spi_driver->driver.configure = spi_driver->configure;
ret = SpiDriverRegister(&spi_driver->driver);
if (EOK != ret) {
KPrintf("SpiDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("SpiDriverInit DriverRegister driver has been register state%u\n", spi_driver->driver.driver_state);
}
return ret;
}
int SpiReleaseBus(struct SpiBus *spi_bus)
{
NULL_PARAM_CHECK(spi_bus);
return BusRelease(&spi_bus->bus);
}
int SpiDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("SpiDriverAttachToBus find spi bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_SPI_BUS == bus->bus_type) {
driver = SpiDriverFind(drv_name, TYPE_SPI_DRV);
if (NONE == driver) {
KPrintf("SpiDriverAttachToBus find spi driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_SPI_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("SpiDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+194
View File
@@ -0,0 +1,194 @@
/*
* 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 dev_spi.c
* @brief register spi dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_spi.h>
#include <dev_spi.h>
static DoubleLinklistType spidev_linklist;
/*Create the spi device linklist*/
static void SpiDeviceLinkInit()
{
InitDoubleLinkList(&spidev_linklist);
}
static uint32 SpiDeviceOpen(void *dev)
{
NULL_PARAM_CHECK(dev);
SpiDevConfigureCs(dev, 1, 0);
return EOK;
}
static uint32 SpiDeviceClose(void *dev)
{
NULL_PARAM_CHECK(dev);
SpiDevConfigureCs(dev, 0, 1);
return EOK;
}
static uint32 SpiDeviceWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
struct SpiHardwareDevice *spi_dev = (struct SpiHardwareDevice *)dev;
struct SpiDataStandard spi_msg;
spi_msg.tx_buff = (uint8 *)write_param->buffer;
spi_msg.rx_buff = NONE;
spi_msg.length = write_param->size;
spi_msg.spi_chip_select = 0;
spi_msg.spi_cs_release = 0;
spi_msg.next = NONE;
return spi_dev->spi_dev_done->write(spi_dev, &spi_msg);
}
static uint32 SpiDeviceRead(void *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(read_param);
struct SpiHardwareDevice *spi_dev = (struct SpiHardwareDevice *)dev;
struct SpiDataStandard spi_msg;
spi_msg.tx_buff = NONE;
spi_msg.rx_buff = (uint8 *)read_param->buffer;
spi_msg.length = read_param->size;
spi_msg.spi_chip_select = 0;
spi_msg.spi_cs_release = 0;
spi_msg.next = NONE;
return spi_dev->spi_dev_done->read(spi_dev, &spi_msg);
}
static const struct HalDevDone dev_done =
{
.open = SpiDeviceOpen,
.close = SpiDeviceClose,
.write = SpiDeviceWrite,
.read = SpiDeviceRead,
};
HardwareDevType SpiDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &spidev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("SpiDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int SpiDeviceRegister(struct SpiHardwareDevice *spi_device, void *spi_param, const char *device_name)
{
NULL_PARAM_CHECK(spi_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (dev_link_flag) {
SpiDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != spi_device->haldev.dev_state) {
strncpy(spi_device->haldev.dev_name, device_name, NAME_NUM_MAX);
spi_device->haldev.dev_type = TYPE_SPI_DEV;
spi_device->haldev.dev_state = DEV_INSTALL;
//only spi bus dev need to register dev_done
if (RET_TRUE != spi_device->spi_dev_flag) {
spi_device->haldev.dev_done = &dev_done;
}
spi_device->haldev.private_data = spi_param;
DoubleLinkListInsertNodeAfter(&spidev_linklist, &(spi_device->haldev.dev_link));
} else {
KPrintf("SpiDeviceRegister device has been register state%u\n", spi_device->haldev.dev_state);
}
return ret;
}
int SpiDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("SpiDeviceAttachToBus find spi bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_SPI_BUS == bus->bus_type) {
device = SpiDeviceFind(dev_name, TYPE_SPI_DEV);
if (NONE == device) {
KPrintf("SpiDeviceAttachToBus find spi device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_SPI_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("SpiDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
int SpiDevConfigureCs(struct HardwareDev *dev, uint8 spi_chip_select, uint8 spi_cs_release)
{
NULL_PARAM_CHECK(dev);
struct SpiHardwareDevice *spi_dev = (struct SpiHardwareDevice *)dev;
struct SpiDataStandard msg;
memset(&msg, 0, sizeof(struct SpiDataStandard));
msg.spi_chip_select = spi_chip_select;
msg.spi_cs_release = spi_cs_release;
return spi_dev->spi_dev_done->write(spi_dev, &msg);
}
+67
View File
@@ -0,0 +1,67 @@
/*
* 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 drv_spi.c
* @brief register spi drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_spi.h>
#include <dev_spi.h>
static DoubleLinklistType spidrv_linklist;
/*Create the driver linklist*/
static void SpiDrvLinkInit()
{
InitDoubleLinkList(&spidrv_linklist);
}
DriverType SpiDriverFind(const char *drv_name, enum DriverType drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &spidrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("SpiDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int SpiDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
SpiDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&spidrv_linklist, &(driver->driver_link));
return ret;
}
+348
View File
@@ -0,0 +1,348 @@
/*
* 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 flash_spi.c
* @brief support spi-flash dev function using spi bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <flash_spi.h>
/**
* This function supports to write data to the flash.
*
* @param dev flash dev descriptor
* @param write_param flash dev write datacfg param
*/
static uint32 SpiFlashWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
x_err_t ret = EOK;
x_OffPos pos;
x_size_t size;
const uint8 *write_buffer;
sfud_flash *sfud_flash_dev;
SpiFlashDeviceType spi_flash_dev;
HardwareDevType haldev = (struct HardwareDev *)dev;
struct SpiHardwareDevice *flash_dev;
flash_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev);
spi_flash_dev = CONTAINER_OF(flash_dev, struct SpiFlashDevice, flash_dev);
sfud_flash_dev = (sfud_flash *)spi_flash_dev->flash_param.flash_private_data;
pos = write_param->pos * spi_flash_dev->flash_param.flash_block_param.sector_bytes;
size = write_param->size * spi_flash_dev->flash_param.flash_block_param.sector_bytes;
write_buffer = (uint8 *)write_param->buffer;
ret = sfud_erase_write(sfud_flash_dev, pos, size, write_buffer);
if (SFUD_SUCCESS != ret) {
KPrintf("SpiFlashWrite error %d pos %d size %d buffer %p\n", ret, pos, size, write_buffer);
return ERROR;
}
return ret;
}
/**
* This function supports to read data from the flash.
*
* @param dev flash dev descriptor
* @param read_param flash dev read datacfg param
*/
static uint32 SpiFlashRead(void *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(read_param);
x_err_t ret = EOK;
x_OffPos pos;
x_size_t size;
uint8 *read_buffer;
sfud_flash *sfud_flash_dev;
SpiFlashDeviceType spi_flash_dev;
HardwareDevType haldev = (struct HardwareDev *)dev;
struct SpiHardwareDevice *flash_dev;
flash_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev);
spi_flash_dev = CONTAINER_OF(flash_dev, struct SpiFlashDevice, flash_dev);
sfud_flash_dev = (sfud_flash *)spi_flash_dev->flash_param.flash_private_data;
pos = read_param->pos * spi_flash_dev->flash_param.flash_block_param.sector_bytes;
size = read_param->size * spi_flash_dev->flash_param.flash_block_param.sector_bytes;
read_buffer = (uint8 *)read_param->buffer;
ret = sfud_read(sfud_flash_dev, pos, size, read_buffer);
if (SFUD_SUCCESS != ret) {
KPrintf("SpiFlashRead error %d pos %d size %d buffer %p\n", ret, pos, size, read_buffer);
return ERROR;
}
return ret;
}
/**
* This function supports to get block data from the flash dev.
*
* @param dev flash dev descriptor
* @param block_param flash dev read datacfg param
*/
static int SpiFlashControl(struct HardwareDev *dev, struct HalDevBlockParam *block_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(block_param);
x_err_t ret = EOK;
x_size_t size;
uint32_t addr;
sfud_flash *sfud_flash_dev;
SpiFlashDeviceType spi_flash_dev;
struct SpiHardwareDevice *flash_dev;
flash_dev = CONTAINER_OF(dev, struct SpiHardwareDevice, haldev);
spi_flash_dev = CONTAINER_OF(flash_dev, struct SpiFlashDevice, flash_dev);
sfud_flash_dev = (sfud_flash *)spi_flash_dev->flash_param.flash_private_data;
if (OPER_BLK_GETGEOME == block_param->cmd) {
block_param->dev_block.size_perbank = spi_flash_dev->flash_param.flash_block_param.sector_bytes;
block_param->dev_block.block_size = spi_flash_dev->flash_param.flash_block_param.block_size;
block_param->dev_block.bank_num = spi_flash_dev->flash_param.flash_block_param.sector_num;
} else if (OPER_BLK_ERASE == block_param->cmd) {
NULL_PARAM_CHECK(block_param->dev_addr);
if (block_param->dev_addr->start > block_param->dev_addr->end) {
KPrintf("SpiFlashControl erase start %u > end %u addr\n", block_param->dev_addr->start, block_param->dev_addr->end);
return ERROR;
} else if (block_param->dev_addr->start == block_param->dev_addr->end) {
block_param->dev_addr->end++;
}
addr = block_param->dev_addr->start * spi_flash_dev->flash_param.flash_block_param.sector_bytes;
size = (block_param->dev_addr->end - block_param->dev_addr->start)* spi_flash_dev->flash_param.flash_block_param.sector_bytes;
ret = sfud_erase(sfud_flash_dev, addr, size);
if (SFUD_SUCCESS != ret) {
KPrintf("SpiFlashControl erase error %d addr %p size %d\n", ret, addr, size);
return ERROR;
}
} else {
KPrintf("SpiFlashControl do not suppot the cmd 0x%x\n", block_param->cmd);
}
return ret;
}
static uint32 FlashSpiConfigure(SpiFlashDeviceType spi_flash_dev)
{
NULL_PARAM_CHECK(spi_flash_dev);
x_err_t ret = EOK;
struct Driver *spi_drv = spi_flash_dev->spi_dev->haldev.owner_bus->owner_driver;
struct BusConfigureInfo configure_info;
struct SpiMasterParam spi_master_param;
spi_master_param.spi_data_bit_width = 8;
spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB;
spi_master_param.spi_maxfrequency = SPI_FLASH_FREQUENCY;
spi_master_param.spi_data_endian = 0;
ret = spi_flash_dev->spi_dev->haldev.owner_bus->match(spi_drv, &spi_flash_dev->spi_dev->haldev);
if (EOK != ret) {
KPrintf("FLASH SPI dev match spi drv error!\n");
return ret;
}
configure_info.configure_cmd = OPE_CFG;
configure_info.private_data = (void *)&spi_master_param;
ret = BusDrvConfigure(spi_drv, &configure_info);
if (ret) {
KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", spi_drv, &spi_master_param);
return ERROR;
}
configure_info.configure_cmd = OPE_INT;
ret = BusDrvConfigure(spi_drv, &configure_info);
if (ret) {
KPrintf("spi drv OPE_INT error drv %8p\n", spi_drv);
return ERROR;
}
return ret;
}
/**
* This function supports to find sfud_flash descriptor by flash_name
*
* @param flash_name flash dev name
*/
sfud_flash_t SpiFlashFind(char *flash_name)
{
NULL_PARAM_CHECK(flash_name);
HardwareDevType haldev = SpiDeviceFind(flash_name, TYPE_SPI_DEV);
if (NONE == haldev) {
KPrintf("SpiFlashFind %s error! \n", flash_name);
return NONE;
}
struct SpiHardwareDevice *flash_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev);
SpiFlashDeviceType spi_flash_dev = CONTAINER_OF(flash_dev, struct SpiFlashDevice, flash_dev);
sfud_flash_t sfud_flash_dev = (sfud_flash_t)spi_flash_dev->flash_param.flash_private_data;
return sfud_flash_dev;
}
static const struct FlashDevDone flash_done =
{
.open = NONE,
.close = NONE,
.write = SpiFlashWrite,
.read = SpiFlashRead,
};
/**
* This function supports to init spi_flash_dev and sfud_flash descriptor
*
* @param bus_name spi bus name
* @param dev_name spi dev name
* @param drv_name spi drv name
* @param flash_name flash dev name
*/
SpiFlashDeviceType SpiFlashInit(char *bus_name, char *dev_name, char *drv_name, char *flash_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(flash_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret;
HardwareDevType haldev = SpiDeviceFind(dev_name, TYPE_SPI_DEV);
if (NONE == haldev) {
KPrintf("SpiFlashInit find spi haldev %s error! \n", dev_name);
return NONE;
}
SpiFlashDeviceType spi_flash_dev = (SpiFlashDeviceType)malloc(sizeof(struct SpiFlashDevice));
if (NONE == spi_flash_dev) {
KPrintf("SpiFlashInit malloc spi_flash_dev failed\n");
free(spi_flash_dev);
return NONE;
}
sfud_flash *sfud_flash_dev = (sfud_flash_t)malloc(sizeof(sfud_flash));
if (NONE == sfud_flash_dev) {
KPrintf("SpiFlashInit malloc sfud_flash_dev failed\n");
free(spi_flash_dev);
free(sfud_flash_dev);
return NONE;
}
memset(spi_flash_dev, 0, sizeof(struct SpiFlashDevice));
memset(sfud_flash_dev, 0, sizeof(sfud_flash));
spi_flash_dev->spi_dev = CONTAINER_OF(haldev, struct SpiHardwareDevice, haldev);
spi_flash_dev->flash_dev.spi_dev_flag = RET_TRUE;
spi_flash_dev->flash_param.flash_private_data = (void *)sfud_flash_dev;
spi_flash_dev->flash_dev.haldev.dev_done = (struct HalDevDone *)&flash_done;
spi_flash_dev->flash_dev.haldev.dev_block_control = SpiFlashControl;
spi_flash_dev->spi_dev->haldev.owner_bus->owner_driver = SpiDriverFind(drv_name, TYPE_SPI_DRV);
if (NONE == spi_flash_dev->spi_dev->haldev.owner_bus->owner_driver) {
KPrintf("SpiFlashInit find spi driver %s error! \n", drv_name);
free(spi_flash_dev);
free(sfud_flash_dev);
return NONE;
}
ret = FlashSpiConfigure(spi_flash_dev);
if (EOK != ret) {
KPrintf("SpiFlashInit configure failed\n");
free(spi_flash_dev);
free(sfud_flash_dev);
return NONE;
}
sfud_flash_dev->name = flash_name;
sfud_flash_dev->user_data = (void *)spi_flash_dev;
sfud_flash_dev->spi.name = dev_name;
sfud_flash_dev->spi.user_data = (void *)sfud_flash_dev;
ret = sfud_device_init(sfud_flash_dev);
if (SFUD_SUCCESS != ret) {
KPrintf("sfud_device_init failed %d\n", ret);
free(spi_flash_dev);
free(sfud_flash_dev);
return NONE;
}
spi_flash_dev->flash_param.flash_block_param.block_size = sfud_flash_dev->chip.erase_gran;
spi_flash_dev->flash_param.flash_block_param.sector_bytes = sfud_flash_dev->chip.erase_gran;
spi_flash_dev->flash_param.flash_block_param.sector_num = sfud_flash_dev->chip.capacity / sfud_flash_dev->chip.erase_gran;
ret = SpiDeviceRegister(&spi_flash_dev->flash_dev, NONE, flash_name);
if (EOK != ret) {
KPrintf("SpiFlashInit SpiDeviceRegister device %s error %d\n", flash_name, ret);
free(spi_flash_dev);
free(sfud_flash_dev);
return NONE;
}
ret = SpiDeviceAttachToBus(flash_name, bus_name);
if (EOK != ret) {
KPrintf("SpiFlashInit SpiDeviceAttachToBus device %s error %d\n", flash_name, ret);
free(spi_flash_dev);
free(sfud_flash_dev);
return NONE;
}
spi_flash_dev->flash_lock = KMutexCreate();
return spi_flash_dev;
}
/**
* This function supports to release spi_flash_dev and sfud_flash descriptor
*
* @param spi_flash_dev spi flash descriptor
*/
uint32 SpiFlashRelease(SpiFlashDeviceType spi_flash_dev)
{
NULL_PARAM_CHECK(spi_flash_dev);
x_err_t ret;
sfud_flash *sfud_flash_dev = (sfud_flash_t)spi_flash_dev->flash_param.flash_private_data;
DeviceDeleteFromBus(spi_flash_dev->flash_dev.haldev.owner_bus, &spi_flash_dev->flash_dev.haldev);
KMutexDelete(spi_flash_dev->flash_lock);
free(sfud_flash_dev);
free(spi_flash_dev);
return EOK;
}
+6
View File
@@ -0,0 +1,6 @@
SRC_FILES := sd_spi.c
include $(KERNEL_ROOT)/compiler.mk
File diff suppressed because it is too large Load Diff
+9
View File
@@ -0,0 +1,9 @@
ifeq ($(CONFIG_RESOURCES_SPI_SFUD),y)
SRC_DIR += SFUD
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,7 @@
SRC_DIR += sfud
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,297 @@
# SFUD (Serial Flash Universal Driver) 串行 Flash 通用驱动库
---
## 0、SFUD 是什么
[SFUD](https://github.com/armink/SFUD) 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行 Flash 种类居多,各个 Flash 的规格及命令存在差异, SFUD 就是为了解决这些 Flash 的差异现状而设计,让我们的产品能够支持不同品牌及规格的 Flash,提高了涉及到 Flash 功能的软件的可重用性及可扩展性,同时也可以规避 Flash 缺货或停产给产品所带来的风险。
- 主要特点:支持 SPI/QSPI 接口、面向对象(同时支持多个 Flash 对象)、可灵活裁剪、扩展性强、支持 4 字节地址
- 资源占用
- 标准占用:RAM:0.2KB ROM:5.5KB
- 最小占用:RAM:0.1KB ROM:3.6KB
- 设计思路:
- **什么是 SFDP** :它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B ([点击这里查看](https://www.jedec.org/standards-documents/docs/jesd216b))。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数。
- **不支持 SFDP 怎么办** :如果该 Flash 不支持 SFDP 标准,SFUD 会查询配置文件 ( [`/sfud/inc/sfud_flash_def.h`](https://github.com/armink/SFUD/blob/4bee2d0417a7ce853cc7aa3639b03fe825611fd9/sfud/inc/sfud_flash_def.h#L116-L142) ) 中提供的 **Flash 参数信息表** 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 [2.5 添加库目前不支持的 Flash](#25-添加库目前不支持的-flash))。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。
## 1、为什么选择 SFUD
- 避免项目因 Flash 缺货、Flash 停产或产品扩容而带来的风险;
- 越来越多的项目将固件存储到串行 Flash 中,例如:ESP8266 的固件、主板中的 BIOS 及其他常见电子产品中的固件等等,但是各种 Flash 规格及命令不统一。使用 SFUD 即可避免,在相同功能的软件平台基础下,无法适配不同 Flash 种类的硬件平台的问题,提高软件的可重用性;
- 简化软件流程,降低开发难度。现在只需要配置好 SPI 通信,即可畅快的开始玩串行 Flash 了;
- 可以用来制作 Flash 编程器/烧写器
## 2、SFUD 如何使用
### 2.1 已支持 Flash
下表为所有已在 Demo 平台上进行过真机测试过的 Flash。显示为 **不支持** SFDP 标准的 Flash 已经在 Flash 参数信息表中定义,更多不支持 SFDP 标准的 Flash 需要大家以后 **共同来完善和维护** **([Github](https://github.com/armink/SFUD)|[OSChina](http://git.oschina.net/armink/SFUD)|[Coding](https://coding.net/u/armink/p/SFUD/git))** 。
如果觉得这个开源项目很赞,可以点击 [项目主页](https://github.com/armink/SFUD) 右上角的 **Star** ,同时把它推荐给更多有需要的朋友。
|型号|制造商|容量|最高速度|SFDP 标准|QSPI 模式|备注|
|:--:|:----:|:--:|:--:|:--:|:--:|----|
|[W25Q40BV](http://microchip.ua/esp8266/W25Q40BV(EOL).pdf)|Winbond|4Mb|50Mhz|不支持|双线|已停产|
|[W25Q80DV](http://www.winbond.com/resource-files/w25q80dv_revg_07212015.pdf)|Winbond|8Mb|104Mhz|支持|双线||
|[W25Q16BV](https://media.digikey.com/pdf/Data%20Sheets/Winbond%20PDFs/W25Q16BV.pdf)|Winbond|16Mb|104Mhz|不支持|双线| by [slipperstree](https://github.com/slipperstree)|
|[W25Q16CV](http://www.winbond.com/resource-files/da00-w25q16cvf1.pdf)|Winbond|16Mb|104Mhz|支持|未测试||
|[W25Q16DV](http://www.winbond.com/resource-files/w25q16dv%20revk%2005232016%20doc.pdf)|Winbond|16Mb|104Mhz|支持|未测试| by [slipperstree](https://github.com/slipperstree)|
|[W25Q32BV](http://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf)|Winbond|32Mb|104Mhz|支持|双线||
|[W25Q64CV](http://www.winbond.com/resource-files/w25q64cv_revh_052214[2].pdf)|Winbond|64Mb|80Mhz|支持|四线||
|[W25Q128BV](http://www.winbond.com/resource-files/w25q128bv_revh_100313_wo_automotive.pdf)|Winbond|128Mb|104Mhz|支持|四线||
|[W25Q256FV](http://www.winbond.com/resource-files/w25q256fv%20revi%2002262016%20kms.pdf)|Winbond|256Mb|104Mhz|支持|四线||
|[MX25L3206E](http://www.macronix.com/Lists/DataSheet/Attachments/3199/MX25L3206E,%203V,%2032Mb,%20v1.5.pdf)|Macronix|32Mb|86MHz|支持|双线||
|[KH25L4006E](http://www.macronix.com.hk/Lists/Datasheet/Attachments/117/KH25L4006E.pdf)|Macronix|4Mb|86Mhz|支持|未测试| by [JiapengLi](https://github.com/JiapengLi)|
|[KH25L3206E](http://www.macronix.com.hk/Lists/Datasheet/Attachments/131/KH25L3206E.pdf)|Macronix|32Mb|86Mhz|支持|双线||
|[SST25VF016B](http://ww1.microchip.com/downloads/en/DeviceDoc/20005044C.pdf)|Microchip|16Mb|50MHz|不支持|不支持| SST 已被 Microchip 收购|
|[M25P40](https://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/m25p/m25p40.pdf)|Micron|4Mb|75Mhz|不支持|未测试| by [redocCheng](https://github.com/redocCheng)|
|[M25P80](https://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/m25p/m25p80.pdf)|Micron|8Mb|75Mhz|不支持|未测试| by [redocCheng](https://github.com/redocCheng)|
|[M25P32](https://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/m25p/m25p32.pdf)|Micron|32Mb|75Mhz|不支持|不支持||
|[EN25Q32B](http://www.kean.com.au/oshw/WR703N/teardown/EN25Q32B%2032Mbit%20SPI%20Flash.pdf)|EON|32Mb|104MHz|不支持|未测试||
|[GD25Q16B](http://www.gigadevice.com/product/detail/5/410.html)|GigaDevice|16Mb|120Mhz|不支持|未测试| by [TanekLiang](https://github.com/TanekLiang) |
|[GD25Q32C](http://www.gigadevice.com/product/detail/5/410.html)|GigaDevice|32Mb|120Mhz|不支持|未测试| by [gaupen1186](https://github.com/gaupen1186) |
|[GD25Q64B](http://www.gigadevice.com/product/detail/5/364.html)|GigaDevice|64Mb|120Mhz|不支持|双线||
|[S25FL216K](http://www.cypress.com/file/197346/download)|Cypress|16Mb|65Mhz|不支持|双线||
|[S25FL032P](http://www.cypress.com/file/196861/download)|Cypress|32Mb|104Mhz|不支持|未测试| by [yc_911](https://gitee.com/yc_911) |
|[S25FL164K](http://www.cypress.com/file/196886/download)|Cypress|64Mb|108Mhz|支持|未测试||
|[A25L080](http://www.amictechnology.com/datasheets/A25L080.pdf)|AMIC|8Mb|100Mhz|不支持|双线||
|[A25LQ64](http://www.amictechnology.com/datasheets/A25LQ64.pdf)|AMIC|64Mb|104Mhz|支持|支持||
|[F25L004](http://www.esmt.com.tw/db/manager/upload/f25l004.pdf)|ESMT|4Mb|100Mhz|不支持|不支持||
|[PCT25VF016B](http://pctgroup.com.tw/attachments/files/files/248_25VF016B-P.pdf)|PCT|16Mb|80Mhz|不支持|不支持|SST 授权许可,会被识别为 SST25VF016B|
|[AT45DB161E](http://www.adestotech.com/wp-content/uploads/doc8782.pdf)|ADESTO|16Mb|85MHz|不支持|不支持|ADESTO 收购 Atmel 串行闪存产品线|
> 注:QSPI 模式中,双线表示支持双线快读,四线表示支持四线快读。
>
> 一般情况下,支持四线快读的 FLASH 也支持两线快读。
### 2.2 API 说明
先说明下本库主要使用的一个结构体 `sfud_flash` 。其定义位于 `/sfud/inc/sfud_def.h`。每个 SPI Flash 会对应一个该结构体,该结构体指针下面统称为 Flash 设备对象。初始化成功后在 `sfud_flash->chip` 结构体中会存放 SPI Flash 的常见参数。如果 SPI Flash 还支持 SFDP ,还可以通过 `sfud_flash->sfdp` 看到更加全面的参数信息。以下很多函数都将使用 Flash 设备对象作为第一个入参,实现对指定 SPI Flash 的操作。
#### 2.2.1 初始化 SFUD 库
将会调用 `sfud_device_init` ,初始化 Flash 设备表中的全部设备。如果只有一个 Flash 也可以只使用 `sfud_device_init` 进行单一初始化。
> **注意**:初始化完的 SPI Flash 默认都 **已取消写保护** 状态,如需开启写保护,请使用 sfud_write_status 函数修改 SPI Flash 状态。
```C
sfud_err sfud_init(void)
```
#### 2.2.2 初始化指定的 Flash 设备
```C
sfud_err sfud_device_init(sfud_flash *flash)
```
|参数 |描述|
|:----- |:----|
|flash |待初始化的 Flash 设备|
#### 2.2.3 使能快速读模式(仅当 SFUD 开启 QSPI 模式后可用)
当 SFUD 开启 QSPI 模式后,SFUD 中的 Flash 驱动支持使用 QSPI 总线进行通信。相比传统的 SPI 模式,使用 QSPI 能够加速 Flash 数据的读取,但当数据需要写入时,由于 Flash 本身的数据写入速度慢于 SPI 传输速度,所以 QSPI 模式下的数据写入速度提升并不明显。
所以 SFUD 对于 QSPI 模式的支持仅限于快速读命令。通过该函数可以配置 Flash 所使用的 QSPI 总线的实际支持的数据线最大宽度,例如:1 线(默认值,即传统的 SPI 模式)、2 线、4 线。
设置后,SFUD 会去结合当前设定的 QSPI 总线数据线宽度,去 [QSPI Flash 扩展信息表](https://github.com/armink/SFUD/blob/069d2b409ec239f84d675b2c3d37894e908829e6/sfud/inc/sfud_flash_def.h#L149-L177) 中匹配最合适的、速度最快的快速读命令,之后用户在调用 sfud_read() 时,会使用 QSPI 模式的传输函数发送该命令。
```C
sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width)
```
| 参数 | 描述 |
| :-------------- | :------------------------------------------- |
| flash | Flash 设备 |
| data_line_width | QSPI 总线支持的数据线最大宽度,例如:1、2、4 |
#### 2.2.4 获取 Flash 设备对象
在 SFUD 配置文件中会定义 Flash 设备表,负责存放所有将要使用的 Flash 设备对象,所以 SFUD 支持多个 Flash 设备同时驱动。设备表的配置在 `/sfud/inc/sfud_cfg.h``SFUD_FLASH_DEVICE_TABLE` 宏定义,详细配置方法参照 [2.3 配置方法 Flash](#23-配置方法))。本方法通过 Flash 设备位于设备表中索引值来返回 Flash 设备对象,超出设备表范围返回 `NULL`
```C
sfud_flash *sfud_get_device(size_t index)
```
|参数 |描述|
|:----- |:----|
|index |Flash 设备位于 FLash 设备表中的索引值|
#### 2.2.5 读取 Flash 数据
```C
sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t *data)
```
|参数 |描述|
|:----- |:----|
|flash |Flash 设备对象|
|addr |起始地址|
|size |从起始地址开始读取数据的总大小|
|data |读取到的数据|
#### 2.2.6 擦除 Flash 数据
> 注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 `sfud_flash->chip.erase_gran` 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。
```C
sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size)
```
|参数 |描述|
|:----- |:----|
|flash |Flash 设备对象|
|addr |起始地址|
|size |从起始地址开始擦除数据的总大小|
#### 2.2.7 擦除 Flash 全部数据
```C
sfud_err sfud_chip_erase(const sfud_flash *flash)
```
|参数 |描述|
|:----- |:----|
|flash |Flash 设备对象|
#### 2.2.8 往 Flash 写数据
```C
sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data)
```
|参数 |描述|
|:----- |:----|
|flash |Flash 设备对象|
|addr |起始地址|
|size |从起始地址开始写入数据的总大小|
|data |待写入的数据|
#### 2.2.9 先擦除再往 Flash 写数据
> 注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 `sfud_flash->chip.erase_gran` 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。
```C
sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data)
```
|参数 |描述|
|:----- |:----|
|flash |Flash 设备对象|
|addr |起始地址|
|size |从起始地址开始写入数据的总大小|
|data |待写入的数据|
#### 2.2.10 读取 Flash 状态
```C
sfud_err sfud_read_status(const sfud_flash *flash, uint8_t *status)
```
|参数 |描述|
|:----- |:----|
|flash |Flash 设备对象|
|status |当前状态寄存器值|
#### 2.2.11 写(修改) Flash 状态
```C
sfud_err sfud_write_status(const sfud_flash *flash, bool is_volatile, uint8_t status)
```
|参数 |描述|
|:----- |:----|
|flash |Flash 设备对象|
|is_volatile |是否为易闪失的,true: 易闪失的,及断电后会丢失|
|status |当前状态寄存器值|
### 2.3 配置方法
所有配置位于 `/sfud/inc/sfud_cfg.h` ,请参考下面的配置介绍,选择适合自己项目的配置。
#### 2.3.1 调试模式
打开/关闭 `SFUD_DEBUG_MODE` 宏定义
#### 2.3.2 是否使用 SFDP 参数功能
打开/关闭 `SFUD_USING_SFDP` 宏定义
> 注意:关闭后只会查询该库在 `/sfud/inc/sfud_flash_def.h` 中提供的 Flash 信息表。这样虽然会降低软件的适配性,但减少代码量。
#### 2.3.3 是否使用该库自带的 Flash 参数信息表
打开/关闭 `SFUD_USING_FLASH_INFO_TABLE` 宏定义
> 注意:关闭后该库只驱动支持 SFDP 规范的 Flash,也会适当的降低部分代码量。另外 2.3.2 及 2.3.3 这两个宏定义至少定义一种,也可以两种方式都选择。
#### 2.3.4 既不使用 SFDP ,也不使用 Flash 参数信息表
为了进一步降低代码量,`SFUD_USING_SFDP``SFUD_USING_FLASH_INFO_TABLE` 也可以 **都不定义**
此时,只要在定义 Flash 设备时,指定好 Flash 参数,之后再调用 `sfud_device_init` 对该设备进行初始化。参考如下代码:
```C
sfud_flash sfud_norflash0 = {
.name = "norflash0",
.spi.name = "SPI1",
.chip = { "W25Q64FV", SFUD_MF_ID_WINBOND, 0x40, 0x17, 8L * 1024L * 1024L, SFUD_WM_PAGE_256B, 4096, 0x20 } };
......
sfud_device_init(&sfud_norflash0);
......
```
#### 2.3.5 Flash 设备表
如果产品中存在多个 Flash ,可以添加 Flash 设备表。修改 `SFUD_FLASH_DEVICE_TABLE` 这个宏定义,示例如下:
```C
enum {
SFUD_W25Q64CV_DEVICE_INDEX = 0,
SFUD_GD25Q64B_DEVICE_INDEX = 1,
};
#define SFUD_FLASH_DEVICE_TABLE \
{ \
[SFUD_W25Q64CV_DEVICE_INDEX] = {.name = "W25Q64CV", .spi.name = "SPI1"}, \
[SFUD_GD25Q64B_DEVICE_INDEX] = {.name = "GD25Q64B", .spi.name = "SPI3"}, \
}
```
上面定义了两个 Flash 设备(大部分产品一个足以),两个设备的名称为 `"W25Q64CV"``"GD25Q64B"` ,分别对应 `"SPI1"``"SPI3"` 这两个 SPI 设备名称(在移植 SPI 接口时会用到,位于 `/sfud/port/sfud_port.c` ), `SFUD_W25Q16CV_DEVICE_INDEX``SFUD_GD25Q64B_DEVICE_INDEX` 这两个枚举定义了两个设备位于设备表中的索引,可以通过 `sfud_get_device_table()` 方法获取到设备表,再配合这个索引值来访问指定的设备。
#### 2.3.6 QSPI 模式
打开/关闭 `SFUD_USING_QSPI` 宏定义
开启后,SFUD 也将支持使用 QSPI 总线连接的 Flash。
### 2.4 移植说明
移植文件位于 `/sfud/port/sfud_port.c` ,文件中的 `sfud_err sfud_spi_port_init(sfud_flash *flash)` 方法是库提供的移植方法,在里面完成各个设备 SPI 读写驱动(必选)、重试次数(必选)、重试接口(可选)及 SPI 锁(可选)的配置。更加详细的移植内容,可以参考 demo 中的各个平台的移植文件。
### 2.5 添加库目前不支持的 Flash
这里需要修改 `/sfud/inc/sfdu_flash_def.h` ,所有已经支持的 Flash 见 `SFUD_FLASH_CHIP_TABLE` 宏定义,需要提前准备的 Flash 参数内容分别为:| 名称 | 制造商 ID | 类型 ID | 容量 ID | 容量 | 写模式 | 擦除粒度(擦除的最小单位) | 擦除粒度对应的命令 | 。这里以添加 兆易创新 ( GigaDevice ) 的 `GD25Q64B` Flash 来举例。
此款 Flash 为兆易创新的早期生产的型号,所以不支持 SFDP 标准。首先需要下载其数据手册,找到 0x9F 命令返回的 3 种 ID, 这里需要最后面两字节 ID ,即 `type id``capacity id``GD25Q64B` 对应这两个 ID 分别为 `0x40``0x17` 。上面要求的其他 Flash 参数都可以在数据手册中找到,这里要重点说明下 **写模式** 这个参数,库本身提供的写模式共计有 4 种,详见文件顶部的 `sfud_write_mode` 枚举类型,同一款 Flash 可以同时支持多种写模式,视情况而定。对于 `GD25Q64B` 而言,其支持的写模式应该为 `SFUD_WM_PAGE_256B` ,即写 1-256 字节每页。结合上述 `GD25Q64B` 的 Flash 参数应如下:
```
{"GD25Q64B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, 8*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20},
```
再将其增加到 `SFUD_FLASH_CHIP_TABLE` 宏定义末尾,即可完成该库对 `GD25Q64B` 的支持。
### 2.6 Demo
目前已支持如下平台下的 Demo
|路径 |平台描述|
|:----- |:----|
|[/demo/stm32f10x_non_os](https://github.com/armink/SFUD/tree/master/demo/stm32f10x_non_os) |STM32F10X 裸机平台|
|[/demo/stm32f2xx_rtt](https://github.com/armink/SFUD/tree/master/demo/stm32f2xx_rtt) |STM32F2XX + [RT-Thread](http://www.rt-thread.org/) 操作系统平台|
|[/demo/stm32l475_non_os_qspi](https://github.com/armink/SFUD/tree/master/demo/stm32l475_non_os_qspi) |STM32L475 + QSPI 模式 裸机平台|
### 2.7 许可
采用 MIT 开源协议,细节请阅读项目中的 LICENSE 文件内容。
@@ -0,0 +1,7 @@
SRC_DIR += src port
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,197 @@
/*
* This file is part of the Serial Flash Universal Driver Library.
*
* Copyright (c) 2016-2018, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is an head file for this library. You can see all of the functions which can be called by user.
* Created on: 2016-04-23
*/
/**
* @file sfud.h
* @brief define sfud lib function api
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
/*************************************************
File name: sfud.h
Description: support sfud lib function api
Others: add sfud.h to support SPI Flash function based on SFUD LIB
https://github.com/armink/SFUD
History:
1. Date: 2021-04-24
Author: AIIT XUOS Lab
Modification:
*************************************************/
#ifndef _SFUD_H_
#define _SFUD_H_
#include <sfud_def.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ../src/sfup.c */
/**
* SFUD library initialize.
*
* @return result
*/
sfud_err sfud_init(void);
/**
* SFUD initialize by flash device
*
* @param flash flash device
*
* @return result
*/
sfud_err sfud_device_init(sfud_flash *flash);
/**
* get flash device by its index which in the flash information table
*
* @param index the index which in the flash information table @see flash_table
*
* @return flash device
*/
sfud_flash *sfud_get_device(size_t index);
/**
* get flash device total number on flash device information table @see flash_table
*
* @return flash device total number
*/
size_t sfud_get_device_num(void);
/**
* get flash device information table @see flash_table
*
* @return flash device table pointer
*/
const sfud_flash *sfud_get_device_table(void);
#ifdef SFUD_USING_QSPI
/**
* Enbale the fast read mode in QSPI flash mode. Default read mode is normal SPI mode.
*
* it will find the appropriate fast-read instruction to replace the read instruction(0x03)
* fast-read instruction @see SFUD_FLASH_EXT_INFO_TABLE
*
* @note When Flash is in QSPI mode, the method must be called after sfud_device_init().
*
* @param flash flash device
* @param data_line_width the data lines max width which QSPI bus supported, such as 1, 2, 4
*
* @return result
*/
sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width);
#endif /* SFUD_USING_QSPI */
/**
* read flash data
*
* @param flash flash device
* @param addr start address
* @param size read size
* @param data read data pointer
*
* @return result
*/
sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t *data);
/**
* erase flash data
*
* @note It will erase align by erase granularity.
*
* @param flash flash device
* @param addr start address
* @param size erase size
*
* @return result
*/
sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size);
/**
* write flash data (no erase operate)
*
* @param flash flash device
* @param addr start address
* @param data write data
* @param size write size
*
* @return result
*/
sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data);
/**
* erase and write flash data
*
* @param flash flash device
* @param addr start address
* @param size write size
* @param data write data
*
* @return result
*/
sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data);
/**
* erase all flash data
*
* @param flash flash device
*
* @return result
*/
sfud_err sfud_chip_erase(const sfud_flash *flash);
/**
* read flash register status
*
* @param flash flash device
* @param status register status
*
* @return result
*/
sfud_err sfud_read_status(const sfud_flash *flash, uint8_t *status);
/**
* write status register
*
* @param flash flash device
* @param is_volatile true: volatile mode, false: non-volatile mode
* @param status register status
*
* @return result
*/
sfud_err sfud_write_status(const sfud_flash *flash, bool is_volatile, uint8_t status);
#ifdef __cplusplus
}
#endif
#endif /* _SFUD_H_ */
@@ -0,0 +1,69 @@
/*
* This file is part of the Serial Flash Universal Driver Library.
*
* Copyright (c) 2016-2018, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is the configure head file for this library.
* Created on: 2016-04-23
*/
/**
* @file sfud_cfg.h
* @brief define SFUD_DEBUG_MODE and SFUD_FLASH_DEVICE_TABLE
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
/*************************************************
File name: sfud_cfg.h
Description: support sfud debug log and device table configure
Others: add sfud_cfg.h to support SPI Flash function based on SFUD LIB
https://github.com/armink/SFUD
History:
1. Date: 2021-04-24
Author: AIIT XUOS Lab
Modification:
1. add xsconfig.h support
*************************************************/
#ifndef _SFUD_CFG_H_
#define _SFUD_CFG_H_
#include <xsconfig.h>
#ifdef SFUD_DEBUG_LOG
#define SFUD_DEBUG_MODE
#endif
enum {
SFUD_XXXX_DEVICE_INDEX = 0,
};
#define SFUD_FLASH_DEVICE_TABLE \
{ \
[SFUD_XXXX_DEVICE_INDEX] = {.name = "XXXX", .spi.name = "SPIX"}, \
}
//#define SFUD_USING_QSPI
#endif /* _SFUD_CFG_H_ */
@@ -0,0 +1,315 @@
/*
* This file is part of the Serial Flash Universal Driver Library.
*
* Copyright (c) 2016-2018, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is the macro definition head file for this library.
* Created on: 2016-04-23
*/
/**
* @file sfud_def.h
* @brief define sfud function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
/*************************************************
File name: sfud_def.h
Description: support sfud function and struct
Others: add sfud_def.h to support SPI Flash function based on SFUD LIB
https://github.com/armink/SFUD
History:
1. Date: 2021-04-24
Author: AIIT XUOS Lab
Modification:
*************************************************/
#ifndef _SFUD_DEF_H_
#define _SFUD_DEF_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <sfud_cfg.h>
#include <sfud_flash_def.h>
#ifdef __cplusplus
extern "C" {
#endif
/* debug print function. Must be implement by user. */
#ifdef SFUD_DEBUG_MODE
#ifndef SFUD_DEBUG
#define SFUD_DEBUG(...) sfud_log_debug(__FILE__, __LINE__, __VA_ARGS__)
#endif /* SFUD_DEBUG */
#else
#define SFUD_DEBUG(...)
#endif /* SFUD_DEBUG_MODE */
#ifndef SFUD_INFO
#define SFUD_INFO(...) sfud_log_info(__VA_ARGS__)
#endif
/* CHECK for developer. */
#ifdef SFUD_DEBUG_MODE
#define SFUD_ASSERT(EXPR) \
if (!(EXPR)) \
{ \
SFUD_DEBUG("(%s) has CHECK failed at %s.", #EXPR, __FUNCTION__); \
while (1); \
}
#else
#define SFUD_ASSERT(EXPR)
#endif
/**
* retry process
*
* @param delay delay function for every retry. NULL will not delay for every retry.
* @param retry retry counts
* @param result SFUD_ERR_TIMEOUT: retry timeout
*/
#define SFUD_RETRY_PROCESS(delay, retry, result) \
void (*__delay_temp)(void) = (void (*)(void))delay; \
if (retry == 0) {result = SFUD_ERR_TIMEOUT;break;} \
else {if (__delay_temp) {__delay_temp();} retry --;}
/* software version number */
#define SFUD_SW_VERSION "1.1.0"
/*
* all defined supported command
*/
#ifndef SFUD_CMD_WRITE_ENABLE
#define SFUD_CMD_WRITE_ENABLE 0x06
#endif
#ifndef SFUD_CMD_WRITE_DISABLE
#define SFUD_CMD_WRITE_DISABLE 0x04
#endif
#ifndef SFUD_CMD_READ_STATUS_REGISTER
#define SFUD_CMD_READ_STATUS_REGISTER 0x05
#endif
#ifndef SFUD_VOLATILE_SR_WRITE_ENABLE
#define SFUD_VOLATILE_SR_WRITE_ENABLE 0x50
#endif
#ifndef SFUD_CMD_WRITE_STATUS_REGISTER
#define SFUD_CMD_WRITE_STATUS_REGISTER 0x01
#endif
#ifndef SFUD_CMD_PAGE_PROGRAM
#define SFUD_CMD_PAGE_PROGRAM 0x02
#endif
#ifndef SFUD_CMD_AAI_WORD_PROGRAM
#define SFUD_CMD_AAI_WORD_PROGRAM 0xAD
#endif
#ifndef SFUD_CMD_ERASE_CHIP
#define SFUD_CMD_ERASE_CHIP 0xC7
#endif
#ifndef SFUD_CMD_READ_DATA
#define SFUD_CMD_READ_DATA 0x03
#endif
#ifndef SFUD_CMD_DUAL_OUTPUT_READ_DATA
#define SFUD_CMD_DUAL_OUTPUT_READ_DATA 0x3B
#endif
#ifndef SFUD_CMD_DUAL_IO_READ_DATA
#define SFUD_CMD_DUAL_IO_READ_DATA 0xBB
#endif
#ifndef SFUD_CMD_QUAD_IO_READ_DATA
#define SFUD_CMD_QUAD_IO_READ_DATA 0xEB
#endif
#ifndef SFUD_CMD_QUAD_OUTPUT_READ_DATA
#define SFUD_CMD_QUAD_OUTPUT_READ_DATA 0x6B
#endif
#ifndef SFUD_CMD_MANUFACTURER_DEVICE_ID
#define SFUD_CMD_MANUFACTURER_DEVICE_ID 0x90
#endif
#ifndef SFUD_CMD_JEDEC_ID
#define SFUD_CMD_JEDEC_ID 0x9F
#endif
#ifndef SFUD_CMD_READ_UNIQUE_ID
#define SFUD_CMD_READ_UNIQUE_ID 0x4B
#endif
#ifndef SFUD_CMD_READ_SFDP_REGISTER
#define SFUD_CMD_READ_SFDP_REGISTER 0x5A
#endif
#ifndef SFUD_CMD_ENABLE_RESET
#define SFUD_CMD_ENABLE_RESET 0x66
#endif
#ifndef SFUD_CMD_RESET
#define SFUD_CMD_RESET 0x99
#endif
#ifndef SFUD_CMD_ENTER_4B_ADDRESS_MODE
#define SFUD_CMD_ENTER_4B_ADDRESS_MODE 0xB7
#endif
#ifndef SFUD_CMD_EXIT_4B_ADDRESS_MODE
#define SFUD_CMD_EXIT_4B_ADDRESS_MODE 0xE9
#endif
#ifndef SFUD_WRITE_MAX_PAGE_SIZE
#define SFUD_WRITE_MAX_PAGE_SIZE 256
#endif
/* send dummy data for read data */
#ifndef SFUD_DUMMY_DATA
#define SFUD_DUMMY_DATA 0xFF
#endif
/* maximum number of erase type support on JESD216 (V1.0) */
#define SFUD_SFDP_ERASE_TYPE_MAX_NUM 4
/**
* status register bits
*/
enum {
SFUD_STATUS_REGISTER_BUSY = (1 << 0), /**< busing */
SFUD_STATUS_REGISTER_WEL = (1 << 1), /**< write enable latch */
SFUD_STATUS_REGISTER_SRP = (1 << 7), /**< status register protect */
};
/**
* error code
*/
typedef enum {
SFUD_SUCCESS = 0, /**< success */
SFUD_ERR_NOT_FOUND = 1, /**< not found or not supported */
SFUD_ERR_WRITE = 2, /**< write error */
SFUD_ERR_READ = 3, /**< read error */
SFUD_ERR_TIMEOUT = 4, /**< timeout error */
SFUD_ERR_ADDR_OUT_OF_BOUND = 5, /**< address is out of flash bound */
} sfud_err;
#ifdef SFUD_USING_QSPI
/**
* QSPI flash read cmd format
*/
typedef struct {
uint8_t instruction;
uint8_t instruction_lines;
uint8_t address_size;
uint8_t address_lines;
uint8_t alternate_bytes_lines;
uint8_t dummy_cycles;
uint8_t data_lines;
} sfud_qspi_read_cmd_format;
#endif /* SFUD_USING_QSPI */
/* SPI bus write read data function type */
typedef sfud_err (*spi_write_read_func)(const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, size_t read_size);
#ifdef SFUD_USING_SFDP
/**
* the SFDP (Serial Flash Discoverable Parameters) parameter info which used on this library
*/
typedef struct {
bool available; /**< available when read SFDP OK */
uint8_t major_rev; /**< SFDP Major Revision */
uint8_t minor_rev; /**< SFDP Minor Revision */
uint16_t write_gran; /**< write granularity (bytes) */
uint8_t erase_4k; /**< 4 kilobyte erase is supported throughout the device */
uint8_t erase_4k_cmd; /**< 4 Kilobyte erase command */
bool sr_is_non_vola; /**< status register is supports non-volatile */
uint8_t vola_sr_we_cmd; /**< volatile status register write enable command */
bool addr_3_byte; /**< supports 3-Byte addressing */
bool addr_4_byte; /**< supports 4-Byte addressing */
uint32_t capacity; /**< flash capacity (bytes) */
struct {
uint32_t size; /**< erase sector size (bytes). 0x00: not available */
uint8_t cmd; /**< erase command */
} eraser[SFUD_SFDP_ERASE_TYPE_MAX_NUM]; /**< supported eraser types table */
//TODO lots of fast read-related stuff (like modes supported and number of wait states/dummy cycles needed in each)
} sfud_sfdp, *sfud_sfdp_t;
#endif
/**
* SPI device
*/
typedef struct __sfud_spi {
/* SPI device name */
char *name;
/* SPI bus write read data function */
sfud_err (*wr)(const struct __sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf,
size_t read_size);
#ifdef SFUD_USING_QSPI
/* QSPI fast read function */
sfud_err (*qspi_read)(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format,
uint8_t *read_buf, size_t read_size);
#endif
/* lock SPI bus */
void (*lock)(const struct __sfud_spi *spi);
/* unlock SPI bus */
void (*unlock)(const struct __sfud_spi *spi);
/* some user data */
void *user_data;
} sfud_spi, *sfud_spi_t;
/**
* serial flash device
*/
typedef struct {
char *name; /**< serial flash name */
size_t index; /**< index of flash device information table @see flash_table */
sfud_flash_chip chip; /**< flash chip information */
sfud_spi spi; /**< SPI device */
bool init_ok; /**< initialize OK flag */
bool addr_in_4_byte; /**< flash is in 4-Byte addressing */
struct {
void (*delay)(void); /**< every retry's delay */
size_t times; /**< default times for error retry */
} retry;
void *user_data; /**< some user data */
#ifdef SFUD_USING_QSPI
sfud_qspi_read_cmd_format read_cmd_format; /**< fast read cmd format */
#endif
#ifdef SFUD_USING_SFDP
sfud_sfdp sfdp; /**< serial flash discoverable parameters by JEDEC standard */
#endif
} sfud_flash, *sfud_flash_t;
#ifdef __cplusplus
}
#endif
#endif /* _SFUD_DEF_H_ */
@@ -0,0 +1,208 @@
/*
* This file is part of the Serial Flash Universal Driver Library.
*
* Copyright (c) 2016-2018, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is the flash types and specification macro definition head file for this library.
* Created on: 2016-06-09
*/
/**
* @file sfud_flash_def.h
* @brief define sfud flash function, struct and device table
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
/*************************************************
File name: sfud_flash_def.h
Description: support sfud flash function, struct adn device table
Others: add sfud_flash_def.h to support SPI Flash function based on SFUD LIB
https://github.com/armink/SFUD
History:
1. Date: 2021-04-24
Author: AIIT XUOS Lab
Modification:
*************************************************/
#ifndef _SFUD_FLASH_DEF_H_
#define _SFUD_FLASH_DEF_H_
#include <stdint.h>
#include <sfud_cfg.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* flash program(write) data mode
*/
enum sfud_write_mode {
SFUD_WM_PAGE_256B = 1 << 0, /**< write 1 to 256 bytes per page */
SFUD_WM_BYTE = 1 << 1, /**< byte write */
SFUD_WM_AAI = 1 << 2, /**< auto address increment */
SFUD_WM_DUAL_BUFFER = 1 << 3, /**< dual-buffer write, like AT45DB series */
};
/* manufacturer information */
typedef struct {
char *name;
uint8_t id;
} sfud_mf;
/* flash chip information */
typedef struct {
char *name; /**< flash chip name */
uint8_t mf_id; /**< manufacturer ID */
uint8_t type_id; /**< memory type ID */
uint8_t capacity_id; /**< capacity ID */
uint32_t capacity; /**< flash capacity (bytes) */
uint16_t write_mode; /**< write mode @see sfud_write_mode */
uint32_t erase_gran; /**< erase granularity (bytes) */
uint8_t erase_gran_cmd; /**< erase granularity size block command */
} sfud_flash_chip;
#ifdef SFUD_USING_QSPI
/* QSPI flash chip's extended information compared with SPI flash */
typedef struct {
uint8_t mf_id; /**< manufacturer ID */
uint8_t type_id; /**< memory type ID */
uint8_t capacity_id; /**< capacity ID */
uint8_t read_mode; /**< supported read mode on this qspi flash chip */
} sfud_qspi_flash_ext_info;
#endif
/* SFUD support manufacturer JEDEC ID */
#define SFUD_MF_ID_CYPRESS 0x01
#define SFUD_MF_ID_FUJITSU 0x04
#define SFUD_MF_ID_EON 0x1C
#define SFUD_MF_ID_ATMEL 0x1F
#define SFUD_MF_ID_MICRON 0x20
#define SFUD_MF_ID_AMIC 0x37
#define SFUD_MF_ID_SANYO 0x62
#define SFUD_MF_ID_INTEL 0x89
#define SFUD_MF_ID_ESMT 0x8C
#define SFUD_MF_ID_FUDAN 0xA1
#define SFUD_MF_ID_HYUNDAI 0xAD
#define SFUD_MF_ID_SST 0xBF
#define SFUD_MF_ID_MICRONIX 0xC2
#define SFUD_MF_ID_GIGADEVICE 0xC8
#define SFUD_MF_ID_ISSI 0xD5
#define SFUD_MF_ID_WINBOND 0xEF
/* SFUD supported manufacturer information table */
#define SFUD_MF_TABLE \
{ \
{"Cypress", SFUD_MF_ID_CYPRESS}, \
{"Fujitsu", SFUD_MF_ID_FUJITSU}, \
{"EON", SFUD_MF_ID_EON}, \
{"Atmel", SFUD_MF_ID_ATMEL}, \
{"Micron", SFUD_MF_ID_MICRON}, \
{"AMIC", SFUD_MF_ID_AMIC}, \
{"Sanyo", SFUD_MF_ID_SANYO}, \
{"Intel", SFUD_MF_ID_INTEL}, \
{"ESMT", SFUD_MF_ID_ESMT}, \
{"Fudan", SFUD_MF_ID_FUDAN}, \
{"Hyundai", SFUD_MF_ID_HYUNDAI}, \
{"SST", SFUD_MF_ID_SST}, \
{"GigaDevice", SFUD_MF_ID_GIGADEVICE}, \
{"ISSI", SFUD_MF_ID_ISSI}, \
{"Winbond", SFUD_MF_ID_WINBOND}, \
{"Micronix", SFUD_MF_ID_MICRONIX}, \
}
#ifdef SFUD_USING_FLASH_INFO_TABLE
/* SFUD supported flash chip information table. If the flash not support JEDEC JESD216 standard,
* then the SFUD will find the flash chip information by this table. You can add other flash to here then
* notice me for update it. The configuration information name and index reference the sfud_flash_chip structure.
* | name | mf_id | type_id | capacity_id | capacity | write_mode | erase_gran | erase_gran_cmd |
*/
#define SFUD_FLASH_CHIP_TABLE \
{ \
{"AT45DB161E", SFUD_MF_ID_ATMEL, 0x26, 0x00, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_DUAL_BUFFER, 512, 0x81}, \
{"W25Q40BV", SFUD_MF_ID_WINBOND, 0x40, 0x13, 512L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q16BV", SFUD_MF_ID_WINBOND, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q32BV", SFUD_MF_ID_WINBOND, 0x40, 0x16, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q64CV", SFUD_MF_ID_WINBOND, 0x40, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q64DW", SFUD_MF_ID_WINBOND, 0x60, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q128BV", SFUD_MF_ID_WINBOND, 0x40, 0x18, 16L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q256FV", SFUD_MF_ID_WINBOND, 0x40, 0x19, 32L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"SST25VF080B", SFUD_MF_ID_SST, 0x25, 0x8E, 1L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \
{"SST25VF016B", SFUD_MF_ID_SST, 0x25, 0x41, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \
{"M25P32", SFUD_MF_ID_MICRON, 0x20, 0x16, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 64L*1024L, 0xD8}, \
{"M25P80", SFUD_MF_ID_MICRON, 0x20, 0x14, 1L*1024L*1024L, SFUD_WM_PAGE_256B, 64L*1024L, 0xD8}, \
{"M25P40", SFUD_MF_ID_MICRON, 0x20, 0x13, 512L*1024L, SFUD_WM_PAGE_256B, 64L*1024L, 0xD8}, \
{"EN25Q32B", SFUD_MF_ID_EON, 0x30, 0x16, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"GD25Q64B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"GD25Q16B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"GD25Q32C", SFUD_MF_ID_GIGADEVICE, 0x40, 0x16, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"S25FL216K", SFUD_MF_ID_CYPRESS, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"S25FL032P", SFUD_MF_ID_CYPRESS, 0x02, 0x15, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"A25L080", SFUD_MF_ID_AMIC, 0x30, 0x14, 1L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"F25L004", SFUD_MF_ID_ESMT, 0x20, 0x13, 512L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \
{"PCT25VF016B", SFUD_MF_ID_SST, 0x25, 0x41, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \
}
#endif /* SFUD_USING_FLASH_INFO_TABLE */
#ifdef SFUD_USING_QSPI
/* This table saves flash read-fast instructions in QSPI mode,
* SFUD can use this table to select the most appropriate read instruction for flash.
* | mf_id | type_id | capacity_id | qspi_read_mode |
*/
#define SFUD_FLASH_EXT_INFO_TABLE \
{ \
/* W25Q40BV */ \
{SFUD_MF_ID_WINBOND, 0x40, 0x13, NORMAL_SPI_READ|DUAL_OUTPUT}, \
/* W25Q80JV */ \
{SFUD_MF_ID_WINBOND, 0x40, 0x14, NORMAL_SPI_READ|DUAL_OUTPUT}, \
/* W25Q16BV */ \
{SFUD_MF_ID_WINBOND, 0x40, 0x15, NORMAL_SPI_READ|DUAL_OUTPUT}, \
/* W25Q32BV */ \
{SFUD_MF_ID_WINBOND, 0x40, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT|QUAD_OUTPUT|QUAD_IO}, \
/* W25Q64JV */ \
{SFUD_MF_ID_WINBOND, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \
/* W25Q128JV */ \
{SFUD_MF_ID_WINBOND, 0x40, 0x18, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \
/* W25Q256FV */ \
{SFUD_MF_ID_WINBOND, 0x40, 0x19, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \
/* EN25Q32B */ \
{SFUD_MF_ID_EON, 0x30, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT|QUAD_IO}, \
/* S25FL216K */ \
{SFUD_MF_ID_CYPRESS, 0x40, 0x15, NORMAL_SPI_READ|DUAL_OUTPUT}, \
/* A25L080 */ \
{SFUD_MF_ID_AMIC, 0x30, 0x14, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO}, \
/* A25LQ64 */ \
{SFUD_MF_ID_AMIC, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_IO}, \
/* MX25L3206E and KH25L3206E */ \
{SFUD_MF_ID_MICRONIX, 0x20, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT}, \
/* GD25Q64B */ \
{SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT}, \
}
#endif /* SFUD_USING_QSPI */
#ifdef __cplusplus
}
#endif
#endif /* _SFUD_FLASH_DEF_H_ */
@@ -0,0 +1,72 @@
/*
* 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 sfud_port.h
* @brief define spi flash function and struct using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#ifndef SFUD_PORT_H
#define SFUD_PORT_H
#include <device.h>
#include <sfud.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SPI_FLASH_FREQUENCY 10000000
typedef struct SpiFlashDevice *SpiFlashDeviceType;
struct FlashDevDone
{
uint32 (*open) (void *dev);
uint32 (*close) (void *dev);
uint32 (*write) (void *dev, struct BusBlockWriteParam *write_param);
uint32 (*read) (void *dev, struct BusBlockReadParam *read_param);
};
struct FlashBlockParam
{
uint32 sector_num;
uint32 sector_bytes;
uint32 block_size;
};
struct SpiFlashParam
{
struct FlashBlockParam flash_block_param;
void *flash_private_data;
};
struct SpiFlashDevice
{
struct SpiHardwareDevice *spi_dev;
struct SpiFlashParam flash_param;
struct SpiHardwareDevice flash_dev;
int flash_lock;
};
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,7 @@
SRC_FILES += sfud_port.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,315 @@
/*
* This file is part of the Serial Flash Universal Driver Library.
*
* Copyright (c) 2016-2018, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: Portable interface for each platform.
* Created on: 2016-04-23
*
*/
/**
* @file sfud_port.c
* @brief support sfud function register based on spi bus driver
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
/*************************************************
File name: sfud_port.c
Description: support spi bus driver function, then register to sfud lib
Others: add sfud_port.c to support SPI Flash function based on SFUD LIB
https://github.com/armink/SFUD
History:
1. Date: 2021-04-24
Author: AIIT XUOS Lab
Modification:
1、implement sfud_port APIs with XiUOS driver framework APIs
2、add flash dev write、read and control functions
*************************************************/
#include <sfud_port.h>
#include <stdarg.h>
static char log_buf[256];
void sfud_log_debug(const char *file, const long line, const char *format, ...);
/**
* This function supports to obtain the spi bus.
*
* @param spi_flash_dev flash dev descriptor
*/
static uint32 spi_flash_obtain_bus(SpiFlashDeviceType spi_flash_dev)
{
NULL_PARAM_CHECK(spi_flash_dev);
x_err_t ret;
struct Driver *spi_drv = spi_flash_dev->spi_dev->haldev.owner_bus->owner_driver;
struct BusConfigureInfo configure_info;
struct SpiMasterParam spi_master_param;
spi_master_param.spi_data_bit_width = 8;
spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB;
spi_master_param.spi_maxfrequency = SPI_FLASH_FREQUENCY;
spi_master_param.spi_data_endian = 0;
configure_info.private_data = (void *)&spi_master_param;
ret = DeviceObtainBus(spi_flash_dev->spi_dev->haldev.owner_bus, &spi_flash_dev->spi_dev->haldev, spi_drv->drv_name, &configure_info);
if (EOK != ret) {
KPrintf("spi_flash_obtain_bus error!\n");
KMutexAbandon(spi_flash_dev->spi_dev->haldev.owner_bus->bus_lock);
return ERROR;
}
return ret;
}
/**
* This function supports to read and write data by the spi bus.
*
* @param spi_flash_dev flash dev descriptor
* @param write_buf write buffer descriptor
* @param write_size write data length
* @param read_buf read buffer descriptor
* @param read_size read data length
*/
static void spi_bus_read_write(SpiFlashDeviceType spi_flash_dev, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, size_t read_size)
{
struct BusBlockWriteParam write_param;
struct BusBlockReadParam read_param;
BusDevOpen(&spi_flash_dev->spi_dev->haldev);
write_param.buffer = (void *)write_buf;
write_param.size = write_size;
BusDevWriteData(&spi_flash_dev->spi_dev->haldev, &write_param);
read_param.buffer = (void *)read_buf;
read_param.size = read_size;
BusDevReadData(&spi_flash_dev->spi_dev->haldev, &read_param);
BusDevClose(&spi_flash_dev->spi_dev->haldev);
}
/**
* This function supports to read data by the spi bus.
*
* @param spi_flash_dev flash dev descriptor
* @param read_buf read buffer descriptor
* @param read_size read data length
*/
static void spi_bus_read(SpiFlashDeviceType spi_flash_dev, uint8_t *read_buf, size_t read_size)
{
struct BusBlockReadParam read_param;
BusDevOpen(&spi_flash_dev->spi_dev->haldev);
read_param.buffer = (void *)read_buf;
read_param.size = read_size;
BusDevReadData(&spi_flash_dev->spi_dev->haldev, &read_param);
BusDevClose(&spi_flash_dev->spi_dev->haldev);
}
/**
* This function supports to write data by the spi bus.
*
* @param spi_flash_dev flash dev descriptor
* @param write_buf write buffer descriptor
* @param write_size write data length
*/
static void spi_bus_write(SpiFlashDeviceType spi_flash_dev, const uint8_t *write_buf, size_t write_size)
{
struct BusBlockWriteParam write_param;
BusDevOpen(&spi_flash_dev->spi_dev->haldev);
write_param.buffer = (void *)write_buf;
write_param.size = write_size;
BusDevWriteData(&spi_flash_dev->spi_dev->haldev, &write_param);
BusDevClose(&spi_flash_dev->spi_dev->haldev);
}
/**
* SPI write data then read data
*/
static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf,
size_t read_size) {
sfud_err result = SFUD_SUCCESS;
/**
* add your spi write and read code
*/
x_err_t ret;
SpiFlashDeviceType spi_flash_dev;
sfud_flash *sfud_flash_dev = (sfud_flash *) (spi->user_data);
spi_flash_dev = (SpiFlashDeviceType)sfud_flash_dev->user_data;
NULL_PARAM_CHECK(sfud_flash_dev);
NULL_PARAM_CHECK(spi_flash_dev);
if (write_size && read_size) {
NULL_PARAM_CHECK(write_buf);
NULL_PARAM_CHECK(read_buf);
ret = spi_flash_obtain_bus(spi_flash_dev);
if (EOK != ret) {
return SFUD_ERR_TIMEOUT;
}
spi_bus_read_write(spi_flash_dev, write_buf, write_size, read_buf, read_size);
} else if (read_size) {
NULL_PARAM_CHECK(read_buf);
ret = spi_flash_obtain_bus(spi_flash_dev);
if (EOK != ret) {
return SFUD_ERR_TIMEOUT;
}
spi_bus_read(spi_flash_dev, read_buf, read_size);
} else if (write_size) {
NULL_PARAM_CHECK(write_buf);
ret = spi_flash_obtain_bus(spi_flash_dev);
if (EOK != ret) {
return SFUD_ERR_TIMEOUT;
}
spi_bus_write(spi_flash_dev, write_buf, write_size);
} else {
KPrintf("spi_write_read write or read size error\n");
return SFUD_ERR_NOT_FOUND;
}
KMutexAbandon(spi_flash_dev->spi_dev->haldev.owner_bus->bus_lock);
return result;
}
#ifdef SFUD_USING_QSPI
/**
* read flash data by QSPI
*/
static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format,
uint8_t *read_buf, size_t read_size) {
sfud_err result = SFUD_SUCCESS;
/**
* add your qspi read flash data code
*/
return result;
}
#endif /* SFUD_USING_QSPI */
static void spi_lock(const sfud_spi *spi)
{
SpiFlashDeviceType spi_flash_dev;
sfud_flash *sfud_flash_dev = (sfud_flash *) (spi->user_data);
spi_flash_dev = (SpiFlashDeviceType)sfud_flash_dev->user_data;
CHECK(sfud_flash_dev);
CHECK(spi_flash_dev);
KMutexObtain(spi_flash_dev->flash_lock, WAITING_FOREVER);
}
static void spi_unlock(const sfud_spi *spi)
{
SpiFlashDeviceType spi_flash_dev;
sfud_flash *sfud_flash_dev = (sfud_flash *) (spi->user_data);
spi_flash_dev = (SpiFlashDeviceType)sfud_flash_dev->user_data;
CHECK(sfud_flash_dev);
CHECK(spi_flash_dev);
KMutexAbandon(spi_flash_dev->flash_lock);
}
sfud_err sfud_spi_port_init(sfud_flash *flash) {
sfud_err result = SFUD_SUCCESS;
/**
* add your port spi bus and device object initialize code like this:
* 1. rcc initialize
* 2. gpio initialize
* 3. spi device initialize
* 4. flash->spi and flash->retry item initialize
* flash->spi.wr = spi_write_read; //Required
* flash->spi.qspi_read = qspi_read; //Required when QSPI mode enable
* flash->spi.lock = spi_lock;
* flash->spi.unlock = spi_unlock;
* flash->spi.user_data = &spix;
* flash->retry.delay = null;
* flash->retry.times = 10000; //Required
*/
CHECK(flash);
flash->spi.wr = spi_write_read;
flash->spi.lock = spi_lock;
flash->spi.unlock = spi_unlock;
flash->spi.user_data = flash;
flash->retry.delay = NONE;
flash->retry.times = 10000 * 60;
return result;
}
/**
* This function is print debug info.
*
* @param file the file which has call this function
* @param line the line number which has call this function
* @param format output format
* @param ... args
*/
void sfud_log_debug(const char *file, const long line, const char *format, ...) {
va_list args;
/* args point to the first variable parameter */
va_start(args, format);
KPrintf("[SFUD](%s:%ld) ", file, line);
/* must use vprintf to print */
vsnprintf(log_buf, sizeof(log_buf), format, args);
KPrintf("%s\n", log_buf);
va_end(args);
}
/**
* This function is print routine info.
*
* @param format output format
* @param ... args
*/
void sfud_log_info(const char *format, ...) {
va_list args;
/* args point to the first variable parameter */
va_start(args, format);
KPrintf("[SFUD]");
/* must use vprintf to print */
vsnprintf(log_buf, sizeof(log_buf), format, args);
KPrintf("%s\n", log_buf);
va_end(args);
}
@@ -0,0 +1,7 @@
SRC_FILES += sfud.c sfud_sfdp.c
include $(KERNEL_ROOT)/compiler.mk
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,406 @@
/*
* This file is part of the Serial Flash Universal Driver Library.
*
* Copyright (c) 2016, Armink, <armink.ztl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: Analyze the SFDP (Serial Flash Discoverable Parameters) which from JESD216/A/B (V1.X) standard.
* JESD216 (V1.0) document: http://www.jedec.org/sites/default/files/docs/JESD216.pdf
* JESD216A (V1.5) document: http://www.jedec.org/sites/default/files/docs/JESD216A.pdf
* JESD216B (V1.6) document: http://www.jedec.org/sites/default/files/docs/JESD216B.pdf
*
* Created on: 2016-05-26
*/
/**
* @file sfud_sfdp.c
* @brief support sfud sfdp function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
/*************************************************
File name: sfud_sfdp.c
Description: support sfud sfdp function
Others: add sfud_sfdp.c to support SPI Flash function based on SFUD LIB
https://github.com/armink/SFUD
History:
1. Date: 2021-04-24
Author: AIIT XUOS Lab
Modification:
*************************************************/
#include <sfud.h>
/**
* JEDEC Standard JESD216 Terms and definitions:
*
* DWORD: Four consecutive 8-bit bytes used as the basic 32-bit building block for headers and parameter tables.
*
* Sector: The minimum granularity - size and alignment - of an area that can be erased in the data array
* of a flash memory device. Different areas within the address range of the data array may have a different
* minimum erase granularity (sector size).
*/
#ifdef SFUD_USING_SFDP
/* support maximum SFDP major revision by driver */
#define SUPPORT_MAX_SFDP_MAJOR_REV 1
/* the JEDEC basic flash parameter table length is 9 DWORDs (288-bit) on JESD216 (V1.0) initial release standard */
#define BASIC_TABLE_LEN 9
/* the smallest eraser in SFDP eraser table */
#define SMALLEST_ERASER_INDEX 0
/**
* SFDP parameter header structure
*/
typedef struct {
uint8_t id; /**< Parameter ID LSB */
uint8_t minor_rev; /**< Parameter minor revision */
uint8_t major_rev; /**< Parameter major revision */
uint8_t len; /**< Parameter table length(in double words) */
uint32_t ptp; /**< Parameter table 24bit pointer (byte address) */
} sfdp_para_header;
static sfud_err read_sfdp_data(const sfud_flash *flash, uint32_t addr, uint8_t *read_buf, size_t size);
static bool read_sfdp_header(sfud_flash *flash);
static bool read_basic_header(const sfud_flash *flash, sfdp_para_header *basic_header);
static bool read_basic_table(sfud_flash *flash, sfdp_para_header *basic_header);
/* ../port/sfup_port.c */
extern void sfud_log_debug(const char *file, const long line, const char *format, ...);
extern void sfud_log_info(const char *format, ...);
/**
* Read SFDP parameter information
*
* @param flash flash device
*
* @return true: read OK
*/
bool sfud_read_sfdp(sfud_flash *flash) {
SFUD_ASSERT(flash);
/* JEDEC basic flash parameter header */
sfdp_para_header basic_header;
if (read_sfdp_header(flash) && read_basic_header(flash, &basic_header)) {
return read_basic_table(flash, &basic_header);
} else {
SFUD_INFO("Warning: Read SFDP parameter header information failed. The %s is not support JEDEC SFDP.", flash->name);
return false;
}
}
/**
* Read SFDP parameter header
*
* @param flash flash device
*
* @return true: read OK
*/
static bool read_sfdp_header(sfud_flash *flash) {
sfud_sfdp *sfdp = &flash->sfdp;
/* The SFDP header is located at address 000000h of the SFDP data structure.
* It identifies the SFDP Signature, the number of parameter headers, and the SFDP revision numbers. */
/* sfdp parameter header address */
uint32_t header_addr = 0;
/* each parameter header being 2 DWORDs (64-bit) */
uint8_t header[2 * 4] = { 0 };
SFUD_ASSERT(flash);
sfdp->available = false;
/* read SFDP header */
if (read_sfdp_data(flash, header_addr, header, sizeof(header)) != SFUD_SUCCESS) {
SFUD_INFO("Error: Can't read SFDP header.");
return false;
}
/* check SFDP header */
if (!(header[0] == 'S' &&
header[1] == 'F' &&
header[2] == 'D' &&
header[3] == 'P')) {
SFUD_DEBUG("Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P').");
return false;
}
sfdp->minor_rev = header[4];
sfdp->major_rev = header[5];
if (sfdp->major_rev > SUPPORT_MAX_SFDP_MAJOR_REV) {
SFUD_INFO("Error: This reversion(V%d.%d) SFDP is not supported.", sfdp->major_rev, sfdp->minor_rev);
return false;
}
SFUD_DEBUG("Check SFDP header is OK. The reversion is V%d.%d, NPN is %d.", sfdp->major_rev, sfdp->minor_rev,
header[6]);
return true;
}
/**
* Read JEDEC basic parameter header
*
* @param flash flash device
*
* @return true: read OK
*/
static bool read_basic_header(const sfud_flash *flash, sfdp_para_header *basic_header) {
/* The basic parameter header is mandatory, is defined by this standard, and starts at byte offset 08h. */
uint32_t header_addr = 8;
/* each parameter header being 2 DWORDs (64-bit) */
uint8_t header[2 * 4] = { 0 };
SFUD_ASSERT(flash);
SFUD_ASSERT(basic_header);
/* read JEDEC basic flash parameter header */
if (read_sfdp_data(flash, header_addr, header, sizeof(header)) != SFUD_SUCCESS) {
SFUD_INFO("Error: Can't read JEDEC basic flash parameter header.");
return false;
}
basic_header->id = header[0];
basic_header->minor_rev = header[1];
basic_header->major_rev = header[2];
basic_header->len = header[3];
basic_header->ptp = (long)header[4] | (long)header[5] << 8 | (long)header[6] << 16;
/* check JEDEC basic flash parameter header */
if (basic_header->major_rev > SUPPORT_MAX_SFDP_MAJOR_REV) {
SFUD_INFO("Error: This reversion(V%d.%d) JEDEC basic flash parameter header is not supported.",
basic_header->major_rev, basic_header->minor_rev);
return false;
}
if (basic_header->len < BASIC_TABLE_LEN) {
SFUD_INFO("Error: The JEDEC basic flash parameter table length (now is %d) error.", basic_header->len);
return false;
}
SFUD_DEBUG("Check JEDEC basic flash parameter header is OK. The table id is %d, reversion is V%d.%d,"
" length is %d, parameter table pointer is 0x%06lX.", basic_header->id, basic_header->major_rev,
basic_header->minor_rev, basic_header->len, basic_header->ptp);
return true;
}
/**
* Read JEDEC basic parameter table
*
* @param flash flash device
*
* @return true: read OK
*/
static bool read_basic_table(sfud_flash *flash, sfdp_para_header *basic_header) {
sfud_sfdp *sfdp = &flash->sfdp;
/* parameter table address */
uint32_t table_addr = basic_header->ptp;
/* parameter table */
uint8_t table[BASIC_TABLE_LEN * 4] = { 0 }, i, j;
SFUD_ASSERT(flash);
SFUD_ASSERT(basic_header);
/* read JEDEC basic flash parameter table */
if (read_sfdp_data(flash, table_addr, table, sizeof(table)) != SFUD_SUCCESS) {
SFUD_INFO("Warning: Can't read JEDEC basic flash parameter table.");
return false;
}
/* print JEDEC basic flash parameter table info */
SFUD_DEBUG("JEDEC basic flash parameter table info:");
SFUD_DEBUG("MSB-LSB 3 2 1 0");
for (i = 0; i < BASIC_TABLE_LEN; i++) {
SFUD_DEBUG("[%04d] 0x%02X 0x%02X 0x%02X 0x%02X", i + 1, table[i * 4 + 3], table[i * 4 + 2], table[i * 4 + 1],
table[i * 4]);
}
/* get block/sector 4 KB erase supported and command */
sfdp->erase_4k_cmd = table[1];
switch (table[0] & 0x03) {
case 1:
sfdp->erase_4k = true;
SFUD_DEBUG("4 KB Erase is supported throughout the device. Command is 0x%02X.", sfdp->erase_4k_cmd);
break;
case 3:
sfdp->erase_4k = false;
SFUD_DEBUG("Uniform 4 KB erase is unavailable for this device.");
break;
default:
SFUD_INFO("Error: Uniform 4 KB erase supported information error.");
return false;
}
/* get write granularity */
//TODO 目前为 1.0 所提供的方式,后期支持 V1.5 及以上的方式读取 page size
switch ((table[0] & (0x01 << 2)) >> 2) {
case 0:
sfdp->write_gran = 1;
SFUD_DEBUG("Write granularity is 1 byte.");
break;
case 1:
sfdp->write_gran = 256;
SFUD_DEBUG("Write granularity is 64 bytes or larger.");
break;
}
/* volatile status register block protect bits */
switch ((table[0] & (0x01 << 3)) >> 3) {
case 0:
/* Block Protect bits in device's status register are solely non-volatile or may be
* programmed either as volatile using the 50h instruction for write enable or non-volatile
* using the 06h instruction for write enable.
*/
sfdp->sr_is_non_vola = true;
SFUD_DEBUG("Target flash status register is non-volatile.");
break;
case 1:
/* block protect bits in device's status register are solely volatile. */
sfdp->sr_is_non_vola = false;
SFUD_DEBUG("Block Protect bits in device's status register are solely volatile.");
/* write enable instruction select for writing to volatile status register */
switch ((table[0] & (0x01 << 4)) >> 4) {
case 0:
sfdp->vola_sr_we_cmd = SFUD_VOLATILE_SR_WRITE_ENABLE;
SFUD_DEBUG("Flash device requires instruction 50h as the write enable prior "
"to performing a volatile write to the status register.");
break;
case 1:
sfdp->vola_sr_we_cmd = SFUD_CMD_WRITE_ENABLE;
SFUD_DEBUG("Flash device requires instruction 06h as the write enable prior "
"to performing a volatile write to the status register.");
break;
}
break;
}
/* get address bytes, number of bytes used in addressing flash array read, write and erase. */
switch ((table[2] & (0x03 << 1)) >> 1) {
case 0:
sfdp->addr_3_byte = true;
sfdp->addr_4_byte = false;
SFUD_DEBUG("3-Byte only addressing.");
break;
case 1:
sfdp->addr_3_byte = true;
sfdp->addr_4_byte = true;
SFUD_DEBUG("3- or 4-Byte addressing.");
break;
case 2:
sfdp->addr_3_byte = false;
sfdp->addr_4_byte = true;
SFUD_DEBUG("4-Byte only addressing.");
break;
default:
sfdp->addr_3_byte = false;
sfdp->addr_4_byte = false;
SFUD_INFO("Error: Read address bytes error!");
return false;
}
/* get flash memory capacity */
uint32_t table2_temp = ((long)table[7] << 24) | ((long)table[6] << 16) | ((long)table[5] << 8) | (long)table[4];
switch ((table[7] & (0x01 << 7)) >> 7) {
case 0:
sfdp->capacity = 1 + (table2_temp >> 3);
break;
case 1:
table2_temp &= 0x7FFFFFFF;
if (table2_temp > sizeof(sfdp->capacity) * 8 + 3) {
sfdp->capacity = 0;
SFUD_INFO("Error: The flash capacity is grater than 32 Gb/ 4 GB! Not Supported.");
return false;
}
sfdp->capacity = 1L << (table2_temp - 3);
break;
}
SFUD_DEBUG("Capacity is %ld Bytes.", sfdp->capacity);
/* get erase size and erase command */
for (i = 0, j = 0; i < SFUD_SFDP_ERASE_TYPE_MAX_NUM; i++) {
if (table[28 + 2 * i] != 0x00) {
sfdp->eraser[j].size = 1L << table[28 + 2 * i];
sfdp->eraser[j].cmd = table[28 + 2 * i + 1];
SFUD_DEBUG("Flash device supports %ldKB block erase. Command is 0x%02X.", sfdp->eraser[j].size / 1024,
sfdp->eraser[j].cmd);
j++;
}
}
/* sort the eraser size from small to large */
for (i = 0, j = 0; i < SFUD_SFDP_ERASE_TYPE_MAX_NUM; i++) {
if (sfdp->eraser[i].size) {
for (j = i + 1; j < SFUD_SFDP_ERASE_TYPE_MAX_NUM; j++) {
if (sfdp->eraser[j].size != 0 && sfdp->eraser[i].size > sfdp->eraser[j].size) {
/* swap the small eraser */
uint32_t temp_size = sfdp->eraser[i].size;
uint8_t temp_cmd = sfdp->eraser[i].cmd;
sfdp->eraser[i].size = sfdp->eraser[j].size;
sfdp->eraser[i].cmd = sfdp->eraser[j].cmd;
sfdp->eraser[j].size = temp_size;
sfdp->eraser[j].cmd = temp_cmd;
}
}
}
}
sfdp->available = true;
return true;
}
static sfud_err read_sfdp_data(const sfud_flash *flash, uint32_t addr, uint8_t *read_buf, size_t size) {
uint8_t cmd[] = {
SFUD_CMD_READ_SFDP_REGISTER,
(addr >> 16) & 0xFF,
(addr >> 8) & 0xFF,
(addr >> 0) & 0xFF,
SFUD_DUMMY_DATA,
};
SFUD_ASSERT(flash);
SFUD_ASSERT(addr < 1L << 24);
SFUD_ASSERT(read_buf);
SFUD_ASSERT(flash->spi.wr);
return flash->spi.wr(&flash->spi, cmd, sizeof(cmd), read_buf, size);
}
/**
* get the most suitable eraser for erase process from SFDP parameter
*
* @param flash flash device
* @param addr start address
* @param erase_size will be erased size
*
* @return the eraser index of SFDP eraser table @see sfud_sfdp.eraser[]
*/
size_t sfud_sfdp_get_suitable_eraser(const sfud_flash *flash, uint32_t addr, size_t erase_size) {
size_t index = SMALLEST_ERASER_INDEX, i;
/* only used when flash supported SFDP */
SFUD_ASSERT(flash->sfdp.available);
/* the address isn't align by smallest eraser's size, then use the smallest eraser */
if (addr % flash->sfdp.eraser[SMALLEST_ERASER_INDEX].size) {
return SMALLEST_ERASER_INDEX;
}
/* Find the suitable eraser.
* The largest size eraser is at the end of eraser table.
* In order to decrease erase command counts, so the find process is from the end of eraser table. */
for (i = SFUD_SFDP_ERASE_TYPE_MAX_NUM - 1;; i--) {
if ((flash->sfdp.eraser[i].size != 0) && (erase_size >= flash->sfdp.eraser[i].size)
&& (addr % flash->sfdp.eraser[i].size == 0)) {
index = i;
break;
}
if (i == SMALLEST_ERASER_INDEX) {
break;
}
}
return index;
}
#endif /* SFUD_USING_SFDP */
+3
View File
@@ -0,0 +1,3 @@
SRC_FILES := bus_hwtimer.c dev_hwtimer.c drv_hwtimer.c
include $(KERNEL_ROOT)/compiler.mk
+117
View File
@@ -0,0 +1,117 @@
/*
* 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 bus_hwtimer.c
* @brief register hwtimer bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_hwtimer.h>
#include <dev_hwtimer.h>
int HwtimerBusInit(struct HwtimerBus *hwtimer_bus, const char *bus_name)
{
NULL_PARAM_CHECK(hwtimer_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != hwtimer_bus->bus.bus_state) {
strncpy(hwtimer_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
hwtimer_bus->bus.bus_type = TYPE_HWTIMER_BUS;
hwtimer_bus->bus.bus_state = BUS_INSTALL;
hwtimer_bus->bus.private_data = hwtimer_bus->private_data;
ret = BusRegister(&hwtimer_bus->bus);
if (EOK != ret) {
KPrintf("HwtimerBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("HwtimerBusInit BusRegister bus has been register state%u\n", hwtimer_bus->bus.bus_state);
}
return ret;
}
int HwtimerDriverInit(struct HwtimerDriver *hwtimer_driver, const char *driver_name)
{
NULL_PARAM_CHECK(hwtimer_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != hwtimer_driver->driver.driver_state) {
hwtimer_driver->driver.driver_type = TYPE_HWTIMER_DRV;
hwtimer_driver->driver.driver_state = DRV_INSTALL;
strncpy(hwtimer_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
hwtimer_driver->driver.configure = hwtimer_driver->configure;
ret = HwtimerDriverRegister(&hwtimer_driver->driver);
if (EOK != ret) {
KPrintf("HwtimerDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("HwtimerDriverInit DriverRegister driver has been register state%u\n", hwtimer_driver->driver.driver_state);
}
return ret;
}
int HwtimerReleaseBus(struct HwtimerBus *hwtimer_bus)
{
NULL_PARAM_CHECK(hwtimer_bus);
return BusRelease(&hwtimer_bus->bus);
}
int HwtimerDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("HwtimerDriverAttachToBus find hwtimer bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_HWTIMER_BUS == bus->bus_type) {
driver = HwtimerDriverFind(drv_name);
if (NONE == driver) {
KPrintf("HwtimerDriverAttachToBus find hwtimer driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_HWTIMER_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("HwtimerDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+115
View File
@@ -0,0 +1,115 @@
/*
* 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 dev_hwtimer.c
* @brief register hwtimer dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_hwtimer.h>
#include <dev_hwtimer.h>
static DoubleLinklistType hwtimerdev_linklist;
/*Create the hwtimer device linklist*/
static void HwtimerDeviceLinkInit()
{
InitDoubleLinkList(&hwtimerdev_linklist);
}
HardwareDevType HwtimerDeviceFind(const char *dev_name)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &hwtimerdev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if (!strcmp(device->dev_name, dev_name)) {
return device;
}
}
KPrintf("HwtimerDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int HwtimerDeviceRegister(struct HwtimerHardwareDevice *hwtimer_device, void *hwtimer_param, const char *device_name)
{
NULL_PARAM_CHECK(hwtimer_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (dev_link_flag) {
HwtimerDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != hwtimer_device->haldev.dev_state) {
strncpy(hwtimer_device->haldev.dev_name, device_name, NAME_NUM_MAX);
hwtimer_device->haldev.dev_type = TYPE_HWTIMER_DEV;
hwtimer_device->haldev.dev_state = DEV_INSTALL;
hwtimer_device->haldev.dev_done = (struct HalDevDone *)hwtimer_device->dev_done;
hwtimer_device->haldev.private_data = hwtimer_param;
DoubleLinkListInsertNodeAfter(&hwtimerdev_linklist, &(hwtimer_device->haldev.dev_link));
} else {
KPrintf("HwtimerDeviceRegister device has been register state%u\n", hwtimer_device->haldev.dev_state);
}
return ret;
}
int HwtimerDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("HwtimerDeviceAttachToBus find hwtimer bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_HWTIMER_BUS == bus->bus_type) {
device = HwtimerDeviceFind(dev_name);
if (NONE == device) {
KPrintf("HwtimerDeviceAttachToBus find hwtimer device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_HWTIMER_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("HwtimerDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+67
View File
@@ -0,0 +1,67 @@
/*
* 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 drv_hwtimer.c
* @brief register hwtimer drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_hwtimer.h>
#include <dev_hwtimer.h>
static DoubleLinklistType hwtimerdrv_linklist;
/*Create the driver linklist*/
static void HwtimerDrvLinkInit()
{
InitDoubleLinkList(&hwtimerdrv_linklist);
}
DriverType HwtimerDriverFind(const char *drv_name)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &hwtimerdrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if (!strcmp(driver->drv_name, drv_name)) {
return driver;
}
}
KPrintf("HwtimerDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int HwtimerDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
HwtimerDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&hwtimerdrv_linklist, &(driver->driver_link));
return ret;
}
+5
View File
@@ -0,0 +1,5 @@
SRC_FILES += drv_touch.c dev_touch.c bus_touch.c
include $(KERNEL_ROOT)/compiler.mk
+117
View File
@@ -0,0 +1,117 @@
/*
* 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 bus_touch.c
* @brief register touch bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_touch.h>
#include <dev_touch.h>
int TouchBusInit(struct TouchBus *touch_bus, const char *bus_name)
{
NULL_PARAM_CHECK(touch_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != touch_bus->bus.bus_state) {
strncpy(touch_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
touch_bus->bus.bus_type = TYPE_TOUCH_BUS;
touch_bus->bus.bus_state = BUS_INSTALL;
touch_bus->bus.private_data = touch_bus->private_data;
ret = BusRegister(&touch_bus->bus);
if (EOK != ret) {
KPrintf("touchBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("touchBusInit BusRegister bus has been register state%u\n", touch_bus->bus.bus_state);
}
return ret;
}
int TouchDriverInit(struct TouchDriver *touch_driver, const char *driver_name)
{
NULL_PARAM_CHECK(touch_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != touch_driver->driver.driver_state) {
touch_driver->driver.driver_type = TYPE_TOUCH_DRV;
touch_driver->driver.driver_state = DRV_INSTALL;
strncpy(touch_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
touch_driver->driver.configure =touch_driver->configure;
ret = TouchDriverRegister(&touch_driver->driver);
if (EOK != ret) {
KPrintf("TouchDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("TouchDriverInit DriverRegister driver has been register state%u\n", touch_driver->driver.driver_state);
}
return ret;
}
int TouchReleaseBus(struct TouchBus *touch_bus)
{
NULL_PARAM_CHECK(touch_bus);
return BusRelease(&touch_bus->bus);
}
int TouchDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("TouchDriverAttachToBus find touch bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_TOUCH_BUS == bus->bus_type) {
driver = TouchDriverFind(drv_name, TYPE_TOUCH_DRV);
if (NONE == driver) {
KPrintf("TouchDriverAttachToBus find touch driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_TOUCH_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("TouchDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+116
View File
@@ -0,0 +1,116 @@
/*
* 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 dev_touch.c
* @brief register touch dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_touch.h>
#include <dev_touch.h>
static DoubleLinklistType touchdev_linklist;
/*Create the touch device linklist*/
static void TouchDeviceLinkInit()
{
InitDoubleLinkList(&touchdev_linklist);
}
HardwareDevType TouchDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &touchdev_linklist;
for (node = head->node_next; node != head; node = node->node_next){
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("TouchDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int TouchDeviceRegister(struct TouchHardwareDevice *touch_device, void *touch_param, const char *device_name)
{
NULL_PARAM_CHECK(touch_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (!dev_link_flag) {
TouchDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != touch_device->haldev.dev_state) {
strncpy(touch_device->haldev.dev_name, device_name, NAME_NUM_MAX);
touch_device->haldev.dev_type = TYPE_TOUCH_DEV;
touch_device->haldev.dev_state = DEV_INSTALL;
touch_device->haldev.dev_done = (struct HalDevDone *)touch_device->dev_done;
touch_device->haldev.private_data = touch_param;
DoubleLinkListInsertNodeAfter(&touchdev_linklist, &(touch_device->haldev.dev_link));
} else {
KPrintf("TouchDeviceRegister device has been register state%u\n", touch_device->haldev.dev_state);
}
return ret;
}
int TouchDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("TouchDeviceAttachToBus find touch bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_TOUCH_BUS == bus->bus_type) {
device = TouchDeviceFind(dev_name, TYPE_TOUCH_DEV);
if (NONE == device) {
KPrintf("TouchDeviceAttachToBus find TOUCH device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_TOUCH_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("TouchDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+67
View File
@@ -0,0 +1,67 @@
/*
* 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 drv_touch.c
* @brief register touch drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_touch.h>
#include <dev_touch.h>
static DoubleLinklistType touchdrv_linklist;
/*Create the driver linklist*/
static void TouchDrvLinkInit()
{
InitDoubleLinkList(&touchdrv_linklist);
}
DriverType TouchDriverFind(const char *drv_name, enum DriverType drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &touchdrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("TouchDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int TouchDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
TouchDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&touchdrv_linklist, &(driver->driver_link));
return ret;
}
+4
View File
@@ -0,0 +1,4 @@
SRC_DIR := third_party_usb
SRC_FILES += dev_usb.c drv_usb.c bus_usb.c
include $(KERNEL_ROOT)/compiler.mk
+125
View File
@@ -0,0 +1,125 @@
/*
* 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 bus_usb.c
* @brief register usb bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_usb.h>
#include <dev_usb.h>
/*Register the USB BUS*/
int UsbBusInit(struct UsbBus *usb_bus, const char *bus_name)
{
NULL_PARAM_CHECK(usb_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != usb_bus->bus.bus_state) {
strncpy(usb_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
usb_bus->bus.bus_type = TYPE_USB_BUS;
usb_bus->bus.bus_state = BUS_INSTALL;
usb_bus->bus.private_data = usb_bus->private_data;
ret = BusRegister(&usb_bus->bus);
if (EOK != ret) {
KPrintf("UsbBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("UsbBusInit BusRegister bus has been register state%u\n", usb_bus->bus.bus_state);
}
return ret;
}
/*Register the USB Driver*/
int UsbDriverInit(struct UsbDriver *usb_driver, const char *driver_name)
{
NULL_PARAM_CHECK(usb_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != usb_driver->driver.driver_state) {
usb_driver->driver.driver_type = TYPE_USB_DRV;
usb_driver->driver.driver_state = DRV_INSTALL;
strncpy(usb_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
usb_driver->driver.configure = usb_driver->configure;
usb_driver->driver.private_data = usb_driver->private_data;
ret = UsbDriverRegister(&usb_driver->driver);
if (EOK != ret) {
KPrintf("UsbDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("UsbDriverInit DriverRegister driver has been register state%u\n", usb_driver->driver.driver_state);
}
return ret;
}
/*Release the USB device*/
int UsbReleaseBus(struct UsbBus *usb_bus)
{
NULL_PARAM_CHECK(usb_bus);
return BusRelease(&usb_bus->bus);
}
/*Register the USB Driver to the USB BUS*/
int UsbDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("UsbDriverAttachToBus find usb bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_USB_BUS == bus->bus_type) {
driver = UsbDriverFind(drv_name, TYPE_USB_DRV);
if (NONE == driver) {
KPrintf("UsbDriverAttachToBus find usb driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_USB_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("UsbDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}
+118
View File
@@ -0,0 +1,118 @@
/*
* 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 dev_usb.c
* @brief register usb dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_usb.h>
#include <dev_usb.h>
static DoubleLinklistType usbdev_linklist;
/*Create the usb device linklist*/
static void USBDeviceLinkInit()
{
InitDoubleLinkList(&usbdev_linklist);
}
/*Find the register USB device*/
HardwareDevType USBDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &usbdev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("USBDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
/*Register the USB device*/
int USBDeviceRegister(struct UsbHardwareDevice *usb_device, void *usb_param, const char *device_name)
{
NULL_PARAM_CHECK(usb_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (dev_link_flag) {
USBDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != usb_device->haldev.dev_state) {
strncpy(usb_device->haldev.dev_name, device_name, NAME_NUM_MAX);
usb_device->haldev.dev_type = TYPE_USB_DEV;
usb_device->haldev.dev_state = DEV_INSTALL;
usb_device->haldev.dev_done = (struct HalDevDone *)usb_device->dev_done;
usb_device->haldev.private_data = usb_param;
DoubleLinkListInsertNodeAfter(&usbdev_linklist, &(usb_device->haldev.dev_link));
} else {
KPrintf("USBDeviceRegister device has been register state%u\n", usb_device->haldev.dev_state);
}
return ret;
}
/*Register the USB Device to the USB BUS*/
int USBDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("USBDeviceAttachToBus find usb bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_USB_BUS == bus->bus_type) {
device = USBDeviceFind(dev_name, TYPE_USB_DEV);
if (NONE == device) {
KPrintf("USBDeviceAttachToBus find usb device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_USB_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("usbDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}
+69
View File
@@ -0,0 +1,69 @@
/*
* 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 drv_usb.c
* @brief register usb drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
#include <bus_usb.h>
#include <dev_usb.h>
static DoubleLinklistType usbdrv_linklist;
/*Create the driver linklist*/
static void UsbDrvLinkInit()
{
InitDoubleLinkList(&usbdrv_linklist);
}
/*Find the regiter driver*/
DriverType UsbDriverFind(const char *drv_name, enum DriverType drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &usbdrv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("UsbDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
/*Register the Driver, manage with the double linklist*/
int UsbDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
UsbDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&usbdrv_linklist, &(driver->driver_link));
return ret;
}
+3
View File
@@ -0,0 +1,3 @@
SRC_DIR := usbhost
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,4 @@
SRC_DIR := core class
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,4 @@
SRC_FILES += mass.c
SRC_FILES += udisk.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,571 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-12-12 Yi Qiu first version
*/
/**
* @file mass.c
* @brief support usb storage function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: mass.c
Description: support usb storage function
Others: take RT-Thread v4.0.2/components/drivers/usb/usbhost/class/mass.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. support usb storage configure, function and struct
2. support usb bus driver framework
*************************************************/
#include <xiuos.h>
#include <usb_host.h>
#include "mass.h"
#ifdef USBH_MSTORAGE
extern x_err_t UdiskRun(struct uhintf* intf);
extern x_err_t UdiskStop(struct uhintf* intf);
static struct UclassDriver StorageDriver;
static x_err_t PipeCheck(struct uhintf* intf, upipe_t pipe)
{
struct uinstance* device;
x_err_t ret;
UstorPointer stor;
int size = 0;
struct UstorageCsw csw;
if(intf == NONE || pipe == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
device = intf->device;
stor = (UstorPointer)intf->UserData;
if(pipe->status == UPIPE_STATUS_OK) return EOK;
if(pipe->status == UPIPE_STATUS_ERROR)
{
KPrintf("pipe status error\n");
return -EPIO;
}
if(pipe->status == UPIPE_STATUS_STALL)
{
ret = UsbhClearFeature(device, pipe->ep.bEndpointAddress,
USB_FEATURE_ENDPOINT_HALT);
if(ret != EOK) return ret;
}
DelayKTask(50);
KPrintf("pipes1 0x%x, 0x%x\n", stor->pipe_in, stor->pipe_out);
stor->pipe_in->status = UPIPE_STATUS_OK;
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("clean storage in pipe stall\n"));
size = UsbHcdPipeXfer(stor->pipe_in->inst->hcd,
stor->pipe_in, &csw, SIZEOF_CSW, 100);
if(size != SIZEOF_CSW)
{
KPrintf("receive the csw after stall failed\n");
return -EPIO;
}
return -ERROR;
}
static x_err_t UsbBulkOnlyXfer(struct uhintf* intf,
UstorageCbwPointer cmd, uint8* buffer, int timeout)
{
x_size_t size;
x_err_t ret;
upipe_t pipe;
struct UstorageCsw csw;
UstorPointer stor;
NULL_PARAM_CHECK(cmd);
if(intf == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
stor = (UstorPointer)intf->UserData;
do
{
size = UsbHcdPipeXfer(stor->pipe_out->inst->hcd, stor->pipe_out,
cmd, SIZEOF_CBW, timeout);
if(size != SIZEOF_CBW)
{
KPrintf("CBW size error\n");
return -EPIO;
}
if(cmd->XferLen != 0)
{
pipe = (cmd->dflags == CBWFLAGS_DIR_IN) ? stor->pipe_in :
stor->pipe_out;
size = UsbHcdPipeXfer(pipe->inst->hcd, pipe, (void*)buffer,
cmd->XferLen, timeout);
if(size != cmd->XferLen)
{
KPrintf("request size %d, transfer size %d\n",
cmd->XferLen, size);
break;
}
}
size = UsbHcdPipeXfer(stor->pipe_in->inst->hcd, stor->pipe_in,
&csw, SIZEOF_CSW, timeout);
if(size != SIZEOF_CSW)
{
KPrintf("csw size error\n");
return -EPIO;
}
}while(0);
ret = PipeCheck(intf, stor->pipe_in);
if(ret != EOK)
{
KPrintf("in pipe error\n");
return ret;
}
ret = PipeCheck(intf, stor->pipe_out);
if(ret != EOK)
{
KPrintf("out pipe error\n");
return ret;
}
if(csw.signature != CSW_SIGNATURE || csw.tag != CBW_TAG_VALUE)
{
KPrintf("csw signature error\n");
return -EPIO;
}
if(csw.status != 0)
{
return -ERROR;
}
return EOK;
}
x_err_t UsbhStorageGetMaxLun(struct uhintf* intf, uint8* MaxLun)
{
struct uinstance* device;
struct urequest setup;
int timeout = USB_TIMEOUT_BASIC;
if(intf == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
NULL_PARAM_CHECK(intf->device);
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("UsbhStorageGetMaxLun\n"));
device = intf->device;
setup.RequestType = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_INTERFACE;
setup.bRequest = USBREQ_GET_MAX_LUN;
setup.wValue = intf->IntfDesc->bInterfaceNumber;
setup.wIndex = 0;
setup.wLength = 1;
if(UsbHcdSetupXfer(device->hcd, device->PipeEp0Out, &setup, timeout) != 8)
{
return -EPIO;
}
if(UsbHcdPipeXfer(device->hcd, device->PipeEp0In, MaxLun, 1, timeout) != 1)
{
return -EPIO;
}
if(UsbHcdPipeXfer(device->hcd, device->PipeEp0Out, NONE, 0, timeout) != 0)
{
return -EPIO;
}
return EOK;
}
x_err_t UsbhStorageReset(struct uhintf* intf)
{
struct urequest setup;
struct uinstance* device;
int timeout = USB_TIMEOUT_BASIC;
if(intf == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
NULL_PARAM_CHECK(intf->device);
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("UsbhStorageReset\n"));
device = intf->device;
setup.RequestType = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS |
USB_REQ_TYPE_INTERFACE;
setup.bRequest = USBREQ_MASS_STORAGE_RESET;
setup.wIndex = intf->IntfDesc->bInterfaceNumber;
setup.wLength = 0;
setup.wValue = 0;
if(UsbHcdSetupXfer(device->hcd, device->PipeEp0Out, &setup, timeout) != 8)
{
return -EPIO;
}
if(UsbHcdPipeXfer(device->hcd, device->PipeEp0In, NONE, 0, timeout) != 0)
{
return -EPIO;
}
return EOK;
}
x_err_t UsbhStorageRead10(struct uhintf* intf, uint8 *buffer,
uint32 sector, x_size_t count, int timeout)
{
struct UstorageCbw cmd;
if(intf == NONE)
{
KPrintf("interface is not available\n");
return -EPIO;
}
NULL_PARAM_CHECK(intf->device);
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("UsbhStorageRead10\n"));
memset(&cmd, 0, sizeof(struct UstorageCbw));
cmd.signature = CBW_SIGNATURE;
cmd.tag = CBW_TAG_VALUE;
cmd.XferLen = SECTOR_SIZE * count;
cmd.dflags = CBWFLAGS_DIR_IN;
cmd.lun = 0;
cmd.CbLen = 10;
cmd.cb[0] = SCSI_READ_10;
cmd.cb[1] = 0;
cmd.cb[2] = (uint8)(sector >> 24);
cmd.cb[3] = (uint8)(sector >> 16);
cmd.cb[4] = (uint8)(sector >> 8);
cmd.cb[5] = (uint8)sector;
cmd.cb[6] = 0;
cmd.cb[7] = (count & 0xff00) >> 8;
cmd.cb[8] = (uint8) count & 0xff;
return UsbBulkOnlyXfer(intf, &cmd, buffer, timeout);
}
x_err_t UsbhStorageWrite10(struct uhintf* intf, uint8 *buffer,
uint32 sector, x_size_t count, int timeout)
{
struct UstorageCbw cmd;
if(intf == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
NULL_PARAM_CHECK(intf->device);
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("UsbhStorageWrite10\n"));
memset(&cmd, 0, sizeof(struct UstorageCbw));
cmd.signature = CBW_SIGNATURE;
cmd.tag = CBW_TAG_VALUE;
cmd.XferLen = SECTOR_SIZE * count;
cmd.dflags = CBWFLAGS_DIR_OUT;
cmd.lun = 0;
cmd.CbLen = 10;
cmd.cb[0] = SCSI_WRITE_10;
cmd.cb[1] = 0;
cmd.cb[2] = (uint8)(sector >> 24);
cmd.cb[3] = (uint8)(sector >> 16);
cmd.cb[4] = (uint8)(sector >> 8);
cmd.cb[5] = (uint8)sector;
cmd.cb[6] = 0;
cmd.cb[7] = (count & 0xff00) >> 8;
cmd.cb[8] = (uint8) count & 0xff;
return UsbBulkOnlyXfer(intf, &cmd, buffer, timeout);
}
x_err_t UsbhStorageRequestSense(struct uhintf* intf, uint8* buffer)
{
struct UstorageCbw cmd;
int timeout = USB_TIMEOUT_LONG;
if(intf == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
NULL_PARAM_CHECK(intf->device);
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("UsbhStorageRequestSense\n"));
memset(&cmd, 0, sizeof(struct UstorageCbw));
cmd.signature = CBW_SIGNATURE;
cmd.tag = CBW_TAG_VALUE;
cmd.XferLen = 18;
cmd.dflags = CBWFLAGS_DIR_IN;
cmd.lun = 0;
cmd.CbLen = 6;
cmd.cb[0] = SCSI_REQUEST_SENSE;
cmd.cb[4] = 18;
return UsbBulkOnlyXfer(intf, &cmd, buffer, timeout);
}
x_err_t UsbhStorageTestUnitReady(struct uhintf* intf)
{
struct UstorageCbw cmd;
int timeout = USB_TIMEOUT_LONG;
if(intf == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
NULL_PARAM_CHECK(intf->device);
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("UsbhStorageTestUnitReady\n"));
memset(&cmd, 0, sizeof(struct UstorageCbw));
cmd.signature = CBW_SIGNATURE;
cmd.tag = CBW_TAG_VALUE;
cmd.XferLen = 0;
cmd.dflags = CBWFLAGS_DIR_OUT;
cmd.lun = 0;
cmd.CbLen = 12;
cmd.cb[0] = SCSI_TEST_UNIT_READY;
return UsbBulkOnlyXfer(intf, &cmd, NONE, timeout);
}
x_err_t UsbhStorageInquiry(struct uhintf* intf, uint8* buffer)
{
struct UstorageCbw cmd;
int timeout = USB_TIMEOUT_LONG;
if(intf == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
NULL_PARAM_CHECK(intf->device);
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("UsbhStorageInquiry\n"));
memset(&cmd, 0, sizeof(struct UstorageCbw));
cmd.signature = CBW_SIGNATURE;
cmd.tag = CBW_TAG_VALUE;
cmd.XferLen = 36;
cmd.dflags = CBWFLAGS_DIR_IN;
cmd.lun = 0;
cmd.CbLen = 6;
cmd.cb[0] = SCSI_INQUIRY_CMD;
cmd.cb[4] = 36;
return UsbBulkOnlyXfer(intf, &cmd, buffer, timeout);
}
x_err_t UsbhStorageGetCapacity(struct uhintf* intf, uint8* buffer)
{
struct UstorageCbw cmd;
int timeout = USB_TIMEOUT_LONG;
if(intf == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
NULL_PARAM_CHECK(intf->device);
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("UsbhStorageGetCapacity\n"));
memset(&cmd, 0, sizeof(struct UstorageCbw));
cmd.signature = CBW_SIGNATURE;
cmd.tag = CBW_TAG_VALUE;
cmd.XferLen = 8;
cmd.dflags = CBWFLAGS_DIR_IN;
cmd.lun = 0;
cmd.CbLen = 12;
cmd.cb[0] = SCSI_READ_CAPACITY;
return UsbBulkOnlyXfer(intf, &cmd, buffer, timeout);
}
static x_err_t UsbhStorageEnable(void* arg)
{
int i = 0;
x_err_t ret;
UstorPointer stor;
struct uhintf* intf = (struct uhintf*)arg;
if(intf == NONE)
{
KPrintf("the interface is not available\n");
return -EPIO;
}
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("subclass %d, protocal %d\n",
intf->IntfDesc->bInterfaceSubClass,
intf->IntfDesc->bInterfaceProtocol));
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("usbh_storage_run\n"));
stor = x_malloc(sizeof(struct ustor));
NULL_PARAM_CHECK(stor);
memset(stor, 0, sizeof(struct ustor));
intf->UserData = (void*)stor;
for(i=0; i<intf->IntfDesc->bNumEndpoints; i++)
{
UepDescPointer EpDesc;
UsbhGetEndpointDescriptor(intf->IntfDesc, i, &EpDesc);
if(EpDesc == NONE)
{
KPrintf("usb_get_endpoint_descriptor error\n");
return -ERROR;
}
if((EpDesc->bmAttributes & USB_EP_ATTR_TYPE_MASK) != USB_EP_ATTR_BULK)
continue;
if(EpDesc->bEndpointAddress & USB_DIR_IN)
{
stor->pipe_in = UsbInstanceFindPipe(intf->device,EpDesc->bEndpointAddress);
}
else
{
stor->pipe_out = UsbInstanceFindPipe(intf->device,EpDesc->bEndpointAddress);
}
}
if(stor->pipe_in == NONE || stor->pipe_out == NONE)
{
KPrintf("pipe error, unsupported device\n");
return -ERROR;
}
ret = UdiskRun(intf);
if(ret != EOK) return ret;
return EOK;
}
static x_err_t UsbhStorageDisable(void* arg)
{
UstorPointer stor;
struct uhintf* intf = (struct uhintf*)arg;
NULL_PARAM_CHECK(intf);
NULL_PARAM_CHECK(intf->UserData);
NULL_PARAM_CHECK(intf->device );
SYS_KDEBUG_LOG(SYS_DEBUG_USB, ("usbh_storage_stop\n"));
stor = (UstorPointer)intf->UserData;
UdiskStop(intf);
if(stor != NONE) x_free(stor);
return EOK;
}
UcdPointer UsbhClassDriverStorage(void)
{
StorageDriver.ClassCode = USB_CLASS_MASS_STORAGE;
StorageDriver.enable = UsbhStorageEnable;
StorageDriver.disable = UsbhStorageDisable;
return &StorageDriver;
}
#endif
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-12-12 Yi Qiu first version
*/
/**
* @file mass.h
* @brief define usb storage function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: mass.h
Description: define usb storage function and struct
Others: take RT-Thread v4.0.2/components/drivers/usb/usbhost/class/mass.h for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. support define usb storage configure, function and struct
2. support usb bus driver framework
*************************************************/
#ifndef __MASS_H__
#define __MASS_H__
#include <xiuos.h>
#define MAX_PARTITION_COUNT 4
#define SECTOR_SIZE 512
struct UstorData
{
struct uhintf* intf;
int UdiskId;
const char path;
};
struct ustor
{
upipe_t pipe_in;
upipe_t pipe_out;
uint32 capicity[2];
uint8 DevCnt;
};
typedef struct ustor* UstorPointer;
x_err_t UsbhStorageGetMaxLun(struct uhintf* intf, uint8* MaxLun);
x_err_t UsbhStorageReset(struct uhintf* intf);
x_err_t UsbhStorageRead10(struct uhintf* intf, uint8 *buffer,
uint32 sector, x_size_t count, int timeout);
x_err_t UsbhStorageWrite10(struct uhintf* intf, uint8 *buffer,
uint32 sector, x_size_t count, int timeout);
x_err_t UsbhStorageRequestSense(struct uhintf* intf, uint8* buffer);
x_err_t UsbhStorageTestUnitReady(struct uhintf* intf);
x_err_t UsbhStorageInquiry(struct uhintf* intf, uint8* buffer);
x_err_t UsbhStorageGetCapacity(struct uhintf* intf, uint8* buffer);
#endif

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