Fire_RT1021_EVK_FSPIAsSPI/src/app_fspi.c

123 lines
4.1 KiB
C

#include "app_fspi.h"
#include "fsl_clock.h"
#include "fsl_flexspi.h"
#define FSPI_BASE FLEXSPI
#define FSPI_PORT kFLEXSPI_PortB1
#define FSPI_SEQ_WR_IDX 0
#define FSPI_SEQ_W1_IDX 1
#define FSPI_SEQ_RD_IDX 2
#define FSPI_SEQ_R_REG_IDX 3
#define FSPI_SEQ_INVALID 4
/* clang-format off */
static uint32_t s_fspi_lut[4 * (FSPI_SEQ_INVALID + 1)] = {
/* Multi-byte write sequence, 1st is RADDR to avoid internal confusion */
[4 * FSPI_SEQ_WR_IDX + 0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 8U, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0U),
/* Single-byte write sequence, use RADDR to avoid internal confusion */
[4 * FSPI_SEQ_W1_IDX + 0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 8U, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0U),
/* Multi-byte read sequence */
[4 * FSPI_SEQ_RD_IDX + 0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0U, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0U),
/* Register read sequence, the first byte is register address, the length can be modified by changing op0. */
[4 * FSPI_SEQ_R_REG_IDX + 0] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 8U, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0U),
};
/* clang-format on */
status_t fspi_init(void) {
status_t ret = kStatus_Success;
flexspi_config_t fspi_cfg;
FLEXSPI_GetDefaultConfig(&fspi_cfg);
FLEXSPI_Init(FSPI_BASE, &fspi_cfg);
flexspi_device_config_t fspi_dev_cfg = {
.flexspiRootClk = CLOCK_GetClockRootFreq(kCLOCK_FlexspiClkRoot),
.flashSize = 1 * 1024 * 1024, /* Don't care */
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
.CSInterval = 2,
.CSHoldTime = 3,
.CSSetupTime = 3,
.dataValidTime = 2,
.columnspace = 0,
.enableWordAddress = false,
.AWRSeqIndex = FSPI_SEQ_INVALID,
.AWRSeqNumber = 1,
.ARDSeqIndex = FSPI_SEQ_INVALID,
.ARDSeqNumber = 1,
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
.AHBWriteWaitInterval = 0,
.enableWriteMask = false,
};
FLEXSPI_SetFlashConfig(FSPI_BASE, &fspi_dev_cfg, FSPI_PORT);
FLEXSPI_UpdateLUT(FSPI_BASE, 0, s_fspi_lut, 4 * (FSPI_SEQ_INVALID + 1));
FLEXSPI_SoftwareReset(FSPI_BASE);
return ret;
}
status_t fspi_write(uint8_t *data, uint32_t len) {
flexspi_transfer_t ip_xfer = {
.port = FSPI_PORT,
.deviceAddress = data[0],
.cmdType = kFLEXSPI_Write,
.seqIndex = FSPI_SEQ_W1_IDX,
.SeqNumber = 1U,
.data = (uint32_t *)data,
.dataSize = 1,
};
if (len > 1) {
ip_xfer.seqIndex = FSPI_SEQ_WR_IDX;
ip_xfer.dataSize = len - 1;
ip_xfer.data = (uint32_t *)(&data[1]);
}
return FLEXSPI_TransferBlocking(FSPI_BASE, &ip_xfer);
}
status_t fspi_read(uint8_t *data, uint32_t len) {
flexspi_transfer_t ip_xfer = {
.port = FSPI_PORT,
.deviceAddress = 0UL,
.cmdType = kFLEXSPI_Read,
.seqIndex = FSPI_SEQ_RD_IDX,
.SeqNumber = 1U,
.data = (uint32_t *)data,
.dataSize = len,
};
return FLEXSPI_TransferBlocking(FSPI_BASE, &ip_xfer);
}
status_t fspi_read_registers(uint8_t addr, uint8_t *data, uint32_t len) {
flexspi_transfer_t ip_xfer = {
.port = FSPI_PORT,
.deviceAddress = addr,
.cmdType = kFLEXSPI_Read,
.seqIndex = FSPI_SEQ_R_REG_IDX,
.SeqNumber = 1U,
.data = (uint32_t *)data,
.dataSize = len,
};
return FLEXSPI_TransferBlocking(FSPI_BASE, &ip_xfer);
}
status_t fspi_write_registers(uint8_t addr, uint8_t *data, uint32_t len) {
flexspi_transfer_t ip_xfer = {
.port = FSPI_PORT,
.deviceAddress = addr,
.cmdType = kFLEXSPI_Write,
.seqIndex = FSPI_SEQ_WR_IDX,
.SeqNumber = 1U,
.data = (uint32_t *)data,
.dataSize = len,
};
return FLEXSPI_TransferBlocking(FSPI_BASE, &ip_xfer);
}