📄 device.c
字号:
if ( !TMPL_WaitUntilReady( TMPL_PROGRAM_TIMEOUT ) )
{
stat.Result = StatTimeout;
if ( returnSR )
{
stat.SR = TMPL_ReadStatus();
}
return( stat );
}
else
{
if ( returnSR )
{
TMPL_ClearStatus();
}
/* if (start address is not TMPL_BUFFER_SIZE-byte aligned ) */
if ( ( address % TMPL_BUFFER_SIZE ) != 0 )
{
/* if ( buffer size is > TMPL_BUFFER_SIZE ) or
( buffer crosses block boundary ) */
if ( ( numbytes > TMPL_BUFFER_SIZE ) ||
( ( address & 0x1 ) && ( numbytes >= TMPL_BUFFER_SIZE ) ) ||
( ( address + numbytes -1 ) > ( address | TMPL_BLOCK_MASK) )
)
{
/* write partial buffer */
numwritebytes = ( TMPL_BUFFER_SIZE - ( address % TMPL_BUFFER_SIZE ) );
}
else
{
/* write all remaining bytes */
numwritebytes = numbytes;
}
byteswritten = numwritebytes;
TMPL_WriteF( cmndaddress, TMPL_WRITE_TO_BUFFER );
numitems = numwritebytes / sizeof(TMPL_FDATA);
if ( ( ( numwritebytes % sizeof(TMPL_FDATA) ) != 0 ) ||
( ( numwritebytes > 0x01 ) && ( address & 0x01 ) ) )
{
numitems++;
}
TMPL_WriteF( cmndaddress, numitems-1 );
if ( numwritebytes > 0 ) /* while more data to write */
{
while ( numwritebytes > 0 ) /* if more bytes still to write */
{
if ( ( address & 0x1 ) != 0 ) /* if destination address is odd */
{
address--;
#if (BIG_ENDIAN_ARCHITECTURE)
writedata = (TMPL_FDATA) *buffer;
writedata |= 0xff00;
#else /* little endian */
writedata = *((TMPL_FDATA_PTR)buffer);
writedata = ( writedata << 8 ) | 0x00ff;
#endif
numwritebytes--;
buffer++;
}
else /* destination address is even */
{
#if BIG_ENDIAN_ARCHITECTURE
/* grab first byte */
writedata = (TMPL_FDATA)( *buffer );
writedata = ( ( writedata << 8 ) & 0xff00 );
/* grab second byte */
writedata = writedata | ( (TMPL_FDATA) *(buffer+1) );
#else /* little endian architecture */
/* grab 2 bytes */
writedata = *( (TMPL_FDATA_PTR)buffer );
#endif /* BIG_ENDIAN_ARCHITECTURE */
if ( numwritebytes == 1 )
{
#if BIG_ENDIAN_ARCHITECTURE
writedata |= 0x00ff;
#else
writedata |= 0xff00;
#endif
numwritebytes--;
}
else
{
numwritebytes -= sizeof(TMPL_FDATA);
}
buffer += sizeof(TMPL_FDATA);
}
fptr = TMPL_GetFptr(address);
*fptr = writedata;
address += sizeof(TMPL_FDATA);
}
}
TMPL_WriteF( cmndaddress, TMPL_CONFIRM );
if ( !TMPL_WaitUntilReady( TMPL_PROGRAM_TIMEOUT ) )
{
stat.Result = StatTimeout;
if ( returnSR )
{
stat.SR = TMPL_ReadStatus();
}
return( stat );
}
numbytes -= byteswritten;
} /* end if ( ( address % TMPL_BUFFER_SIZE ) != 0 ) ) */
/* while bytes remain */
while ( numbytes != 0 )
{
/* if TMPL_BUFFER_SIZE bytes remain */
if ( numbytes > TMPL_BUFFER_SIZE )
{
/* write full TMPL_BUFFER_SIZE-byte buffer */
numwritebytes = TMPL_BUFFER_SIZE;
}
/* else */
else
{
/* write partial buffer */
numwritebytes = numbytes;
}
/* end if */
byteswritten = numwritebytes;
cmndaddress = address;
TMPL_WriteF( cmndaddress, TMPL_WRITE_TO_BUFFER );
numitems = numwritebytes / sizeof(TMPL_FDATA);
if ( ( numwritebytes % sizeof(TMPL_FDATA) ) != 0 )
{
numitems++;
}
TMPL_WriteF( cmndaddress, numitems-1 );
if ( numwritebytes > 0 ) /* while more data to write */
{
while ( numwritebytes > 0 ) /* if more bytes still to write */
{ /* address is known even at this point */
#if BIG_ENDIAN_ARCHITECTURE
/* grab first byte */
writedata = (TMPL_FDATA)( *buffer );
writedata = ( ( writedata << 8 ) & 0xff00 );
/* grab second byte */
writedata = writedata | ( (TMPL_FDATA) *(buffer+1) );
#else /* little endian architecture */
/* grab 2 bytes */
writedata = *( (TMPL_FDATA_PTR)buffer );
#endif /* BIG_ENDIAN_ARCHITECTURE */
if ( numwritebytes == 1 )
{
#if BIG_ENDIAN_ARCHITECTURE
writedata |= 0x00ff;
#else
writedata |= 0xff00;
#endif
numwritebytes--;
}
else
{
numwritebytes -= sizeof(TMPL_FDATA);
}
buffer += sizeof(TMPL_FDATA);
fptr = TMPL_GetFptr(address);
*fptr = writedata;
address += sizeof(TMPL_FDATA);
}
}
TMPL_WriteF( cmndaddress, TMPL_CONFIRM );
if ( !TMPL_WaitUntilReady( TMPL_PROGRAM_TIMEOUT ) )
{
stat.Result = StatTimeout;
if ( returnSR )
{
stat.SR = TMPL_ReadStatus();
}
return( stat );
}
numbytes -= byteswritten;
} /* end while numbytes != 0 ) */
}/* end if ( !TMPL_WaitUntilReady( TMPL_PROGRAM_TIMEOUT ) ) */
if ( returnSR )
{
stat.SR = TMPL_ReadStatus();
}
/* return device to read array mode */
TMPL_WriteF( TMPL_BASE_FLASH_ADDRESS, TMPL_READ_ARRAY );
return( stat );
}
#endif /* X_16 */
/****************************************************************************
*
* TMPL_ProgramProtection
*
* Description:
*
* This procedure is called to program the protection register on
* the flash device at the specified location with the specified data
* value. See the flash device datasheet for specific details on this
* command.
*
* Parameters:
*
* IN location - the protection register location on the flash
* device to be programmed.
*
* IN value - the data item to be programmed.
*
* IN returnSR - flag to indicate whether the device status register
* value should be returned by this function.
*
* Returns:
*
* TMPL_Status - includes function return status defined by enum
* TMPL_CommandStat and optionally the flash device
* status register value.
*
* Assumptions:
*
* NONE
*
***************************************************************************/
TMPL_Status TMPL_ProgramProtection ( UINT32 location,
TMPL_FDATA value,
UINT8 returnSR )
{
UINT32 baseaddr;
UINT32 address;
TMPL_Status stat;
if ( location > TMPL_OTP_NUMWORDS )
{
stat.Result = StatBadOtp;
return( stat );
}
baseaddr = TMPL_BASE_FLASH_ADDRESS;
address = TMPL_OTP_BASE + TMPL_BASE_FLASH_ADDRESS;
address += ( location * sizeof(TMPL_FDATA) );
if ( returnSR )
{
TMPL_ClearStatus();
}
TMPL_WriteF( baseaddr, TMPL_OTP_PROGRAM );
TMPL_WriteF( address, value );
if ( !TMPL_WaitUntilReady( TMPL_PROGRAM_TIMEOUT ) )
{
stat.Result = StatTimeout;
}
else
{
stat.Result = StatCompleted;
}
if ( returnSR )
{
stat.SR = TMPL_ReadStatus();
}
/* return device to read array mode */
TMPL_WriteF( TMPL_BASE_FLASH_ADDRESS, TMPL_READ_ARRAY );
return( stat );
}
/****************************************************************************
*
* TMPL_ProgramSuspend
*
* Description:
*
* This procedure is called to issue the program suspend command to
* the flash device. See the flash device datasheet for specific details
* on this command.
*
* Parameters:
*
* IN blocknum - the block number on the device.
*
* IN returnSR - flag to indicate whether the device status register
* value should be returned by this function.
*
* Returns:
*
* TMPL_Status - includes function return status defined by enum
* TMPL_CommandStat and optionally the flash device
* status register value.
*
* Assumptions:
*
* When this function is called the device is currently in the program
* mode for the block identified.
*
***************************************************************************/
TMPL_Status TMPL_ProgramSuspend ( UINT16 blocknum,
UINT8 returnSR )
{
TMPL_Status stat;
UINT32 blockaddr;
stat = TMPL_GetBlockAddress( blocknum, &blockaddr );
if ( stat.Result != StatCompleted )
{
return( stat );
}
TMPL_WriteF( blockaddr, TMPL_BLOCK_SUSPEND);
if ( !TMPL_WaitUntilReady( TMPL_PROGRAM_TIMEOUT ) )
{
stat.Result = StatTimeout;
}
else
{
stat.Result = StatCompleted;
}
if ( returnSR )
{
stat.SR = TMPL_ReadStatus();
}
/* return device to read array mode */
TMPL_WriteF( TMPL_BASE_FLASH_ADDRESS, TMPL_READ_ARRAY );
return( stat );
}
/****************************************************************************
*
* TMPL_ReadBlockStatus
*
* Description:
*
* This procedure is called to read the status for the specified block
* from the flash device. See the flash device datasheet for specific
* details on this command.
*
* Parameters:
*
* IN blocknum - the block number on the device.
*
* OUT blockstat- the status of the block as: unlocked, locked,
* or locked down.
*
* Returns:
*
* TMPL_Status - includes function return status defined by enum
* TMPL_CommandStat.
*
* Assumptions:
*
* NONE
*
***************************************************************************/
TMPL_Status TMPL_ReadBlockStatus ( UINT16 blocknum,
TMPL_FDATA *blockstat )
{
UINT32 stataddress;
TMPL_Status stat;
UINT32 blockaddr;
stat = TMPL_GetBlockAddress( blocknum, &blockaddr );
if ( stat.Result != StatCompleted )
{
return( stat );
}
#if X_8
stataddress = ( blockaddr + 4 );
#endif
#if X_16
stataddress = ( blockaddr + ( 2 * sizeof( TMPL_FDATA ) ) );
#endif
TMPL_WriteF( TMPL_BASE_FLASH_ADDRESS, TMPL_READ_ID_CODES );
TMPL_ReadF( stataddress, blockstat );
/* return device to read array mode */
TMPL_WriteF( TMPL_BASE_FLASH_ADDRESS, TMPL_READ_ARRAY );
stat.Result = StatCompleted;
return( stat );
}
#if X_16
/****************************************************************************
*
* TMPL_ReadProtection
*
* Description:
*
* This procedure is called to read the protection register value on
* the flash device from the specified location. See the flash device
* datasheet for specific details on this command.
*
* Parameters:
*
* IN location - the protection register location on the flash
* device to be read from.
*
* OUT value - the data item read from the register.
*
* Returns:
*
* TMPL_Status - includes function return status defined by enum
* TMPL_CommandStat.
*
* Assumptions:
*
* NONE
*
***************************************************************************/
TMPL_Status TMPL_ReadProtection ( UINT32 location,
TMPL_FDATA_PTR value )
{
UINT32 baseaddr;
UINT32 address;
TMPL_Status stat;
if ( location > TMPL_OTP_NUMWORDS )
{
stat.Result = StatBadOtp;
return( stat );
}
baseaddr = TMPL_BASE_FLASH_ADDRESS;
address = TMPL_OTP_BASE + TMPL_BASE_FLASH_ADDRESS;
address += ( location * sizeof(TMPL_FDATA) );
TMPL_WriteF( baseaddr, TMPL_OTP_READ );
TMPL_ReadF( address, value );
/* return device to read array mode */
TMPL_WriteF( TMPL_BASE_FLASH_ADDRESS, TMPL_READ_ARRAY );
stat.Result = StatCompleted;
return( stat );
}
#endif /* X_16 */
/****************************************************************************
*
* TMPL_Resume
*
* Description:
*
* This procedure is called to issue the resume command to the flash
* device for the specified block. See the flash device datasheet for
* specific details on this command.
*
* Parameters:
*
* IN blocknum - the block number to resume.
*
* IN returnSR - flag to indicate whether the device status register
* value should be returned by this function.
*
* Returns:
*
* TMPL_Status - includes function return status defined by enum
* TMPL_CommandStat and optionally the flash device
* status register value.
*
* Assumptions:
*
* The block indicated was previously program suspended or erase
* suspended.
*
***************************************************************************/
TMPL_Status TMPL_Resume ( UINT16 blocknum,
UINT8 returnSR )
{
TMPL_Status stat;
UINT32 blockaddr;
TMPL_FDATA status;
stat = TMPL_GetBlockAddress( blocknum, &blockaddr );
if ( stat.Result != StatCompleted )
{
return( stat );
}
if ( returnSR )
{
TMPL_ClearStatus();
}
TMPL_WriteF( blockaddr, TMPL_BLOCK_RESUME );
if ( !TMPL_WaitUntilReady( TMPL_PROGRAM_TIMEOUT ) )
{
stat.Result = StatTimeout;
}
else
{
stat.Result = StatCompleted;
}
if ( returnSR )
{
stat.SR = TMPL_ReadStatus();
}
return( stat );
}
/****************************************************************************
*
* TMPL_UnlockAllBlocks
*
* Description:
*
* This procedure is called to unlock all blocks on the flash device.
* See the flash device datasheet for specific details on this command.
*
* Parameters:
*
* IN returnSR - flag to indicate whether the device status register
* value should be returned by this function.
*
* Returns:
*
* TMPL_Status - includes function return status defined by enum
* TMPL_CommandStat and optionally the flash device
* status register value.
*
* Assumptions:
*
* The blocks were previously locked.
*
***************************************************************************/
TMPL_Status TMPL_UnlockAllBlocks ( UINT8 returnSR )
{
TMPL_Status stat;
if ( returnSR )
{
TMPL_ClearStatus();
}
TMPL_WriteF( TMPL_BASE_FLASH_ADDRESS, TMPL_CONFIG_SETUP );
TMPL_WriteF( TMPL_BASE_FLASH_ADDRESS, TMPL_LOCK_BIT_CLEAR );
if ( !TMPL_WaitUntilReady( TMPL_PROGRAM_TIMEOUT ) )
{
stat.Result = StatTimeout;
}
else
{
stat.Result = StatCompleted;
}
if ( returnSR )
{
stat.SR = TMPL_ReadStatus();
}
/* return device to read array mode */
TMPL_WriteF(TMPL_BASE_FLASH_ADDRESS, TMPL_READ_ARRAY );
return( stat );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -