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

📄 flash.c

📁 vt6528芯片交换机API函数和文档运行程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    u16Tmp = *pu16OpC;
    u16FlshID = ((UINT8)ftohs(u16Tmp)) << 8;
    // read device id
    pu16OpC++;
    u16Tmp = *pu16OpC;
    u16FlshID |= ((UINT8)ftohs(u16Tmp));

    // exit autoselect mode
    *pu16OpC = htofs(0x00F0);

    INTR_vCriticalSectionLeave();

    DBG_PRN_FLSH(" FLSH: AMDid=[%04X]", u16FlshID);
    return u16FlshID;
}


static UINT16 s_u16ReadSstId (UINT32 u32Addr)
{
    volatile UINT8  *pbyOpA, *pbyOpB, *pbyOpC;
    UINT16  u16FlshID;


    u32Addr |= ASIC_NON_CACHE_ADDR;          // For non-cache access
    u16FlshID = 0;

    // SST read manufacturer id procedure
    pbyOpA = (PUINT8)((u32Addr & 0xFFFF0000) | 0x5555);
    pbyOpB = (PUINT8)((u32Addr & 0xFFFF0000) | 0x2AAA);
    pbyOpC = (PUINT8)(u32Addr & 0xFFF80000);

    // protect flash erase/program address sequence from being interrupted
    INTR_vCriticalSectionEnter();
    // enter product identifier mode
    *pbyOpA = 0xAA;
    *pbyOpB = 0x55;
    *pbyOpA = 0x90;
    // read manufacturer id
    SOC_vDelayPoll(5);
    u16FlshID = (*pbyOpC) << 8;
    // read device id
    pbyOpC++;
    u16FlshID |= (*pbyOpC);
    // exit product identifier mode
    *pbyOpC = 0xF0;
    SOC_vDelayPoll(5);
    INTR_vCriticalSectionLeave();

    DBG_PRN_FLSH(" FLSH: SSTid=[%04X]", u16FlshID);
    return u16FlshID;
}


static void s_vConfigFlshIdAndBase (UINT32 u32Addr)
{
    // try AMD read manufacturer and device id procedure

    sg_wFlshID = s_u16ReadAmdId(u32Addr);

    if (sg_wFlshID == AMD_MANU_ID) {
        // if ROM0 is AMD
        if (s_u16ReadAmdId(ASIC_ROM_BASE_ADDR) == AMD_MANU_ID)
            sg_u32FlshBase = ASIC_ROM_BASE_ADDR;
        else
            sg_u32FlshBase = ASIC_ROM_BASE_ADDR + ASIC_ROM_0_SIZE;
    }
    else {
        sg_wFlshID = s_u16ReadSstId(u32Addr);
        sg_u32FlshBase = ASIC_ROM_BASE_ADDR;
    }

    sg_u32FlshBase |= ASIC_NON_CACHE_ADDR;
}


static void s_vEraseSect (UINT32 u32SectAddr)
{
    volatile UINT8  *pbyOpA, *pbyOpB, *pbyOpC;
    volatile UINT16 *pu16OpA, *pu16OpB, *pu16OpC;
    UINT8   byTmp1 = 0, byTmp2 = 0;
    UINT16  u16Tmp;


    if (sg_wFlshID == AMD_MANU_ID) {

        pu16OpA = (PUINT16)(sg_u32FlshBase | (0x555 << 1));
        pu16OpB = (PUINT16)(sg_u32FlshBase | (0x2AA << 1));
        pu16OpC = (PUINT16)u32SectAddr;

        *pu16OpA = htofs(0x00AA);
        *pu16OpB = htofs(0x0055);
        *pu16OpA = htofs(0x0080);
        *pu16OpA = htofs(0x00AA);
        *pu16OpB = htofs(0x0055);
        *pu16OpC = htofs(0x0030);

        // check toggle bit
        do {
            u16Tmp = *pu16OpC;
            byTmp1 = (UINT8)ftohs(u16Tmp);
            u16Tmp = *pu16OpC;
            byTmp2 = (UINT8)ftohs(u16Tmp);
            byTmp1 ^= byTmp2;
        } while (byTmp1 & 0x40);
    }
    else if (sg_wFlshID == SST_MANU_ID) {

        pbyOpA = (PUINT8)(sg_u32FlshBase | 0x5555);
        pbyOpB = (PUINT8)(sg_u32FlshBase | 0x2AAA);
        pbyOpC = (PUINT8)u32SectAddr;

        *pbyOpA = 0xAA;
        *pbyOpB = 0x55;
        *pbyOpA = 0x80;
        *pbyOpA = 0xAA;
        *pbyOpB = 0x55;
        *pbyOpC = 0x30;

        // check toggle bit
        do {
            byTmp1 = *pbyOpC;
            byTmp2 = *pbyOpC;
            byTmp1 ^= byTmp2;
        } while (byTmp1 & 0x40);
    }
}


static void s_vProgramSect (UINT32 u32SectAddr, UINT32 u32SectSize, BOOL bEndianConvt)
{
    volatile UINT8  *pbyOpA, *pbyOpB, *pbyOpC;
    volatile UINT16 *pu16OpA, *pu16OpB, *pu16OpC;
    UINT8   byTmp1 = 0, byTmp2 = 0;
    UINT16  u16Index = 0;
    UINT16  u16Tmp;


    if (sg_wFlshID == AMD_MANU_ID) {

        pu16OpA = (PUINT16)(sg_u32FlshBase | (0x555 << 1));
        pu16OpB = (PUINT16)(sg_u32FlshBase | (0x2AA << 1));
        pu16OpC = (PUINT16)u32SectAddr;

        // enter unlock bypass mode
        *pu16OpA = htofs(0x00AA);
        *pu16OpB = htofs(0x0055);
        *pu16OpA = htofs(0x0020);

        for (u16Index = 0; u16Index < (u32SectSize / 2); u16Index++) {
            // unlock bypass program
            *pu16OpA = htofs(0x00A0);
            u16Tmp = *(((PUINT16)sg_abyBuf) + u16Index);
            if (bEndianConvt)
                u16Tmp = REV_WORD(u16Tmp);
            pu16OpC[u16Index] = u16Tmp;

            // check toggle bit
            do {
                u16Tmp = *pu16OpC;
                byTmp1 = (UINT8)ftohs(u16Tmp);
                u16Tmp = *pu16OpC;
                byTmp2 = (UINT8)ftohs(u16Tmp);
                byTmp1 ^= byTmp2;
            } while (byTmp1 & 0x40);
        }

        // exit unlock bypass mode
        *pu16OpA = htofs(0x0090);
        *pu16OpA = htofs(0x0000);
    }
    else if (sg_wFlshID == SST_MANU_ID) {

        pbyOpA = (PUINT8)(sg_u32FlshBase | 0x5555);
        pbyOpB = (PUINT8)(sg_u32FlshBase | 0x2AAA);
        pbyOpC = (PUINT8)u32SectAddr;


        for (u16Index = 0; u16Index < u32SectSize; u16Index++) {
            *pbyOpA = 0xAA;
            *pbyOpB = 0x55;
            *pbyOpA = 0xA0;
            pbyOpC[u16Index] = sg_abyBuf[u16Index];

            // check toggle bit
            do {
                byTmp1 = *pbyOpC;
                byTmp2 = *pbyOpC;
                byTmp1 ^= byTmp2;
            } while (byTmp1 & 0x40);
        }
    }
}


static BOOL s_bVerifyBlock (UINT32 u32Addr, PUINT8 pu8Data, UINT32 u32BlockSize, BOOL bEndianConvt)
{
    UINT32  u32Idx;


    u32Addr |= ASIC_NON_CACHE_ADDR;          // For non-cache access

    if (bEndianConvt) {
        for (u32Idx = 0; u32Idx < u32BlockSize; u32Idx += 2) {
            if ((*(PUINT16)(u32Addr + u32Idx)) != REV_WORD(*(PUINT16)(pu8Data + u32Idx)))
                return FALSE;
        }
    }
    else {
        for (u32Idx = 0; u32Idx < u32BlockSize; u32Idx++) {
            if ((*(PUINT8)(u32Addr + u32Idx)) != *(pu8Data + u32Idx)) {
                DBG_PRN_FLSH(" FLSH: [%04X]!=[%04X]", *(PUINT8)(u32Addr + u32Idx), *(pu8Data + u32Idx));
                return FALSE;
            }
        }
    }
    return TRUE;
}


//
// Sector Erase operation
//
void FLSH_vEraseSect (UINT32 u32SectAddr)
{
    u32SectAddr |= ASIC_NON_CACHE_ADDR;      // For non-cache access

    s_vConfigFlshIdAndBase(u32SectAddr);

    // protect flash erase/program address sequence from being interrupted
    INTR_vCriticalSectionEnter();
    s_vEraseSect(u32SectAddr);
    INTR_vCriticalSectionLeave();
}


//
// Sector Program operation
//
void FLSH_vProgramSect (UINT32 u32SectAddr, UINT32 u32SectSize)
{
    u32SectAddr |= ASIC_NON_CACHE_ADDR;      // For non-cache access

    s_vConfigFlshIdAndBase(u32SectAddr);

    // protect flash erase/program address sequence from being interrupted
    INTR_vCriticalSectionEnter();
    s_vProgramSect(u32SectAddr, u32SectSize, FALSE);
    INTR_vCriticalSectionLeave();
}


BOOL FLSH_bUpdateChksum (UINT32 u32StartAddr, UINT32 u32EndAddr)
{
    UINT32  u32ChkSum = 0;
    UINT16  u16ChkSum;
    UINT16  u16TmpBuf;
    UINT32  uu;
    UINT32  u32Size = u32EndAddr - u32StartAddr;


    // if not 2-byte alignment, error
    if ((u32Size % 2) != 0)
        return FALSE;

    for (uu = 0; uu < (u32Size / 2); uu++) {
        FLSH_bReadBlock(u32StartAddr + uu * 2, (PUINT8)&u16TmpBuf, 2);
        u32ChkSum += u16TmpBuf;
    }
    u16ChkSum = ((UINT16)u32ChkSum) + ((UINT16)(u32ChkSum >> 16));
    u16ChkSum = ~u16ChkSum;

    if (!FLSH_bWriteBlock(u32EndAddr, (PUINT8)(&u16ChkSum), 2, FALSE))
        return FALSE;

    return TRUE;
}


⌨️ 快捷键说明

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