forked from xuos/xiuos
First commit XiUOS
This commit is contained in:
@@ -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
|
||||
@@ -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
@@ -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 framework;2、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 successful:EOK,failed:ERROR
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:bus pointer,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:ERROR
|
||||
*/
|
||||
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 successful:EOK,failed:ERROR
|
||||
*/
|
||||
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 successful:EOK,failed:ERROR
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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 successful:EOK,failed:NONE
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
SRC_FILES += dev_can.c drv_can.c bus_can.c
|
||||
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
SRC_FILES += dev_i2c.c drv_i2c.c bus_i2c.c
|
||||
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 endian:0,big endian:1
|
||||
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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
SRC_FILES += dev_lcd.c bus_lcd.c drv_lcd.c
|
||||
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
SRC_FILES +=bus_pin.c dev_pin.c drv_pin.c
|
||||
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
SRC_FILES += bus_rtc.c dev_rtc.c drv_rtc.c
|
||||
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,5 @@
|
||||
SRC_FILES +=bus_sdio.c dev_sdio.c drv_sdio.c
|
||||
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES += bus_serial.c drv_serial.c dev_serial.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
SRC_FILES := sd_spi.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := bus_hwtimer.c dev_hwtimer.c drv_hwtimer.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
SRC_FILES += drv_touch.c dev_touch.c bus_touch.c
|
||||
|
||||
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user