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

📄 ezusb_lib.c

📁 WinDriver Cypress USB 偵錯程式 for Wince 5.0
💻 C
字号:
/**************************************************************
 * File - ezusb_lib.c
 *
 * Library for accessing EZ-USB devices.
 * The library accesses the hardware via WinDriver functions.
 *
 * Copyright (c) 2003 - 2006 Jungo Ltd.  http://www.jungo.com
 **************************************************************/

#include <stdio.h>
#include "wdu_lib.h"
#include "status_strings.h"
#include "utils.h"
#include "ezusb_lib.h"
/* Implementation of the Firmware download starts here. */
#include "Vend_Ax.h"

#if !defined(ERR)
#define ERR printf
#endif
#if !defined(TRACE)
#define TRACE printf
#endif

#define MAX_FILE_SIZE 1024 * 8
#define TGT_IMG_SIZE 0x10000 /* 64KB (65,536 Byte) target image */
#define TGT_SEG_SIZE 16 /* 16 byte segments */
#define DEFAULT_TIMEOUT 10000

static BYTE BlkBuf[MAX_FILE_SIZE];
static BYTE VenBuf[MAX_FILE_SIZE];
static DWORD Offset, Len;
char sInfoString[4000];

typedef struct
{
    DWORD TAddr; /* Target Address */
    DWORD HAddr; /* Host Address */
    DWORD Size; /* block size */
    DWORD Stat; /* status */
    PCHAR pData; /* data bytes */
} MemSeg;

typedef struct
{
    CHAR data[TGT_IMG_SIZE]; /* target image store */
} TMemImg;

typedef struct
{
    TMemImg *pImg;
    int nSeg; /* segment count */
    MemSeg pSeg[TGT_IMG_SIZE/TGT_SEG_SIZE]; /* info about segments */
} TMemCache;

static int FileToString(TMemCache* pMemCache, CHAR *pHexFileName);
static BOOL DownloadIntelHex(HANDLE hDev, BOOL IsFx2);
static BOOL DownLoadBuf(HANDLE hDev, DWORD address, DWORD length, void *buffer,
    BYTE bRequest);
static DWORD ResetBit(HANDLE hDev, int DoReset, BOOL IsFx2);

BOOL DownloadFirmware(HANDLE hDev, PCHAR pHexFileName, BOOL IsFx2)
{
    BYTE *pbuf = BlkBuf;
    BYTE *pVenbuf = VenBuf;
    TMemCache *pMemCache;
    DWORD dwNumRead;
    BOOL rc = FALSE;
    int i;

    sInfoString[0] = '\0';

    pMemCache = (TMemCache *)malloc(sizeof(TMemCache));
    if (!pMemCache)
    {
        sprintf(sInfoString, "DownloadFirmware: Insufficient resources\n");
        goto Exit;
    }
    pMemCache->pImg = (TMemImg *)malloc(TGT_IMG_SIZE);
    if (!pMemCache->pImg)
    {
        sprintf(sInfoString, "DownloadFirmware: Insufficient resources\n");
        goto Exit;
    }

    dwNumRead = FileToString(pMemCache, pHexFileName);

    if (!dwNumRead)
        goto Exit;

    /* check for high mem first, load loader first if necessary */
    for (i=0; i<pMemCache->nSeg; i++)
    {
        if (pMemCache->pSeg[i].TAddr >= 0x2000)
        {
            if (!DownloadIntelHex(hDev, IsFx2))
                goto Exit;
            break;
        }
    }

    /* load all high mem first */
    for (i=0; i<pMemCache->nSeg; i++)
    {
        if (pMemCache->pSeg[i].TAddr >= 0x2000)
        {
            memcpy(pVenbuf, pMemCache->pSeg[i].pData, pMemCache->pSeg[i].Size);
            if (!DownLoadBuf(hDev, pMemCache->pSeg[i].TAddr,
                pMemCache->pSeg[i].Size, pVenbuf, 0xA3))
            {
                goto Exit;
            }
        }
    }

    ResetBit(hDev, 1, IsFx2);

    /* load all low mem last */
    for (i=0; i<pMemCache->nSeg; i++)
    {
        if (pMemCache->pSeg[i].TAddr < 0x2000)
        {
            memcpy(pbuf, pMemCache->pSeg[i].pData, pMemCache->pSeg[i].Size);
            Len = pMemCache->pSeg[i].Size;
            Offset = pMemCache->pSeg[i].TAddr;
            if (!DownLoadBuf(hDev, Offset, Len, pbuf, 0xA0))
                goto Exit;
        }
    }

    ResetBit(hDev, 0, IsFx2);

    rc = TRUE;
Exit:

    if (pMemCache)
    {
        if (pMemCache->pImg)
            free(pMemCache->pImg);
        free(pMemCache);
    }
    return rc;
}

#define MAXSTR 256 /* Maximum length of Intel Hex file string */
/* 4K Control EP0 transfer limit imposed by OS */
#define MAX_EP0_XFER_SIZE (1024*4)

static int FileToString(TMemCache* pMemCache, CHAR *pHexFileName)
{
    FILE *fp;
    int i, curSeg, recType, cnt;
    int CNTFIELD, ADDRFIELD, RECFIELD, DATAFIELD;
    CHAR str[MAXSTR];
    DWORD byte, addr, totalRead;
    PCHAR ptr;

    fp = fopen(pHexFileName, "rb");
    if (!fp)
    {
        sprintf(sInfoString, "Can't open %s file.\n"
            "Please make sure that the file exists in the specified location\n",
            pHexFileName);
        return 0;
    }

    /* offsets of fields within record -- may change later due to "spaces" 
     * setting */
    CNTFIELD = 1;
    ADDRFIELD = 3;
    RECFIELD = 7;
    DATAFIELD = 9;

    addr = 0;
    curSeg = 0;
    totalRead = 0;
    pMemCache->nSeg = 0;

    while (fgets(str, MAXSTR, fp))
    {
        if (str[0]!=':')
            return 0;

        if (str[1]==' ') /* get the record type */
        {
            CNTFIELD = 1 + 1;
            ADDRFIELD = 3 + 2;
            RECFIELD = 7 + 3;
            DATAFIELD = 9 + 4;
        }

        sscanf(str+RECFIELD, "%2x", &recType);

        ptr = (PCHAR)pMemCache->pImg;
        switch(recType)
        {
            case 2: /* seg record */
                sscanf(str+DATAFIELD, "%4x", &curSeg);
                curSeg *= 0x10;
                break;

            case 0: /* data record */
                sscanf(str+CNTFIELD, "%2x", &cnt);
                sscanf(str+ADDRFIELD, "%4lx", &addr);
                if (addr>=TGT_IMG_SIZE)
                {
                    sprintf(sInfoString, "Error loading file: address out of "
                        "range\n");
                    return 0;
                }
                ptr += addr; /* get pointer to location in image */

                if (pMemCache->nSeg &&
                   (pMemCache->pSeg[pMemCache->nSeg-1].TAddr ==
                        addr - pMemCache->pSeg[pMemCache->nSeg-1].Size) &&
                   (pMemCache->pSeg[pMemCache->nSeg-1].Size + cnt <=
                        MAX_EP0_XFER_SIZE))
                {
                    /* if the segment is contiguous to the last segment, 
                     * and it's not too big yet append to previous segment */
                    pMemCache->pSeg[pMemCache->nSeg-1].Size += cnt;
                }
                else
                {
                    /* start a new segment */
                    pMemCache->pSeg[pMemCache->nSeg].TAddr = addr;
                    pMemCache->pSeg[pMemCache->nSeg].Size = cnt;
                    pMemCache->pSeg[pMemCache->nSeg].pData = ptr;
                    pMemCache->nSeg++;
                }

                for (i=0; i<cnt; i++)
                {
                    sscanf(str+DATAFIELD+i*2, "%2lx", &byte);
                    *(ptr + i) = (CHAR)byte;
                    totalRead++;
                }
                break;

            case 1: /* end record */
                fclose(fp);
                return totalRead;
            default:
                break;
        }
    }

    if (fp)
        fclose(fp);

    return 0; /* missing end record */
}

static BOOL DownloadIntelHex(HANDLE hDev, BOOL IsFx2)
{
    BYTE* pbuf = BlkBuf;
    BYTE* ptmp = NULL;
    PINTEL_HEX_RECORD ptr = IsFx2 ? Vend_Ax_Fx2 : Vend_Ax;

    ResetBit(hDev, 1, IsFx2);

    while (ptr->Type==0)  /* load low mem */
    {
        if (ptmp &&   /* continue a segment */
            Offset+Len==(DWORD)ptr->Address &&
            Len+ptr->Length<=MAX_EP0_XFER_SIZE)
        {
            memcpy(ptmp, ptr->Data, ptr->Length);
            Len += ptr->Length;
            ptmp += ptr->Length;
        }
        else  /* start a new segment */
        {
            if (ptmp)  /* send previous segment first */
            {
                if (!DownLoadBuf(hDev, Offset, Len, pbuf, 0xA0))
                    return FALSE;
            }
            ptmp = pbuf;
            memcpy(ptmp, ptr->Data, ptr->Length);
            Len = ptr->Length;
            Offset = ptr->Address;
            ptmp += ptr->Length;
        }
        ptr++;
    }

    if (ptmp) /* send final segment */
    {
        if (!DownLoadBuf(hDev, Offset, Len, pbuf, 0xA0))
            return FALSE;
    }

    ResetBit(hDev, 0, IsFx2);
    return TRUE;
}

/* The download will be split into CHUNK_SIZE pieces and downloaded with 
 * multiple setup transfers. CHUNK_SIZE should not exceed 64 bytes, as larger
 * transfers can result in data corruption when other USB devices are 
 * present. */
#define CHUNK_SIZE 64

static BOOL DownLoadBuf(HANDLE hDev, DWORD address, DWORD length, void *buffer,
    BYTE bRequest)
{
    BYTE SetupPacket[8];
    DWORD dwBytesTransferred, i, size, chunkCount;
    DWORD dwStatus = 0, dwOptions = 0;
    void  *cur;

    chunkCount = (length + CHUNK_SIZE - 1) / CHUNK_SIZE;
    for (i=0; i<chunkCount; i++)
    {
        if (i==chunkCount-1 && length % CHUNK_SIZE)
            size = length % CHUNK_SIZE;
        else
            size = CHUNK_SIZE;

        SetupPacket[0] = 0x40;
        SetupPacket[1] = bRequest;
        SetupPacket[2] = (BYTE)((address + i*CHUNK_SIZE) & 0xFF);
        SetupPacket[3] = (BYTE)(((address + i*CHUNK_SIZE) & 0xFF00) >> 8);
        SetupPacket[4] = 0;
        SetupPacket[5] = 0;
        SetupPacket[6] = (BYTE) size & 0xFF;
        SetupPacket[7] = (BYTE) ((size & 0xFF00) >> 8);
        cur = (PVOID)((DWORD)buffer + i*CHUNK_SIZE);
        dwStatus = WDU_TransferDefaultPipe(hDev, FALSE, dwOptions, cur, size,
            &dwBytesTransferred, SetupPacket, DEFAULT_TIMEOUT);
    }
    if (dwStatus)
    {
        sprintf(sInfoString, "DownLoadBuf: WDU_TransferDefaultPipe failed with status 0x%lx - %s\n",
            dwStatus, Stat2Str(dwStatus));
        return FALSE;
    }
    return TRUE;
}

#define CPUCS_REG_EZUSB    0x7F92
#define CPUCS_REG_FX2      0xE600

static DWORD ResetBit(HANDLE hDev, int DoReset, BOOL IsFx2)
{
    BYTE reset = (BYTE)DoReset;
    BYTE SetupPacket[8];
    DWORD dwBytesTransferred;
    DWORD dwCpucs = IsFx2 ? CPUCS_REG_FX2 : CPUCS_REG_EZUSB;
    sInfoString[0] = '\0';

    SetupPacket[0] = 0x40;
    SetupPacket[1] = 0xA0;
    SetupPacket[2] = (BYTE)(dwCpucs & 0xFF);
    SetupPacket[3] = (BYTE)((dwCpucs & 0xFF00) >> 8);
    SetupPacket[4] = 0;
    SetupPacket[5] = 0;
    SetupPacket[6] = 1;
    SetupPacket[7] = 0;

    return WDU_TransferDefaultPipe(hDev, FALSE, 0, &reset, 1,
        &dwBytesTransferred, SetupPacket, DEFAULT_TIMEOUT);
}

⌨️ 快捷键说明

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