support spi module and plc module

This commit is contained in:
wlyu
2022-01-24 18:30:44 +08:00
parent 28cf201808
commit 1dfcf0edbe
27 changed files with 5328 additions and 90 deletions

View File

@@ -1,4 +1,4 @@
SRC_FILES := plc.c
SRC_FILES := plc.c plc_dev.c plc_bus.c plc_drv.c
include $(KERNEL_ROOT)/compiler.mk

View File

@@ -0,0 +1,266 @@
/*
* 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
#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_e
{
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_PLC_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_e
{
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_e 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_e 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

View File

@@ -18,15 +18,23 @@
* @date 2021.12.15
*/
#include "../interoperability/opcua/open62541.h"
//#include "open62541.h"
#include "plc.h"
#include "plc_bus.h"
#include "plc_dev.h"
#define PLC_BUS_NAME "plc bus"
#define PLC_DRV_NAME "plc driver"
struct PlcDevice plc_device;
struct PlcBus plc_bus;
struct PlcDriver plc_drv;
// open and connect PLC device
void plc_open(struct PlcDevice *pdev)
{
}
// close and disconnect PLC device
@@ -52,6 +60,15 @@ void plc_ioctl(struct PlcDevice *pdev, int cmd, void *arg)
void plc_init(struct PlcDevice *plc_dev)
{
PlcBusInit(&plc_bus, PLC_BUS_NAME);
PlcDriverInit(&plc_drv, PLC_DRV_NAME);
}
void test_plc_bus(int argc, char *argv[])
{
plc_init(NULL);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
plc, test_plc_bus, test PLC);

View File

@@ -15,10 +15,13 @@
* @brief plc relative definition and structure
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.12.15
* @date 2022-01-24
*/
#include "xs_klist.h"
#ifndef __PLC_H_
#define __PLC_H_
#include "list.h"
#define IP_ADDR_SIZE 32
#define PLC_NAME_SIZE 32
@@ -77,7 +80,7 @@ enum PlcCtlType {
enum PlcIndHybridNet
{
//PLC Field Bus
// PLC Field Bus
PLC_IND_FIELD_MODBUS_485,
PLC_IND_FIELD_PROFIBUS,
PLC_IND_FIELD_CANOPEN,
@@ -91,7 +94,7 @@ enum PlcIndHybridNet
PLC_IND_ENET_SERCOS,
PLC_IND_ENET_OPCUA,
//PLC wireless net
// PLC wireless net
PLC_IND_WIRELESS
};
@@ -113,12 +116,13 @@ struct PlcInterface
// identify PLC device
struct PlcDevice {
const char name[PLC_NAME_SIZE]; /* name of the device */
char name[PLC_NAME_SIZE]; /* name of the device */
enum PlcCtlType type; /* PLC Control Type */
struct PlcInfo info;/* Plc info, such as vendor name and model name */
union PlcCfg cfg;
struct PlcOps ops; /* filesystem-like APIs for data transferring */
struct PlcInterface interface; /* protocols used for transferring data from program to plc */
DoubleLinklistType link;/* link list node */
DoublelistType link;/* link list node */
};
#endif

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file bus_plc.c
* @brief register plc bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-01-24
*/
#include "plc_bus.h"
#include "plc_dev.h"
int PlcBusInit(struct PlcBus *plc_bus, const char *bus_name)
{
NULL_PARAM_CHECK(plc_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != plc_bus->bus.bus_state) {
strncpy(plc_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
plc_bus->bus.bus_type = TYPE_SPI_BUS;
plc_bus->bus.bus_state = BUS_INSTALL;
plc_bus->bus.private_data = plc_bus->private_data;
ret = BusRegister(&plc_bus->bus);
if (EOK != ret) {
KPrintf("PlcBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("PlcBusInit BusRegister bus has been register state%u\n", plc_bus->bus.bus_state);
}
return ret;
}
int PlcDriverInit(struct PlcDriver *plc_driver, const char *driver_name)
{
NULL_PARAM_CHECK(plc_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != plc_driver->driver.driver_state) {
plc_driver->driver.driver_type = TYPE_SPI_DRV;
plc_driver->driver.driver_state = DRV_INSTALL;
strncpy(plc_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
plc_driver->driver.configure = plc_driver->configure;
ret = PlcDriverRegister(&plc_driver->driver);
if (EOK != ret) {
KPrintf("PlcDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("PlcDriverInit DriverRegister driver has been register state%u\n", plc_driver->driver.driver_state);
}
return ret;
}
int PlcReleaseBus(struct PlcBus *plc_bus)
{
NULL_PARAM_CHECK(plc_bus);
return BusRelease(&plc_bus->bus);
}
int PlcDriverAttachToBus(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("PlcDriverAttachToBus find plc bus error!name %s\n", bus_name);
return ERROR;
}
// if (TYPE_SPI_BUS == bus->bus_type) {
driver = PlcDriverFind(drv_name, TYPE_SPI_DRV);
if (NONE == driver) {
KPrintf("PlcDriverAttachToBus find plc driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_SPI_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("PlcDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
// }
return ret;
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file bus_plc.h
* @brief define PLC bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-01-24
*/
#ifndef BUS_PLC_H
#define BUS_PLC_H
#ifdef __cplusplus
extern "C" {
#endif
#include "transform.h"
#include "plc.h"
struct PlcDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
};
struct PlcBus
{
struct Bus bus;
void *private_data;
};
/*Register the plc bus*/
int PlcBusInit(struct PlcBus *plc_bus, const char *bus_name);
/*Register the plc driver*/
int PlcDriverInit(struct PlcDriver *plc_driver, const char *driver_name);
/*Release the plc device*/
int PlcReleaseBus(struct PlcBus *plc_bus);
/*Register the plc driver to the plc bus*/
int PlcDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int PlcDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType PlcDriverFind(const char *drv_name, enum DriverType_e drv_type);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,239 @@
/*
* 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_plc.c
* @brief register plc dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-01-24
*/
#include "transform.h"
#include "plc.h"
#include "plc_bus.h"
#include "plc_dev.h"
static DoublelistType plcdev_linklist;
/*Create the plc device linklist*/
static void PlcDeviceLinkInit()
{
AppInitDoubleList(&plcdev_linklist);
}
static uint32 PlcDeviceOpen(void *dev)
{
NULL_PARAM_CHECK(dev);
PlcDevConfigureCs(dev, 1, 0);
return EOK;
}
static uint32 PlcDeviceClose(void *dev)
{
NULL_PARAM_CHECK(dev);
PlcDevConfigureCs(dev, 0, 1);
return EOK;
}
static uint32 PlcDeviceWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
int ret;
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
struct PlcDataStandard *plc_msg;
plc_msg = (struct PlcDataStandard *)x_malloc(sizeof(struct PlcDataStandard));
if (NONE == plc_msg) {
KPrintf("PlcDeviceWrite x_malloc msg error\n");
x_free(plc_msg);
return ERROR;
}
//memset(plc_msg, 0, sizeof(struct PlcDataStandard));
plc_msg->tx_buff = (uint8 *)write_param->buffer;
plc_msg->rx_buff = NONE;
plc_msg->length = write_param->size;
plc_msg->plc_chip_select = 0;
plc_msg->plc_cs_release = 0;
plc_msg->next = NONE;
ret = plc_dev->ops.write(plc_dev, plc_msg, plc_msg->length);
x_free(plc_msg);
return ret;
}
static uint32 PlcDeviceRead(void *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(read_param);
int ret;
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
struct PlcDataStandard *plc_msg;
plc_msg = (struct PlcDataStandard *)x_malloc(sizeof(struct PlcDataStandard));
if (NONE == plc_msg) {
KPrintf("PlcDeviceRead x_malloc msg error\n");
x_free(plc_msg);
return ERROR;
}
//memset(plc_msg, 0, sizeof(struct PlcDataStandard));
plc_msg->tx_buff = NONE;
plc_msg->rx_buff = (uint8 *)read_param->buffer;
plc_msg->length = read_param->size;
plc_msg->plc_chip_select = 0;
plc_msg->plc_cs_release = 0;
plc_msg->next = NONE;
ret = plc_dev->ops.read(plc_dev, plc_msg, plc_msg->length);
x_free(plc_msg);
return ret;
}
static const struct HalDevDone dev_done =
{
.open = PlcDeviceOpen,
.close = PlcDeviceClose,
.write = PlcDeviceWrite,
.read = PlcDeviceRead,
};
struct PlcDevice *PlcDeviceFind(const char *dev_name, enum PlcCtlType ctl_type)
{
NULL_PARAM_CHECK(dev_name);
struct PlcDevice *plc_dev = NONE;
DoublelistType *node = NONE;
DoublelistType *head = &plcdev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
plc_dev = SYS_DOUBLE_LINKLIST_ENTRY(node, struct PlcDevice, link);
if ((!strcmp(plc_dev->name, dev_name)) && (ctl_type == plc_dev->type)) {
return plc_dev;
}
}
KPrintf("PlcDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int PlcDeviceRegister(struct PlcDevice *plc_device, void *plc_param, const char *device_name)
{
NULL_PARAM_CHECK(plc_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (!dev_link_flag) {
PlcDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if ("" != plc_device->name) {
strncpy(plc_device->name, device_name, PLC_NAME_SIZE);
// plc_device->haldev.dev_type = TYPE_SPI_DEV;
// plc_device->haldev.dev_state = DEV_INSTALL;
//
// //only plc bus dev need to register dev_done
// if (RET_TRUE != plc_device->plc_dev_flag) {
// plc_device->haldev.dev_done = &dev_done;
// }
//
// plc_device->haldev.private_data = plc_param;
AppDoubleListInsertNodeAfter(&plcdev_linklist, &(plc_device->link));
} else {
// KPrintf("PlcDeviceRegister device has been register state%u\n", plc_device->haldev.dev_state);
}
return ret;
}
int PlcDeviceAttachToBus(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 PlcDevice *device;
struct HardwareDev *hard_dev;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("PlcDeviceAttachToBus find plc bus error!name %s\n", bus_name);
return ERROR;
}
// if (TYPE_PLC_BUS == bus->bus_type) {
device = PlcDeviceFind(dev_name, PLC_ABILITY_HSC);
if (NONE == device) {
KPrintf("PlcDeviceAttachToBus find plc device error!name %s\n", dev_name);
return ERROR;
}
if (PLC_ABILITY_HSC == device->type) {
ret = DeviceRegisterToBus(bus, hard_dev);
if (EOK != ret) {
KPrintf("PlcDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
// }
return EOK;
}
int PlcDevConfigureCs(struct PlcDevice *dev, uint8 plc_chip_select, uint8 plc_cs_release)
{
NULL_PARAM_CHECK(dev);
int ret;
struct PlcDevice *plc_dev = (struct PlcDevice *)dev;
struct PlcDataStandard *msg;
msg = (struct PlcDataStandard *)x_malloc(sizeof(struct PlcDataStandard));
if (NONE == msg) {
KPrintf("PlcDevConfigureCs x_malloc msg error\n");
x_free(msg);
return ERROR;
}
//memset(msg, 0, sizeof(struct PlcDataStandard));
msg->length = 0;
msg->rx_buff = NONE;
msg->tx_buff = NONE;
msg->next = NONE;
msg->plc_chip_select = plc_chip_select;
msg->plc_cs_release = plc_cs_release;
ret = plc_dev->ops.write(plc_dev, msg, msg->length);
x_free(msg);
return ret;
}

View File

@@ -0,0 +1,140 @@
/*
* 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_plc.h
* @brief define plc dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-01-24
*/
#ifndef DEV_PLC_H
#define DEV_PLC_H
#include <bus.h>
#ifdef __cpluspluss
extern "C" {
#endif
#define PLC_MAX_CLOCK 40000000
#define plc_device_max_num 4
#define PLC_LINE_CPHA (1 << 0)
#define PLC_LINE_CPOL (1 << 1)
#define PLC_LSB (0 << 2)
#define PLC_MSB (1 << 2)
#define PLC_MASTER (0 << 3)
#define DEV_PLC_SLAVE (1 << 3)
#define PLC_MODE_0 (0 | 0)
#define PLC_MODE_1 (0 | PLC_LINE_CPHA)
#define PLC_MODE_2 (PLC_LINE_CPOL | 0)
#define PLC_MODE_3 (PLC_LINE_CPOL | PLC_LINE_CPHA)
#define PLC_MODE_MASK (PLC_LINE_CPHA | PLC_LINE_CPOL | PLC_MSB)
#define PLC_CS_HIGH (1 << 4)
#define PLC_NO_CS (1 << 5)
#define PLC_3WIRE (1 << 6)
#define PLC_READY (1 << 7)
struct PlcDataStandard
{
uint8 plc_chip_select;
uint8 plc_cs_release;
const uint8 *tx_buff;
uint32 tx_len;
uint8 *rx_buff;
uint32 rx_len;
uint32 length;
struct PlcDataStandard *next;
};
struct PlcMasterParam
{
uint8 plc_work_mode;//CPOL CPHA
uint8 plc_frame_format;//frame format
uint8 plc_data_bit_width;//bit width
uint8 plc_data_endian;//little endian: big endian
uint32 plc_maxfrequency;//work frequency
};
struct PlcDmaParam
{
uint8 plc_master_id;
uint8 plc_dmac_txchannel;
uint8 plc_dmac_rxchannel;
};
struct PlcSlaveParam
{
uint8 plc_slave_id;
uint8 plc_cs_gpio_pin;
uint8 plc_cs_select_id;
};
typedef struct
{
struct PlcDmaParam *plc_dma_param;
struct PlcSlaveParam *plc_slave_param;
struct PlcMasterParam *plc_master_param;
}PlcDeviceParam;
struct PlcDevice;
struct PlcDevDone
{
uint32 (*dev_open) (struct PlcDevice *dev);
uint32 (*dev_close) (struct PlcDevice *dev);
uint32 (*dev_write) (struct PlcDevice *dev, struct PlcDataStandard *msg);
uint32 (*dev_read) (struct PlcDevice *dev, struct PlcDataStandard *msg);
};
struct PlcHardwareDevice
{
struct HardwareDev haldev;
PlcDeviceParam plc_param;
x_bool plc_dev_flag;
const struct PlcDevDone *plc_dev_done;
void *private_data;
};
/*Register the plc device*/
int PlcDeviceRegister(struct PlcDevice *plc_device, void *plc_param, const char *device_name);
/*Register the plc device to the plc bus*/
int PlcDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register plc device*/
struct PlcDevice *PlcDeviceFind(const char *dev_name, enum PlcCtlType dev_type);
/*Configure the cs pin of plc dev*/
int PlcDevConfigureCs(struct PlcDevice *dev, uint8 plc_chip_select, uint8 plc_cs_release);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file drv_plc.c
* @brief register plc drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-01-24
*/
#include "transform.h"
#include "plc_bus.h"
#include "plc_dev.h"
static DoubleLinklistType plcdrv_linklist;
/*Create the driver linklist*/
static void PlcDrvLinkInit()
{
InitDoubleLinkList(&plcdrv_linklist);
}
DriverType PlcDriverFind(const char *drv_name, enum DriverType_e drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &plcdrv_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("PlcDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int PlcDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
PlcDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&plcdrv_linklist, &(driver->driver_link));
return ret;
}

View File

@@ -107,7 +107,7 @@ struct PinDevIrq
struct PinParam
{
int cmd;//< cmd:GPIO_CONFIG_MODE/GPIO_IRQ_REGISTER/GPIO_IRQ_FREE/GPIO_IRQ_DISABLE/GPIO_IRQ_ENABLE
long pin;//< pin number
long pin;//< pin number
int mode;//< pin mode: input/output
struct PinDevIrq irq_set;//< pin irq set
uint64 arg;
@@ -170,9 +170,6 @@ int PrivMutexDelete(pthread_mutex_t *p_mutex);
int PrivMutexObtain(pthread_mutex_t *p_mutex);
int PrivMutexAbandon(pthread_mutex_t *p_mutex);
/*********************semaphore**********************/
int PrivSemaphoreCreate(sem_t *sem, int pshared, unsigned int value);