⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flashhelper.c

📁 意法半导体ARM7 STR710+DM9000A的TCP/IP实现
💻 C
字号:
#include "FlashHelper.h"
#include "gpio.h"

/* address offset of each sector in internal flash memory */
static const struct flash_sector_info {
        u32 base, mask;
} FlashSectorInfo[] = {
        {0x000000, FLASH_B0F0},
        {0x002000, FLASH_B0F1},
        {0x004000, FLASH_B0F2},
        {0x006000, FLASH_B0F3},
        {0x008000, FLASH_B0F4},
        {0x010000, FLASH_B0F5},
        {0x020000, FLASH_B0F6},
        {0x030000, FLASH_B0F7},
        {0x040000, ~0},
        {0x0C0000, FLASH_B1F0},
        {0x0C2000, FLASH_B1F1},
        {0x0C4000, ~0},
        {~0, ~0},
};

void Flash_Init(void)
{
        FLASH_Init();
        GPIO_Config(GPIO2, 0x001F, GPIO_AF_PP);
}

int IntFlash_Erase(u32 addr, u32 size)
{
        const struct flash_sector_info *p;
        u32 limit, mask;

        addr -= INT_FLASH_BASE;
        limit = addr + size;

        p = FlashSectorInfo;
        while(addr >= p[1].base)
                p++;
        mask = p->mask;
        while(limit > p[1].base)
                mask |= (++p)->mask;
        if(mask == ~0)
                return -1;

        FLASH_WritePrConfig(mask, DISABLE);
        FLASH_SectorErase(mask);

        return 0;
}

int IntFlash_Program(u32 addr, const void *buf, u32 size)
{
        const struct flash_sector_info *p;
        u32 limit, mask;

        addr -= INT_FLASH_BASE;
        limit = addr + size;

        p = FlashSectorInfo;
        while(addr >= p[1].base)
                p++;
        mask = p->mask;
        while(limit > p[1].base)
                mask |= (++p)->mask;
        if(mask == ~0)
                return -1;

        FLASH_WritePrConfig(mask, DISABLE);
        FLASH_SectorErase(mask);
        FLASH_BlockWrite((u32)buf, addr, size + 3 >> 2);

        return 0;
}

#define FLASH_DATA(n)   n   /*( (n) >> 0  & 0x8000 |   */       /* D15 -> D15 */
                            /*  (n) >> 1  & 0x2000 |   */       /* D14 -> D13 */
                            /*  (n) >> 2  & 0x0800 |   */       /* D13 -> D11 */
                            /*  (n) >> 3  & 0x0200 |   */       /* D12 -> D9  */
                            /*  (n) >> 4  & 0x0080 |   */       /* D11 -> D7  */
                            /*  (n) >> 5  & 0x0020 |   */       /* D10 -> D5  */
                            /*  (n) >> 6  & 0x0008 |   */       /* D9  -> D3  */
                            /*  (n) >> 7  & 0x0002 |   */       /* D8  -> D1  */
                            /*  (n) << 7  & 0x4000 |   */       /* D7  -> D14 */
                            /*  (n) << 6  & 0x1000 |   */       /* D6  -> D12 */
                            /*  (n) << 5  & 0x0400 |   */       /* D5  -> D10 */
                            /*  (n) << 4  & 0x0100 |   */       /* D4  -> D8  */
                            /*  (n) << 3  & 0x0040 |   */       /* D3  -> D6  */
                            /*  (n) << 2  & 0x0010 |   */       /* D2  -> D4  */
                            /*  (n) << 1  & 0x0004 |   */       /* D1  -> D2  */
                            /*  (n) << 0  & 0x0001 )   */       /* D0  -> D0  */

#define FLASH_ADDR(a)   ((vu16 *)(EXT_FLASH_BASE + ((a) << 1)))
#define FLASH_WRITE(addr, word) (*FLASH_ADDR(addr) = FLASH_DATA(word))

static void Check_Toggle_Ready(u32 addr)
{
        int TimeOut;
        int PreData = *FLASH_ADDR(addr) & FLASH_DATA(0x0040);
        for(TimeOut = 0; TimeOut < 0x07FFFFFF; TimeOut++)
        {
                int CurData = *FLASH_ADDR(addr) & FLASH_DATA(0x0040);
                if(PreData == CurData)
                        break;
                PreData = CurData;
        }
}

void ExtFlash_Command(u32 addr, u32 cmd)
{
        FLASH_WRITE(addr, cmd);
}

void ExtFlash_ChipErase(void)
{
        FLASH_WRITE(0x5555, 0xaaaa);
        FLASH_WRITE(0x2aaa, 0x5555);
        FLASH_WRITE(0x5555, 0x8080);

        FLASH_WRITE(0x5555, 0xaaaa);
        FLASH_WRITE(0x2aaa, 0x5555);
        FLASH_WRITE(0x5555, 0x1010);

        Check_Toggle_Ready(0);
}

int ExtFlash_SectorErase(u32 addr)
{
        addr = addr - EXT_FLASH_BASE >> 1;
        if(addr >= EXT_FLASH_SIZE)
                return -1;

        FLASH_WRITE(0x5555, 0xaaaa);
        FLASH_WRITE(0x2aaa, 0x5555);
        FLASH_WRITE(0x5555, 0x8080);

        FLASH_WRITE(0x5555, 0xaaaa);
        FLASH_WRITE(0x2aaa, 0x5555);
        FLASH_WRITE(addr, 0x3030);

        Check_Toggle_Ready(addr);

        return 0;
}

int ExtFlash_BlockErase(u32 addr)
{
        addr = addr - EXT_FLASH_BASE >> 1;
        if(addr >= EXT_FLASH_SIZE)
                return -1;

        FLASH_WRITE(0x5555, 0xaaaa);
        FLASH_WRITE(0x2aaa, 0x5555);
        FLASH_WRITE(0x5555, 0x8080);

        FLASH_WRITE(0x5555, 0xaaaa);
        FLASH_WRITE(0x2aaa, 0x5555);
        FLASH_WRITE(addr, 0x5050);

        Check_Toggle_Ready(addr);

        return 0;
}

int ExtFlash_WordWrite(u32 addr, u16 data)
{
        vu16 *ptr = (vu16 *)addr;

        addr = addr - EXT_FLASH_BASE >> 1;
        if(addr >= EXT_FLASH_SIZE)
                return -1;

        FLASH_WRITE(0x5555, 0xaaaa);
        FLASH_WRITE(0x2aaa, 0x5555);
        FLASH_WRITE(0x5555, 0xa0a0);

        *ptr = data;

        Check_Toggle_Ready(addr);

        return *ptr;
}

int ExtFlash_Program(u32 addr, const void *buf, u32 size)
{
        u32 i, limit = addr + size;

        if(addr < EXT_FLASH_BASE || limit >= EXT_FLASH_LIMIT)
                return -1;

        for(i = addr & ~(SECTOR_SIZE - 1); i < limit; i += SECTOR_SIZE)
                ExtFlash_SectorErase(i);
        for(i = addr; i < limit; i += 2)
        {
                int PreData, TimeOut;

                FLASH_WRITE(0x5555, 0xaaaa);
                FLASH_WRITE(0x2aaa, 0x5555);
                FLASH_WRITE(0x5555, 0xa0a0);

                *(vu16 *)i = *(u16 *)buf;

                PreData = *(vu16 *)i & FLASH_DATA(0x0040);
                for(TimeOut = 0; TimeOut < 0x07FFFFFF; TimeOut++)
                {
                        int CurData = *(vu16 *)i & FLASH_DATA(0x0040);
                        if(PreData == CurData)
                                break;
                        PreData = CurData;
                }
                buf = (u16 *)buf + 1;
        }
        return 0;
}

/*******************************************************************************
* Function Name  : FLASH_WriteBlock
* Description    : Writes Data To the Flash
* Input 1        : Address of the Data source
* Input 2        : Address of the Destination
* Input 3        : Nbr of words to be stored
* Return         : None
*******************************************************************************/
void FLASH_BlockWrite(u32 XsourceAdd, u32 XtargetAdd, u32 XdataLength)
{
  u32 TmpAddrS, TmpAddrD;
  u32 NbrW, NbrDW;
  u32 TmpData0, TmpData1;
  // Get The Source Address
  TmpAddrS = XsourceAdd;
  // Get The Destination Address
  TmpAddrD = XtargetAdd;
  // Get Number of Double Words
  NbrDW    = XdataLength >> 1;
  // Get Number of single Words
  NbrW     = XdataLength & 0x00000001;
  // Programming Double Words
  while (NbrDW > 0)
  {
    // Get The First 32 bits
    TmpData0 = *(u32 *)TmpAddrS;
    // Increment The Source Address
    TmpAddrS += 4;
    // Get The Second 32 bits
    TmpData1 = *(u32 *)TmpAddrS;
    // Increment The Source Address
    TmpAddrS += 4;
    // Use The FLASH_DWordWrite function to program the 64 bits
    FLASH_DWordWrite(TmpAddrD, TmpData0, TmpData1);
    // Decrease number of Double word
    NbrDW--;
    // Increment The destination Address
    TmpAddrD += 8;
    // Waits for the data to be programmed
    FLASH_Delay();
  }

  if (NbrW > 0)
  {
    // Get The First 32 bits
    TmpData1 = *(u32 *)TmpAddrS;
    // Use The FLASH_WordWrite function to program the 32 bits
    FLASH_WordWrite(TmpAddrD, TmpData1);
    // Waits for the data to be programmed
    FLASH_Delay();
  }
   FLASH_WaitForLastTask();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -