This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C129XNCZAD: on board spi_flash write or read issue

Part Number: TM4C129XNCZAD
Other Parts Discussed in Thread: EK-TM4C1294XL

i am using dk-tm4c129x tiva board .
in that i am using on board spi flash memory (MX25L25635F)
i am write two way code in that my buffer size is 105535
1)only flash write
2)only flash read
in that am successfully work sequentially upload but when i am murge both code read or write that in not work properly . in that merge code only 60 bytes read or write properly more than 60 bytes in upload then code is not working.
i want 105535 byte read or write.

in that read_write code is not work.

write_spi 

// usb_dev_msc.c - Main routines for the device mass storage class example.
// write_spi


#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/udma.h"
#include "grlib/grlib.h"
#include "usblib/usblib.h"
#include "usblib/device/usbdevice.h"
#include "usblib/device/usbdmsc.h"
#include "utils/ustdlib.h"
#include "fatfs/src/diskio.h"
#include "drivers/frame.h"
#include "drivers/kentec320x240x16_ssd2119.h"
#include "drivers/mx66l51235f.h"
#include "drivers/pinout.h"
#include "usbdspiflash.h"
#include "usb_msc_structs.h"




#define NUM_SSI_DATA                105535
//***************************
//
// Graphics context used to show text on the display.
//
//***************************
tContext g_sContext;


//***************************
//
// A buffer used for updating the read/write counts.
//
//***************************
uint8_t g_pcBuffer[NUM_SSI_DATA];
uint8_t Data[NUM_SSI_DATA];



//***************************
//
// The system clock frequency in Hz.
//
//***************************
uint32_t g_ui32SysClock;

//***************************
//
// The error routine that is called if the driver library encounters an error.
//
//***************************
#ifdef DEBUG
void
_error_(char *pcFilename, uint32_t ui32Line)
{
}
#endif

//***************************
//
// This is the main loop that runs the application.
//
//***************************
int
main(void)
{
    uint32_t ui32Read, ui32Write,ui32Index;
    uint32_t ui32PLLRate;

    //
    // Run from the PLL at 120 MHz.
    //
    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                             SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
                                             SYSCTL_CFG_VCO_480), 120000000);

    for(ui32Index=0;ui32Index<NUM_SSI_DATA;ui32Index++)
    {
      Data[ui32Index]=ui32Index/5;
      g_pcBuffer[ui32Index]=0;
    }

    //
    // Configure the device pins.
    //
    PinoutSet();

    //
    // Initialize the display driver.
    //
    Kentec320x240x16_SSD2119Init(g_ui32SysClock);

    //
    // Initialize the graphics context.
    //
    GrContextInit(&g_sContext, &g_sKentec320x240x16_SSD2119);

    //
    // Draw the application frame.
    //
    FrameDraw(&g_sContext, "usb-dev-msc");


    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOQ))
    {

    }
    GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_7);


    //
    // Enable the SSI3 used by SPI flash.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
    ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_SSI3);


    //
    // Configure and enable uDMA
    //


    MX66L51235FInit(g_ui32SysClock);
    
    
    USBDMSCStorageWrite(0, Data, 0,NUM_SSI_DATA);//write buffer
    
    SysCtlDelay(g_ui32SysClock/10);

  

    while(1)
    {
        uint8_t c=!c;
        GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7,c<<7);
        SysCtlDelay(g_ui32SysClock/10000);
     }
}

//read_spi


#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/udma.h"
#include "grlib/grlib.h"
#include "usblib/usblib.h"
#include "usblib/device/usbdevice.h"
#include "usblib/device/usbdmsc.h"
#include "utils/ustdlib.h"
#include "fatfs/src/diskio.h"
#include "drivers/frame.h"
#include "drivers/kentec320x240x16_ssd2119.h"
#include "drivers/mx66l51235f.h"
#include "drivers/pinout.h"
#include "usbdspiflash.h"
#include "usb_msc_structs.h"




#define NUM_SSI_DATA                105535
//***************************
//
// Graphics context used to show text on the display.
//
//***************************
tContext g_sContext;


//***************************
//
// A buffer used for updating the read/write counts.
//
//***************************
uint8_t g_pcBuffer[NUM_SSI_DATA];
uint8_t Data[NUM_SSI_DATA];



//***************************
//
// The system clock frequency in Hz.
//
//***************************
uint32_t g_ui32SysClock;

//***************************
//
// The error routine that is called if the driver library encounters an error.
//
//***************************
#ifdef DEBUG
void
_error_(char *pcFilename, uint32_t ui32Line)
{
}
#endif

//***************************
//
// This is the main loop that runs the application.
//
//***************************
int
main(void)
{
    uint32_t ui32Read, ui32Write,ui32Index;
    uint32_t ui32PLLRate;

    //
    // Run from the PLL at 120 MHz.
    //
    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                             SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
                                             SYSCTL_CFG_VCO_480), 120000000);

    for(ui32Index=0;ui32Index<NUM_SSI_DATA;ui32Index++)
    {
      Data[ui32Index]=ui32Index/5;
      g_pcBuffer[ui32Index]=0;
    }

    //
    // Configure the device pins.
    //
    PinoutSet();

    //
    // Initialize the display driver.
    //
    Kentec320x240x16_SSD2119Init(g_ui32SysClock);

    //
    // Initialize the graphics context.
    //
    GrContextInit(&g_sContext, &g_sKentec320x240x16_SSD2119);

    //
    // Draw the application frame.
    //
    FrameDraw(&g_sContext, "usb-dev-msc");


    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOQ))
    {

    }
    GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_7);


    //
    // Enable the SSI3 used by SPI flash.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
    ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_SSI3);


    //
    // Configure and enable uDMA
    //


    MX66L51235FInit(g_ui32SysClock);
    
    
    USBDMSCStorageRead(0, g_pcBuffer, 0,NUM_SSI_DATA);//read buffer

    while(1)
    {
        uint8_t c=!c;
        GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7,c<<7);
        SysCtlDelay(g_ui32SysClock/10000);
     }
}
// read_ write_spi


#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/udma.h"
#include "grlib/grlib.h"
#include "usblib/usblib.h"
#include "usblib/device/usbdevice.h"
#include "usblib/device/usbdmsc.h"
#include "utils/ustdlib.h"
#include "fatfs/src/diskio.h"
#include "drivers/frame.h"
#include "drivers/kentec320x240x16_ssd2119.h"
#include "drivers/mx66l51235f.h"
#include "drivers/pinout.h"
#include "usbdspiflash.h"
#include "usb_msc_structs.h"




#define NUM_SSI_DATA                105535
//***************************
//
// Graphics context used to show text on the display.
//
//***************************
tContext g_sContext;


//***************************
//
// A buffer used for updating the read/write counts.
//
//***************************
uint8_t g_pcBuffer[NUM_SSI_DATA];
uint8_t Data[NUM_SSI_DATA];



//***************************
//
// The system clock frequency in Hz.
//
//***************************
uint32_t g_ui32SysClock;

//***************************
//
// The error routine that is called if the driver library encounters an error.
//
//***************************
#ifdef DEBUG
void
_error_(char *pcFilename, uint32_t ui32Line)
{
}
#endif

//***************************
//
// This is the main loop that runs the application.
//
//***************************
int
main(void)
{
    uint32_t ui32Read, ui32Write,ui32Index;
    uint32_t ui32PLLRate;

    //
    // Run from the PLL at 120 MHz.
    //
    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                             SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
                                             SYSCTL_CFG_VCO_480), 120000000);

    for(ui32Index=0;ui32Index<NUM_SSI_DATA;ui32Index++)
    {
      Data[ui32Index]=ui32Index/5;
      g_pcBuffer[ui32Index]=0;
    }

    //
    // Configure the device pins.
    //
    PinoutSet();

    //
    // Initialize the display driver.
    //
    Kentec320x240x16_SSD2119Init(g_ui32SysClock);

    //
    // Initialize the graphics context.
    //
    GrContextInit(&g_sContext, &g_sKentec320x240x16_SSD2119);

    //
    // Draw the application frame.
    //
    FrameDraw(&g_sContext, "usb-dev-msc");


    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOQ))
    {

    }
    GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_7);


    //
    // Enable the SSI3 used by SPI flash.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI3);
    ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_SSI3);


    //
    // Configure and enable uDMA
    //


    MX66L51235FInit(g_ui32SysClock);
    
    
    USBDMSCStorageWrite(0, Data, 0,NUM_SSI_DATA);//write buffer
    
    SysCtlDelay(g_ui32SysClock/10);

    USBDMSCStorageRead(0, g_pcBuffer, 0,NUM_SSI_DATA);//read buffer

    while(1)
    {
        uint8_t c=!c;
        GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7,c<<7);
        SysCtlDelay(g_ui32SysClock/10000);
     }
}

  • Hi,

      Please refer to the source code for USBDMSCStorageWrite and USBDMSCStorageRead. You can find these functions in C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\dk-tm4c129x\usb_dev_msc\usbdspiflash.c file.    As you can see, the last argument to USBDMSCStorageWrite is the number of blocks, not number of bytes. The total number of blocks for the MX66L51235F can be obtained by calling USBDMSCStorageNumBlocks(). As you can see the number of blocks will be MX66L51235F_MEMORY_SIZE / MX66L51235F_BLOCK_SIZE which is 0x4000000 / 0x1000 = 16384 maximum blocks. You are passing a value of 105535 as the number of blocks which exceeds the maximum. 

    USBDMSCStorageWrite(void *pvDrive, uint8_t *pui8Data, uint32_t ui32Sector, uint32_t ui32NumBlocks). 

    //*****************************************************************************
    //
    // This function will read a block from a device opened by the
    // USBDMSCStorageOpen() call.
    //
    // \param pvDrive is the pointer that was returned from a call to
    // USBDMSCStorageOpen().
    // \param pucData is the buffer that data will be written into.
    // \param ui32NumBlocks is the number of blocks to read.
    //
    // This function is use to read blocks from a physical device and return them
    // in the \e pucData buffer.  The data area pointed to by \e pucData should be
    // at least \e ui32NumBlocks * Block Size bytes to prevent overwriting data.
    //
    // \return Returns the number of bytes that were read from the device.
    //
    //*****************************************************************************
    uint32_t
    USBDMSCStorageRead(void *pvDrive, uint8_t *pui8Data, uint32_t ui32Sector,
                       uint32_t ui32NumBlocks)
    {
        ASSERT(pvDrive != 0);
    
        g_ui32ReadCount += ui32NumBlocks * MX66L51235F_BLOCK_SIZE;
    
        MX66L51235FRead(ui32Sector * MX66L51235F_BLOCK_SIZE, pui8Data, 
                        ui32NumBlocks * MX66L51235F_BLOCK_SIZE);
    
        return(ui32NumBlocks * MX66L51235F_BLOCK_SIZE);
    }
    
    //*****************************************************************************
    //
    // This function will write a block to a device opened by the
    // USBDMSCStorageOpen() call.
    //
    // \param pvDrive is the pointer that was returned from a call to
    // USBDMSCStorageOpen().
    // \param pucData is the buffer that data will be used for writing.
    // \param ui32NumBlocks is the number of blocks to write.
    //
    // This function is use to write blocks to a physical device from the buffer
    // pointed to by the \e pucData buffer.  If the number of blocks is greater
    // than one then the block address will increment and write to the next block
    // until \e ui32NumBlocks * Block Size bytes have been written.
    //
    // \return Returns the number of bytes that were written to the device.
    //
    //*****************************************************************************
    uint32_t
    USBDMSCStorageWrite(void *pvDrive, uint8_t *pui8Data, uint32_t ui32Sector,
                        uint32_t ui32NumBlocks)
    {
        uint32_t ui32Idx, ui32BlockAddr;
        uint32_t ui32PageIdx;
    
        ASSERT(pvDrive != 0);
    
        g_ui32WriteCount += ui32NumBlocks * MX66L51235F_BLOCK_SIZE;
    
        for(ui32Idx = 0; ui32Idx < ui32NumBlocks; ui32Idx++)
        {
            //
            // each block is 4K(0x1000) bytes
            //
            ui32BlockAddr = (ui32Sector + ui32Idx) * MX66L51235F_BLOCK_SIZE;
    
            //
            // erase the block
            // 
            MX66L51235FSectorErase(ui32BlockAddr);
    
            //
            // program the block one page(256 bytes) a time
            // 
            for(ui32PageIdx = 0; ui32PageIdx < (MX66L51235F_BLOCK_SIZE / 256);
                ui32PageIdx++)
            {
                MX66L51235FPageProgram((ui32BlockAddr + (ui32PageIdx * 256)), 
                                       (pui8Data +
                                        (ui32Idx * MX66L51235F_BLOCK_SIZE) +
                                        (ui32PageIdx * 256)), 256);
            }
        }
    
        return(ui32NumBlocks * MX66L51235F_BLOCK_SIZE);
    }
    

  • Thank you for response

    now i am able to communication with spi flash
    now my question is

    1)how can increase speed increase via quad spi?
    2)how can write particular write start addresh to write not sector?

  • Hi,

    You can reference C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\ssi_quad_mode to set up QSSI mode. 

     Please refer to the SPIFlashPageProgram() API in C:\ti\TivaWare_C_Series-2.2.0.295\utils for programming a specific address. 

    //*****************************************************************************
    //
    //! Programs the SPI flash.
    //!
    //! \param ui32Base is the SSI module base address.
    //! \param ui32Addr is the SPI flash address to be programmed.
    //! \param pui8Data is a pointer to the data to be programmed.
    //! \param ui32Count is the number of bytes to be programmed.
    //!
    //! This function programs data into the SPI flash, using PIO mode.  This
    //! function will not return until the entire program command has been written
    //! into the SSI transmit FIFO.  This uses the 0x02 SPI flash command.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    SPIFlashPageProgram(uint32_t ui32Base, uint32_t ui32Addr,
                        const uint8_t *pui8Data, uint32_t ui32Count)
    {
        //
        // Set the SSI module into write-only mode.
        //
        MAP_SSIAdvModeSet(ui32Base, SSI_ADV_MODE_WRITE);
    
        //
        // Send the page program command.
        //
        MAP_SSIDataPut(ui32Base, CMD_PP);
    
        //
        // Send the address of the first byte to program.
        //
        MAP_SSIDataPut(ui32Base, (ui32Addr >> 16) & 0xff);
        MAP_SSIDataPut(ui32Base, (ui32Addr >> 8) & 0xff);
        MAP_SSIDataPut(ui32Base, ui32Addr & 0xff);
    
        //
        // Loop while there is more than one data byte left to be sent.
        //
        while(ui32Count-- != 1)
        {
            //
            // Send the next data byte.
            //
            MAP_SSIDataPut(ui32Base, *pui8Data++);
        }
    
        //
        // Send the last data byte, marking it as the end of the frame.
        //
        MAP_SSIAdvDataPutFrameEnd(ui32Base, *pui8Data);
    }