optimize I2C and SPI codes and add rtc module

This commit is contained in:
wlyu 2022-03-04 15:54:43 +08:00
parent 06b2ed5235
commit 598f92babb
32 changed files with 398 additions and 3053 deletions

View File

@ -103,7 +103,7 @@ void UaBrowserObjectsTestTask(void* param)
UA_ClientConfig* config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER);
UA_StatusCode retval = UA_Client_connect(client, opc_server_url);
if(retval != UA_STATUSCODE_GOOD)
{
@ -157,7 +157,7 @@ void UaGetInfoTestTask(void* param)
UA_ClientConfig* config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER);
UA_StatusCode retval = UA_Client_connect(client, opc_server_url);
if(retval != UA_STATUSCODE_GOOD)
{
@ -209,7 +209,7 @@ void UaAddNodesTask(void* param)
UA_ClientConfig* config = UA_Client_getConfig(client);
UA_ClientConfig_setDefault(config);
UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER);
UA_StatusCode retval = UA_Client_connect(client, opc_server_url);
if(retval != UA_STATUSCODE_GOOD)
{

View File

@ -26,24 +26,15 @@
#include "plc_dev.h"
#include "plc_demo.h"
#define PLC_NS_FORMAT "n%d,%s"
struct PlcChannel plc_demo_ch;
struct PlcDriver plc_demo_drv;
struct PlcDevice plc_demo_dev;
PlcCtrlParamType plc_ctrl_param;
char plc_demo_ip[] = {192, 168, 250, 2};
#define TEST_STR_NID "ServiceInterfaces"
#define PLC_NS_FORMAT "n%d,%s"
UA_NodeId test_nodeid =
{
4,
UA_NODEIDTYPE_NUMERIC,
5
};
UA_NodeId test_nodeid = {4, UA_NODEIDTYPE_NUMERIC, 5};
/******************************************************************************/
@ -54,7 +45,7 @@ void PlcDemoChannelDrvInit(void)
return;
init_flag = 1;
lwip_config_tcp(lwip_ipaddr, lwip_netmask, plc_demo_ip);
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
PlcChannelInit(&plc_demo_ch, PLC_CH_NAME);
if(PlcDriverInit(&plc_demo_drv, PLC_DRV_NAME) == EOK)
{
@ -84,7 +75,7 @@ static void PlcCtrlDemoInit(void)
}
UaParamType* ua_ptr = plc_demo_dev.priv_data;
memset(ua_ptr, 0, sizeof(UaParamType));
strcpy(ua_ptr->ua_remote_ip, OPC_SERVER);
strcpy(ua_ptr->ua_remote_ip, opc_server_url);
ua_ptr->act = UA_ACT_ATTR;
memcpy(&ua_ptr->ua_id, &test_nodeid, sizeof(test_nodeid));
@ -166,8 +157,8 @@ void PlcWriteUATask(void* arg)
struct PlcOps* ops = NULL;
char buf[PLC_BUF_SIZE];
memset(buf, 0, sizeof(buf));
PlcCtrlDemoInit();
PlcCtrlDemoInit();
ops = plc_demo_dev.ops;
ret = ops->open(&plc_demo_dev);

View File

@ -41,13 +41,14 @@ typedef struct UaParam
UA_Client *client;
}UaParamType;
#define OPC_SERVER "opc.tcp://192.168.250.2:4840"
#define ua_print //KPrintf
#define ua_trace() //KPrintf("ua: [%s] line %d checked!\n", __func__, __LINE__)
#define ua_pr_info KPrintf
#define ua_debug //KPrintf
extern const char *opc_server_url;
extern char test_ua_ip[];
int ua_server_connect(void);
void ua_browser_nodes(UA_Client *client);
void ua_browser_id(UA_Client *client, UA_NodeId id);

View File

@ -24,6 +24,8 @@
#define UA_RESPONSE_TIMEOUT 10000
const char *opc_server_url = {"opc.tcp://192.168.250.2:4840"};
#ifdef UA_ENABLE_SUBSCRIPTIONS
static void handler_TheAnswerChanged(UA_Client* client, UA_UInt32 subId, void* subContext,
UA_UInt32 monId, void* monContext, UA_DataValue* value)
@ -52,7 +54,7 @@ int ua_get_points(UA_Client* client)
/* Listing endpoints */
UA_EndpointDescription* endpointArray = NULL;
size_t endpointArraySize = 0;
UA_StatusCode ret = UA_Client_getEndpoints(client, OPC_SERVER,
UA_StatusCode ret = UA_Client_getEndpoints(client, opc_server_url,
&endpointArraySize, &endpointArray);
if(ret != UA_STATUSCODE_GOOD)

View File

@ -82,7 +82,7 @@ int ua_test_interact_server(UA_Client *client)
int16 ua_test(void)
{
UA_Client *client = UA_Client_new();
UA_StatusCode retval = UA_Client_connect(client, OPC_SERVER);
UA_StatusCode retval = UA_Client_connect(client, opc_server_url);
if(retval != UA_STATUSCODE_GOOD) {
UA_Client_delete(client);
return (int)retval;

View File

@ -55,3 +55,11 @@ menuconfig BSP_USING_SEMC
if BSP_USING_SEMC
source "$BSP_DIR/third_party_driver/semc/Kconfig"
endif
menuconfig BSP_USING_RTC
bool "Using RTC device"
default n
select RESOURCES_RTC
if BSP_USING_RTC
source "$BSP_DIR/third_party_driver/rtc/Kconfig"
endif

View File

@ -24,4 +24,8 @@ ifeq ($(CONFIG_BSP_USING_SEMC),y)
SRC_DIR += semc
endif
ifeq ($(CONFIG_BSP_USING_RTC),y)
SRC_DIR += rtc
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -9,3 +9,4 @@ if BSP_USING_I2C
string "i2c bus 1 device 0 name"
default "i2c1_dev0"
endif

View File

@ -1,3 +1,3 @@
SRC_FILES := connect_i2c.c i2c_eeprom.c i2c_eeprom_test.c fsl_lpi2c.c i2c_rtc_rx8010.c i2c_rtc_rx8010_test.c
SRC_FILES := connect_i2c.c connect_i2c_eeprom.c hardware_i2c.c fsl_lpi2c.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -10,30 +10,29 @@
/**
* @file connect_i2c.c
* @brief support ok1052-c-board i2c function and register to bus framework
* @brief support ok1052-c i2c function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-1-25
* @date 2022-03-01
*/
/*************************************************
File name: connect_i2c.c
Description: support ok1052-c-board i2c configure and i2c bus register function
Description: support ok1052-c i2c configure and i2c bus register function
Others: take RT-Thread v4.0.2/components/drivers/i2c/i2c-bit-ops.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2022-1-25
1. Date: 2022-03-01
Author: AIIT XUOS Lab
Modification:
1. support ok1052-c-board i2c bit configure, write and read
2. support ok1052-c-board i2c bus device and driver register
1. support ok1052-c i2c bit configure, write and read
2. support ok1052-c i2c bus device and driver register
*************************************************/
#include <board.h>
#include "connect_i2c.h"
#include "bus_serial.h"
#include "i2c_rtc_rx8010.h"
#include "i2c_eeprom.h"
#include "connect_i2c.h"
#include "fsl_lpi2c.h"
#ifndef BSP_USING_I2C1
#define BSP_USING_I2C1
@ -41,27 +40,22 @@ Modification:
static uint32 I2cWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
{
int32 ret;
if(i2c_dev->i2c_dev_addr == I2C_RTC_ADDR){
ret = rx8010_set_time(msg->buf);
} else if(i2c_dev->i2c_dev_addr == I2C_EEPROM_ADDR) {
ret = eeprom_write(msg->buf);
}
return ret;
status_t ret;
Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data;
ret = I2cHardwareWrite(param->base, param->slave_addr, param->sub_addr, msg->buf, msg->len);
if(kStatus_Success == ret)
return 1;
return 0;
}
static uint32 I2cReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
{
int32 ret;
if(i2c_dev->i2c_dev_addr == I2C_RTC_ADDR){
ret = rx8010_get_time();
} else if(i2c_dev->i2c_dev_addr == I2C_EEPROM_ADDR) {
ret = eeprom_read(msg->buf);
}
return ret;
status_t ret;
Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data;
ret = I2cHardwareRead(param->base, i2c_dev->i2c_dev_addr, param->sub_addr, msg->buf, msg->len);
if(kStatus_Success == ret)
return 1;
return 0;
}
static uint32 I2cInit(struct I2cDriver *i2c_drv, struct BusConfigureInfo *configure_info)
@ -75,7 +69,7 @@ static uint32 I2cInit(struct I2cDriver *i2c_drv, struct BusConfigureInfo *config
return EOK;
}
KPrintf("I2cInit need set i2c dev addr\n");
i2c_print("I2cInit need set i2c dev addr\n");
return ERROR;
}
@ -117,7 +111,7 @@ static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver)
i2c_bus->private_data = (void *)NULL;
ret = I2cBusInit(i2c_bus, I2C_BUS_NAME_1);
if (EOK != ret) {
KPrintf("board_i2c_init I2cBusInit error %d\n", ret);
i2c_print("BoardI2cBusInit I2cBusInit error %d\n", ret);
return ERROR;
}
@ -125,14 +119,14 @@ static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver)
i2c_driver->private_data = (void *)NULL;
ret = I2cDriverInit(i2c_driver, I2C_DRV_NAME_1);
if (EOK != ret) {
KPrintf("board_i2c_init I2cDriverInit error %d\n", ret);
i2c_print("BoardI2cBusInit I2cDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the i2c driver to the i2c bus*/
ret = I2cDriverAttachToBus(I2C_DRV_NAME_1, I2C_BUS_NAME_1);
if (EOK != ret) {
KPrintf("board_i2c_init I2cDriverAttachToBus error %d\n", ret);
i2c_print("BoardI2cBusInit I2cDriverAttachToBus error %d\n", ret);
return ERROR;
}
@ -150,13 +144,13 @@ static int BoardI2cDevBend(void)
ret = I2cDeviceRegister(&i2c_device0, NONE, I2C_1_DEVICE_NAME_0);
if (EOK != ret) {
KPrintf("board_i2c_init I2cDeviceInit device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
i2c_print("BoardI2cDevBend I2cDeviceInit device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
return ERROR;
}
ret = I2cDeviceAttachToBus(I2C_1_DEVICE_NAME_0, I2C_BUS_NAME_1);
if (EOK != ret) {
KPrintf("board_i2c_init I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
i2c_print("BoardI2cDevBend I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
return ERROR;
}
@ -185,13 +179,13 @@ int Stm32HwI2cInit(void)
ret = BoardI2cBusInit(&i2c_bus, &i2c_driver);
if (EOK != ret) {
KPrintf("board_i2c_Init error ret %u\n", ret);
i2c_print("board_i2c_Init error ret %u\n", ret);
return ERROR;
}
ret = BoardI2cDevBend();
if (EOK != ret) {
KPrintf("board_i2c_Init error ret %u\n", ret);
i2c_print("board_i2c_Init error ret %u\n", ret);
return ERROR;
}
#endif

View File

@ -32,71 +32,35 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file connect_i2c_eeprom.h
* @brief ok1052-c eeprom relative codes
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-03-01
*/
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_iomuxc.h"
#include "fsl_gpio.h"
#include "connect_i2c.h"
#include "fsl_lpi2c.h"
#include "i2c_eeprom.h"
#include "pin_mux.h"
#include "clock_config.h"
#include <device.h>
#include <bus.h>
/*******************************************************************************
* Definitions
******************************************************************************/
#define i2c_print KPrintf
#define EE_I2C_BUS_NAME I2C_BUS_NAME_1 /* I2C bus name */
#define EE_I2C_DEV_NAME I2C_1_DEVICE_NAME_0 /* I2C device name */
#define EE_I2C_DRV_NAME I2C_DRV_NAME_1 /* I2C driver name */
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief delay a while.
*/
void I2C_EEPROM_TEST(void);
/*******************************************************************************
* Variables
******************************************************************************/
#define I2C_EEPROM_BASE LPI2C1
#define I2C_EEPROM_ADDR (0xA0 >> 1)
/*******************************************************************************
* Code
******************************************************************************/
int eeprom_read(uint8_t *dat)
{
uint32_t ret;
ret = I2C_EEPROM_Read(I2C_EEPROM_BASE, 0, dat, 8);
return ret;
}
int eeprom_write(uint8_t *dat)
{
uint32_t ret;
ret = I2C_EEPROM_Write(I2C_EEPROM_BASE, 0, dat, 8);
return ret;
}
/*!
* @brief I2C_EEPROM_TEST: Write and Read
*/
void I2C_EEPROM_TEST(void)
void I2cEEpromTestWrite(void)
{
uint8_t dat[8] = {0};
if(!I2C_EEPROM_Read(I2C_EEPROM_BASE, 0, dat, 8))
if(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
{
i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n",
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
@ -104,32 +68,32 @@ void I2C_EEPROM_TEST(void)
for(uint8_t i = 0; i < 8; i++)
{
dat[i] = 1;
dat[i] ++;
}
if(!I2C_EEPROM_Write(I2C_EEPROM_BASE, 0, dat, 8))
if(I2cHardwareWrite(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
{
i2c_print("Write to EEPROM %d %d %d %d %d %d %d %d\r\n",
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
}
memset(dat, 0, 8);
if(!I2C_EEPROM_Read(I2C_EEPROM_BASE, 0, dat, 8))
if(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
{
i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n",
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
}
}
int test_eerpom(void)
int I2cEEpromTest(void)
{
Stm32HwI2cInit();
BOARD_InitI2C1Pins();
I2C_EEPROM_Init();
I2C_EEPROM_TEST();
I2cHardwareInit();
I2cEEpromTestWrite();
return 0;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(0),
eeprom, test_eerpom, i2c eeprom);
eeprom, I2cEEpromTest, test i2c eeprom);

View File

@ -33,34 +33,30 @@
*/
/**
* @file i2c_RTC_RX8010.c
* @brief I2C RTC drivers
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.1.18
*/
* @file hardware_i2c.c
* @brief ok1052-c i2c relative codes
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-03-01
*/
#include "fsl_common.h"
#include "fsl_debug_console.h"
#include "fsl_lpi2c.h"
#include "i2c_rtc_rx8010.h"
#define I2C_BASE LPI2C1
/////////////////////////////EEPROM INIT/////////////////////////////////////////
/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
void I2C_Init()
#define I2C_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
#define I2C_BAUDRATE 100000U
void I2cHardwareInit(void)
{
lpi2c_master_config_t masterConfig = {0};
/*
* masterConfig.debugEnable = false;
* masterConfig.ignoreAck = false;
* masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
* masterConfig.baudRate_Hz = 100000U;
* masterConfig.busIdleTimeout_ns = 0;
* masterConfig.pinLowTimeout_ns = 0;
* masterConfig.sdaGlitchFilterWidth_ns = 0;
* masterConfig.sclGlitchFilterWidth_ns = 0;
*/
LPI2C_MasterGetDefaultConfig(&masterConfig);
/* Change the default baudrate configuration */
@ -70,58 +66,29 @@ void I2C_Init()
LPI2C_MasterInit(I2C_BASE, &masterConfig, I2C_CLOCK_FREQ);
}
//struct _lpi2c_master_transfer
//{
// uint32_t
// flags; /*!< Bit mask of options for the transfer. See enumeration #_lpi2c_master_transfer_flags for available
// options. Set to 0 or #kLPI2C_TransferDefaultFlag for normal transfers. */
// uint16_t slaveAddress; /*!< The 7-bit slave address. */
// lpi2c_direction_t direction; /*!< Either #kLPI2C_Read or #kLPI2C_Write. */
// uint32_t subaddress; /*!< Sub address. Transferred MSB first. */
// size_t subaddressSize; /*!< Length of sub address to send in bytes. Maximum size is 4 bytes. */
// void *data; /*!< Pointer to data to transfer. */
// size_t dataSize; /*!< Number of bytes to transfer. */
//};
status_t I2C_Write(LPI2C_Type *base,uint32_t subAdd,uint8_t *dataBuff,uint16_t dataLen)
status_t I2cHardwareWrite(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuff, uint16_t dataLen)
{
// lpi2c_master_transfer_t *xfer = &(handle->xfer);
lpi2c_master_transfer_t xfer;
status_t status;
xfer.slaveAddress = 0x32; ////RX8010 SLEVEADDRESS 7BIT
xfer.slaveAddress = slave_addr;
xfer.direction = kLPI2C_Write;
xfer.subaddress = subAdd;
xfer.subaddressSize = 0x01;
xfer.data = dataBuff;
xfer.dataSize = dataLen;
xfer.flags = kLPI2C_TransferDefaultFlag;
status = LPI2C_MasterTransferBlocking(base, &xfer);
return status;
return LPI2C_MasterTransferBlocking(base, &xfer);
}
uint32_t I2C_Read(LPI2C_Type *base,uint32_t subAdd,uint8_t* dataBuffer, uint16_t dataLen)
status_t I2cHardwareRead(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuffer, uint16_t dataLen)
{
lpi2c_master_transfer_t masterXfer = {0};
status_t reVal = kStatus_Fail;
masterXfer.slaveAddress = 0x32;
masterXfer.slaveAddress = slave_addr;
masterXfer.direction = kLPI2C_Read;
masterXfer.subaddress = subAdd;
masterXfer.subaddressSize = 0x01;
masterXfer.data = dataBuffer;
masterXfer.dataSize = dataLen;
masterXfer.flags = kLPI2C_TransferDefaultFlag;
reVal = LPI2C_MasterTransferBlocking(base, &masterXfer);
if (reVal != kStatus_Success)
{
return 1;
}
return 0;
return LPI2C_MasterTransferBlocking(base, &masterXfer);
}

View File

@ -1,110 +0,0 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_common.h"
#include "fsl_lpi2c.h"
#include "i2c_eeprom.h"
/////////////////////////////EEPROM INIT/////////////////////////////////////////
void I2C_EEPROM_Init()
{
lpi2c_master_config_t masterConfig = {0};
/*
* masterConfig.debugEnable = false;
* masterConfig.ignoreAck = false;
* masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
* masterConfig.baudRate_Hz = 100000U;
* masterConfig.busIdleTimeout_ns = 0;
* masterConfig.pinLowTimeout_ns = 0;
* masterConfig.sdaGlitchFilterWidth_ns = 0;
* masterConfig.sclGlitchFilterWidth_ns = 0;
*/
LPI2C_MasterGetDefaultConfig(&masterConfig);
/* Change the default baudrate configuration */
masterConfig.baudRate_Hz = I2C_EEPROM_BAUDRATE;
/* Initialize the LPI2C master peripheral */
LPI2C_MasterInit(I2C_EEPROM_BASE, &masterConfig, I2C_EEPROM_CLOCK_FREQ);
}
//struct _lpi2c_master_transfer
//{
// uint32_t
// flags; /*!< Bit mask of options for the transfer. See enumeration #_lpi2c_master_transfer_flags for available
// options. Set to 0 or #kLPI2C_TransferDefaultFlag for normal transfers. */
// uint16_t slaveAddress; /*!< The 7-bit slave address. */
// lpi2c_direction_t direction; /*!< Either #kLPI2C_Read or #kLPI2C_Write. */
// uint32_t subaddress; /*!< Sub address. Transferred MSB first. */
// size_t subaddressSize; /*!< Length of sub address to send in bytes. Maximum size is 4 bytes. */
// void *data; /*!< Pointer to data to transfer. */
// size_t dataSize; /*!< Number of bytes to transfer. */
//};
status_t I2C_EEPROM_Write(LPI2C_Type* base, uint32_t subAdd, uint8_t* dataBuff, uint16_t dataLen)
{
// lpi2c_master_transfer_t *xfer = &(handle->xfer);
lpi2c_master_transfer_t xfer;
status_t status;
xfer.slaveAddress =(0xA0 >> 1);
xfer.direction = kLPI2C_Write;
xfer.subaddress = subAdd;
xfer.subaddressSize = 0x01;
xfer.data = dataBuff;
xfer.dataSize = dataLen;
xfer.flags = kLPI2C_TransferDefaultFlag;
status = LPI2C_MasterTransferBlocking(base, &xfer);
return status;
}
uint32_t I2C_EEPROM_Read(LPI2C_Type* base, uint32_t subAdd, uint8_t* dataBuffer, uint16_t dataLen)
{
lpi2c_master_transfer_t masterXfer = {0};
status_t reVal = kStatus_Fail;
masterXfer.slaveAddress =(0XA0>>1);
masterXfer.direction = kLPI2C_Read;
masterXfer.subaddress = subAdd;
masterXfer.subaddressSize = 0x01;
masterXfer.data = dataBuffer;
masterXfer.dataSize = dataLen;
masterXfer.flags = kLPI2C_TransferDefaultFlag;
reVal = LPI2C_MasterTransferBlocking(base, &masterXfer);
if(reVal != kStatus_Success)
{
return 1;
}
return 0;
}

View File

@ -1,27 +0,0 @@
#ifndef __I2C_EEPROM_H_
#define __I2C_EEPROM_H_
#include "fsl_common.h"
/* Macros for the touch touch controller. */
#define I2C_EEPROM_BASE LPI2C1
/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
#define I2C_EEPROM_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
#define I2C_EEPROM_BAUDRATE 100000U
void I2C_EEPROM_Init ( void );
status_t I2C_EEPROM_Write ( LPI2C_Type* base,uint32_t subAdd,uint8_t* dataBuff,uint16_t dataLen );
uint32_t I2C_EEPROM_Read ( LPI2C_Type* base,uint32_t subAdd,uint8_t* dataBuff, uint16_t dataLen );
int eeprom_read(uint8_t *dat);
int eeprom_write(uint8_t *dat);
#endif

View File

@ -1,27 +0,0 @@
#ifndef __I2C_RTC_RX8010_H_
#define __I2C_RTC_RX8010_H_
#include "fsl_common.h"
/* Macros for the touch touch controller. */
#define I2C_BASE LPI2C1
/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
#define I2C_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
#define I2C_BAUDRATE 100000U
#define I2C_RTC_ADDR 0x32
#define I2C_EEPROM_ADDR 0x0
void I2C_Init(void);
status_t I2C_Write(LPI2C_Type *base,uint32_t subAdd,uint8_t *dataBuff,uint16_t dataLen);
uint32_t I2C_Read(LPI2C_Type *base,uint32_t subAdd,uint8_t* dataBuff, uint16_t dataLen);
int rx8010_set_time(uint8_t* asc_date);
int rx8010_get_time(void);
#endif

View File

@ -1,26 +1,5 @@
/**
******************************************************************************
* @file connect_ethernet.h
* @author MCD Application Team
* @version V1.0.0
* @date 31-October-2011
* @brief STM32F4x7 Ethernet hardware configuration.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/*
* Copyright (c) 2020 AIIT XUOS Lab
/*
* Copyright (c) 2021 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:
@ -39,35 +18,22 @@
* @date 2021-12-7
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __ETH_BSP_H
#define __ETH_BSP_H
#ifndef __CONNECT_ETHERNET_H_
#define __CONNECT_ETHERNET_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
#ifndef sourceClock
#define sourceClock CLOCK_GetFreq(kCLOCK_CoreSysClk)
#endif
/* Exported functions ------------------------------------------------------- */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4x7_ETH_BSP_H */
#endif
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* Copyright (c) 2022 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:
@ -9,17 +9,17 @@
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_gpio.h
* @brief define stm32f407-st-discovery-board gpio function and struct
* @version 1.0
* @brief define ok1052-c gpio function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
* @date 2022-03-01
*/
#ifndef CONNECT_GPIO_H
#define CONNECT_GPIO_H
#ifndef __CONNECT_GPIO_H_
#define __CONNECT_GPIO_H_
#include <device.h>

View File

@ -28,6 +28,15 @@ extern "C" {
#endif
typedef struct Stm32I2c
{
LPI2C_Type* base;
uint16_t slave_addr;
uint32_t sub_addr;
}Stm32I2cType;
#define i2c_print KPrintf
int Stm32HwI2cInit(void);
#ifdef __cplusplus

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_rtc.h
* @brief define ok1052-c rtc function and structure
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-03-01
*/
#ifndef __CONNECT_RTC_H_
#define __CONNECT_RTC_H_
#include "fsl_common.h"
#include "fsl_lpi2c.h"
#define I2C_RTC_BASE LPI2C1
#define I2C_RTC_ADDR 0x32
void RtcI2cInit(void);
status_t RtcI2cWrite(LPI2C_Type *base, uint32_t sub_addr, uint8_t *buf, uint16_t size);
uint32_t RtcI2cRead(LPI2C_Type *base, uint32_t sub_addr, uint8_t *buf, uint16_t size);
int RtcSetTime(uint8_t* asc_date);
int RtcGetTime(void);
#endif

View File

@ -5,6 +5,26 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file fsl_lpi2c.h
* @brief support ok1052-c i2c driver
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-03-01
*/
/*************************************************
File name: fsl_lpi2c.h
Description: support ok1052-c i2c driver
History:
1. Date: 2022-03-01
Author: AIIT XUOS Lab
Modification:
1. add i2c hardware interface
*************************************************/
#ifndef _FSL_LPI2C_H_
#define _FSL_LPI2C_H_
@ -1259,6 +1279,11 @@ void LPI2C_SlaveTransferHandleIRQ(LPI2C_Type *base, lpi2c_slave_handle_t *handle
/*! @} */
void I2cHardwareInit(void);
status_t I2cHardwareWrite(LPI2C_Type* base, uint16_t slave_addr, uint32_t sub_addr, uint8_t* buf, uint16_t size);
status_t I2cHardwareRead(LPI2C_Type* base, uint16_t slave_addr, uint32_t sub_addr, uint8_t* buf, uint16_t size);
#if defined(__cplusplus)
}
#endif

View File

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

View File

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

View File

@ -32,24 +32,34 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file connect_rtc.c
* @brief ok1052-c rtc function and structure
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-03-01
*/
/*************************************************
File name: connect_rtc.c
Description: support ok1052-c rtc configure and spi bus register function
History:
1. Date: 2022-03-01
Author: AIIT XUOS Lab
Modification:
1. change command for XUOS
*************************************************/
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_lpi2c.h"
#include "i2c_rtc_rx8010.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "connect_rtc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define EXAMPLE_DELAY_COUNT 8000000
#undef GETCHAR
#define GETCHAR getchar
#undef PUTCHAR
#define PUTCHAR putchar
#define rtc_print KPrintf
///////////RX8010///////////
@ -137,32 +147,25 @@ uint8_t bcd2bin(uint8_t data)
}
// 8010 initialization
int rx8010_init(void)
int RtcInit(void)
{
uint8_t flag = 0;
uint8_t data = 0;
uint8_t ctrl[2];
int need_clear = 0, err = 0;
err = I2C_Read(I2C_BASE, RX8010_FLAG, &flag, 1);
err = RtcI2cRead(I2C_RTC_BASE, RX8010_FLAG, &flag, 1);
flag &= ~(RX8010_FLAG_VLF);
err = I2C_Write(I2C_BASE, RX8010_FLAG, &flag, 1);
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_FLAG, &flag, 1);
/* Initialize reserved registers as specified in datasheet */
data = 0xD8;
err = I2C_Write(I2C_BASE, RX8010_RESV17, &data, 1);
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_RESV17, &data, 1);
data = 0x00;
err = I2C_Write(I2C_BASE, RX8010_RESV30, &data, 1);
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_RESV30, &data, 1);
data = 0x08;
err = I2C_Write(I2C_BASE, RX8010_RESV31, &data, 1);
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_RESV31, &data, 1);
data = 0x00;
err = I2C_Write(I2C_BASE, RX8010_IRQ, &data, 1);
err = I2C_Read(I2C_BASE, RX8010_FLAG, ctrl, 2);
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_IRQ, &data, 1);
err = RtcI2cRead(I2C_RTC_BASE, RX8010_FLAG, ctrl, 2);
if(ctrl[0] & RX8010_FLAG_VLF)
{
@ -188,7 +191,7 @@ int rx8010_init(void)
if(need_clear)
{
ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
err = I2C_Write(I2C_BASE, RX8010_FLAG, ctrl,1);
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_FLAG, ctrl,1);
if(!err)
{
@ -200,18 +203,18 @@ int rx8010_init(void)
}
// check format and get BCD format date like 2018-06-21 16:29:30
int get_bcd_date(uint8_t* date, uint8_t* bcd_date)
int RtcGetBcdDate(uint8_t* date, uint8_t* bcd_date)
{
int i;
int temp_date[6];
if(sscanf(date, "20%2d-%2d-%2d %2d:%2d:%2d",
&temp_date[5],
&temp_date[4],
&temp_date[3],
&temp_date[2],
&temp_date[1],
&temp_date[0]) == EOF)
&temp_date[5],
&temp_date[4],
&temp_date[3],
&temp_date[2],
&temp_date[1],
&temp_date[0]) == EOF)
{
rtc_print("i2c %s failed\n", __func__);
return -1;
@ -219,37 +222,37 @@ int get_bcd_date(uint8_t* date, uint8_t* bcd_date)
for(i = 0; i < 6; i++)
{
bcd_date[i] = TO_BCD(temp_date[i]);
bcd_date[i] = TO_BCD(temp_date[i]);
}
return 0;
}
// setup time
int rx8010_set_time(uint8_t* asc_date)
int RtcSetTime(uint8_t* asc_date)
{
uint8_t bcd_date[6];
int ret, err;
if(get_bcd_date(asc_date, bcd_date))
if(RtcGetBcdDate(asc_date, bcd_date))
{
rtc_print("\r\n Date format error! \r\n");
return -1;
}
err = I2C_Write(I2C_BASE, RX8010_SEC, bcd_date, 3);
err |= I2C_Write(I2C_BASE, RX8010_MDAY, &bcd_date[3], 3);
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_SEC, bcd_date, 3);
err |= RtcI2cWrite(I2C_RTC_BASE, RX8010_MDAY, &bcd_date[3], 3);
return err;
}
// get rx8010 time
int rx8010_get_time(void)
int RtcGetTime(void)
{
uint8_t date[7];
uint8_t dateRsul[7];
uint8_t flagreg;
int err;
err = I2C_Read(I2C_BASE, RX8010_FLAG, &flagreg, 1);
err = RtcI2cRead(I2C_RTC_BASE, RX8010_FLAG, &flagreg, 1);
if(flagreg & RX8010_FLAG_VLF)
{
@ -257,7 +260,7 @@ int rx8010_get_time(void)
return 1;
}
err = I2C_Read(I2C_BASE, RX8010_SEC, date, 7);
err = RtcI2cRead(I2C_RTC_BASE, RX8010_SEC, date, 7);
dateRsul[0] = bcd2bin(date[RX8010_SEC - RX8010_SEC] & 0x7f);
dateRsul[1] = bcd2bin(date[RX8010_MIN - RX8010_SEC] & 0x7f);
dateRsul[2] = bcd2bin(date[RX8010_HOUR - RX8010_SEC] & 0x3f);
@ -266,30 +269,30 @@ int rx8010_get_time(void)
dateRsul[6] = bcd2bin(date[RX8010_YEAR - RX8010_SEC]);
dateRsul[3] = date[RX8010_WDAY - RX8010_SEC] & 0x7f;
rtc_print("RX8010 Time: 20%d%d-%d%d-%d%d %d%d:%d%d:%d%d\r\n",
dateRsul[6]/10, dateRsul[6]%10, dateRsul[5]/10, dateRsul[5]%10, dateRsul[4]/10, dateRsul[4]%10,
dateRsul[2]/10, dateRsul[2]%10, dateRsul[1]/10, dateRsul[1]%10, dateRsul[0]/10, dateRsul[0]%10);
dateRsul[6]/10, dateRsul[6]%10, dateRsul[5]/10, dateRsul[5]%10, dateRsul[4]/10, dateRsul[4]%10,
dateRsul[2]/10, dateRsul[2]%10, dateRsul[1]/10, dateRsul[1]%10, dateRsul[0]/10, dateRsul[0]%10);
return 0;
}
void test_rtc_rx8010(int argc, char *argv[])
void RtcTestRx8010(int argc, char* argv[])
{
BOARD_InitI2C1Pins();
I2C_Init();
rx8010_init();
RtcI2cInit();
RtcInit();
if(argc == 2)
{
if(rx8010_set_time(argv[1]) == 0)
if(RtcSetTime(argv[1]) == 0)
{
rx8010_get_time();
RtcGetTime();
}
}
else
{
rx8010_get_time();
RtcGetTime();
}
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(3),
rtc, test_rtc_rx8010, i2c rtc "date time");
rtc, RtcTestRx8010, i2c rtc "date time");

View File

@ -0,0 +1,71 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file hardware_rtc.c
* @brief I2C RTC drivers
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.1.18
*/
/*************************************************
File name: hardware_rtc.c
Description: support ok1052-c rtc driver I2C function
History:
1. Date: 2022-01-18
Author: AIIT XUOS Lab
Modification:
1. support ok1052-c rtc
*************************************************/
#include "connect_rtc.h"
#include "connect_i2c.h"
void RtcI2cInit()
{
I2cHardwareInit();
}
status_t RtcI2cWrite(LPI2C_Type *base, uint32_t sub_addr, uint8_t *buf, uint16_t size)
{
return I2cHardwareWrite(base, I2C_RTC_ADDR, sub_addr, buf, size);
}
uint32_t RtcI2cRead(LPI2C_Type *base,uint32_t sub_addr,uint8_t* buf, uint16_t size)
{
return I2cHardwareRead(base, I2C_RTC_ADDR, sub_addr, buf, size);
}

View File

@ -1,3 +1,3 @@
SRC_FILES := fsl_lpspi.c connect_spi.c connect_flash_spi.c flexspi_nor_flash_ops.c flexspi_nor_polling_transfer.c fsl_flexspi.c
SRC_FILES := fsl_lpspi.c connect_spi.c connect_flash_spi.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,63 +0,0 @@
/*
* 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_ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 RT-Thread Development Team
* Copyright (c) 2022 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -13,7 +13,7 @@
* @brief support ok1052-c-board spi flash function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
* @date 2022-03-01
*/
/*************************************************
@ -22,34 +22,18 @@ Description: support ok1052-c-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
1. Date: 2022-03-01
Author: AIIT XUOS Lab
Modification:
1. support ok1052-c-board spi flash register to spi bus
2. support ok1052-c-board spi flash init
1. for ok1052-c compilation
*************************************************/
//#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;
}

View File

@ -1,22 +1,39 @@
/*
* Copyright (c) 2022 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.
*/
* Copyright (c) 2020 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-5 SummerGift first version
* 2018-12-11 greedyhao Porting for stm32f7xx
* 2019-01-03 zylx modify DMA initialization and spixfer function
* 2020-01-15 whj4674672 Porting for stm32h7xx
* 2020-06-18 thread-liu Porting for stm32mp1xx
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
*/
/**
* @file connect_spi.c
* @brief Demo for SPI function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.1.18
*/
* @file connect_spi.c
* @brief support ok1052-c spi function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-03-01
*/
/*************************************************
File name: connect_spi.c
Description: support ok1052-c spi configure and spi bus register function
Others: take RT-Thread v4.0.2/bsp/stm32/libraries/HAL_Drivers/drv_spi.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2022-03-01
Author: AIIT XUOS Lab
Modification:
1. support ok1052-c spi configure, write and read
2. support ok1052-c spi bus device and driver register
3. add ok1052-c spi test letter command
*************************************************/
#include "board.h"
#include "connect_spi.h"
@ -487,25 +504,6 @@ int SpiReadData(struct Stm32HwSpi *spi_param, uint8_t *buf, int len)
LPSPI_Deinit(spi_base);
}
void SpiReadTest(void *arg)
{
uint32_t i;
uint8_t test_buf[32] = {0};
struct Stm32HwSpi spi_param;
spi_param.base = LPSPI1;
spi_param.irq = LPSPI1_IRQn;
SpiReadData(&spi_param, test_buf, 32);
for(i = 0; i < sizeof(test_buf) ;i ++)
{
spi_print("%d - %x\n", i, test_buf[i]);
}
}
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
spiread, SpiReadTest, SPI Read);
void SpiWriteData(struct Stm32HwSpi *spi_param, const uint8_t *buf, uint16_t len)
{
uint32_t errorCount;
@ -580,34 +578,6 @@ void SpiWriteData(struct Stm32HwSpi *spi_param, const uint8_t *buf, uint16_t len
LPSPI_Deinit(spi_base);
}
void SpiWriteTest(void *arg)
{
uint32_t i;
uint8_t test_buf[100] = {0};
struct Stm32HwSpi spi_param;
spi_param.base = LPSPI1;
spi_param.irq = LPSPI1_IRQn;
for(i = 0; i < sizeof(test_buf) ;i ++)
{
test_buf[i] = i;
}
SpiWriteData(&spi_param, test_buf, 100);
}
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
spiwrite, SpiWriteTest, SPI Write );
/**
* This function SPI write data
*
* @param spi_dev SPI device structure handle
*
* @param spi_datacfg SPI device information structure handle
*
* @return datacfg length
*/
static uint32 Stm32SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
{
int state;
@ -654,15 +624,6 @@ static uint32 Stm32SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDat
return EOK;
}
/**
* This function SPI read data
*
* @param spi_dev SPI device structure handle
*
* @param spi_datacfg SPI device information structure handle
*
* @return datacfg length
*/
static uint32 Stm32SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
{
int state;
@ -710,7 +671,6 @@ static uint32 Stm32SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiData
return spi_read_length;
}
/*manage the spi device operations*/
static const struct SpiDevDone spi_dev_done =
{
.dev_open = NONE,
@ -725,13 +685,6 @@ static x_err_t Stm32SpiInit(struct Stm32Spi *spi_drv, struct SpiMasterParam *cfg
NULL_PARAM_CHECK(cfg);
}
/**
* This function SPI driver initialization function
*
* @param spi_drv SPI driver structure handle
*
* @return if successful return EOK
*/
static uint32 SpiDrvInit(struct SpiDriver *spi_drv)
{
NULL_PARAM_CHECK(spi_drv);
@ -743,15 +696,6 @@ static uint32 SpiDrvInit(struct SpiDriver *spi_drv)
return Stm32SpiInit(StmSpi, dev_param->spi_master_param);
}
/**
* This function SPI driver configuration param
*
* @param spi_drv SPI driver structure handle
*
* @param spi_param SPI master param structure handle
*
* @return if successful return EOK
*/
static uint32 SpiDrvConfigure(struct SpiDriver *spi_drv, struct SpiMasterParam *spi_param)
{
NULL_PARAM_CHECK(spi_drv);
@ -791,16 +735,6 @@ static uint32 Stm32SpiDrvConfigure(void *drv, struct BusConfigureInfo *configure
return ret;
}
/**
* This function Init the spi bus spi driver and attach to the bus
*
* @param spi_bus Spi bus info pointer
*
* @param spi_driver Spi driver info pointer
*
* @return EOK
*/
static int BoardSpiBusInit(struct Stm32Spi *stm32spi_bus, struct SpiDriver *spi_driver, char* drv_name)
{
x_err_t ret = EOK;
@ -829,11 +763,6 @@ static int BoardSpiBusInit(struct Stm32Spi *stm32spi_bus, struct SpiDriver *spi_
return ret;
}
/**
* This function SPI bus initialization
*
* @return EOK
*/
static int Stm32HwSpiBusInit(void)
{
x_err_t ret = EOK;
@ -953,19 +882,6 @@ static int Stm32HwSpiBusInit(void)
return EOK;
}
/**
* This function Mount the spi device to the bus
*
* @param bus_name Bus Name
*
* @param device_name spi device name
*
* @param cs_gpiox GPIO pin configuration handle
*
* @param cs_gpio_pin GPIO number
*
* @return EOK
*/
x_err_t HwSpiDeviceAttach(const char *bus_name, const char *device_name)
{
NULL_PARAM_CHECK(bus_name);
@ -998,13 +914,46 @@ x_err_t HwSpiDeviceAttach(const char *bus_name, const char *device_name)
return result;
}
/**
* This function hardware spi initialization
*
* @return EOK
*/
int Imrt1052HwSpiInit(void)
{
return Stm32HwSpiBusInit();
}
void SpiReadTest(void *arg)
{
uint32_t i;
uint8_t test_buf[32] = {0};
struct Stm32HwSpi spi_param;
spi_param.base = LPSPI1;
spi_param.irq = LPSPI1_IRQn;
SpiReadData(&spi_param, test_buf, 32);
for(i = 0; i < sizeof(test_buf) ;i ++)
{
spi_print("%d - %x\n", i, test_buf[i]);
}
}
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
spiread, SpiReadTest, SPI Read);
void SpiWriteTest(void *arg)
{
uint32_t i;
uint8_t test_buf[100] = {0};
struct Stm32HwSpi spi_param;
spi_param.base = LPSPI1;
spi_param.irq = LPSPI1_IRQn;
for(i = 0; i < sizeof(test_buf) ;i ++)
{
test_buf[i] = i;
}
SpiWriteData(&spi_param, test_buf, 100);
}
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
spiwrite, SpiWriteTest, SPI Write );

View File

@ -1,288 +0,0 @@
/*
* 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);
}

View File

@ -1,237 +0,0 @@
/*
* 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 );

View File

@ -1,831 +0,0 @@
/*
* 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_ */