CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help to make driver of MX25L6445E

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kongfu1



Joined: 26 Apr 2010
Posts: 56

View user's profile Send private message

Help to make driver of MX25L6445E
PostPosted: Fri Jul 12, 2013 8:38 pm     Reply with quote

Hi,

Somehow a driver of MX25L6445E is not working. Please help.

CCS 4.144
PIC24EP512GU810

Code:


#define  TRANS_LENGTH  16
#define  RANDOM_SEED   106
#define  FLASH_TARGET_ADDR  0x00000000


uint32 FlashID = 0xc2201700;
uint8 ElectronicID = 0x16;

void SendFlashAddr( uint32 flash_address)
{
    spi_write( flash_address >> 24 ); // A31-A0
    spi_write( flash_address >> 16 );
    spi_write( flash_address >> 8 );
    spi_write( flash_address );
}

//enable write bit
ReturnMsg CMD_WREN( void )
{
    // Chip select go low to start a flash command
    output_low(FLS_MEM_CS);

    // Write Enable command = 0x06, Setting Write Enable Latch Bit
    spi_write( FLASH_CMD_WREN );

    // Chip select go high to end a flash command
    output_high(FLS_MEM_CS);

    return FlashOperationSuccess;
}

//page program
ReturnMsg CMD_PP( uint32 flash_address, uint8 *source_address, uint32 byte_length )
{
    uint32 index;
    uint8  addr_4byte_mode;

    // Check flash is busy or not
    if( IsFlashBusy() )    return FlashIsBusy;

    // Check 3-byte or 4-byte mode
    addr_4byte_mode = TRUE;  // 4-byte mode
   
    // Setting Write Enable Latch bit
    CMD_WREN();

    // Chip select go low to start a flash command
    output_low(FLS_MEM_CS);

    // Write Page Program command
    spi_write( FLASH_CMD_PP );
    SendFlashAddr( flash_address );

    // Set a loop to down load whole page data into flash's buffer
    // Note: only last 256 byte will be programmed
    for( index=0; index < byte_length; index++ )
    {
        spi_write( *(source_address + index) );
    }

    // Chip select go high to end a flash command
    output_high(FLS_MEM_CS);

    if( WaitFlashReady( 2000 ) )
        return FlashOperationSuccess;
    else
        return FlashTimeOut;
}

//erase flash
ReturnMsg CMD_SE( uint32 flash_address )
{
    uint8  addr_4byte_mode;

    // Check flash is busy or not
    if( IsFlashBusy() )    return FlashIsBusy;

    addr_4byte_mode = TRUE;  // 4-byte mode
   
    // Setting Write Enable Latch bit
    CMD_WREN();

    // Chip select go low to start a flash command
    output_low(FLS_MEM_CS);

    //Write Sector Erase command = 0x20;
    spi_write( FLASH_CMD_SE );
    SendFlashAddr( flash_address );

    // Chip select go high to end a flash command
    output_high(FLS_MEM_CS);

    if( WaitFlashReady( 5000 ) )
        return FlashOperationSuccess;
    else
        return FlashTimeOut;
}

//read Status Register Bits.
ReturnMsg CMD_RDSR( uint8 *StatusReg )
{
    uint8  gDataBuffer;

    // Chip select go low to start a flash command
    output_low(FLS_MEM_CS);

    // Send command
    spi_write( FLASH_CMD_RDSR );
    gDataBuffer = spi_read( 0 );

    // Chip select go high to end a flash command
    output_high(FLS_MEM_CS);

    *StatusReg = gDataBuffer;

    return FlashOperationSuccess;
}

//read flash
ReturnMsg CMD_READ( uint32 flash_address, uint8 *target_address, uint32 byte_length )
{
    uint32 index;
   
    // Chip select go low to start a flash command
    output_low(FLS_MEM_CS);

    // Write READ command and address
    spi_write( FLASH_CMD_READ );
    SendFlashAddr( flash_address );

    // Set a loop to read data into buffer
    for( index=0; index < byte_length; index++ )
    {
        // Read data one byte at a time
        *(target_address + index) = spi_read( 0 );
    }

    // Chip select go high to end a flash command
    output_high(FLS_MEM_CS);

    return FlashOperationSuccess;
}

//read mfg id
ReturnMsg CMD_RDID( uint32 *Identification )
{
    uint32 temp;
    uint8  gDataBuffer[3];

    // Chip select go low to start a flash command
    output_low(FLS_MEM_CS);

    // Send command
    spi_write( FLASH_CMD_RDID);

    // Get manufacturer identification, device identification
    gDataBuffer[0] = spi_read( 0 );
    gDataBuffer[1] = spi_read( 0 );
    gDataBuffer[2] = spi_read( 0 );

    // Chip select go high to end a command
    output_high(FLS_MEM_CS);

    // Store identification
    temp =  gDataBuffer[0];
    temp =  (temp << 8) | gDataBuffer[1];
    *Identification =  (temp << 8) | gDataBuffer[2];

    return FlashOperationSuccess;
}
//read electronic ID
ReturnMsg CMD_RES( uint8 *ElectricIdentification )
{

    // Chip select go low to start a flash command
    output_low(FLS_MEM_CS);

    // Send flash command and insert dummy cycle
    spi_write( FLASH_CMD_RES);
    //Insert Dummy Cycle - 24 bits
    spi_read(0);
    spi_read(0);
    spi_read(0);

    // Get electric identification
    *ElectricIdentification = spi_read(0);

    // Chip select go high to end a flash command
    output_high(FLS_MEM_CS);

    return FlashOperationSuccess;
}

BOOL IsFlashBusy( void )
{
    uint8  gDataBuffer;

    CMD_RDSR( &gDataBuffer );
    if( (gDataBuffer & FLASH_WIP_MASK)  == FLASH_WIP_MASK )
        return TRUE;
    else
        return FALSE;
}

BOOL WaitFlashReady( uint32 ExpectTime )
{

    uint32 temp = 0;
    while( IsFlashBusy() )
    {
        if( temp > ExpectTime )
        {
            return FALSE;
        }
        temp = temp + 1;
        delay_ms(1);
    }
    return TRUE;

}

uint8 FlashID_Test( void )
{
    uint32  flash_id = 0;
    uint16  error_cnt = 0;
    uint16  rems_id;
    uint8   electric_id = 0;
    FlashStatus  flash_state = {0};
    ReturnMsg  msg;

    /* Read flash device id */
    msg =  CMD_RDID( &flash_id );
    if( msg != (ReturnMsg)FlashOperationSuccess )
        return FALSE;

    msg = CMD_RES( &electric_id );
    if( msg != (ReturnMsg)FlashOperationSuccess )
        return FALSE;

   /* Compare to expected value */
    if( flash_id != FlashID )
        return FALSE;

    if( electric_id != ElectronicID )
        return FALSE;

    return TRUE;
}

uint8 FlashReadWrite_Test( void )
{
    ReturnMsg  message= 0;
    FlashStatus  flash_state = {0};

    uint32  flash_addr;
    uint32  trans_len = 0;
    uint16  i=0, error_cnt = 0;
    uint16  seed = 0;
    uint8   st_reg = 0;
    uint8   memory_addr[TRANS_LENGTH] = {0};
    uint8   memory_addr_cmp[TRANS_LENGTH] = {0};

    /* Assign initial condition */
    flash_addr = FLASH_TARGET_ADDR;
    trans_len = TRANS_LENGTH;
    seed = RANDOM_SEED;

    /* Prepare data to transfer */
    srand( seed );
    for( i=0; i< trans_len; i=i+1 ){
        memory_addr[i] = rand()%256;   // generate random byte data
    }

    /* Erase 4K sector of flash memory
       Note: It needs to erase dirty sector before program */
    CMD_SE( flash_addr );

    /* Program data to flash memory */
    CMD_PP( flash_addr, memory_addr, trans_len );

    /* Read flash memory data to memory buffer */
    CMD_READ( flash_addr, memory_addr_cmp, trans_len );

    /* Compare original data and flash data */
    for( i=0; i < (trans_len); i=i+1 )
    {
        if( memory_addr[i] != memory_addr_cmp[i] )
            error_cnt++;
    }

    /* Erase 4K sector of flash memory */
    CMD_SE( flash_addr );

    if( error_cnt != 0 )
        return FALSE;
    else
        return TRUE;

}

void initFSHMem(void)
{
   uint8 theRet;
   BOOL theBool;
   output_high(FLS_MEM_CS);
   output_high(FLS_MEM_CS);
   setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_512);

   theBool = WaitFlashReady( 1000 );
   if(theBool)
      theRet = FlashReadWrite_Test();
      //theRet = FlashID_Test();
}

Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Jul 12, 2013 9:43 pm     Reply with quote

Quote:
Somehow a driver of MX25L6445E is not working. Please help.

Check your code. For SPI applications, the first thing to check is your
setup_spi() statement:
Quote:
setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_512);


Here are the #define statements for the SPI modes:
Code:
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)
 


Now you should look in the MX25L6445E data sheet, at the following
figure, and see what SPI modes it supports:
Quote:
Figure 1-1. Serial Modes Supported (for Normal Serial mode)

Compare that to the mode in your setup_spi() statement.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group