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.