|
|
View previous topic :: View next topic |
Author |
Message |
kongfu1
Joined: 26 Apr 2010 Posts: 56
|
Help to make driver of MX25L6445E |
Posted: Fri Jul 12, 2013 8:38 pm |
|
|
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
|
|
Posted: Fri Jul 12, 2013 9:43 pm |
|
|
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. |
|
|
|
|
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
|