📄 at25f512_drv.i
字号:
*****************************************************************/
unsigned char get_char_array(unsigned long address, unsigned long nb_of_byte, unsigned char *destination)
{
unsigned char sr; /* SPI memory status register */
unsigned char AccessStatus; /* Access status value */
unsigned int byteread_cnt; /* Read byte counter (range 1 to memory size) */
unsigned char *current_dest;
current_dest = destination; /* copy destination pointer because it needs to be incremented */
if ((address) <= 0x00FFFF ) /* TOP ADDR = 0x00FFFF */
{
if (read_status_register(&sr) == 0x01 ) /* Is the SPI interface currently not busy */
{
if (!(sr & (1<<0 ))) /* is the SPI memory ready ? */
{
SPCR |= (1<<6); /* Enable SPI Interface */
PORTB.2 = 0; /* Enable AT25F512A Chip Select (L) */
spi_transfer(0x03); /* transmitt the op_code READ */
spi_transfer((unsigned char)(address>>16)); /* Address phase is 3 byte long for SPI flashes */
spi_transfer((unsigned char)(address>>8)); /* send MSByte address first */
spi_transfer((unsigned char)(address)); /* send LSByte address */
byteread_cnt = 0;
while (byteread_cnt < nb_of_byte)
{
*current_dest++ = spi_transfer(0xFF); /* store read byte, post increment the current_dest pointer */
byteread_cnt++;
}
PORTB.2 = 1; /* Disable AT25F512A Chip Select (H) */
SPCR &= ~(1<<6); /* Enable SPI Interface */
AccessStatus = 0x01 ;
}
else
{
AccessStatus = 0xFF ;
}
}
else
{
AccessStatus = 0xFF ;
}
}
else
{
AccessStatus = 0xFD ;
}
return AccessStatus;
}
/*F**************************************************************
/ Function: put_char_array
/----------------------------------------------------------------
/ Description: Write Status Register (WRSR)
/----------------------------------------------------------------
/ Parameter: address : get data address
nb_of_byte : get number of byte
destination : the result area
/ Return: TRANSFER_COMPLETED : the read access is completed without error
BUSY : the SPI peripheral is busy
OUT_OF_RANGE : address out of range (0x00FFFF)
/----------------------------------------------------------------
/ Note:
*****************************************************************/
unsigned char put_char_array(unsigned long start_add, unsigned char nb_of_byte, unsigned char* source)
{
unsigned char sr; /* SPI memory status register */
if (start_add <= 0x00FFFF )
{
if (read_status_register(&sr) == 0x01 ) /* Is the SPI interface currently not busy */
{
if (!(sr & (1<<0 ))) /* is the SPI memory ready ? */
{
if (test_write_protect(start_add, sr) == 0x0 )
{
while(write_command(0x06)!= 0x01 );/* always perform a WREN command before any write operation */
spi_state = 0x01 ; /* Serial SPI memory write access WRITE start */
nb_byte = nb_of_byte;
byte_cnt = 0;
address = start_add;
data_ptr = source;
SPCR |= (1<<6); /* Enable SPI Interface */
SPCR |= (1<< 7);
PORTB.2 = 0; /* Enable AT25F512A Chip Select (L) */
SPDR = 0x02;
return 0x00 ;
}
else
{
return 0xFE ;
}
}
else
{
return 0xFF ;
}
}
else
{
return 0xFF ;
}
}
else
{
return 0xFD ;
}
}
/*F**************************************************************
/ Function: erase_sector
/----------------------------------------------------------------
/ Description: Erase Sector (0x000000 ~ 0x007FFF), (0x008000 ~ 0x00FFFF)
/----------------------------------------------------------------
/ Parameter: address : erase sector (0x007FFF / 0x00FFFF)
/ Return: TRANSFER_COMPLETED : the read access is completed without error
BUSY : the SPI peripheral is busy
DATA_WR_PROTECTED : the selected sector is write protected.
/----------------------------------------------------------------
/ Note:
*****************************************************************/
unsigned char erase_sector(unsigned long long_add)
{
unsigned char sr; /* read status register */
if (read_status_register(&sr) == 0x01 ) /* Is the SPI interface currently not busy */
{
if (!(sr & (1<<0 ))) /* is the serial memory ready ? */
{
if (test_write_protect(long_add, sr) == 0x0 )
{
while(write_command(0x06)!=0x01 ); /* always perform a WREN command before any write operation */
SPCR |= (1<<6); /* Enable SPI Interface */
PORTB.2 = 0; /* Enable AT25F512A Chip Select (L) */
spi_transfer(0x52); /* transmit the SECTOR_ERASE op_code */
spi_transfer((unsigned char)(long_add>>16)); /* transmit the most significant address byte */
spi_transfer((unsigned char)(long_add>>8)); /* transmit the middle address byte */
spi_transfer((unsigned char)(long_add)); /* transmit the less significant address byte */
PORTB.2 = 1; /* Disable AT25F512A Chip Select (H) */
SPCR &= ~(1<<6);
return 0x01 ;
}
else
{
return 0xFE ;
}
}
else
{
return 0xFF ;
}
}
else
{
return 0xFF ;
}
}
/*F**************************************************************
/ Function: erase_chip
/----------------------------------------------------------------
/ Description: Erase ALL (0x000000 ~ 0x00FFFF)
/----------------------------------------------------------------
/ Parameter:
/ Return: TRANSFER_COMPLETED : the read access is completed without error
BUSY : the SPI peripheral is busy
DATA_WR_PROTECTED : the selected sector is write protected.
/----------------------------------------------------------------
/ Note:
*****************************************************************/
unsigned char erase_chip(void)
{
unsigned char sr; /* read status register */
if (read_status_register(&sr) == 0x01 ) /* Is the SPI interface currently not busy */
{
if (!(sr & (1<<0 ))) /* is the serial memory ready ? */
{
if (test_write_protect(0, sr) == 0x0 ) /* test if the first byte is write protected to detect a full array write protection */
{
while(write_command(0x06) != 0x01 ); /* always perform a WREN command before any write operation */
SPCR |= (1<<6); /* Enable SPI Interface */
PORTB.2 = 0; /* Enable AT25F512A Chip Select (L) */
spi_transfer(0x62); /* transmit the CHIP_ERASE op_code */
PORTB.2 = 1; /* Disable AT25F512A Chip Select (H) */
SPCR &= ~(1<<6); /* Disable SPI Interface */
return 0x01 ;
}
else
{
return 0xFE ;
}
}
else
{
return 0xFF ;
}
}
else
{
return 0xFF ;
}
}
/*F**************************************************************
/ Function: Read_mem_id
/----------------------------------------------------------------
/ Description: Read Mem ID (ATMEL manufacurer: 0x1F, Device Code: 0x65)
/----------------------------------------------------------------
/ Parameter:
/ Return: TRANSFER_COMPLETED : the read access is completed without error
BUSY : the SPI peripheral is busy
/----------------------------------------------------------------
/ Note:
*****************************************************************/
unsigned char get_mem_id(unsigned char *id)
{
unsigned char sr; /* read status register */
if (read_status_register(&sr) == 0x01 ) /* Is the SPI interface not currently busy */
{
if (!(sr & (1<<0 ))) /* is the serial memory ready ? */
{
SPCR |= (1<<6); /* Enable SPI Interface */
PORTB.2 = 0; /* Enable AT25F512 Chip Select (L) */
spi_transfer(0x15); /* transmit the SECTOR_ERASE op_code */
spi_transfer(0xFF); /* receive the manufacturing code */
*id = spi_transfer(0xFF); /* receive the ID code */
PORTB.2 = 1; /* Disable AT25F512A Chip Select (H) */
SPCR &= ~(1<<6); /* Disable SPI Interface */
return 0x01 ;
}
else
{
return 0xFF ;
}
}
else
{
return 0xFF ;
}
}
/*F**************************************************************
/ Function: test_write_protect
/----------------------------------------------------------------
/ Description: Check write protect (Y/N)
/----------------------------------------------------------------
/ Parameter: address : test write protect address
/ status_register : check status
/ Return: WRITE_ALLOWED : allowed write data
WRITE_PROTECTED : protected write data
/----------------------------------------------------------------
/ Note:
*****************************************************************/
unsigned char test_write_protect(unsigned long address, unsigned int status_register)
{
if ((status_register & (1 << 2 )) == (0x00 << 2)) /* if no write protection area is configured */
{
return 0x0 ;
}
else
{
return 0x1 ;
}
}
/*F**************************************************************
/ Function: write_protected_area
/----------------------------------------------------------------
/ Description: Set Write Protected Area
/----------------------------------------------------------------
/ Parameter: area : the region of the serial memory to be protected
/ status_register : check status
/ Return: TRANSFER_COMPLETED : the write access was completed without error
BUSY : the SPI peripheral or the serial memory is busy.
HW_PROTECTED : the serial memory is hardware write protected.
/----------------------------------------------------------------
/ Note:
*****************************************************************/
unsigned char set_write_protected_area(unsigned char area)
{
unsigned char sr; /* status register byte */
if (read_status_register(&sr) == 0x01 ) /* Is the SPI interface not currently busy */
{
if (!(sr & (1<<0 ))) /* is the serial memory ready ? */
{
while ( write_status_register(0<<7 ) != 0x01 ){}; /* Disable software write protection */
while ( write_status_register((1<<7 )|area) != 0x01 ){}; /* set software write portection to the selecte area */
do
{
read_status_register(&sr);
}while (sr & (1<<0 )); /* read backs status register */
if (sr != ((1<<7 )|area)) /* detect hardware protection */
{
return 0x2 ;
}
else
{
return 0x01 ;
}
}
else
{
return 0xFF ;
}
}
else
{
return 0xFF ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -