📄 fs_spi_flashprg.c
字号:
/*----------------------------------------------------------------------------
* R T L - F l a s h F i l e S y s t e m
*----------------------------------------------------------------------------
* Name: FS_SPI_FLASHPRG.C
* Purpose: Flash Programming Functions - Atmel Data Flash AT45DB321C (SPI)
* Rev.: V3.22
*----------------------------------------------------------------------------
* This code is part of the RealView Run-Time Library.
* Copyright (c) 2004-2007 KEIL - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/
#include <File_Config.h>
#define PAGE_SZ 528 /* Page size */
#define BLOCK_SZ (8*PAGE_SZ) /* Block size (used for erase) */
#define SECT_SZ (16*BLOCK_SZ) /* Virtual sector size */
/* SPI Data Flash Commands */
#define SPI_READ_DATA 0xE8
#define SPI_READ_STATUS 0xD7
#define SPI_BLOCK_ERASE 0x50
#define SPI_BUF1_WRITE 0x84
#define SPI_PAGE_PROGRAM 0x83
#define SPI_PAGE_READ 0x53
/* Local variables */
static U8 spibuf[PAGE_SZ];
/* Local functions */
static void set_adr (U8 *cmd, U32 adr);
static void spi_write (U8 cmnd, U8 cmndlen, U32 adr, U8 *buf, U32 sz);
/*----------------------------------------------------------------------------
* Initialize Flash Programming Functions
* Return Value: 0 - Init OK
* 1 - Init Failed
*---------------------------------------------------------------------------*/
int fs_spi_Init (void) {
/* Initialize SPI host interface. */
spi_init ();
return (0);
} /* end of fs_spi_Init */
/*----------------------------------------------------------------------------
* Erase Sector in Flash Memory.
* Parameter: adr: Virtual Sector Address
* Return Value: 0 - Erase OK
* 1 - Erase Failed
*---------------------------------------------------------------------------*/
int fs_spi_EraseSector (U32 adr) {
U32 i;
/* Virtual sector size is 16 blocks. */
for (i = 0; i < (SECT_SZ/BLOCK_SZ); i++) {
spi_write (SPI_BLOCK_ERASE, 4, adr, NULL, 0);
adr += BLOCK_SZ;
}
return (0);
} /* end of fs_spi_EraseSector */
/*----------------------------------------------------------------------------
* Program Page in Flash Memory.
* Parameter: adr: Start Address
* sz: Size
* buf: Data
* Return Value: 0 - Program OK
* 1 - Program failed
*---------------------------------------------------------------------------*/
int fs_spi_ProgramPage (U32 adr, U32 sz, U8 *buf) {
U32 cnt;
while (sz) {
/* Read Flash Page to Buf 1. */
spi_write (SPI_PAGE_READ, 4, adr, NULL, 0);
cnt = PAGE_SZ - (adr % PAGE_SZ);
if (cnt > sz) cnt = sz;
spi_write (SPI_BUF1_WRITE, 4, adr, buf, cnt);
spi_write (SPI_PAGE_PROGRAM, 4, adr, buf, PAGE_SZ);
adr += cnt;
buf += cnt;
sz -= cnt;
}
return (0);
} /* end of fs_spi_ProgramPage */
/*----------------------------------------------------------------------------
* Read Data from Flash Memory.
* Parameter: adr: Start Address
* sz: Size
* buf: Data
* Return Value: 0 - Read OK
* 1 - Read failed
*---------------------------------------------------------------------------*/
int fs_spi_ReadData (U32 adr, U32 sz, U8 *buf) {
U8 cmd[9];
cmd[0] = 8;
cmd[1] = SPI_READ_DATA;
set_adr (&cmd[2], adr);
spi_command (&cmd[0], buf, buf, sz);
return (0);
} /* end of fs_spi_ReadData */
/*----------------------------------------------------------------------------
* Send SPI Command to Data Flash.
*---------------------------------------------------------------------------*/
static void spi_write (U8 cmnd, U8 cmndlen, U32 adr, U8 *buf, U32 sz) {
U8 cmd[5];
cmd[0] = cmndlen;
cmd[1] = cmnd;
set_adr (&cmd[2], adr);
spi_command (&cmd[0], buf, spibuf, sz);
/* Wait while device is Busy. */
do {
cmd[0] = 2;
cmd[1] = SPI_READ_STATUS;
spi_command (&cmd[0], NULL, NULL, 0);
} while ((cmd[2] & 0x80) == 0);
}
/*----------------------------------------------------------------------------
* Convert linear address to segmented Data Flash address
*---------------------------------------------------------------------------*/
static void set_adr (U8 *cmd, U32 adr) {
U32 bl_adr, pg_adr;
bl_adr = adr / PAGE_SZ;
pg_adr = adr % PAGE_SZ;
adr = (bl_adr << 10) | pg_adr;
cmd[0] = (U8)(adr >> 16);
cmd[1] = (U8)(adr >> 8 );
cmd[2] = (U8)(adr >> 0 );
}
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -