support spi module and plc module
This commit is contained in:
parent
28cf201808
commit
1dfcf0edbe
|
@ -28,6 +28,8 @@
|
|||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define TCP_DEMO_BUF_SIZE 65535
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
@ -38,8 +40,6 @@
|
|||
|
||||
char tcp_socket_ip[] = {192, 168, 250, 252};
|
||||
|
||||
#define TCP_DEMO_BUF_SIZE 65535
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
@ -80,7 +80,7 @@ static void tcp_recv_demo(void *arg)
|
|||
}
|
||||
|
||||
lw_print("tcp bind success, start to receive.\n");
|
||||
lw_print("\n\nLocal Port:%d\n\n", LWIP_LOCAL_PORT);
|
||||
lw_pr_info("\n\nLocal Port:%d\n\n", LWIP_LOCAL_PORT);
|
||||
|
||||
// setup socket fd as listening mode
|
||||
if (listen(fd, 5) != 0 )
|
||||
|
@ -91,7 +91,7 @@ static void tcp_recv_demo(void *arg)
|
|||
|
||||
// accept client connection
|
||||
clientfd = accept(fd, (struct sockaddr *)&tcp_addr, (socklen_t*)&addr_len);
|
||||
lw_print("client %s connected\n", inet_ntoa(tcp_addr.sin_addr));
|
||||
lw_pr_info("client %s connected\n", inet_ntoa(tcp_addr.sin_addr));
|
||||
|
||||
while(1)
|
||||
{
|
||||
|
@ -163,7 +163,7 @@ static void tcp_send_demo(void *arg)
|
|||
}
|
||||
|
||||
lw_print("tcp connect success, start to send.\n");
|
||||
lw_pr_info("\n\nTarget Port:%d\n\n", tcp_sock.sin_port);
|
||||
lw_pr_info("\n\nTarget Port:%d\n\n", LWIP_TARGET_PORT);
|
||||
|
||||
while (cnt --)
|
||||
{
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
extern char udp_target[];
|
||||
static struct udp_pcb *udpecho_raw_pcb;
|
||||
char udp_socket_ip[] = {192, 168, 250, 252};
|
||||
|
@ -59,14 +60,14 @@ static void udp_recv_demo(void *arg)
|
|||
while(1)
|
||||
{
|
||||
recv_buf = (char *)malloc(UDP_BUF_SIZE);
|
||||
if (recv_buf == NULL)
|
||||
if(recv_buf == NULL)
|
||||
{
|
||||
lw_print("No memory\n");
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (socket_fd < 0)
|
||||
if(socket_fd < 0)
|
||||
{
|
||||
lw_print("Socket error\n");
|
||||
goto __exit;
|
||||
|
@ -77,7 +78,7 @@ static void udp_recv_demo(void *arg)
|
|||
udp_addr.sin_port = htons(LWIP_LOCAL_PORT);
|
||||
memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero));
|
||||
|
||||
if (bind(socket_fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1)
|
||||
if(bind(socket_fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1)
|
||||
{
|
||||
lw_print("Unable to bind\n");
|
||||
goto __exit;
|
||||
|
@ -96,11 +97,15 @@ static void udp_recv_demo(void *arg)
|
|||
}
|
||||
|
||||
__exit:
|
||||
if (socket_fd >= 0)
|
||||
if(socket_fd >= 0)
|
||||
{
|
||||
closesocket(socket_fd);
|
||||
}
|
||||
|
||||
if (recv_buf)
|
||||
if(recv_buf)
|
||||
{
|
||||
free(recv_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +140,7 @@ static void udp_send_demo(void *arg)
|
|||
memset(send_str, 0, sizeof(send_str));
|
||||
|
||||
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (socket_fd < 0)
|
||||
if(socket_fd < 0)
|
||||
{
|
||||
lw_print("Socket error\n");
|
||||
goto __exit;
|
||||
|
@ -144,10 +149,10 @@ static void udp_send_demo(void *arg)
|
|||
struct sockaddr_in udp_sock;
|
||||
udp_sock.sin_family = AF_INET;
|
||||
udp_sock.sin_port = htons(LWIP_TARGET_PORT);
|
||||
udp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(udp_target[0],udp_target[1],udp_target[2],udp_target[3]));
|
||||
udp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(udp_target[0], udp_target[1], udp_target[2], udp_target[3]));
|
||||
memset(&(udp_sock.sin_zero), 0, sizeof(udp_sock.sin_zero));
|
||||
|
||||
if (connect(socket_fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)))
|
||||
if(connect(socket_fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)))
|
||||
{
|
||||
lw_print("Unable to connect\n");
|
||||
goto __exit;
|
||||
|
@ -165,7 +170,7 @@ static void udp_send_demo(void *arg)
|
|||
}
|
||||
|
||||
__exit:
|
||||
if (socket_fd >= 0)
|
||||
if(socket_fd >= 0)
|
||||
{
|
||||
closesocket(socket_fd);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -72,6 +72,7 @@ void BOARD_InitBootPins(void);
|
|||
*/
|
||||
void BOARD_InitPins(void);
|
||||
void BOARD_InitI2C1Pins(void);
|
||||
void BOARD_InitSPIPins(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
|
|
@ -110,8 +110,6 @@ int test_adc(void)
|
|||
adc_config_t adcConfigStrcut;
|
||||
adc_channel_config_t adcChannelConfigStruct;
|
||||
|
||||
// TestAdcInit();
|
||||
|
||||
EnableIRQ(DEMO_ADC_IRQn);
|
||||
|
||||
adc_print("\r\nADC interrupt Example.\r\n");
|
||||
|
@ -169,9 +167,7 @@ int test_adc(void)
|
|||
for each command.
|
||||
*/
|
||||
ADC_SetChannelConfig(DEMO_ADC_BASE, DEMO_ADC_CHANNEL_GROUP, &adcChannelConfigStruct);
|
||||
while (g_AdcConversionDoneFlag == false)
|
||||
{
|
||||
}
|
||||
while (g_AdcConversionDoneFlag == false);
|
||||
adc_print("ADC Value: %d\r\n", g_AdcConversionValue);
|
||||
adc_print("ADC Interrupt Counter: %d\r\n", g_AdcInterruptCounter);
|
||||
}
|
||||
|
|
|
@ -88,6 +88,128 @@ BOARD_InitPins:
|
|||
* Description : Configures pin routing and optionally pin electrical features.
|
||||
*
|
||||
* END ****************************************************************************************************************/
|
||||
|
||||
void BOARD_InitSPIPins(void){
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 is configured as LPUART1_TX */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 is configured as LPUART1_RX */
|
||||
0U); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, /* GPIO_SD_B1_05 is configured as FLEXSPIA_DQS */
|
||||
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_05 */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, /* GPIO_SD_B1_06 is configured as FLEXSPIA_SS0_B */
|
||||
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_06 */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, /* GPIO_SD_B1_07 is configured as FLEXSPIA_SCLK */
|
||||
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_07 */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, /* GPIO_SD_B1_08 is configured as FLEXSPIA_DATA00 */
|
||||
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_08 */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, /* GPIO_SD_B1_09 is configured as FLEXSPIA_DATA01 */
|
||||
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_09 */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, /* GPIO_SD_B1_10 is configured as FLEXSPIA_DATA02 */
|
||||
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_10 */
|
||||
IOMUXC_SetPinMux(
|
||||
IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, /* GPIO_SD_B1_11 is configured as FLEXSPIA_DATA03 */
|
||||
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_11 */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 PAD functional properties : */
|
||||
0x10B0u); /* Slew Rate Field: Slow Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 PAD functional properties : */
|
||||
0x10B0u); /* Slew Rate Field: Slow Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: medium(100MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, /* GPIO_SD_B1_05 PAD functional properties : */
|
||||
0x10F1u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, /* GPIO_SD_B1_06 PAD functional properties : */
|
||||
0x10F1u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, /* GPIO_SD_B1_07 PAD functional properties : */
|
||||
0x10F1u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, /* GPIO_SD_B1_08 PAD functional properties : */
|
||||
0x10F1u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, /* GPIO_SD_B1_09 PAD functional properties : */
|
||||
0x10F1u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, /* GPIO_SD_B1_10 PAD functional properties : */
|
||||
0x10F1u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
IOMUXC_SetPinConfig(
|
||||
IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, /* GPIO_SD_B1_11 PAD functional properties : */
|
||||
0x10F1u); /* Slew Rate Field: Fast Slew Rate
|
||||
Drive Strength Field: R0/6
|
||||
Speed Field: max(200MHz)
|
||||
Open Drain Enable Field: Open Drain Disabled
|
||||
Pull / Keep Enable Field: Pull/Keeper Enabled
|
||||
Pull / Keep Select Field: Keeper
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Down
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
}
|
||||
|
||||
|
||||
void BOARD_InitPins(void) {
|
||||
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
|
||||
|
||||
|
@ -297,6 +419,7 @@ void BOARD_InitPins(void) {
|
|||
Pull / Keep Select Field: Pull
|
||||
Pull Up / Down Config. Field: 100K Ohm Pull Up
|
||||
Hyst. Enable Field: Hysteresis Disabled */
|
||||
|
||||
}
|
||||
|
||||
void BOARD_InitI2C1Pins(void) {
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
SRC_FILES := fsl_lpspi.c lpspi_interrupt.c
|
||||
SRC_FILES := fsl_lpspi.c lpspi_interrupt.c connect_flash_spi.c flexspi_nor_flash_ops.c flexspi_nor_polling_transfer.c fsl_flexspi.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef _APP_H_
|
||||
#define _APP_H_
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*${macro:start}*/
|
||||
#define EXAMPLE_FLEXSPI FLEXSPI
|
||||
#define FLASH_SIZE 0x2000 /* 64Mb/KByte */
|
||||
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE
|
||||
#define FLASH_PAGE_SIZE 256
|
||||
#define EXAMPLE_SECTOR 0
|
||||
#define SECTOR_SIZE 0x1000 /* 4K */
|
||||
#define EXAMPLE_FLEXSPI_CLOCK kCLOCK_FlexSpi
|
||||
|
||||
#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 7
|
||||
#define NOR_CMD_LUT_SEQ_IDX_READ_FAST 13
|
||||
#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 0
|
||||
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS 1
|
||||
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 2
|
||||
#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 3
|
||||
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE 6
|
||||
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 4
|
||||
#define NOR_CMD_LUT_SEQ_IDX_READID 8
|
||||
#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 9
|
||||
#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10
|
||||
#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 11
|
||||
#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 12
|
||||
#define NOR_CMD_LUT_SEQ_IDX_ERASECHIP 5
|
||||
|
||||
#define CUSTOM_LUT_LENGTH 60
|
||||
#define FLASH_QUAD_ENABLE 0x40
|
||||
#define FLASH_BUSY_STATUS_POL 1
|
||||
#define FLASH_BUSY_STATUS_OFFSET 0
|
||||
|
||||
/*${macro:end}*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/*${prototype:start}*/
|
||||
void BOARD_InitHardware(void);
|
||||
|
||||
static inline void flexspi_clock_init(void)
|
||||
{
|
||||
const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
|
||||
|
||||
CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
|
||||
CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24); /* Set PLL3 PFD0 clock 360MHZ. */
|
||||
CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
|
||||
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2); /* flexspi clock 120M. */
|
||||
}
|
||||
/*${prototype:end}*/
|
||||
|
||||
#endif /* _APP_H_ */
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2020 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-27 SummerGift add spi flash port file
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_flash_spi.c
|
||||
* @brief support stm32f407-st-discovery-board spi flash function and register to bus framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-25
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: connect_flash_spi.c
|
||||
Description: support stm32f407-st-discovery-board spi flash bus register function
|
||||
Others: take RT-Thread v4.0.2/bsp/stm32/stm32f407-atk-explorer/board/ports/spi-flash-init.c
|
||||
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||
History:
|
||||
1. Date: 2021-04-25
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support stm32f407-st-discovery-board spi flash register to spi bus
|
||||
2. support stm32f407-st-discovery-board spi flash init
|
||||
*************************************************/
|
||||
|
||||
//#include "connect_spi.h"
|
||||
#include "flash_spi.h"
|
||||
|
||||
int FlashW25qxxSpiDeviceInit(void)
|
||||
{
|
||||
#ifdef BSP_USING_SPI1
|
||||
|
||||
// __IO uint32_t tmpreg = 0x00U;
|
||||
// RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
|
||||
// tmpreg = RCC->AHB1ENR & RCC_AHB1ENR_GPIOBEN;
|
||||
// (void)tmpreg;
|
||||
//
|
||||
// if (EOK != HwSpiDeviceAttach(SPI_BUS_NAME_1, "spi1_dev0", GPIOB, GPIO_Pin_0)) {
|
||||
// return ERROR;
|
||||
// }
|
||||
//
|
||||
// if (NONE == SpiFlashInit(SPI_BUS_NAME_1, "spi1_dev0", SPI_1_DRV_NAME, "spi1_W25Q64")) {
|
||||
// return ERROR;
|
||||
// }
|
||||
|
||||
#endif
|
||||
|
||||
return EOK;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_flexspi.h"
|
||||
#include "app.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
*****************************************************************************/
|
||||
extern flexspi_device_config_t deviceconfig;
|
||||
extern const uint32_t customLUT[CUSTOM_LUT_LENGTH];
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
status_t flexspi_nor_write_enable(FLEXSPI_Type *base, uint32_t baseAddr)
|
||||
{
|
||||
flexspi_transfer_t flashXfer;
|
||||
status_t status;
|
||||
|
||||
/* Write enable */
|
||||
flashXfer.deviceAddress = baseAddr;
|
||||
flashXfer.port = kFLEXSPI_PortA1;
|
||||
flashXfer.cmdType = kFLEXSPI_Command;
|
||||
flashXfer.SeqNumber = 1;
|
||||
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;
|
||||
|
||||
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base)
|
||||
{
|
||||
/* Wait status ready. */
|
||||
bool isBusy;
|
||||
uint32_t readValue;
|
||||
status_t status;
|
||||
flexspi_transfer_t flashXfer;
|
||||
|
||||
flashXfer.deviceAddress = 0;
|
||||
flashXfer.port = kFLEXSPI_PortA1;
|
||||
flashXfer.cmdType = kFLEXSPI_Read;
|
||||
flashXfer.SeqNumber = 1;
|
||||
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG;
|
||||
flashXfer.data = &readValue;
|
||||
flashXfer.dataSize = 1;
|
||||
|
||||
do
|
||||
{
|
||||
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
||||
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
if (FLASH_BUSY_STATUS_POL)
|
||||
{
|
||||
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET))
|
||||
{
|
||||
isBusy = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isBusy = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET))
|
||||
{
|
||||
isBusy = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
isBusy = true;
|
||||
}
|
||||
}
|
||||
|
||||
} while (isBusy);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base)
|
||||
{
|
||||
flexspi_transfer_t flashXfer;
|
||||
status_t status;
|
||||
uint32_t writeValue = FLASH_QUAD_ENABLE;
|
||||
|
||||
/* Write enable */
|
||||
status = flexspi_nor_write_enable(base, 0);
|
||||
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Enable quad mode. */
|
||||
flashXfer.deviceAddress = 0;
|
||||
flashXfer.port = kFLEXSPI_PortA1;
|
||||
flashXfer.cmdType = kFLEXSPI_Write;
|
||||
flashXfer.SeqNumber = 1;
|
||||
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG;
|
||||
flashXfer.data = &writeValue;
|
||||
flashXfer.dataSize = 1;
|
||||
|
||||
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = flexspi_nor_wait_bus_busy(base);
|
||||
|
||||
/* Do software reset. */
|
||||
FLEXSPI_SoftwareReset(base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address)
|
||||
{
|
||||
status_t status;
|
||||
flexspi_transfer_t flashXfer;
|
||||
|
||||
/* Write enable */
|
||||
flashXfer.deviceAddress = address;
|
||||
flashXfer.port = kFLEXSPI_PortA1;
|
||||
flashXfer.cmdType = kFLEXSPI_Command;
|
||||
flashXfer.SeqNumber = 1;
|
||||
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;
|
||||
|
||||
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
||||
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
flashXfer.deviceAddress = address;
|
||||
flashXfer.port = kFLEXSPI_PortA1;
|
||||
flashXfer.cmdType = kFLEXSPI_Command;
|
||||
flashXfer.SeqNumber = 1;
|
||||
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ERASESECTOR;
|
||||
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
||||
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = flexspi_nor_wait_bus_busy(base);
|
||||
|
||||
/* Do software reset. */
|
||||
FLEXSPI_SoftwareReset(base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src)
|
||||
{
|
||||
status_t status;
|
||||
flexspi_transfer_t flashXfer;
|
||||
|
||||
/* Write enable */
|
||||
status = flexspi_nor_write_enable(base, dstAddr);
|
||||
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Prepare page program command */
|
||||
flashXfer.deviceAddress = dstAddr;
|
||||
flashXfer.port = kFLEXSPI_PortA1;
|
||||
flashXfer.cmdType = kFLEXSPI_Write;
|
||||
flashXfer.SeqNumber = 1;
|
||||
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD;
|
||||
flashXfer.data = (uint32_t *)src;
|
||||
flashXfer.dataSize = FLASH_PAGE_SIZE;
|
||||
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
||||
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = flexspi_nor_wait_bus_busy(base);
|
||||
|
||||
/* Do software reset. */
|
||||
FLEXSPI_SoftwareReset(base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId)
|
||||
{
|
||||
uint32_t temp;
|
||||
flexspi_transfer_t flashXfer;
|
||||
flashXfer.deviceAddress = 0;
|
||||
flashXfer.port = kFLEXSPI_PortA1;
|
||||
flashXfer.cmdType = kFLEXSPI_Read;
|
||||
flashXfer.SeqNumber = 1;
|
||||
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READID;
|
||||
flashXfer.data = &temp;
|
||||
flashXfer.dataSize = 1;
|
||||
|
||||
status_t status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
||||
|
||||
*vendorId = temp;
|
||||
|
||||
/* Do software reset. */
|
||||
FLEXSPI_SoftwareReset(base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t flexspi_nor_erase_chip(FLEXSPI_Type *base)
|
||||
{
|
||||
status_t status;
|
||||
flexspi_transfer_t flashXfer;
|
||||
|
||||
/* Write enable */
|
||||
status = flexspi_nor_write_enable(base, 0);
|
||||
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
flashXfer.deviceAddress = 0;
|
||||
flashXfer.port = kFLEXSPI_PortA1;
|
||||
flashXfer.cmdType = kFLEXSPI_Command;
|
||||
flashXfer.SeqNumber = 1;
|
||||
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ERASECHIP;
|
||||
|
||||
status = FLEXSPI_TransferBlocking(base, &flashXfer);
|
||||
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
status = flexspi_nor_wait_bus_busy(base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void flexspi_nor_flash_init(FLEXSPI_Type *base)
|
||||
{
|
||||
flexspi_config_t config;
|
||||
|
||||
flexspi_clock_init();
|
||||
|
||||
/*Get FLEXSPI default settings and configure the flexspi. */
|
||||
FLEXSPI_GetDefaultConfig(&config);
|
||||
|
||||
/*Set AHB buffer size for reading data through AHB bus. */
|
||||
config.ahbConfig.enableAHBPrefetch = true;
|
||||
config.ahbConfig.enableAHBBufferable = true;
|
||||
config.ahbConfig.enableReadAddressOpt = true;
|
||||
config.ahbConfig.enableAHBCachable = true;
|
||||
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
|
||||
FLEXSPI_Init(base, &config);
|
||||
|
||||
/* Configure flash settings according to serial flash feature. */
|
||||
FLEXSPI_SetFlashConfig(base, &deviceconfig, kFLEXSPI_PortA1);
|
||||
|
||||
/* Update LUT table. */
|
||||
FLEXSPI_UpdateLUT(base, 0, customLUT, CUSTOM_LUT_LENGTH);
|
||||
|
||||
/* Do software reset. */
|
||||
FLEXSPI_SoftwareReset(base);
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2018 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_flexspi.h"
|
||||
#include "app.h"
|
||||
#include "fsl_debug_console.h"
|
||||
#include "fsl_cache.h"
|
||||
|
||||
#include "pin_mux.h"
|
||||
#include "board.h"
|
||||
#include "clock_config.h"
|
||||
#include "fsl_common.h"
|
||||
|
||||
#include <transform.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
static uint8_t s_nor_program_buffer[256];
|
||||
static uint8_t s_nor_read_buffer[256];
|
||||
|
||||
extern status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
|
||||
extern status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src);
|
||||
extern status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId);
|
||||
extern status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base);
|
||||
extern status_t flexspi_nor_erase_chip(FLEXSPI_Type *base);
|
||||
extern void flexspi_nor_flash_init(FLEXSPI_Type *base);
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
flexspi_device_config_t deviceconfig = {
|
||||
.flexspiRootClk = 120000000,
|
||||
.flashSize = FLASH_SIZE,
|
||||
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
|
||||
.CSInterval = 2,
|
||||
.CSHoldTime = 3,
|
||||
.CSSetupTime = 3,
|
||||
.dataValidTime = 0,
|
||||
.columnspace = 0,
|
||||
.enableWordAddress = 0,
|
||||
.AWRSeqIndex = 0,
|
||||
.AWRSeqNumber = 0,
|
||||
.ARDSeqIndex = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD,
|
||||
.ARDSeqNumber = 1,
|
||||
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
|
||||
.AHBWriteWaitInterval = 0,
|
||||
};
|
||||
|
||||
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
|
||||
/* Normal read mode -SDR */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x03, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
|
||||
|
||||
/* Fast read mode - SDR */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x0B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ(
|
||||
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
|
||||
|
||||
/* Fast read quad mode - SDR */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18),
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ(
|
||||
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),
|
||||
|
||||
/* Read extend parameters */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
|
||||
|
||||
/* Write Enable */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
|
||||
|
||||
/* Erase Sector */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
|
||||
|
||||
/* Page Program - single mode */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
|
||||
|
||||
/* Page Program - quad mode */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
|
||||
|
||||
/* Read ID */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_READID] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
|
||||
|
||||
/* Enable Quad mode */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
|
||||
|
||||
/* Enter QPI mode */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_ENTERQPI] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
|
||||
|
||||
/* Exit QPI mode */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_EXITQPI] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xF5, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
|
||||
|
||||
/* Read status register */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
|
||||
|
||||
/* Erase whole chip */
|
||||
[4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] =
|
||||
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
|
||||
};
|
||||
|
||||
|
||||
int test_nor_flash(void)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
status_t status;
|
||||
uint8_t vendorID = 0;
|
||||
|
||||
// BOARD_ConfigMPU();
|
||||
// BOARD_InitPins();
|
||||
// BOARD_BootClockRUN();
|
||||
// BOARD_InitDebugConsole();
|
||||
BOARD_InitSPIPins();
|
||||
// SCB_DisableDCache();
|
||||
// spi_trace();
|
||||
flexspi_nor_flash_init(EXAMPLE_FLEXSPI);
|
||||
|
||||
spi_print("\r\nFLEXSPI example started!\r\n");
|
||||
|
||||
/* Get vendor ID. */
|
||||
status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID);
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
spi_print("flexspi status %d\r\n", status);
|
||||
return status;
|
||||
}
|
||||
spi_print("Vendor ID: 0x%x\r\n", vendorID);
|
||||
|
||||
return 0;
|
||||
#if !(defined(XIP_EXTERNAL_FLASH))
|
||||
/* Erase whole chip . */
|
||||
spi_print("Erasing whole chip over FlexSPI...\r\n");
|
||||
|
||||
status = flexspi_nor_erase_chip(EXAMPLE_FLEXSPI);
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
spi_print("Erase finished !\r\n");
|
||||
|
||||
#endif
|
||||
|
||||
/* Enter quad mode. */
|
||||
status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Erase sectors. */
|
||||
spi_print("Erasing Serial NOR over FlexSPI...\r\n");
|
||||
status = flexspi_nor_flash_erase_sector(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE);
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
spi_print("Erase sector failure !\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(s_nor_program_buffer, 0xFFU, sizeof(s_nor_program_buffer));
|
||||
memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
|
||||
sizeof(s_nor_read_buffer));
|
||||
|
||||
if (memcmp(s_nor_program_buffer, s_nor_read_buffer, sizeof(s_nor_program_buffer)))
|
||||
{
|
||||
spi_print("Erase data - read out data value incorrect !\r\n ");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_print("Erase data - successfully. \r\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < 0xFFU; i++)
|
||||
{
|
||||
s_nor_program_buffer[i] = i;
|
||||
}
|
||||
|
||||
status =
|
||||
flexspi_nor_flash_page_program(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE, (void *)s_nor_program_buffer);
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
spi_print("Page program failure !\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
DCACHE_CleanInvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE, FLASH_PAGE_SIZE);
|
||||
|
||||
memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
|
||||
sizeof(s_nor_read_buffer));
|
||||
|
||||
if (memcmp(s_nor_read_buffer, s_nor_program_buffer, sizeof(s_nor_program_buffer)) != 0)
|
||||
{
|
||||
spi_print("Program data - read out data value incorrect !\r\n ");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
spi_print("Program data - successfully. \r\n");
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
||||
nor, test_nor_flash, Nor flash test );
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,831 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __FSL_FLEXSPI_H_
|
||||
#define __FSL_FLEXSPI_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include "fsl_device_registers.h"
|
||||
#include "fsl_common.h"
|
||||
|
||||
#define spi_print KPrintf
|
||||
#define spi_trace() KPrintf("lw: [%s][%d] passed!\n", __func__, __LINE__)
|
||||
|
||||
/*!
|
||||
* @addtogroup flexspi
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @name Driver version */
|
||||
/*@{*/
|
||||
/*! @brief FLEXSPI driver version 2.1.1. */
|
||||
#define FSL_FLEXSPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
|
||||
/*@}*/
|
||||
|
||||
#define FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNTn(0)
|
||||
|
||||
/*! @breif Formula to form FLEXSPI instructions in LUT table. */
|
||||
#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
|
||||
(FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \
|
||||
FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
|
||||
|
||||
/*! @brief Status structure of FLEXSPI.*/
|
||||
enum _flexspi_status
|
||||
{
|
||||
kStatus_FLEXSPI_Busy = MAKE_STATUS(kStatusGroup_FLEXSPI, 0), /*!< FLEXSPI is busy */
|
||||
kStatus_FLEXSPI_SequenceExecutionTimeout = MAKE_STATUS(kStatusGroup_FLEXSPI, 1), /*!< Sequence execution timeout
|
||||
error occurred during FLEXSPI transfer. */
|
||||
kStatus_FLEXSPI_IpCommandSequenceError = MAKE_STATUS(kStatusGroup_FLEXSPI, 2), /*!< IP command Sequence execution
|
||||
timeout error occurred during FLEXSPI transfer. */
|
||||
kStatus_FLEXSPI_IpCommandGrantTimeout = MAKE_STATUS(kStatusGroup_FLEXSPI, 3), /*!< IP command grant timeout error
|
||||
occurred during FLEXSPI transfer. */
|
||||
};
|
||||
|
||||
/*! @brief CMD definition of FLEXSPI, use to form LUT instruction. */
|
||||
enum _flexspi_command
|
||||
{
|
||||
kFLEXSPI_Command_STOP = 0x00U, /*!< Stop execution, deassert CS. */
|
||||
kFLEXSPI_Command_SDR = 0x01U, /*!< Transmit Command code to Flash, using SDR mode. */
|
||||
kFLEXSPI_Command_RADDR_SDR = 0x02U, /*!< Transmit Row Address to Flash, using SDR mode. */
|
||||
kFLEXSPI_Command_CADDR_SDR = 0x03U, /*!< Transmit Column Address to Flash, using SDR mode. */
|
||||
kFLEXSPI_Command_MODE1_SDR = 0x04U, /*!< Transmit 1-bit Mode bits to Flash, using SDR mode. */
|
||||
kFLEXSPI_Command_MODE2_SDR = 0x05U, /*!< Transmit 2-bit Mode bits to Flash, using SDR mode. */
|
||||
kFLEXSPI_Command_MODE4_SDR = 0x06U, /*!< Transmit 4-bit Mode bits to Flash, using SDR mode. */
|
||||
kFLEXSPI_Command_MODE8_SDR = 0x07U, /*!< Transmit 8-bit Mode bits to Flash, using SDR mode. */
|
||||
kFLEXSPI_Command_WRITE_SDR = 0x08U, /*!< Transmit Programming Data to Flash, using SDR mode. */
|
||||
kFLEXSPI_Command_READ_SDR = 0x09U, /*!< Receive Read Data from Flash, using SDR mode. */
|
||||
kFLEXSPI_Command_LEARN_SDR = 0x0AU, /*!< Receive Read Data or Preamble bit from Flash, SDR mode. */
|
||||
kFLEXSPI_Command_DATSZ_SDR = 0x0BU, /*!< Transmit Read/Program Data size (byte) to Flash, SDR mode. */
|
||||
kFLEXSPI_Command_DUMMY_SDR = 0x0CU, /*!< Leave data lines undriven by FlexSPI controller.*/
|
||||
kFLEXSPI_Command_DUMMY_RWDS_SDR = 0x0DU, /*!< Leave data lines undriven by FlexSPI controller,
|
||||
dummy cycles decided by RWDS. */
|
||||
kFLEXSPI_Command_DDR = 0x21U, /*!< Transmit Command code to Flash, using DDR mode. */
|
||||
kFLEXSPI_Command_RADDR_DDR = 0x22U, /*!< Transmit Row Address to Flash, using DDR mode. */
|
||||
kFLEXSPI_Command_CADDR_DDR = 0x23U, /*!< Transmit Column Address to Flash, using DDR mode. */
|
||||
kFLEXSPI_Command_MODE1_DDR = 0x24U, /*!< Transmit 1-bit Mode bits to Flash, using DDR mode. */
|
||||
kFLEXSPI_Command_MODE2_DDR = 0x25U, /*!< Transmit 2-bit Mode bits to Flash, using DDR mode. */
|
||||
kFLEXSPI_Command_MODE4_DDR = 0x26U, /*!< Transmit 4-bit Mode bits to Flash, using DDR mode. */
|
||||
kFLEXSPI_Command_MODE8_DDR = 0x27U, /*!< Transmit 8-bit Mode bits to Flash, using DDR mode. */
|
||||
kFLEXSPI_Command_WRITE_DDR = 0x28U, /*!< Transmit Programming Data to Flash, using DDR mode. */
|
||||
kFLEXSPI_Command_READ_DDR = 0x29U, /*!< Receive Read Data from Flash, using DDR mode. */
|
||||
kFLEXSPI_Command_LEARN_DDR = 0x2AU, /*!< Receive Read Data or Preamble bit from Flash, DDR mode. */
|
||||
kFLEXSPI_Command_DATSZ_DDR = 0x2BU, /*!< Transmit Read/Program Data size (byte) to Flash, DDR mode. */
|
||||
kFLEXSPI_Command_DUMMY_DDR = 0x2CU, /*!< Leave data lines undriven by FlexSPI controller.*/
|
||||
kFLEXSPI_Command_DUMMY_RWDS_DDR = 0x2DU, /*!< Leave data lines undriven by FlexSPI controller,
|
||||
dummy cycles decided by RWDS. */
|
||||
kFLEXSPI_Command_JUMP_ON_CS = 0x1FU, /*!< Stop execution, deassert CS and save operand[7:0] as the
|
||||
instruction start pointer for next sequence */
|
||||
};
|
||||
|
||||
/*! @brief pad definition of FLEXSPI, use to form LUT instruction. */
|
||||
typedef enum _flexspi_pad
|
||||
{
|
||||
kFLEXSPI_1PAD = 0x00U, /*!< Transmit command/address and transmit/receive data only through DATA0/DATA1. */
|
||||
kFLEXSPI_2PAD = 0x01U, /*!< Transmit command/address and transmit/receive data only through DATA[1:0]. */
|
||||
kFLEXSPI_4PAD = 0x02U, /*!< Transmit command/address and transmit/receive data only through DATA[3:0]. */
|
||||
kFLEXSPI_8PAD = 0x03U, /*!< Transmit command/address and transmit/receive data only through DATA[7:0]. */
|
||||
} flexspi_pad_t;
|
||||
|
||||
/*! @brief FLEXSPI interrupt status flags.*/
|
||||
typedef enum _flexspi_flags
|
||||
{
|
||||
kFLEXSPI_SequenceExecutionTimeoutFlag = FLEXSPI_INTEN_SEQTIMEOUTEN_MASK, /*!< Sequence execution timeout. */
|
||||
kFLEXSPI_AhbBusTimeoutFlag = FLEXSPI_INTEN_AHBBUSTIMEOUTEN_MASK, /*!< AHB Bus timeout. */
|
||||
kFLEXSPI_SckStoppedBecauseTxEmptyFlag =
|
||||
FLEXSPI_INTEN_SCKSTOPBYWREN_MASK, /*!< SCK is stopped during command
|
||||
sequence because Async TX FIFO empty. */
|
||||
kFLEXSPI_SckStoppedBecauseRxFullFlag =
|
||||
FLEXSPI_INTEN_SCKSTOPBYRDEN_MASK, /*!< SCK is stopped during command
|
||||
sequence because Async RX FIFO full. */
|
||||
#if !((defined(FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN)) && (FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN))
|
||||
kFLEXSPI_DataLearningFailedFlag = FLEXSPI_INTEN_DATALEARNFAILEN_MASK, /*!< Data learning failed. */
|
||||
#endif
|
||||
kFLEXSPI_IpTxFifoWatermarkEmpltyFlag = FLEXSPI_INTEN_IPTXWEEN_MASK, /*!< IP TX FIFO WaterMark empty. */
|
||||
kFLEXSPI_IpRxFifoWatermarkAvailableFlag = FLEXSPI_INTEN_IPRXWAEN_MASK, /*!< IP RX FIFO WaterMark available. */
|
||||
kFLEXSPI_AhbCommandSequenceErrorFlag =
|
||||
FLEXSPI_INTEN_AHBCMDERREN_MASK, /*!< AHB triggered Command Sequences Error. */
|
||||
kFLEXSPI_IpCommandSequenceErrorFlag = FLEXSPI_INTEN_IPCMDERREN_MASK, /*!< IP triggered Command Sequences Error. */
|
||||
kFLEXSPI_AhbCommandGrantTimeoutFlag =
|
||||
FLEXSPI_INTEN_AHBCMDGEEN_MASK, /*!< AHB triggered Command Sequences Grant Timeout. */
|
||||
kFLEXSPI_IpCommandGrantTimeoutFlag =
|
||||
FLEXSPI_INTEN_IPCMDGEEN_MASK, /*!< IP triggered Command Sequences Grant Timeout. */
|
||||
kFLEXSPI_IpCommandExcutionDoneFlag =
|
||||
FLEXSPI_INTEN_IPCMDDONEEN_MASK, /*!< IP triggered Command Sequences Execution finished. */
|
||||
kFLEXSPI_AllInterruptFlags = 0xFFFU, /*!< All flags. */
|
||||
} flexspi_flags_t;
|
||||
|
||||
/*! @brief FLEXSPI sample clock source selection for Flash Reading.*/
|
||||
typedef enum _flexspi_read_sample_clock
|
||||
{
|
||||
kFLEXSPI_ReadSampleClkLoopbackInternally = 0x0U, /*!< Dummy Read strobe generated by FlexSPI Controller
|
||||
and loopback internally. */
|
||||
kFLEXSPI_ReadSampleClkLoopbackFromDqsPad = 0x1U, /*!< Dummy Read strobe generated by FlexSPI Controller
|
||||
and loopback from DQS pad. */
|
||||
kFLEXSPI_ReadSampleClkLoopbackFromSckPad = 0x2U, /*!< SCK output clock and loopback from SCK pad. */
|
||||
kFLEXSPI_ReadSampleClkExternalInputFromDqsPad = 0x3U, /*!< Flash provided Read strobe and input from DQS pad. */
|
||||
} flexspi_read_sample_clock_t;
|
||||
|
||||
/*! @brief FLEXSPI interval unit for flash device select.*/
|
||||
typedef enum _flexspi_cs_interval_cycle_unit
|
||||
{
|
||||
kFLEXSPI_CsIntervalUnit1SckCycle = 0x0U, /*!< Chip selection interval: CSINTERVAL * 1 serial clock cycle. */
|
||||
kFLEXSPI_CsIntervalUnit256SckCycle = 0x1U, /*!< Chip selection interval: CSINTERVAL * 256 serial clock cycle. */
|
||||
} flexspi_cs_interval_cycle_unit_t;
|
||||
|
||||
/*! @brief FLEXSPI AHB wait interval unit for writting.*/
|
||||
typedef enum _flexspi_ahb_write_wait_unit
|
||||
{
|
||||
kFLEXSPI_AhbWriteWaitUnit2AhbCycle = 0x0U, /*!< AWRWAIT unit is 2 ahb clock cycle. */
|
||||
kFLEXSPI_AhbWriteWaitUnit8AhbCycle = 0x1U, /*!< AWRWAIT unit is 8 ahb clock cycle. */
|
||||
kFLEXSPI_AhbWriteWaitUnit32AhbCycle = 0x2U, /*!< AWRWAIT unit is 32 ahb clock cycle. */
|
||||
kFLEXSPI_AhbWriteWaitUnit128AhbCycle = 0x3U, /*!< AWRWAIT unit is 128 ahb clock cycle. */
|
||||
kFLEXSPI_AhbWriteWaitUnit512AhbCycle = 0x4U, /*!< AWRWAIT unit is 512 ahb clock cycle. */
|
||||
kFLEXSPI_AhbWriteWaitUnit2048AhbCycle = 0x5U, /*!< AWRWAIT unit is 2048 ahb clock cycle. */
|
||||
kFLEXSPI_AhbWriteWaitUnit8192AhbCycle = 0x6U, /*!< AWRWAIT unit is 8192 ahb clock cycle. */
|
||||
kFLEXSPI_AhbWriteWaitUnit32768AhbCycle = 0x7U, /*!< AWRWAIT unit is 32768 ahb clock cycle. */
|
||||
} flexspi_ahb_write_wait_unit_t;
|
||||
|
||||
/*! @brief Error Code when IP command Error detected.*/
|
||||
typedef enum _flexspi_ip_error_code
|
||||
{
|
||||
kFLEXSPI_IpCmdErrorNoError = 0x0U, /*!< No error. */
|
||||
kFLEXSPI_IpCmdErrorJumpOnCsInIpCmd = 0x2U, /*!< IP command with JMP_ON_CS instruction used. */
|
||||
kFLEXSPI_IpCmdErrorUnknownOpCode = 0x3U, /*!< Unknown instruction opcode in the sequence. */
|
||||
kFLEXSPI_IpCmdErrorSdrDummyInDdrSequence = 0x4U, /*!< Instruction DUMMY_SDR/DUMMY_RWDS_SDR
|
||||
used in DDR sequence. */
|
||||
kFLEXSPI_IpCmdErrorDdrDummyInSdrSequence = 0x5U, /*!< Instruction DUMMY_DDR/DUMMY_RWDS_DDR
|
||||
used in SDR sequence. */
|
||||
kFLEXSPI_IpCmdErrorInvalidAddress = 0x6U, /*!< Flash access start address exceed the whole
|
||||
flash address range (A1/A2/B1/B2). */
|
||||
kFLEXSPI_IpCmdErrorSequenceExecutionTimeout = 0xEU, /*!< Sequence execution timeout. */
|
||||
kFLEXSPI_IpCmdErrorFlashBoundaryAcrosss = 0xFU, /*!< Flash boundary crossed. */
|
||||
} flexspi_ip_error_code_t;
|
||||
|
||||
/*! @brief Error Code when AHB command Error detected.*/
|
||||
typedef enum _flexspi_ahb_error_code
|
||||
{
|
||||
kFLEXSPI_AhbCmdErrorNoError = 0x0U, /*!< No error. */
|
||||
kFLEXSPI_AhbCmdErrorJumpOnCsInWriteCmd = 0x2U, /*!< AHB Write command with JMP_ON_CS instruction
|
||||
used in the sequence. */
|
||||
kFLEXSPI_AhbCmdErrorUnknownOpCode = 0x3U, /*!< Unknown instruction opcode in the sequence. */
|
||||
kFLEXSPI_AhbCmdErrorSdrDummyInDdrSequence = 0x4U, /*!< Instruction DUMMY_SDR/DUMMY_RWDS_SDR used
|
||||
in DDR sequence. */
|
||||
kFLEXSPI_AhbCmdErrorDdrDummyInSdrSequence = 0x5U, /*!< Instruction DUMMY_DDR/DUMMY_RWDS_DDR
|
||||
used in SDR sequence. */
|
||||
kFLEXSPI_AhbCmdSequenceExecutionTimeout = 0x6U, /*!< Sequence execution timeout. */
|
||||
} flexspi_ahb_error_code_t;
|
||||
|
||||
/*! @brief FLEXSPI operation port select.*/
|
||||
typedef enum _flexspi_port
|
||||
{
|
||||
kFLEXSPI_PortA1 = 0x0U, /*!< Access flash on A1 port. */
|
||||
kFLEXSPI_PortA2, /*!< Access flash on A2 port. */
|
||||
kFLEXSPI_PortB1, /*!< Access flash on B1 port. */
|
||||
kFLEXSPI_PortB2, /*!< Access flash on B2 port. */
|
||||
kFLEXSPI_PortCount
|
||||
} flexspi_port_t;
|
||||
|
||||
/*! @brief Trigger source of current command sequence granted by arbitrator.*/
|
||||
typedef enum _flexspi_arb_command_source
|
||||
{
|
||||
kFLEXSPI_AhbReadCommand = 0x0U,
|
||||
kFLEXSPI_AhbWriteCommand = 0x1U,
|
||||
kFLEXSPI_IpCommand = 0x2U,
|
||||
kFLEXSPI_SuspendedCommand = 0x3U,
|
||||
} flexspi_arb_command_source_t;
|
||||
|
||||
typedef enum _flexspi_command_type
|
||||
{
|
||||
kFLEXSPI_Command, /*!< FlexSPI operation: Only command, both TX and Rx buffer are ignored. */
|
||||
kFLEXSPI_Config, /*!< FlexSPI operation: Configure device mode, the TX fifo size is fixed in LUT. */
|
||||
kFLEXSPI_Read, /* /!< FlexSPI operation: Read, only Rx Buffer is effective. */
|
||||
kFLEXSPI_Write, /* /!< FlexSPI operation: Read, only Tx Buffer is effective. */
|
||||
} flexspi_command_type_t;
|
||||
|
||||
typedef struct _flexspi_ahbBuffer_config
|
||||
{
|
||||
uint8_t priority; /*!< This priority for AHB Master Read which this AHB RX Buffer is assigned. */
|
||||
uint8_t masterIndex; /*!< AHB Master ID the AHB RX Buffer is assigned. */
|
||||
uint16_t bufferSize; /*!< AHB buffer size in byte. */
|
||||
bool enablePrefetch; /*!< AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master, allows
|
||||
prefetch disable/enable seperately for each master. */
|
||||
} flexspi_ahbBuffer_config_t;
|
||||
|
||||
/*! @brief FLEXSPI configuration structure. */
|
||||
typedef struct _flexspi_config
|
||||
{
|
||||
flexspi_read_sample_clock_t rxSampleClock; /*!< Sample Clock source selection for Flash Reading. */
|
||||
bool enableSckFreeRunning; /*!< Enable/disable SCK output free-running. */
|
||||
bool enableCombination; /*!< Enable/disable combining PORT A and B Data Pins
|
||||
(SIOA[3:0] and SIOB[3:0]) to support Flash Octal mode. */
|
||||
bool enableDoze; /*!< Enable/disable doze mode support. */
|
||||
bool enableHalfSpeedAccess; /*!< Enable/disable divide by 2 of the clock for half
|
||||
speed commands. */
|
||||
bool enableSckBDiffOpt; /*!< Enable/disable SCKB pad use as SCKA differential clock
|
||||
output, when enable, Port B flash access is not available. */
|
||||
bool enableSameConfigForAll; /*!< Enable/disable same configuration for all connected devices
|
||||
when enabled, same configuration in FLASHA1CRx is applied to all. */
|
||||
uint16_t seqTimeoutCycle; /*!< Timeout wait cycle for command sequence execution,
|
||||
timeout after ahbGrantTimeoutCyle*1024 serial root clock cycles. */
|
||||
uint8_t ipGrantTimeoutCycle; /*!< Timeout wait cycle for IP command grant, timeout after
|
||||
ipGrantTimeoutCycle*1024 AHB clock cycles. */
|
||||
uint8_t txWatermark; /*!< FLEXSPI IP transmit watermark value. */
|
||||
uint8_t rxWatermark; /*!< FLEXSPI receive watermark value. */
|
||||
struct
|
||||
{
|
||||
bool enableAHBWriteIpTxFifo; /*!< Enable AHB bus write access to IP TX FIFO. */
|
||||
bool enableAHBWriteIpRxFifo; /*!< Enable AHB bus write access to IP RX FIFO. */
|
||||
uint8_t ahbGrantTimeoutCycle; /*!< Timeout wait cycle for AHB command grant,
|
||||
timeout after ahbGrantTimeoutCyle*1024 AHB clock cycles. */
|
||||
uint16_t ahbBusTimeoutCycle; /*!< Timeout wait cycle for AHB read/write access,
|
||||
timeout after ahbBusTimeoutCycle*1024 AHB clock cycles. */
|
||||
uint8_t resumeWaitCycle; /*!< Wait cycle for idle state before suspended command sequence
|
||||
resume, timeout after ahbBusTimeoutCycle AHB clock cycles. */
|
||||
flexspi_ahbBuffer_config_t buffer[FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT]; /*!< AHB buffer size. */
|
||||
bool enableClearAHBBufferOpt; /*!< Enable/disable automatically clean AHB RX Buffer and TX Buffer
|
||||
when FLEXSPI returns STOP mode ACK. */
|
||||
bool enableReadAddressOpt; /*!< Enable/disable remove AHB read burst start address alignment limitation.
|
||||
when eanble, there is no AHB read burst start address alignment limitation. */
|
||||
bool enableAHBPrefetch; /*!< Enable/disable AHB read prefetch feature, when enabled, FLEXSPI
|
||||
will fetch more data than current AHB burst. */
|
||||
bool enableAHBBufferable; /*!< Enable/disable AHB bufferable write access support, when enabled,
|
||||
FLEXSPI return before waiting for command excution finished. */
|
||||
bool enableAHBCachable; /*!< Enable AHB bus cachable read access support. */
|
||||
} ahbConfig;
|
||||
} flexspi_config_t;
|
||||
|
||||
/*! @brief External device configuration items. */
|
||||
typedef struct _flexspi_device_config
|
||||
{
|
||||
uint32_t flexspiRootClk; /*!< FLEXSPI serial root clock. */
|
||||
bool isSck2Enabled; /*!< FLEXSPI use SCK2. */
|
||||
uint32_t flashSize; /*!< Flash size in KByte. */
|
||||
flexspi_cs_interval_cycle_unit_t CSIntervalUnit; /*!< CS interval unit, 1 or 256 cycle. */
|
||||
uint16_t CSInterval; /*!< CS line assert interval, mutiply CS interval unit to
|
||||
get the CS line assert interval cycles. */
|
||||
uint8_t CSHoldTime; /*!< CS line hold time. */
|
||||
uint8_t CSSetupTime; /*!< CS line setup time. */
|
||||
uint8_t dataValidTime; /*!< Data valid time for external device. */
|
||||
uint8_t columnspace; /*!< Column space size. */
|
||||
bool enableWordAddress; /*!< If enable word address.*/
|
||||
uint8_t AWRSeqIndex; /*!< Sequence ID for AHB write command. */
|
||||
uint8_t AWRSeqNumber; /*!< Sequence number for AHB write command. */
|
||||
uint8_t ARDSeqIndex; /*!< Sequence ID for AHB read command. */
|
||||
uint8_t ARDSeqNumber; /*!< Sequence number for AHB read command. */
|
||||
flexspi_ahb_write_wait_unit_t AHBWriteWaitUnit; /*!< AHB write wait unit. */
|
||||
uint16_t AHBWriteWaitInterval; /*!< AHB write wait interval, mutiply AHB write interval
|
||||
unit to get the AHB write wait cycles. */
|
||||
bool enableWriteMask; /*!< Enable/Disable FLEXSPI drive DQS pin as write mask
|
||||
when writing to external device. */
|
||||
} flexspi_device_config_t;
|
||||
|
||||
/*! @brief Transfer structure for FLEXSPI. */
|
||||
typedef struct _flexspi_transfer
|
||||
{
|
||||
uint32_t deviceAddress; /*!< Operation device address. */
|
||||
flexspi_port_t port; /*!< Operation port. */
|
||||
flexspi_command_type_t cmdType; /*!< Execution command type. */
|
||||
uint8_t seqIndex; /*!< Sequence ID for command. */
|
||||
uint8_t SeqNumber; /*!< Sequence number for command. */
|
||||
uint32_t *data; /*!< Data buffer. */
|
||||
size_t dataSize; /*!< Data size in bytes. */
|
||||
} flexspi_transfer_t;
|
||||
|
||||
/* Forward declaration of the handle typedef. */
|
||||
typedef struct _flexspi_handle flexspi_handle_t;
|
||||
|
||||
/*! @brief FLEXSPI transfer callback function. */
|
||||
typedef void (*flexspi_transfer_callback_t)(FLEXSPI_Type *base,
|
||||
flexspi_handle_t *handle,
|
||||
status_t status,
|
||||
void *userData);
|
||||
|
||||
/*! @brief Transfer handle structure for FLEXSPI. */
|
||||
struct _flexspi_handle
|
||||
{
|
||||
uint32_t state; /*!< Internal state for FLEXSPI transfer */
|
||||
uint32_t *data; /*!< Data buffer. */
|
||||
size_t dataSize; /*!< Remaining Data size in bytes. */
|
||||
size_t transferTotalSize; /*!< Total Data size in bytes. */
|
||||
flexspi_transfer_callback_t completionCallback; /*!< Callback for users while transfer finish or error occurred */
|
||||
void *userData; /*!< FLEXSPI callback function parameter.*/
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /*_cplusplus. */
|
||||
|
||||
/*!
|
||||
* @name Initialization and deinitialization
|
||||
* @{
|
||||
*/
|
||||
/*!
|
||||
* @brief Initializes the FLEXSPI module and internal state.
|
||||
*
|
||||
* This function enables the clock for FLEXSPI and also configures the FLEXSPI with the
|
||||
* input configure parameters. Users should call this function before any FLEXSPI operations.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param config FLEXSPI configure structure.
|
||||
*/
|
||||
void FLEXSPI_Init(FLEXSPI_Type *base, const flexspi_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Gets default settings for FLEXSPI.
|
||||
*
|
||||
* @param config FLEXSPI configuration structure.
|
||||
*/
|
||||
void FLEXSPI_GetDefaultConfig(flexspi_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief Deinitializes the FLEXSPI module.
|
||||
*
|
||||
* Clears the FLEXSPI state and FLEXSPI module registers.
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
*/
|
||||
void FLEXSPI_Deinit(FLEXSPI_Type *base);
|
||||
|
||||
/*!
|
||||
* @brief Configures the connected device parameter.
|
||||
*
|
||||
* This function configures the connected device relevant parameters, such as the size, command, and so on.
|
||||
* The flash configuration value cannot have a default value. The user needs to configure it according to the
|
||||
* connected device.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param config Flash configuration parameters.
|
||||
* @param port FLEXSPI Operation port.
|
||||
*/
|
||||
void FLEXSPI_SetFlashConfig(FLEXSPI_Type *base, flexspi_device_config_t *config, flexspi_port_t port);
|
||||
|
||||
/*!
|
||||
* @brief Software reset for the FLEXSPI logic.
|
||||
*
|
||||
* This function sets the software reset flags for both AHB and buffer domain and
|
||||
* resets both AHB buffer and also IP FIFOs.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
*/
|
||||
static inline void FLEXSPI_SoftwareReset(FLEXSPI_Type *base)
|
||||
{
|
||||
//tst by wly
|
||||
return;
|
||||
base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK;
|
||||
while (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables the FLEXSPI module.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param enable True means enable FLEXSPI, false means disable.
|
||||
*/
|
||||
static inline void FLEXSPI_Enable(FLEXSPI_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->MCR0 |= FLEXSPI_MCR0_MDIS_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Interrupts
|
||||
* @{
|
||||
*/
|
||||
/*!
|
||||
* @brief Enables the FLEXSPI interrupts.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param mask FLEXSPI interrupt source.
|
||||
*/
|
||||
static inline void FLEXSPI_EnableInterrupts(FLEXSPI_Type *base, uint32_t mask)
|
||||
{
|
||||
base->INTEN |= mask;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Disable the FLEXSPI interrupts.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param mask FLEXSPI interrupt source.
|
||||
*/
|
||||
static inline void FLEXSPI_DisableInterrupts(FLEXSPI_Type *base, uint32_t mask)
|
||||
{
|
||||
base->INTEN &= ~mask;
|
||||
}
|
||||
|
||||
/* @} */
|
||||
|
||||
/*! @name DMA control */
|
||||
/*@{*/
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables FLEXSPI IP Tx FIFO DMA requests.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param enable Enable flag for transmit DMA request. Pass true for enable, false for disable.
|
||||
*/
|
||||
static inline void FLEXSPI_EnableTxDMA(FLEXSPI_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->IPTXFCR |= FLEXSPI_IPTXFCR_TXDMAEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->IPTXFCR &= ~FLEXSPI_IPTXFCR_TXDMAEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Enables or disables FLEXSPI IP Rx FIFO DMA requests.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param enable Enable flag for receive DMA request. Pass true for enable, false for disable.
|
||||
*/
|
||||
static inline void FLEXSPI_EnableRxDMA(FLEXSPI_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->IPRXFCR |= FLEXSPI_IPRXFCR_RXDMAEN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->IPRXFCR &= ~FLEXSPI_IPRXFCR_RXDMAEN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets FLEXSPI IP tx fifo address for DMA transfer.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @retval The tx fifo address.
|
||||
*/
|
||||
static inline uint32_t FLEXSPI_GetTxFifoAddress(FLEXSPI_Type *base)
|
||||
{
|
||||
return (uint32_t)&base->TFDR[0];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets FLEXSPI IP rx fifo address for DMA transfer.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @retval The rx fifo address.
|
||||
*/
|
||||
static inline uint32_t FLEXSPI_GetRxFifoAddress(FLEXSPI_Type *base)
|
||||
{
|
||||
return (uint32_t)&base->RFDR[0];
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*! @name FIFO control */
|
||||
/*@{*/
|
||||
|
||||
/*! @brief Clears the FLEXSPI IP FIFO logic.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param txFifo Pass true to reset TX FIFO.
|
||||
* @param rxFifo Pass true to reset RX FIFO.
|
||||
*/
|
||||
static inline void FLEXSPI_ResetFifos(FLEXSPI_Type *base, bool txFifo, bool rxFifo)
|
||||
{
|
||||
if (txFifo)
|
||||
{
|
||||
base->IPTXFCR |= FLEXSPI_IPTXFCR_CLRIPTXF_MASK;
|
||||
}
|
||||
if (rxFifo)
|
||||
{
|
||||
base->IPRXFCR |= FLEXSPI_IPRXFCR_CLRIPRXF_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Gets the valid data entries in the FLEXSPI FIFOs.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param[out] txCount Pointer through which the current number of bytes in the transmit FIFO is returned.
|
||||
* Pass NULL if this value is not required.
|
||||
* @param[out] rxCount Pointer through which the current number of bytes in the receive FIFO is returned.
|
||||
* Pass NULL if this value is not required.
|
||||
*/
|
||||
static inline void FLEXSPI_GetFifoCounts(FLEXSPI_Type *base, size_t *txCount, size_t *rxCount)
|
||||
{
|
||||
if (txCount)
|
||||
{
|
||||
*txCount = (((base->IPTXFSTS) & FLEXSPI_IPTXFSTS_FILL_MASK) >> FLEXSPI_IPTXFSTS_FILL_SHIFT) * 8U;
|
||||
}
|
||||
if (rxCount)
|
||||
{
|
||||
*rxCount = (((base->IPRXFSTS) & FLEXSPI_IPRXFSTS_FILL_MASK) >> FLEXSPI_IPRXFSTS_FILL_SHIFT) * 8U;
|
||||
}
|
||||
}
|
||||
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name Status
|
||||
* @{
|
||||
*/
|
||||
/*!
|
||||
* @brief Get the FLEXSPI interrupt status flags.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @retval interrupt status flag, use status flag to AND #flexspi_flags_t could get the related status.
|
||||
*/
|
||||
static inline uint32_t FLEXSPI_GetInterruptStatusFlags(FLEXSPI_Type *base)
|
||||
{
|
||||
return base->INTR;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Get the FLEXSPI interrupt status flags.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param interrupt status flag.
|
||||
*/
|
||||
static inline void FLEXSPI_ClearInterruptStatusFlags(FLEXSPI_Type *base, uint32_t mask)
|
||||
{
|
||||
base->INTR |= mask;
|
||||
}
|
||||
|
||||
#if !((defined(FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN)) && (FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN))
|
||||
/*! @brief Gets the sampling clock phase selection after Data Learning.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param portAPhase Pointer to a uint8_t type variable to receive the selected clock phase on PORTA.
|
||||
* @param portBPhase Pointer to a uint8_t type variable to receive the selected clock phase on PORTB.
|
||||
*/
|
||||
static inline void FLEXSPI_GetDataLearningPhase(FLEXSPI_Type *base, uint8_t *portAPhase, uint8_t *portBPhase)
|
||||
{
|
||||
if (portAPhase)
|
||||
{
|
||||
*portAPhase = (base->STS0 & FLEXSPI_STS0_DATALEARNPHASEA_MASK) >> FLEXSPI_STS0_DATALEARNPHASEA_SHIFT;
|
||||
}
|
||||
|
||||
if (portBPhase)
|
||||
{
|
||||
*portBPhase = (base->STS0 & FLEXSPI_STS0_DATALEARNPHASEB_MASK) >> FLEXSPI_STS0_DATALEARNPHASEB_SHIFT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @brief Gets the trigger source of current command sequence granted by arbitrator.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @retval trigger source of current command sequence.
|
||||
*/
|
||||
static inline flexspi_arb_command_source_t FLEXSPI_GetArbitratorCommandSource(FLEXSPI_Type *base)
|
||||
{
|
||||
return (flexspi_arb_command_source_t)((base->STS0 & FLEXSPI_STS0_ARBCMDSRC_MASK) >> FLEXSPI_STS0_ARBCMDSRC_SHIFT);
|
||||
}
|
||||
|
||||
/*! @brief Gets the error code when IP command error detected.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param index Pointer to a uint8_t type variable to receive the sequence index when error detected.
|
||||
* @retval error code when IP command error detected.
|
||||
*/
|
||||
static inline flexspi_ip_error_code_t FLEXSPI_GetIPCommandErrorCode(FLEXSPI_Type *base, uint8_t *index)
|
||||
{
|
||||
*index = (base->STS1 & FLEXSPI_STS1_IPCMDERRID_MASK) >> FLEXSPI_STS1_IPCMDERRID_SHIFT;
|
||||
return (flexspi_ip_error_code_t)((base->STS1 & FLEXSPI_STS1_IPCMDERRCODE_MASK) >> FLEXSPI_STS1_IPCMDERRCODE_SHIFT);
|
||||
}
|
||||
|
||||
/*! @brief Gets the error code when AHB command error detected.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param index Pointer to a uint8_t type variable to receive the sequence index when error detected.
|
||||
* @retval error code when AHB command error detected.
|
||||
*/
|
||||
static inline flexspi_ahb_error_code_t FLEXSPI_GetAHBCommandErrorCode(FLEXSPI_Type *base, uint8_t *index)
|
||||
{
|
||||
*index = (base->STS1 & FLEXSPI_STS1_AHBCMDERRID_MASK) >> FLEXSPI_STS1_AHBCMDERRID_SHIFT;
|
||||
return (flexspi_ahb_error_code_t)((base->STS1 & FLEXSPI_STS1_AHBCMDERRCODE_MASK) >>
|
||||
FLEXSPI_STS1_AHBCMDERRCODE_SHIFT);
|
||||
}
|
||||
|
||||
/*! @brief Returns whether the bus is idle.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @retval true Bus is idle.
|
||||
* @retval false Bus is busy.
|
||||
*/
|
||||
static inline bool FLEXSPI_GetBusIdleStatus(FLEXSPI_Type *base)
|
||||
{
|
||||
return (base->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (base->STS0 & FLEXSPI_STS0_SEQIDLE_MASK);
|
||||
}
|
||||
/*@}*/
|
||||
|
||||
/*!
|
||||
* @name Bus Operations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @brief Update read sample clock source
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param clockSource clockSource of type #flexspi_read_sample_clock_t
|
||||
*/
|
||||
void FLEXSPI_UpdateRxSampleClock(FLEXSPI_Type *base, flexspi_read_sample_clock_t clockSource);
|
||||
|
||||
/*! @brief Enables/disables the FLEXSPI IP command parallel mode.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param enable True means enable parallel mode, false means disable parallel mode.
|
||||
*/
|
||||
static inline void FLEXSPI_EnableIPParallelMode(FLEXSPI_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->IPCR1 |= FLEXSPI_IPCR1_IPAREN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->IPCR1 &= ~FLEXSPI_IPCR1_IPAREN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*! @brief Enables/disables the FLEXSPI AHB command parallel mode.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param enable True means enable parallel mode, false means disable parallel mode.
|
||||
*/
|
||||
static inline void FLEXSPI_EnableAHBParallelMode(FLEXSPI_Type *base, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
base->AHBCR |= FLEXSPI_AHBCR_APAREN_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
base->AHBCR &= ~FLEXSPI_AHBCR_APAREN_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
/*! @brief Updates the LUT table.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param index From which index start to update. It could be any index of the LUT table, which
|
||||
* also allows user to update command content inside a command. Each command consists of up to
|
||||
* 8 instructions and occupy 4*32-bit memory.
|
||||
* @param cmd Command sequence array.
|
||||
* @param count Number of sequences.
|
||||
*/
|
||||
void FLEXSPI_UpdateLUT(FLEXSPI_Type *base, uint32_t index, const uint32_t *cmd, uint32_t count);
|
||||
|
||||
/*!
|
||||
* @brief Writes data into FIFO.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address
|
||||
* @param data The data bytes to send
|
||||
* @param fifoIndex Destination fifo index.
|
||||
*/
|
||||
static inline void FLEXSPI_WriteData(FLEXSPI_Type *base, uint32_t data, uint8_t fifoIndex)
|
||||
{
|
||||
base->TFDR[fifoIndex] = data;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Receives data from data FIFO.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address
|
||||
* @param fifoIndex Source fifo index.
|
||||
* @return The data in the FIFO.
|
||||
*/
|
||||
static inline uint32_t FLEXSPI_ReadData(FLEXSPI_Type *base, uint8_t fifoIndex)
|
||||
{
|
||||
return base->RFDR[fifoIndex];
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Sends a buffer of data bytes using blocking method.
|
||||
* @note This function blocks via polling until all bytes have been sent.
|
||||
* @param base FLEXSPI peripheral base address
|
||||
* @param buffer The data bytes to send
|
||||
* @param size The number of data bytes to send
|
||||
* @retval kStatus_Success write success without error
|
||||
* @retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout
|
||||
* @retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequencen error detected
|
||||
* @retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected
|
||||
*/
|
||||
status_t FLEXSPI_WriteBlocking(FLEXSPI_Type *base, uint32_t *buffer, size_t size);
|
||||
|
||||
/*!
|
||||
* @brief Receives a buffer of data bytes using a blocking method.
|
||||
* @note This function blocks via polling until all bytes have been sent.
|
||||
* @param base FLEXSPI peripheral base address
|
||||
* @param buffer The data bytes to send
|
||||
* @param size The number of data bytes to receive
|
||||
* @retval kStatus_Success read success without error
|
||||
* @retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout
|
||||
* @retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequencen error detected
|
||||
* @retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected
|
||||
*/
|
||||
status_t FLEXSPI_ReadBlocking(FLEXSPI_Type *base, uint32_t *buffer, size_t size);
|
||||
|
||||
/*!
|
||||
* @brief Execute command to transfer a buffer data bytes using a blocking method.
|
||||
* @param base FLEXSPI peripheral base address
|
||||
* @param xfer pointer to the transfer structure.
|
||||
* @retval kStatus_Success command transfer success without error
|
||||
* @retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout
|
||||
* @retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequencen error detected
|
||||
* @retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected
|
||||
*/
|
||||
status_t FLEXSPI_TransferBlocking(FLEXSPI_Type *base, flexspi_transfer_t *xfer);
|
||||
/*! @} */
|
||||
|
||||
/*!
|
||||
* @name Transactional
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes the FLEXSPI handle which is used in transactional functions.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param handle pointer to flexspi_handle_t structure to store the transfer state.
|
||||
* @param callback pointer to user callback function.
|
||||
* @param userData user parameter passed to the callback function.
|
||||
*/
|
||||
void FLEXSPI_TransferCreateHandle(FLEXSPI_Type *base,
|
||||
flexspi_handle_t *handle,
|
||||
flexspi_transfer_callback_t callback,
|
||||
void *userData);
|
||||
|
||||
/*!
|
||||
* @brief Performs a interrupt non-blocking transfer on the FLEXSPI bus.
|
||||
*
|
||||
* @note Calling the API returns immediately after transfer initiates. The user needs
|
||||
* to call FLEXSPI_GetTransferCount to poll the transfer status to check whether
|
||||
* the transfer is finished. If the return status is not kStatus_FLEXSPI_Busy, the transfer
|
||||
* is finished. For FLEXSPI_Read, the dataSize should be multiple of rx watermark levle, or
|
||||
* FLEXSPI could not read data properly.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param handle pointer to flexspi_handle_t structure which stores the transfer state.
|
||||
* @param xfer pointer to flexspi_transfer_t structure.
|
||||
* @retval kStatus_Success Successfully start the data transmission.
|
||||
* @retval kStatus_FLEXSPI_Busy Previous transmission still not finished.
|
||||
*/
|
||||
status_t FLEXSPI_TransferNonBlocking(FLEXSPI_Type *base, flexspi_handle_t *handle, flexspi_transfer_t *xfer);
|
||||
|
||||
/*!
|
||||
* @brief Gets the master transfer status during a interrupt non-blocking transfer.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param handle pointer to flexspi_handle_t structure which stores the transfer state.
|
||||
* @param count Number of bytes transferred so far by the non-blocking transaction.
|
||||
* @retval kStatus_InvalidArgument count is Invalid.
|
||||
* @retval kStatus_Success Successfully return the count.
|
||||
*/
|
||||
status_t FLEXSPI_TransferGetCount(FLEXSPI_Type *base, flexspi_handle_t *handle, size_t *count);
|
||||
|
||||
/*!
|
||||
* @brief Aborts an interrupt non-blocking transfer early.
|
||||
*
|
||||
* @note This API can be called at any time when an interrupt non-blocking transfer initiates
|
||||
* to abort the transfer early.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param handle pointer to flexspi_handle_t structure which stores the transfer state
|
||||
*/
|
||||
void FLEXSPI_TransferAbort(FLEXSPI_Type *base, flexspi_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Master interrupt handler.
|
||||
*
|
||||
* @param base FLEXSPI peripheral base address.
|
||||
* @param handle pointer to flexspi_handle_t structure.
|
||||
*/
|
||||
void FLEXSPI_TransferHandleIRQ(FLEXSPI_Type *base, flexspi_handle_t *handle);
|
||||
/*! @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /*_cplusplus. */
|
||||
/*@}*/
|
||||
|
||||
#endif /* __FSL_FLEXSPI_H_ */
|
|
@ -56,8 +56,8 @@
|
|||
#define TRANSFER_SIZE (512U) /*! Transfer dataSize .*/
|
||||
#define TRANSFER_BAUDRATE (500000U) /*! Transfer baudrate - 500k */
|
||||
|
||||
|
||||
#define spi_print KPrintf
|
||||
#define spi_trace() KPrintf("lw: [%s][%d] passed!\n", __func__, __LINE__)
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
|
@ -233,45 +233,10 @@ void EXAMPLE_LPSPI_MASTER_IRQHandler(int vector, void *param)
|
|||
|
||||
DECLARE_HW_IRQ(EXAMPLE_LPSPI_MASTER_IRQN, EXAMPLE_LPSPI_MASTER_IRQHandler, NONE);
|
||||
|
||||
/*!
|
||||
* @brief Main function
|
||||
*/
|
||||
int test_spi(void)
|
||||
void lpspi_config_init(void)
|
||||
{
|
||||
/*Set clock source for LPSPI*/
|
||||
CLOCK_SetMux(kCLOCK_LpspiMux, EXAMPLE_LPSPI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_SetDiv(kCLOCK_LpspiDiv, EXAMPLE_LPSPI_CLOCK_SOURCE_DIVIDER);
|
||||
|
||||
spi_print("LPSPI functional interrupt example start.\r\n");
|
||||
spi_print("This example use one lpspi instance as master and another as slave on one board.\r\n");
|
||||
spi_print("Master uses interrupt way and slave uses interrupt way.\r\n");
|
||||
spi_print(
|
||||
"Note that some LPSPI instances interrupt is in INTMUX ,"
|
||||
"you should set the intmux when you porting this example accordingly \r\n");
|
||||
|
||||
spi_print("Please make sure you make the correct line connection. Basically, the connection is: \r\n");
|
||||
spi_print("LPSPI_master -- LPSPI_slave \r\n");
|
||||
spi_print(" CLK -- CLK \r\n");
|
||||
spi_print(" PCS -- PCS \r\n");
|
||||
spi_print(" SOUT -- SIN \r\n");
|
||||
spi_print(" SIN -- SOUT \r\n");
|
||||
|
||||
uint32_t errorCount;
|
||||
uint32_t i;
|
||||
lpspi_master_config_t masterConfig;
|
||||
lpspi_slave_config_t slaveConfig;
|
||||
uint32_t whichPcs;
|
||||
uint8_t txWatermark;
|
||||
|
||||
/*Set up the transfer data*/
|
||||
for (i = 0; i < TRANSFER_SIZE; i++)
|
||||
{
|
||||
masterTxData[i] = i % 256;
|
||||
masterRxData[i] = 0;
|
||||
|
||||
slaveTxData[i] = ~masterTxData[i];
|
||||
slaveRxData[i] = 0;
|
||||
}
|
||||
|
||||
/*Master config*/
|
||||
masterConfig.baudRate = TRANSFER_BAUDRATE;
|
||||
|
@ -306,6 +271,48 @@ int test_spi(void)
|
|||
|
||||
LPSPI_SlaveInit(EXAMPLE_LPSPI_SLAVE_BASEADDR, &slaveConfig);
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Main function
|
||||
*/
|
||||
int test_spi(void)
|
||||
{
|
||||
/*Set clock source for LPSPI*/
|
||||
CLOCK_SetMux(kCLOCK_LpspiMux, EXAMPLE_LPSPI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_SetDiv(kCLOCK_LpspiDiv, EXAMPLE_LPSPI_CLOCK_SOURCE_DIVIDER);
|
||||
|
||||
spi_print("LPSPI functional interrupt example start.\r\n");
|
||||
spi_print("This example use one lpspi instance as master and another as slave on one board.\r\n");
|
||||
spi_print("Master uses interrupt way and slave uses interrupt way.\r\n");
|
||||
spi_print(
|
||||
"Note that some LPSPI instances interrupt is in INTMUX ,"
|
||||
"you should set the intmux when you porting this example accordingly \r\n");
|
||||
|
||||
spi_print("Please make sure you make the correct line connection. Basically, the connection is: \r\n");
|
||||
spi_print("LPSPI_master -- LPSPI_slave \r\n");
|
||||
spi_print(" CLK -- CLK \r\n");
|
||||
spi_print(" PCS -- PCS \r\n");
|
||||
spi_print(" SOUT -- SIN \r\n");
|
||||
spi_print(" SIN -- SOUT \r\n");
|
||||
|
||||
uint32_t errorCount;
|
||||
uint32_t i;
|
||||
uint32_t whichPcs;
|
||||
uint8_t txWatermark;
|
||||
|
||||
/*Set up the transfer data*/
|
||||
for (i = 0; i < TRANSFER_SIZE; i++)
|
||||
{
|
||||
masterTxData[i] = i % 256;
|
||||
masterRxData[i] = 0;
|
||||
|
||||
slaveTxData[i] = ~masterTxData[i];
|
||||
slaveRxData[i] = 0;
|
||||
}
|
||||
|
||||
lpspi_config_init();
|
||||
|
||||
/******************Set up slave first ******************/
|
||||
isSlaveTransferCompleted = false;
|
||||
slaveTxCount = 0;
|
||||
|
@ -352,6 +359,9 @@ int test_spi(void)
|
|||
while (LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_SLAVE_BASEADDR) != 0)
|
||||
{
|
||||
}
|
||||
|
||||
spi_trace();
|
||||
|
||||
/*Fill up the TX data in FIFO */
|
||||
while (LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_SLAVE_BASEADDR) < g_slaveFifoSize)
|
||||
{
|
||||
|
@ -364,6 +374,8 @@ int test_spi(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
spi_trace();
|
||||
|
||||
LPSPI_EnableInterrupts(EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_RxInterruptEnable);
|
||||
|
||||
/******************Set up master transfer******************/
|
||||
|
@ -412,6 +424,9 @@ int test_spi(void)
|
|||
while (LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_MASTER_BASEADDR) != 0)
|
||||
{
|
||||
}
|
||||
|
||||
spi_trace();
|
||||
|
||||
/*Fill up the TX data in FIFO */
|
||||
while ((LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_MASTER_BASEADDR) < g_masterFifoSize) &&
|
||||
(masterTxCount - masterRxCount < g_masterFifoSize))
|
||||
|
@ -420,11 +435,15 @@ int test_spi(void)
|
|||
LPSPI_WriteData(EXAMPLE_LPSPI_MASTER_BASEADDR, masterTxData[masterTxCount]);
|
||||
++masterTxCount;
|
||||
|
||||
spi_trace();
|
||||
|
||||
if (masterTxCount == TRANSFER_SIZE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
spi_trace();
|
||||
|
||||
LPSPI_EnableInterrupts(EXAMPLE_LPSPI_MASTER_BASEADDR, kLPSPI_RxInterruptEnable);
|
||||
|
||||
/******************Wait for master and slave transfer completed.******************/
|
||||
|
@ -432,6 +451,8 @@ int test_spi(void)
|
|||
{
|
||||
}
|
||||
|
||||
spi_trace();
|
||||
|
||||
errorCount = 0;
|
||||
for (i = 0; i < TRANSFER_SIZE; i++)
|
||||
{
|
||||
|
@ -462,6 +483,8 @@ int test_spi(void)
|
|||
while (1)
|
||||
{
|
||||
}
|
||||
spi_trace();
|
||||
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
||||
|
|
|
@ -50,11 +50,11 @@ int UserPrintInfo(unsigned long i);
|
|||
|
||||
struct utask
|
||||
{
|
||||
char name[NAME_NUM_MAX];
|
||||
void *func_entry;
|
||||
void *func_param;
|
||||
int32_t stack_size;
|
||||
uint8_t prio;
|
||||
char name[NAME_NUM_MAX];
|
||||
void *func_entry;
|
||||
void *func_param;
|
||||
int32_t stack_size;
|
||||
uint8_t prio;
|
||||
};
|
||||
typedef struct utask UtaskType;
|
||||
|
||||
|
@ -109,7 +109,7 @@ typedef int32 EventIdType;
|
|||
EventIdType UserEventCreate(uint8_t flag);
|
||||
void UserEventDelete(EventIdType event);
|
||||
x_err_t UserEventTrigger(EventIdType event, uint32_t set);
|
||||
x_err_t UserEventProcess(EventIdType event, uint32_t set, uint8_t option,
|
||||
x_err_t UserEventProcess(EventIdType event, uint32_t set, uint8_t option,
|
||||
int32_t wait_time, uint32_t *Recved);
|
||||
x_err_t UserEventReinit(EventIdType event);
|
||||
#endif
|
||||
|
@ -162,7 +162,7 @@ int statfs(const char *path, struct statfs *buf);
|
|||
|
||||
int Userprintf(const char *fmt, ...);
|
||||
|
||||
#define printf Userprintf
|
||||
#define printf Userprintf
|
||||
|
||||
#else
|
||||
|
||||
|
@ -172,11 +172,11 @@ int Userprintf(const char *fmt, ...);
|
|||
|
||||
struct utask
|
||||
{
|
||||
char name[NAME_NUM_MAX];
|
||||
void *func_entry;
|
||||
void *func_param;
|
||||
int32_t stack_size;
|
||||
uint8_t prio;
|
||||
char name[NAME_NUM_MAX];
|
||||
void *func_entry;
|
||||
void *func_param;
|
||||
int32_t stack_size;
|
||||
uint8_t prio;
|
||||
};
|
||||
typedef struct utask UtaskType;
|
||||
int32_t UserTaskCreate(UtaskType utask);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
/**
|
||||
* @file flash_spi.h
|
||||
* @brief define spi-flash dev function using bus driver framework
|
||||
* @version 1.0
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
/**
|
||||
* @file dev_spi.c
|
||||
* @brief register spi dev function using bus driver framework
|
||||
* @version 1.0
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-24
|
||||
*/
|
||||
|
@ -36,7 +36,7 @@ static uint32 SpiDeviceOpen(void *dev)
|
|||
SpiDevConfigureCs(dev, 1, 0);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 SpiDeviceClose(void *dev)
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ static uint32 SpiDeviceClose(void *dev)
|
|||
SpiDevConfigureCs(dev, 0, 1);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 SpiDeviceWrite(void *dev, struct BusBlockWriteParam *write_param)
|
||||
{
|
||||
|
@ -120,7 +120,7 @@ static const struct HalDevDone dev_done =
|
|||
HardwareDevType SpiDeviceFind(const char *dev_name, enum DevType dev_type)
|
||||
{
|
||||
NULL_PARAM_CHECK(dev_name);
|
||||
|
||||
|
||||
struct HardwareDev *device = NONE;
|
||||
|
||||
DoubleLinklistType *node = NONE;
|
||||
|
@ -142,7 +142,7 @@ int SpiDeviceRegister(struct SpiHardwareDevice *spi_device, void *spi_param, con
|
|||
NULL_PARAM_CHECK(spi_device);
|
||||
NULL_PARAM_CHECK(device_name);
|
||||
|
||||
x_err_t ret = EOK;
|
||||
x_err_t ret = EOK;
|
||||
static x_bool dev_link_flag = RET_FALSE;
|
||||
|
||||
if (!dev_link_flag) {
|
||||
|
@ -164,7 +164,7 @@ int SpiDeviceRegister(struct SpiHardwareDevice *spi_device, void *spi_param, con
|
|||
|
||||
DoubleLinkListInsertNodeAfter(&spidev_linklist, &(spi_device->haldev.dev_link));
|
||||
} else {
|
||||
KPrintf("SpiDeviceRegister device has been register state%u\n", spi_device->haldev.dev_state);
|
||||
KPrintf("SpiDeviceRegister device has been register state%u\n", spi_device->haldev.dev_state);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -174,7 +174,7 @@ 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;
|
||||
|
@ -185,7 +185,7 @@ int SpiDeviceAttachToBus(const char *dev_name, const char *bus_name)
|
|||
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) {
|
||||
|
|
Loading…
Reference in New Issue