Tool/software:
HI,
Query 1: I am using SPI-based NAND Flash of 1 GB capacity (Part No.: MT29F8G01ADAFD12) that is interfaced to MibSPI Port-2 & Chipselect (CS0) of Controller,
According to the NAND Flash Datasheet, we need to transfer 4352 bytes per page. How to achieve this from using MibSPI port 2.
Here I have attached the code for reference, but the code is not working to write/program the 4352 bytes.
MIBSPI_Init(MIBSPI2, SPI_25MHZ, 0,SPI_MODE0_CPHA0_CPOL0);
/*
* mibspi_drv.c
*
* Created on: Jun 2, 2023
* Author: Dell
*/
#include <string.h>
#include "common.h"
#include "mibspi.h"
#include "HL_reg_mibspi.h"
UINT32 mibspi_base[5] = {
0xFFF7F400U, /* SPI-1 */
0xFFF7F600U, /* SPI-2 */
0xFFF7F800U, /* SPI-3 */
0xFFF7FA00U, /* SPI-4 */
0xFFF7FC00U, /* SPI-5 */
};
UINT32 mibspi_ram_base[5] = {
0xFF0E0000U, /* SPI-1 */
0xFF080000U, /* SPI-2 */
0xFF0C0000U, /* SPI-3 */
0xFF060000U, /* SPI-4 */
0xFF0A0000U, /* SPI-5 */
};
UINT32 mibspi_port_base[5] = {
0xFFF7F418U, /* PORT-1 */
0xFFF7F618U, /* PORT-2 */
0xFFF7F818U, /* PORT-3 */
0xFFF7FA18U, /* PORT-4 */
0xFFF7FC18U, /* PORT-5 */
};
struct mibspi_devcfg_t {
U8 gpio_chip_sel_enable;
U8 is_multibuffer_mode;
U8 pinmux_gpio_chipsel_enable;
U8 loopback_enable;
};
UINT32 MIBSPI_XFER_ONETIME_ERROR[5] = {0}, MIBSPI_XFER_RUNTIME_ERROR[5] = {0};
struct spi_log_t {
U8 is_write;
U8 data[64];
};
#ifdef CONFIG_SPI_BUS_TRACE
struct spi_log_t gSpiTrace[128];
int gSpiTraceIdx = 0;
int gPrintSpiLog = 0;
#endif
struct mibspi_devcfg_t mibspi_devcfg[5] = {0};
void MIBSPI_ConfigureTgCtrl(mibspi_regs_t *pRegs, U8 group, U8 oneshot, U8 pcurrent_reset, U8 trg_event, U8 trg_src, U8 bufid);
/*****************************************************************************************
\brief : MIBSPI_Init
\desc : MIBSPI_Init
\param :
\returns : 0 on success
*****************************************************************************************/
int MIBSPI_Init(U8 spi_num, U8 baud_prescale, U8 gpio_port, U32 MODE)
{
int i;
U16 ctrl_word;
U8 scs_val = 1;
U32 data;
U8 bufidx,PO,PH;
int retval = 0;
mibspi_regs_t *pRegs;
gio_port_t *portRegs;
mibspi_rambase_t *pRam;
struct mibspi_devcfg_t *dev;
if (spi_num > 4)
return ERROR_INVARG;
pRegs = (mibspi_regs_t *)mibspi_base[spi_num];
portRegs = (gio_port_t *)mibspi_port_base[gpio_port];
pRam = (mibspi_rambase_t *)mibspi_ram_base[spi_num];
dev = (struct mibspi_devcfg_t *)&mibspi_devcfg[spi_num];
dev->is_multibuffer_mode = 1;
/** bring MIBSPI out of reset */
pRegs->GCR0 = 0U;
pRegs->GCR0 = 1U;
/* configure portRegs for MISPI1 for CS0 drive manually */
if (dev->gpio_chip_sel_enable) {
data = portRegs->DIR | 0x1;
portRegs->DIR = data;
}
if (dev->is_multibuffer_mode) {
/** enable MIBSPI1 multibuffered mode and enable buffer RAM */
pRegs->MIBSPIE = (pRegs->MIBSPIE & 0xFFFFFFFEU) | 1U;
}
/** MIBSPI1 master mode and clock configuration */
pRegs->GCR1 = (pRegs->GCR1 & 0xFFFFFFFCU) | ((U32)((U32)1U << 1U) /* CLOKMOD */
| 1U); /* MASTER */
/** MIBSPI1 enable pin configuration */
pRegs->INT0 = (pRegs->INT0 & 0xFEFFFFFFU) | (U32)((U32)0U << 24U); /* ENABLE HIGHZ */
/** - Delays */
pRegs->DELAY = (U32)((U32)0U << 24U) /* C2TDELAY */ //16U
| (U32)((U32)0U << 16U) /* T2CDELAY */
| (U32)((U32)0U << 8U) /* T2EDELAY */
| (U32)((U32)0U << 0U); /* C2EDELAY */
/** - Data Format 0
* PARPOL BIT 23
* 0 = An even parity flag is added at the end of the transmit data stream.
1 = An odd parity flag is added at the end of the transmit data stream.
* WAITENA BIT 21
* 0 = not wait for EN signal from Slave.
1 = wait for EN Signal,Then the master aborts the transfer and sets the TIMEOUT error flag If EN Signal not come.
* SHIFTDIR BIT 20
* 0 = MSB is shifted out first.
1 = LSB is shifted out first.
* POLARITY BIT 17
* 0 = The SPI clock signal is low-inactive, that is, before and after data transfer the clock signal is low.
1 = The SPI clock signal is high-inactive,that is, before and after data transfer the clock signal is high.
* PHASE BIT 16
* 0 = The SPI clock signal is not delayed versus the transmit/receive data stream.
1 = The SPI clock signal is delayed by a half SPI clock cycle versus the transmit/receive data stream.
* */
PO = POLARITY(MODE);
PH = PHASE(MODE);
pRegs->FMT0 = (U32)((U32)0U << 24U) /* wdelay */
| (U32)((U32)0U << 23U) /* parity Polarity */
| (U32)((U32)0U << 22U) /* parity enable */
| (U32)((U32)0U << 21U) /* wait on enable */
| (U32)((U32)0U << 20U) /* shift direction */
| (U32)((U32)PO << 17U) /* clock polarity */ // MIBSPI is in MODE 1
| (U32)((U32)PH << 16U) /* clock phase */
| (U32)((U32)baud_prescale << 8U) /* baudrate prescale */
| (U32)((U32)8U << 0U); /* data word length */
/** - Data Format 1 */
pRegs->FMT1 = (U32)((U32)0U << 24U) /* wdelay */
| (U32)((U32)0U << 23U) /* parity Polarity */
| (U32)((U32)0U << 22U) /* parity enable */
| (U32)((U32)0U << 21U) /* wait on enable */
| (U32)((U32)0U << 20U) /* shift direction */
| (U32)((U32)PO << 17U) /* clock polarity */ // MIBSPI is in MODE 1
| (U32)((U32)PH << 16U) /* clock phase */
| (U32)((U32)baud_prescale << 8U) /* baudrate prescale */
| (U32)((U32)8U << 0U); /* data word length */
/** - Data Format 2 */
pRegs->FMT2 = (U32)((U32)0U << 24U) /* wdelay */
| (U32)((U32)0U << 23U) /* parity Polarity */
| (U32)((U32)0U << 22U) /* parity enable */
| (U32)((U32)0U << 21U) /* wait on enable */
| (U32)((U32)0U << 20U) /* shift direction */
| (U32)((U32)PO << 17U) /* clock polarity */ // MIBSPI is in MODE 1
| (U32)((U32)PH << 16U) /* clock phase */
| (U32)((U32)baud_prescale << 8U) /* baudrate prescale */
| (U32)((U32)8U << 0U); /* data word length */
/** - Data Format 3 */
pRegs->FMT3 = (U32)((U32)0U << 24U) /* wdelay */
| (U32)((U32)0U << 23U) /* parity Polarity */
| (U32)((U32)0U << 22U) /* parity enable */
| (U32)((U32)0U << 21U) /* wait on enable */
| (U32)((U32)0U << 20U) /* shift direction */
| (U32)((U32)PO << 17U) /* clock polarity */ // MIBSPI is in MODE 1
| (U32)((U32)PH << 16U) /* clock phase */
| (U32)((U32)baud_prescale << 8U) /* baudrate prescale */
| (U32)((U32)8U << 0U); /* data word length */
if (dev->is_multibuffer_mode) {
/** - Default Chip Select */
pRegs->DEF = (U32)(0xFFU);
}
if (dev->is_multibuffer_mode) {
/** - wait for buffer initialization complete before accessing MibSPI registers */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
while ((pRegs->FLG & 0x01000000U) != 0U)
{
} /* Wait */
}
if (dev->is_multibuffer_mode) {
/** enable MIBSPI RAM Parity */
pRegs->PAR_ECC_CTRL = (pRegs->PAR_ECC_CTRL & 0xFFFFFFF0U) | (0x00000005U);
/* initialize the TGCTRL */
for (i = 0; i < 8; ++i) {
bufidx = (i == 0) ? 0 : 1;
MIBSPI_ConfigureTgCtrl(pRegs, i, 1, 0, TRG_ALWAYS, TRG_DISABLED, bufidx);
}
pRegs->TGCTRL[8U] = (U32)(1U+0U+0U+0U+0U+0U+0U+0U) << 8U;
pRegs->LTGPEND = (pRegs->LTGPEND & 0xFFFF00FFU) | (U32)((U32)((8U+0U+0U+0U+0U+0U+0U+0U)-1U) << 8U);
ctrl_word = (U16)((U16)4U << 13U) /* buffer mode */
| (U16)((U16)1U << 12U) /* chip select hold */
| (U16)((U16)0U << 10U) /* enable WDELAY */
| (U16)((U16)0U << 11U) /* lock transmission */
| (U16)((U16)0U << 8U) /* data format */
| ((U16)(~((U16)0xFFU ^ (U16)CS_NONE)) & (U16)0x00FFU); /* chip select */
for (i = 0; i < 127; i++) {
pRam->tx[i].control = ctrl_word;
}
pRam->tx[i].control = (U16)((U16)4U << 13U) /* buffer mode */
| (U16)((U16)0U << 12U) /* chip select hold */
| (U16)((U16)0U << 10U) /* enable WDELAY */
| (U16)((U16)0U << 8U) /* data format */
| ((U16)(~((U16)0xFFU ^ (U16)CS_NONE)) & (U16)0x00FFU); /* chip select */
}
/** - set interrupt levels */
pRegs->LVL = (U32)((U32)0U << 9U) /* TXINT */
| (U32)((U32)0U << 8U) /* RXINT */
| (U32)((U32)0U << 6U) /* OVRNINT */
| (U32)((U32)0U << 4U) /* BITERR */
| (U32)((U32)0U << 3U) /* DESYNC */
| (U32)((U32)0U << 2U) /* PARERR */
| (U32)((U32)0U << 1U) /* TIMEOUT */
| (U32)((U32)0U << 0U); /* DLENERR */
/** - clear any pending interrupts */
pRegs->FLG |= 0xFFFFU;
/** - enable interrupts */
pRegs->INT0 = (pRegs->INT0 & 0xFFFF0000U)
| (U32)((U32)0U << 9U) /* TXINT */
| (U32)((U32)0U << 8U) /* RXINT */
| (U32)((U32)0U << 6U) /* OVRNINT */
| (U32)((U32)0U << 4U) /* BITERR */
| (U32)((U32)0U << 3U) /* DESYNC */
| (U32)((U32)0U << 2U) /* PARERR */
| (U32)((U32)0U << 1U) /* TIMEOUT */
| (U32)((U32)0U << 0U); /* DLENERR */
/** @b initialize @b MIBSPI1 @b Port */
/** - MIBSPIx Port output values */
pRegs->PC3 = (U32)((U32)1U << 0U) /* SCS[0] */
| (U32)((U32)1U << 1U) /* SCS[1] */
| (U32)((U32)1U << 2U) /* SCS[2] */
| (U32)((U32)1U << 3U) /* SCS[3] */
| (U32)((U32)1U << 4U) /* SCS[4] */
| (U32)((U32)1U << 5U) /* SCS[5] */
| (U32)((U32)0U << 8U) /* ENA */
| (U32)((U32)0U << 9U) /* CLK */
| (U32)((U32)0U << 10U) /* SIMO[0] */
| (U32)((U32)0U << 11U); /* SOMI[0] */
/** - MIBSPIx Port direction */
pRegs->PC1 = (U32)((U32)1U << 0U) /* SCS[0] DIR OUT*/
| (U32)((U32)1U << 1U) /* SCS[1] */
| (U32)((U32)1U << 2U) /* SCS[2] */
| (U32)((U32)1U << 3U) /* SCS[3] */
| (U32)((U32)1U << 4U) /* SCS[4] */
| (U32)((U32)1U << 5U) /* SCS[5] */
| (U32)((U32)0U << 8U) /* ENA */
| (U32)((U32)1U << 9U) /* CLK */
| (U32)((U32)1U << 10U) /* SIMO[0] */
| (U32)((U32)0U << 11U) ; /* SOMI[0] */
/** - MIBSPIx Port open drain enable */
pRegs->PC6 = (U32)((U32)0U << 0U) /* SCS[0] */
| (U32)((U32)0U << 1U) /* SCS[1] */
| (U32)((U32)0U << 2U) /* SCS[2] */
| (U32)((U32)0U << 3U) /* SCS[3] */
| (U32)((U32)0U << 4U) /* SCS[4] */
| (U32)((U32)0U << 5U) /* SCS[5] */
| (U32)((U32)0U << 8U) /* ENA */
| (U32)((U32)0U << 9U) /* CLK */
| (U32)((U32)0U << 10U) /* SIMO[0] */
| (U32)((U32)0U << 11U); /* SOMI[0] */
/** - MIBSPIx Port pullup / pulldown selection */
pRegs->PC8 = (U32)((U32)1U << 0U) /* SCS[0] */
| (U32)((U32)1U << 1U) /* SCS[1] */
| (U32)((U32)1U << 2U) /* SCS[2] */
| (U32)((U32)1U << 3U) /* SCS[3] */
| (U32)((U32)1U << 4U) /* SCS[4] */
| (U32)((U32)1U << 5U) /* SCS[5] */
| (U32)((U32)1U << 8U) /* ENA */
| (U32)((U32)1U << 9U) /* CLK */
| (U32)((U32)1U << 10U) /* SIMO[0] */
| (U32)((U32)1U << 11U); /* SOMI[0] */
/** - MIBSPIx Port pullup / pulldown enable*/
pRegs->PC7 = (U32)((U32)0U << 0U) /* SCS[0] */
| (U32)((U32)0U << 1U) /* SCS[1] */
| (U32)((U32)0U << 2U) /* SCS[2] */
| (U32)((U32)0U << 3U) /* SCS[3] */
| (U32)((U32)0U << 4U) /* SCS[4] */
| (U32)((U32)0U << 5U) /* SCS[5] */
| (U32)((U32)0U << 8U) /* ENA */
| (U32)((U32)0U << 9U) /* CLK */
| (U32)((U32)0U << 10U) /* SIMO[0] */
| (U32)((U32)0U << 11U); /* SOMI[0] */
scs_val = 1;
if (dev->gpio_chip_sel_enable)
scs_val = 0;
else {
scs_val = 1;
if (dev->pinmux_gpio_chipsel_enable)
scs_val = 0;
}
/* MIBSPIx set all pins to functional */
pRegs->PC0 = (U32)((U32)scs_val << 0U) /* SCS[0] 1: SPICS0 function, 0:GIO function */
| (U32)((U32)1U << 1U) /* SCS[1] */
| (U32)((U32)1U << 2U) /* SCS[2] */
| (U32)((U32)1U << 3U) /* SCS[3] */
| (U32)((U32)1U << 4U) /* SCS[4] */
| (U32)((U32)1U << 5U) /* SCS[5] */
| (U32)((U32)0U << 8U) /* ENA */
| (U32)((U32)1U << 9U) /* CLK */
| (U32)((U32)1U << 10U) /* SIMO[0] */
| (U32)((U32)1U << 11U); /* SOMI[0] */
/** - Finally start MIBSPIx */
pRegs->GCR1 = (pRegs->GCR1 & 0xFEFFFFFFU) | 0x01000000U;
return retval;
}
/*****************************************************************************
* Function : mibspiSetData
* Description : initiate transfer
* mibspi : spi
* group : group number
* returns : 0 on sucesss
******************************************************************************/
void MIBSPI_ConfigureTgCtrl(mibspi_regs_t *pRegs, U8 group, U8 oneshot, U8 pcurrent_reset, U8 trg_event, U8 trg_src, U8 bufid)
{
/** - initialize transfer groups */
pRegs->TGCTRL[group] = (U32)((oneshot & 1) << 30U) /* oneshot */
| ((pcurrent_reset) << 29U) /* pcurrent reset */
| ((trg_event) << 20U) /* trigger event */
| ((trg_src) << 16U) /* trigger source */
| ((bufid) << 8U); /* start buffer */
}
/*****************************************************************************
* Function : mibspiSetData
* Description : initiate transfer
* mibspi : spi
* group : group number
* returns : 0 on sucesss
******************************************************************************/
void mibspiSetData(mibspi_regs_t *mibspi, mibspi_rambase_t *ram, uint32 group, uint16 * data)
{
int k = 0;
uint32 start = (mibspi->TGCTRL[group] >> 8U) & 0xFFU;
uint32 end = (group == 7U) ? (((mibspi->LTGPEND & 0x00007F00U) >> 8U) + 1U) : ((mibspi->TGCTRL[group+1U] >> 8U) & 0xFFU);
if (end == 0U) {end = 128U;}
#ifdef CONFIG_SPI_BUS_TRACE
gSpiTrace[gSpiTraceIdx].is_write = 1;
gSpiTrace[gSpiTraceIdx].data[k++] = start;
gSpiTrace[gSpiTraceIdx].data[k++] = end;
#endif
while (start < end)
{
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
ram->tx[start].data = *data;
#ifdef CONFIG_SPI_BUS_TRACE
gSpiTrace[gSpiTraceIdx].data[k++] = (U8)*data;
#endif
data++;
start++;
}
#ifdef CONFIG_SPI_BUS_TRACE
if (gSpiTraceIdx < 127)
gSpiTraceIdx++;
#endif
}
/*****************************************************************************
* Function : mibspiGetData
* Description : initiate transfer
* mibspi : spi
* group : group number
* returns : 0 on sucesss
******************************************************************************/
uint32 mibspiGetData(mibspi_regs_t *mibspi, mibspi_rambase_t *ram, uint32 group, uint16 * data)
{
int k = 0;
uint32 start = (mibspi->TGCTRL[group] >> 8U) & 0xFFU;
uint32 end = (group == 7U) ? (((mibspi->LTGPEND & 0x00007F00U) >> 8U) + 1U) : ((mibspi->TGCTRL[group+1U] >> 8U) & 0xFFU);
uint16 mibspiFlags = 0U;
uint32 ret;
if (end == 0U) {end = 128U;}
#ifdef CONFIG_SPI_BUS_TRACE
gSpiTrace[gSpiTraceIdx].is_write = 0;
gSpiTrace[gSpiTraceIdx].data[k++] = start;
gSpiTrace[gSpiTraceIdx].data[k++] = end;
#endif
while (start < end)
{
mibspiFlags |= ram->rx[start].flags;
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
*data = ram->rx[start].data;
#ifdef CONFIG_SPI_BUS_TRACE
gSpiTrace[gSpiTraceIdx].data[k++] = (U8)*data;
#endif
data++;
start++;
}
#ifdef CONFIG_SPI_BUS_TRACE
if (gSpiTraceIdx < 127)
gSpiTraceIdx++;
#endif
ret = ((uint32)mibspiFlags >> 8U) & 0x5FU;
return ret;
}
/*****************************************************************************
* Function : mibspiSetupTransfer
* Description : initiate transfer
* mibspi : spi
* group : group number
* returns : 0 on sucesss
******************************************************************************/
void mibspiSetupTransfer(mibspi_rambase_t *pRam, enum chipSelect chip_sel, int length)
{
UINT16 ctrl_word;
int i; //is_cs_hold = 10; hold cs from clk start to end
ctrl_word = (UINT16)((UINT16)4U << 13U) /* buffer mode */
| (UINT16)((UINT16)1 << 12U) /* chip select hold */
| (UINT16)((UINT16)0U << 10U) /* enable WDELAY */
| (UINT16)((UINT16)0U << 11U) /* lock transmission */
| (UINT16)((UINT16)0U << 8U) /* data format */
| ((UINT16)(~((UINT16)0xFFU ^ (UINT16)chip_sel)) & (UINT16)0x00FFU); /* chip select */
pRam->tx[0].control = ctrl_word;
for (i = 1; i < length-1; i++)
pRam->tx[i].control = ctrl_word;
pRam->tx[i].control = (UINT16)((UINT16)4U << 13U) /* buffer mode */
| (UINT16)((UINT16)0 << 12U) /* chip select hold */
| (UINT16)((UINT16)0U << 10U) /* enable WDELAY */
| (UINT16)((UINT16)0 << 8U) /* data format */
| ((UINT16)(~((UINT16)0xFFU ^ (UINT16)chip_sel)) & (UINT16)0x00FFU); /* chip select */
}
/*****************************************************************************
* Function : mibspiTransfer
* Description : initiate transfer
* mibspi : spi
* group : group number
* returns : 0 on sucesss
******************************************************************************/
void mibspiTransfer(mibspi_regs_t *mibspi, uint32 group)
{
mibspi->TGCTRL[group] |= 0x80000000U;
}
/*****************************************************************************
* Function : mibspiIsTransferComplete
* Description : drive gpio chipselect
* mibspi : spi
* group : group number
* returns : 0 on sucesss
******************************************************************************/
boolean mibspiIsTransferComplete(mibspi_regs_t *mibspi, uint32 group)
{
boolean status;
if(((((mibspi->TGINTFLG & 0xFFFF0000U) >> 16U)>> group) & 1U) == 1U)
{
mibspi->TGINTFLG = (mibspi->TGINTFLG & 0x0000FFFFU) | ((uint32)((uint32)1U << group) << 16U);
status = TRUE;
}
else
{
status = FALSE;
}
return (status);
}
/*****************************************************************************
* Function : mibspiGpioChipSelect
* Description : drive gpio chipselect
* portRegs : portRegs
* bit : bit number
* val : value
* returns : 0 on sucess
******************************************************************************/
int mibspiGpioChipSelect(gio_port_t *portRegs, UINT8 bit, UINT8 val)
{
UINT32 data;
if (val) {
data = (1 << bit);
portRegs->DSET = data;
} else {
data = (1 << bit);
portRegs->DCLR = data;
}
return 0;
}
/*****************************************************************************
* Function : MIBSPI_Write
* Description : perform spi write
* spi_num : spi_num
* gpio_port : gpio number
* buffer : write data buffer
* length : length
******************************************************************************/
int MIBSPI_Write(UINT8 spi_num, enum chipSelect chip_sel, UINT8 gpio_port, UINT16 *buffer, int length)
{
int retval = 0, group = 0;
mibspi_regs_t *p_mibspi;
gio_port_t *portRegs;
mibspi_rambase_t *pRam;
if (spi_num > 4 || gpio_port > 4)
return ERROR_INVARG;
p_mibspi = (mibspi_regs_t *)mibspi_base[spi_num];
portRegs = (gio_port_t *)mibspi_port_base[gpio_port];
pRam = (mibspi_rambase_t *)mibspi_ram_base[spi_num];
if (chip_sel == CS_NONE) {
mibspiGpioChipSelect(portRegs, 0, XHIGH);
mibspiGpioChipSelect(portRegs, 0, XLOW);
}
/* set the Transfer length of buffer */
p_mibspi->TGCTRL[group] = (UINT32)((UINT32)1U << 30U) /* oneshot */
| (UINT32)((UINT32)0U << 29U) /* pcurrent reset */
| (UINT32)((UINT32)TRG_ALWAYS << 20U) /* trigger event */
| (UINT32)((UINT32)TRG_DISABLED << 16U) /* trigger source */
| (UINT32)((UINT32)0U << 8U); /* start buffer */
p_mibspi->TGCTRL[group + 1] = (UINT32)((UINT32)1U << 30U) /* oneshot */
| (UINT32)((UINT32)0U << 29U) /* pcurrent reset */
| (UINT32)((UINT32)TRG_ALWAYS << 20U) /* trigger event */
| (UINT32)((UINT32)TRG_DISABLED << 16U) /* trigger source */
| (UINT32)((UINT32)length << 8U); /* start buffer */
p_mibspi->LTGPEND = (p_mibspi->LTGPEND & 0xFFFF00FFU) | ((length-1) << 8U);
mibspiSetupTransfer(pRam, chip_sel, length);
mibspiSetData(p_mibspi, pRam, group, &buffer[0]);
mibspiTransfer(p_mibspi, group);
while (!mibspiIsTransferComplete(p_mibspi, group));
retval = mibspiGetData(p_mibspi, pRam, group, buffer);
MIBSPI_XFER_RUNTIME_ERROR[spi_num] = retval;
if (retval)
MIBSPI_XFER_ONETIME_ERROR[spi_num] |= retval;
MIBSPI_XFER_RUNTIME_ERROR[spi_num] = retval;
if (retval)
MIBSPI_XFER_ONETIME_ERROR[spi_num] |= retval;
if (chip_sel == CS_NONE)
mibspiGpioChipSelect(portRegs, XHIGH, 0);
return retval;
}
/****/
int MIBSPI_Write_Bit(UINT8 spi_num, enum chipSelect chip_sel, UINT8 gpio_port, UINT16 *buffer, UINT8 length)
{
int retval = 0, group = 0;
mibspi_regs_t *p_mibspi;
gio_port_t *portRegs;
mibspi_rambase_t *pRam;
if (spi_num > 4 || gpio_port > 4)
return ERROR_INVARG;
p_mibspi = (mibspi_regs_t *)mibspi_base[spi_num];
portRegs = (gio_port_t *)mibspi_port_base[gpio_port];
pRam = (mibspi_rambase_t *)mibspi_ram_base[spi_num];
if (chip_sel == CS_NONE) {
mibspiGpioChipSelect(portRegs, 0, XHIGH);
mibspiGpioChipSelect(portRegs, 0, XLOW);
}
/* set the Transfer length of buffer */
p_mibspi->TGCTRL[group] = (UINT32)((UINT32)1U << 30U) /* oneshot */
| (UINT32)((UINT32)0U << 29U) /* pcurrent reset */
| (UINT32)((UINT32)TRG_ALWAYS << 20U) /* trigger event */
| (UINT32)((UINT32)TRG_DISABLED << 16U) /* trigger source */
| (UINT32)((UINT32)0U << 8U); /* start buffer */
p_mibspi->TGCTRL[group + 1] = (UINT32)((UINT32)1U << 30U) /* oneshot */
| (UINT32)((UINT32)0U << 29U) /* pcurrent reset */
| (UINT32)((UINT32)TRG_ALWAYS << 20U) /* trigger event */
| (UINT32)((UINT32)TRG_DISABLED << 16U) /* trigger source */
| (UINT32)((UINT32)length << 8U); /* start buffer */
p_mibspi->LTGPEND = (p_mibspi->LTGPEND & 0xFFFF00FFU) | ((length-1) << 8U);
mibspiSetupTransfer1(pRam, chip_sel, length);
mibspiSetData(p_mibspi, pRam, group, &buffer[0]);
mibspiTransfer(p_mibspi, group);
//DelayMilliSec(100);
//mibspiIsTransferComplete(p_mibspi, group);
while (!mibspiIsTransferComplete(p_mibspi, group));
retval = mibspiGetData(p_mibspi, pRam, group, buffer);
MIBSPI_XFER_RUNTIME_ERROR[spi_num] = retval;
if (retval)
MIBSPI_XFER_ONETIME_ERROR[spi_num] |= retval;
MIBSPI_XFER_RUNTIME_ERROR[spi_num] = retval;
if (retval)
MIBSPI_XFER_ONETIME_ERROR[spi_num] |= retval;
if (chip_sel == CS_NONE)
mibspiGpioChipSelect(portRegs, XHIGH, 0);
return retval;
}
void mibspiSetupTransfer1(mibspi_rambase_t *pRam, enum chipSelect chip_sel, UINT8 length)
{
UINT16 ctrl_word;
int i; //is_cs_hold = 10;
ctrl_word = (UINT16)((UINT16)4U << 13U) /* buffer mode */
| (UINT8)((UINT8)1 << 12U) /* chip select hold */
| (UINT8)((UINT8)0U << 10U) /* enable WDELAY */
| (UINT8)((UINT8)0U << 11U) /* lock transmission */
| (UINT8)((UINT8)0U << 8U) /* data format */
| ((UINT16)(~((UINT16)0xFFU ^ (UINT16)chip_sel)) & (UINT16)0x00FFU); /* chip select */
pRam->tx[0].control = ctrl_word;
for (i = 1; i < length-1; i++)
pRam->tx[i].control = ctrl_word;
pRam->tx[i].control = (UINT8)((UINT8)4U << 13U) /* buffer mode */
| (UINT16)((UINT16)0 << 12U) /* chip select hold */
| (UINT16)((UINT16)0U << 10U) /* enable WDELAY */
| (UINT16)((UINT16)0 << 8U) /* data format */
| ((UINT16)(~((UINT16)0xFFU ^ (UINT16)chip_sel)) & (UINT16)0x00FFU); /* chip select */
}
/******/
/*****************************************************************************
* Function : MIBSPI_Read
* Description : perform spi read
* spi_num : spi_num
* gpio_port : gpio number
* buffer : write data buffer
* length : length
******************************************************************************/
int MIBSPI_Read(UINT8 spi_num, enum chipSelect chip_sel, UINT8 gpio_port, UINT16 *buffer, int length)
{
int retval = 0, group = 0;
mibspi_regs_t *p_mibspi;
gio_port_t *portRegs;
mibspi_rambase_t *pRam;
if (spi_num > 4 || gpio_port > 4)
return ERROR_INVARG;
p_mibspi = (mibspi_regs_t *)mibspi_base[spi_num];
portRegs = (gio_port_t *)mibspi_port_base[gpio_port];
pRam = (mibspi_rambase_t *)mibspi_ram_base[spi_num];
if (chip_sel == CS_NONE) {
mibspiGpioChipSelect(portRegs, 0, XHIGH);
mibspiGpioChipSelect(portRegs, 0, XLOW);
}
/* set the Transfer length of buffer */
p_mibspi->TGCTRL[group] = (UINT32)((UINT32)1U << 30U) /* oneshot */
| (UINT32)((UINT32)0U << 29U) /* pcurrent reset */
| (UINT32)((UINT32)TRG_ALWAYS << 20U) /* trigger event */
| (UINT32)((UINT32)TRG_DISABLED << 16U) /* trigger source */
| (UINT32)((UINT32)0U << 8U); /* start buffer */
p_mibspi->TGCTRL[group + 1] = (UINT32)((UINT32)1U << 30U) /* oneshot */
| (UINT32)((UINT32)0U << 29U) /* pcurrent reset */
| (UINT32)((UINT32)TRG_ALWAYS << 20U) /* trigger event */
| (UINT32)((UINT32)TRG_DISABLED << 16U) /* trigger source */
| (UINT32)((UINT32)length << 8U); /* start buffer */
p_mibspi->LTGPEND = (p_mibspi->LTGPEND & 0xFFFF00FFU) | ((length-1) << 8U);
mibspiSetupTransfer(pRam, chip_sel, length);
mibspiSetData(p_mibspi, pRam, group, &buffer[0]);
mibspiTransfer(p_mibspi, group);
while (!mibspiIsTransferComplete(p_mibspi, group));
retval = mibspiGetData(p_mibspi, pRam, group, buffer);
MIBSPI_XFER_RUNTIME_ERROR[spi_num] = retval;
if (retval)
MIBSPI_XFER_ONETIME_ERROR[spi_num] |= retval;
MIBSPI_XFER_RUNTIME_ERROR[spi_num] = retval;
if (retval)
MIBSPI_XFER_ONETIME_ERROR[spi_num] |= retval;
if (chip_sel == CS_NONE)
mibspiGpioChipSelect(portRegs, XHIGH, 0);
return retval;
}
#ifdef CONFIG_SPI_BUS_TRACE
extern UINT8 gTempBuffer;
void printSpiLog(void)
{
int i, j, k;
strcpy(gTempBuffer, "AFDTU ATP Version 0.1");
UartSendBuffer(ATP_UART_PORT_NUM, gTempBuffer, strlen (gTempBuffer));
if (!gPrintSpiLog)
return ;
gPrintSpiLog = 0;
for (i = 0; i < gSpiTraceIdx; ++i) {
k = gSpiTrace[i].data[0];
if (gSpiTrace[i].is_write)
sprintf(gTempBuffer, "[W],");
else
sprintf(gTempBuffer, "[R],");
for (j = k; j < (gSpiTrace[i].data[1] + k); ++j) {
sprintf(gTempBuffer, "'%02X,", gSpiTrace[i].data[2+j]);
UartSendBuffer(ATP_UART_PORT_NUM, gTempBuffer, strlen(gTempBuffer));
}
sprintf(gTempBuffer, "\r\n");
UartSendBuffer(ATP_UART_PORT_NUM, gTempBuffer, strlen(gTempBuffer));
hw_delay(5);
}
gSpiTraceIdx = 0;
}
#else
void printSpiLog(void) { }
#endif
/*
* 1GB_MT29F8G01ADAFD12.c
*
* Created on: 04-NOV-2024
* Author: AST
*/
#include "common.h"
#include "error.h"
#include "stdio.h"
#include "mibspi.h"
#include "1GB_MT29F8G01ADAFD12.h"
UINT16 spi2[125];
UINT8 gTempBuffer[100];
UINT16 *get_buf(void)
{
return &spi2[0];
}
/*****************************************************************************
* Function : FLASH_Write
* Description : perform spi write to FLASH
* Opcode : Opcode
* opcode_len : opcode_len
* wdata : write data buffer
* length : length
******************************************************************************/
int FLASH_Write(UINT8 *opcode, UINT8 opcode_len, UINT8 *wdata, UINT32 length)
{
int i, k = 0;
UINT16 *pDataBuf;
pDataBuf = get_buf();
for (i = 0; i < opcode_len; i++)
pDataBuf[i] = opcode[i];
k = opcode_len;
for (i = 0; i < length; i++)
pDataBuf[k++] = wdata[i];
/* spi read instruction */
return MIBSPI_Write(MIBSPI2, CS_0, 0, pDataBuf, k);
}
int xmti_Write(UINT8 *opcode, UINT8 opcode_len, UINT8 wdata, UINT32 length)
{
int i, k = 0;
UINT16 *pDataBuf;
pDataBuf = get_buf();
for (i = 0; i < opcode_len; i++)
pDataBuf[i] = opcode[i];
k = opcode_len;
for (i = 0; i < length; i++)
pDataBuf[k++] = wdata;
/* spi read instruction */
return MIBSPI_Write(MIBSPI2, CS_0, 0, pDataBuf, k);
}
/*****************************************************************************
* Function : FLASH_Read
* Description : perform spi read from FLASH
* Opcode : Opcode
* opcode_len : opcode_len
* rdata : read data buffer
* length : length
******************************************************************************/
int FLASH_Read(UINT8 *opcode, UINT8 opcode_len, UINT8 *rdata, UINT32 length)
{
int i, k = 0, retval;
UINT16 *pDataBuf;
pDataBuf = get_buf();
for (i = 0; i < opcode_len; i++)
pDataBuf[i] = opcode[i];
k = opcode_len;
for (i = 0; i < length; i++)
pDataBuf[k++] = 0xAA;
/* spi read instruction */
retval = MIBSPI_Read(MIBSPI2, CS_0, 0, pDataBuf, k);
k = 0;
for (i = 0; i < length; ++i)
rdata[k++] = pDataBuf[opcode_len + i];
return retval;
}
void Reset(void){
UINT8 OP = RESET;
FLASH_Write(&OP,1,0,1);
}
void STATUS_REG(UINT8 *RD_STATUS){
UINT8 REG[2] = {GET_FEATURE, R_STATUS};
FLASH_Read(REG,2,RD_STATUS,1);
}
void WRITE_EN(void){
UINT8 WEL = WRITE_ENABLE;
FLASH_Write(&WEL,1,0,1);
}
void WRITE_DIS(void){
UINT8 WEL = WRITE_DISABLE;
FLASH_Write(&WEL,1,0,0);
}
void DIE_SEL(void){
UINT8 DIE[2];
UINT8 data = DIE_STACK1;
DIE[0] = DIE_SET_FEATURE;
DIE[1] = DIE_ADDR;
FLASH_Write(DIE,2,&data,2);
}
void READ_DEV_ID(UINT8 *ID){
UINT8 DEV_ID[2];
DEV_ID[0] = READ_ID;
DEV_ID[1] = DUMMY_BYTE;
FLASH_Read(DEV_ID,2,ID,2);
}
void PAGE_RD_CMD_CACHE(UINT8 *STATUS,UINT8 PAGE, UINT16 BLOCK)
{
UINT32 ROW_ADDR = (0x00 << 20) | (BLOCK << 16) | PAGE;
UINT8 ROW_ADDR2 = (ROW_ADDR >> 16) & 0xFF; // Bits 23-16
UINT8 ROW_ADDR1 = (ROW_ADDR >> 8) & 0xFF; // Bits 15-8
UINT8 ROW_ADDR0 = ROW_ADDR & 0xFF; // Bits 7-0
UINT8 PAGE_CMD[4] = {PAGE_READ, ROW_ADDR2, ROW_ADDR1, ROW_ADDR0};
FLASH_Write(PAGE_CMD,4,0,0);
STATUS_REG(STATUS);
}
void PGM_EXECUTE(UINT8 *STATUS, UINT8 PAGE, UINT16 BLOCK)
{
UINT32 ROW_ADDR = (0x00 << 20) | (BLOCK << 16) | PAGE;
UINT8 ROW_ADDR2 = (ROW_ADDR >> 16) & 0xFF; // Bits 23-16
UINT8 ROW_ADDR1 = (ROW_ADDR >> 8) & 0xFF; // Bits 15-8
UINT8 ROW_ADDR0 = ROW_ADDR & 0xFF; // Bits 7-0
UINT8 PE[4] = {PROGRAM_EXECUTE, ROW_ADDR2, ROW_ADDR1, ROW_ADDR0};
FLASH_Write(PE,4,0,0);
STATUS_REG(STATUS);
}
void RD_FROM_CACHE(UINT8 *data,UINT16 length,UINT16 COLUMN_ADDR)
{
UINT8 COLUMN_ADDR2 = (COLUMN_ADDR >> 8) & 0xFF;
UINT8 COLUMN_ADDR1 = COLUMN_ADDR & 0xFF;
UINT8 PAGE_CMD[3] = {READ_FROM_CACHE_X1, COLUMN_ADDR1, COLUMN_ADDR2};
FLASH_Read(PAGE_CMD,3,data,length);
}
void PGM_LOAD(UINT8 *data,UINT16 length, UINT16 COLUMN_ADDR)
{
UINT8 COLUMN_ADDR2 = (COLUMN_ADDR >> 8) & 0xFF;
UINT8 COLUMN_ADDR1 = COLUMN_ADDR & 0xFF;
UINT8 PL[3] = {PROGRAM_LOAD_X1, COLUMN_ADDR1, COLUMN_ADDR2};
FLASH_Write(PL, 3, data, length);
}
void NAND_RD()
{
int i,a;
UINT8 STATUS,data[512]= {0};
int NO_BYTES = 100;
UINT16 COLUMN_ADDR = 0,BLOCKS = 0;
UINT8 PAGE = 0;
WRITE_DIS();
PAGE_RD_CMD_CACHE(&STATUS,PAGE,BLOCKS);
// for(a = 0;a<2;a++){
for(i = 0; i < NO_BYTES; ++i){
RD_FROM_CACHE(&data,NO_BYTES,COLUMN_ADDR);
sprintf(gTempBuffer, " %X ", data[i]);
UartSendBuffer(2, gTempBuffer, strlen(gTempBuffer));
DelayMilliSec(50);
}
// COLUMN_ADDR = (COLUMN_ADDR << 2);
// }
}
int NAND_WR(UINT16 COLUMN_ADDR,UINT8 w_d){
int i,a;
int NO_BYTES = 100;
UINT8 STATUS;
UINT8 data[512]= {0};
UINT16 BLOCKS = 0;
UINT8 PAGE = 0;
WRITE_EN();
for (i = 0; i < NO_BYTES; ++i)
{
data[i] = w_d;
PGM_LOAD(data,NO_BYTES,COLUMN_ADDR);
w_d++;
}
PGM_EXECUTE(&STATUS,PAGE,BLOCKS);
return w_d;
}
void NAND_BLOCK_ERASE(UINT8 *RD_STATUS, UINT8 PAGE, UINT16 BLOCK)
{
WRITE_EN();
UINT32 ROW_ADDR = (0x00 << 20) | (BLOCK << 16) | PAGE;
UINT8 ROW_ADDR2 = (ROW_ADDR >> 16) & 0xFF; // Bits 23-16
UINT8 ROW_ADDR1 = (ROW_ADDR >> 8) & 0xFF; // Bits 15-8
UINT8 ROW_ADDR0 = ROW_ADDR & 0xFF; // Bits 7-0
UINT8 ER[4] = {BLOCK_ERASE, ROW_ADDR2, ROW_ADDR1, ROW_ADDR0};
FLASH_Write(ER,4,0,0);
STATUS_REG(RD_STATUS);
}
Query 2:

How to reduce the timings between 2 operations in MibSPI.
