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

📄 lpc21isp.c

📁 NXP公司的arm系列芯片LPCXXXX的ISP烧写程序。
💻 C
📖 第 1 页 / 共 5 页
字号:

    FileLength = lseek(fd, 0L, 2);      // Get file size

    if(FileLength == (size_t)-1)
    {
        DebugPrintf( 1, "\nFileLength = -1 !?!\n");
        exit(1);
    }

    lseek(fd, 0L, 0);

    FileContent = malloc(FileLength);

    BinaryMemSize = FileLength * 2;

    IspEnvironment->BinaryLength = 0;   /* Increase length as needed.       */
    IspEnvironment->BinaryOffset = 0;
    IspEnvironment->StartAddress = 0;
    BinaryOffsetDefined = 0;

    IspEnvironment->BinaryContent = malloc(BinaryMemSize);

    read(fd, FileContent, FileLength);

    close(fd);

    DebugPrintf( 2, "File %s:\n\tloaded...\n", IspEnvironment->input_file);

        // Intel-Hex -> Binary Conversion

    if(IspEnvironment->FormatHex != 0)
    {
        unsigned char  RecordLength;
        unsigned short RecordAddress;
        unsigned long  RealAddress = 0;
        unsigned char  RecordType;
        unsigned char  Hexvalue;
        unsigned long  StartAddress;

        DebugPrintf( 3, "Converting file %s to binary format...\n", IspEnvironment->input_file);

        Pos = 0;
        while(Pos < FileLength)
        {
            if(FileContent[Pos] == '\r')
            {
                Pos++;
                continue;
            }

            if(FileContent[Pos] == '\n')
            {
                Pos++;
                continue;
            }

            if(FileContent[Pos] != ':')
            {
                DebugPrintf( 1, "Missing start of record (':') wrong byte %c / %02X\n", FileContent[Pos], FileContent[Pos]);
                exit(1);
            }

            Pos++;

            RecordLength   = Ascii2Hex(FileContent[Pos++]);
            RecordLength <<= 4;
            RecordLength  |= Ascii2Hex(FileContent[Pos++]);

            DebugPrintf( 4, "RecordLength = %02X\n", RecordLength);

            RecordAddress   = Ascii2Hex(FileContent[Pos++]);
            RecordAddress <<= 4;
            RecordAddress  |= Ascii2Hex(FileContent[Pos++]);
            RecordAddress <<= 4;
            RecordAddress  |= Ascii2Hex(FileContent[Pos++]);
            RecordAddress <<= 4;
            RecordAddress  |= Ascii2Hex(FileContent[Pos++]);

            DebugPrintf( 4, "RecordAddress = %04X\n", RecordAddress);

            RealAddress = RealAddress - (RealAddress & 0xffff) + RecordAddress;

            DebugPrintf( 4, "RealAddress = %08lX\n", RealAddress);

            RecordType      = Ascii2Hex(FileContent[Pos++]);
            RecordType    <<= 4;
            RecordType     |= Ascii2Hex(FileContent[Pos++]);

            DebugPrintf( 4, "RecordType = %02X\n", RecordType);

            if(RecordType == 0x00)          // 00 - Data record
            {
                /*
                 * Binary Offset is defined as soon as first data record read
                 */
                BinaryOffsetDefined = 1;
                     // Memory for binary file big enough ?
                while(RealAddress + RecordLength - IspEnvironment->BinaryOffset > BinaryMemSize)
                {
                    BinaryMemSize <<= 1;
                    IspEnvironment->BinaryContent = realloc(IspEnvironment->BinaryContent, BinaryMemSize);
                }

                    // We need to know, what the highest address is,
                    // how many bytes / sectors we must flash
                if(RealAddress + RecordLength - IspEnvironment->BinaryOffset > IspEnvironment->BinaryLength)
                {
                    IspEnvironment->BinaryLength = RealAddress + RecordLength - IspEnvironment->BinaryOffset;
                    DebugPrintf( 3, "Image size now: %ld\n", IspEnvironment->BinaryLength);
                }

                for(i = 0; i < RecordLength; i++)
                {
                    Hexvalue        = Ascii2Hex(FileContent[Pos++]);
                    Hexvalue      <<= 4;
                    Hexvalue       |= Ascii2Hex(FileContent[Pos++]);
                    IspEnvironment->BinaryContent[RealAddress + i - IspEnvironment->BinaryOffset] = Hexvalue;
                }
            }
            else if(RecordType == 0x01)     // 01 - End of file record
            {
                break;
            }
            else if(RecordType == 0x02)     // 02 - Extended segment address record
            {
                for(i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
                {
                    RealAddress <<= 4;
                    if(i == 0)
                    {
                        RealAddress  = Ascii2Hex(FileContent[Pos++]);
                    }
                    else
                    {
                        RealAddress |= Ascii2Hex(FileContent[Pos++]);
                    }
                }
                RealAddress <<= 4;
            }
            else if(RecordType == 0x03)     // 03 - Start segment address record
            {
                for(i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
                {
                    RealAddress <<= 4;
                    if(i == 0)
                    {
                        RealAddress  = Ascii2Hex(FileContent[Pos++]);
                    }
                    else
                    {
                        RealAddress |= Ascii2Hex(FileContent[Pos++]);
                    }
                }
                RealAddress <<= 8;
            }
            else if(RecordType == 0x04)     // 04 - Extended linear address record, used by IAR
            {
                for(i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
                {
                    RealAddress <<= 4;
                    if(i == 0)
                    {
                        RealAddress  = Ascii2Hex(FileContent[Pos++]);
                    }
                    else
                    {
                        RealAddress |= Ascii2Hex(FileContent[Pos++]);
                    }
                }
                RealAddress <<= 16;
                if(!BinaryOffsetDefined)
                {
                    // set startaddress of BinaryContent
                    // use of LPC_FLASHMASK to allow a memory range, not taking the first
                    // [04] record as actual start-address.
                    IspEnvironment->BinaryOffset = RealAddress & LPC_FLASHMASK;
                }
                else
                {
                    if((RealAddress & LPC_FLASHMASK) != IspEnvironment->BinaryOffset)
                    {
                        DebugPrintf(1, "New Extended Linear Address Record [04] out of memory range\n");
                        DebugPrintf(1, "Current Memory starts at: 0x%08X, new Address is: 0x%08X",
                                       IspEnvironment->BinaryOffset, RealAddress);
                        exit(1);
                    }
                }
            }
            else if(RecordType == 0x05)     // 05 - Start linear address record
            {
               StartAddress = 0;
               for(i = 0; i < RecordLength * 2; i++)   // double amount of nibbles
                {
                    StartAddress <<= 4;
                    if(i == 0)
                    {
                        StartAddress  = Ascii2Hex(FileContent[Pos++]);
                    }
                    else
                    {
                        StartAddress |= Ascii2Hex(FileContent[Pos++]);
                    }
                }
                DebugPrintf( 1,"Start Address = 0x%8X\n", StartAddress);
                IspEnvironment->StartAddress = StartAddress;
              }

            while(FileContent[Pos++] != 0x0a)      // Search till line end
            {
            }
        }

        DebugPrintf( 2, "\tconverted to binary format...\n");

            // When debugging is switched on, output result of conversion to file debugout.bin
        if(debug_level >= 4)
        {
            int fdout;
            fdout = open("debugout.bin", O_RDWR | O_BINARY | O_CREAT | O_TRUNC, 0777);
            write(fdout, IspEnvironment->BinaryContent, IspEnvironment->BinaryLength);
            close(fdout);
        }
    }
    else
    {
        memcpy(IspEnvironment->BinaryContent, FileContent, FileLength);

        IspEnvironment->BinaryLength = FileLength;
    }

    DebugPrintf( 2, "\timage size : %ld\n", IspEnvironment->BinaryLength);

        // check length to flash for correct alignment, can happen with broken ld-scripts
    if (IspEnvironment->BinaryLength % 4 != 0)
    {
        unsigned long NewBinaryLength = ((IspEnvironment->BinaryLength + 3)/4) * 4;

        DebugPrintf( 2, "Warning:  data not aligned to 32 bits, padded (length was %lX, now %lX)\n", IspEnvironment->BinaryLength, NewBinaryLength);

        IspEnvironment->BinaryLength = NewBinaryLength;
    }

}


#define ANALOG_DEVICES_SYNC_CHAR        ((BINARY)0x08)
#define ANALOG_DEVICES_SYNC_RESPONSE    ("ADuC")
#define ANALOG_DEVICES_SYNC_SIZE        (strlen( ANALOG_DEVICES_SYNC_RESPONSE))

typedef struct {
    BINARY product_id[15];
    BINARY version[3];
    BINARY reserved[4];
    BINARY terminator[2];
    } AD_SYNC_RESPONSE;

/***************************** AnalogDevicesSync ************************/
/**  Attempt to synchronize with an Analog Device ARM micro.  Sends a
backspace and reads back the microcontrollers response.  Performs
multiple retries. Exits the program on error, returns to caller in the
case of success.
*/
static void AnalogDevicesSync(ISP_ENVIRONMENT *IspEnvironment)
{
    BINARY sync;                        /* Holds sync command.          */
    AD_SYNC_RESPONSE response;          /* Response from micro.         */
    int sync_attempts;                  /* Number of retries.           */

        /*  Make sure we don't read garbage later instead of the        */
        /* response we expect from the micro.                           */
    ClearSerialPortBuffers(IspEnvironment);

    DebugPrintf( 2, "Synchronizing\n"); /* Progress report.             */

    sync = ANALOG_DEVICES_SYNC_CHAR;    /* Build up sync command.       */

        /*  Perform the actual sync attempt.  First send the sync       */
        /* character, the attempt to read back the response.  For the   */
        /* AD ARM micro this is a fixed length block.  If response is   */
        /* received attempt to validate it by comparing the first       */
        /* characters to those expected.  If the received block does    */
        /* not validate or is incomplete empty the serial buffer and    */
        /* retry.                                                       */
    for(sync_attempts = 0; sync_attempts < 5; sync_attempts++)
    {
        SendComPortBlock( IspEnvironment, &sync, 1);

        if( ReceiveComPortBlockComplete( IspEnvironment, &response, sizeof( response),
            500) == 0)
        {

            if( memcmp( response.product_id, ANALOG_DEVICES_SYNC_RESPONSE,
                ANALOG_DEVICES_SYNC_SIZE) == 0)
            {
                return;
            }
            else
            {
                DumpString( 3, &response, sizeof(response),
                    "Unexpected response to sync attempt ");
            }
        }
        else
        {
            DebugPrintf( 3, "No (or incomplete) answer on sync attempt\n");
        }

        ClearSerialPortBuffers(IspEnvironment);
    }

    DebugPrintf( 1, "No (or unacceptable) answer on sync attempt\n");
    exit(4);
}

typedef struct {
    char start1;
    char start2;
    BINARY bytes;
    char cmd;
    BINARY address_h;
    BINARY address_u;
    BINARY address_m;
    BINARY address_l;
    BINARY data[251];
    } AD_PACKET;

/**********

⌨️ 快捷键说明

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