support spi module and plc module

This commit is contained in:
wlyu
2022-01-24 18:30:44 +08:00
parent 28cf201808
commit 1dfcf0edbe
27 changed files with 5328 additions and 90 deletions
@@ -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),
+12 -12
View File
@@ -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
*/
+8 -8
View File
@@ -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) {