📄 lpc21isp.c
字号:
/***************************** DebugPrintf ******************************//** Prints a debug string depending the current debug level. The higherthe debug level the more detail that will be printed. Each printhas an associated level, the higher the level the more detailed thedebugging information being sent.\param [in] level the debug level of the print statement, if the level is less than or equal to the current debug level it will be printed.\param [in] fmt a standard printf style format string.\param [in] ... the usual printf parameters.*/static void DebugPrintf( int level, const char *fmt, ...){ va_list ap; if( level <= debug_level) { va_start( ap, fmt); vprintf( fmt, ap); va_end( ap); fflush( stdout); }}/***************************** ReceiveComPort ***************************//** Receives a buffer from the open com port. Returns when the buffer isfilled, the numer of requested linefeeds has been received or the timeoutperiod has passed\param [in] ISPEnvironment.\param [out] Answer buffer to hold the bytes read from the serial port.\param [in] MaxSize the size of buffer pointed to by Answer.\param [out] RealSize pointer to a long that returns the amout of thebuffer that is actually used.\param [in] WantedNr0x0A the maximum number of linefeeds to accept beforereturning.\param [in] timeOutMilliseconds the maximum amount of time to wait beforereading with an incomplete buffer.*/static void ReceiveComPort( ISP_ENVIRONMENT *IspEnvironment, void *Ans, unsigned long MaxSize, unsigned long *RealSize, unsigned long WantedNr0x0A, unsigned timeOutMilliseconds){ unsigned long tmp_realsize; unsigned long nr_of_0x0A = 0; int eof = 0; unsigned long p; char *Answer; Answer = Ans; SerialTimeoutSet( IspEnvironment, timeOutMilliseconds); (*RealSize) = 0; do { ReceiveComPortBlock( IspEnvironment, Answer + (*RealSize), MaxSize - 1 - (*RealSize), &tmp_realsize); if(tmp_realsize != 0) { for(p = (*RealSize); p < (*RealSize) + tmp_realsize; p++) { if(Answer[p] == 0x0a) { nr_of_0x0A++; } else if(Answer[p] < 0) { eof = 1; } } } (*RealSize) += tmp_realsize; } while(((*RealSize) < MaxSize) && (SerialTimeoutCheck(IspEnvironment) == 0) && (nr_of_0x0A < WantedNr0x0A) && !eof); Answer[(*RealSize)] = 0; DumpString( 3, Answer, (*RealSize), "Answer(Length=%ld): ", (*RealSize));}#if !defined COMPILE_FOR_LPC21/***************************** ReceiveComPortBlockComplete **************//** Receives a fixed block from the open com port. Returns when theblock is completely filled or the timeout period has passed\param [out] block buffer to hold the bytes read from the serial port.\param [in] size the size of the buffer pointed to by block.\param [in] timeOut the maximum amount of time to wait before guvung up oncompleting the read.\return 0 if successful, non-zero otherwise.*/static int ReceiveComPortBlockComplete( ISP_ENVIRONMENT *IspEnvironment, void *block, size_t size, unsigned timeout){ unsigned long realsize = 0, read; char *result; result = block; SerialTimeoutSet( IspEnvironment, timeout); do { ReceiveComPortBlock( IspEnvironment, result + realsize, size - realsize, &read); realsize += read; } while((realsize < size) && (SerialTimeoutCheck(IspEnvironment) == 0)); DumpString( 3, result, realsize, "Answer(Length=%ld): ", realsize); if( realsize != size) { return 1; } return 0;}/***************************** ReadArguments ****************************//** Reads the command line arguments and parses it for the variousoptions. Uses the same arguments as main. Used to separate the commandline parsing from main and improve its readability. This should also makeit easier to modify the command line parsing in the future.\param [in] argc the number of arguments.\param [in] argv an array of pointers to the arguments.*/static void ReadArguments(ISP_ENVIRONMENT *IspEnvironment, int argc, char *argv[]){ int i; if(argc >= 5) { for(i = 1; i < argc - 4; i++) { if(stricmp(argv[i], "-bin") == 0) { IspEnvironment->FormatHex = 0; DebugPrintf( 3, "Binary format file input.\n"); } else if(stricmp(argv[i], "-hex") == 0) { IspEnvironment->FormatHex = 1; DebugPrintf( 3, "Hex format file input.\n"); } else if(stricmp(argv[i], "-term") == 0) { IspEnvironment->TerminalAfterUpload = 1; DebugPrintf( 3, "Invoke terminal after upload.\n"); } else if(stricmp(argv[i], "-termonly") == 0) { IspEnvironment->TerminalOnly = 1; DebugPrintf( 3, "Only provide terminal.\n"); } else if(stricmp(argv[i], "-detectonly") == 0) { IspEnvironment->DetectOnly = 1; DebugPrintf( 3, "Only detect LPC chip part id.\n"); } else if(stricmp(argv[i], "-debug") == 0) { debug_level = 4; DebugPrintf( 3, "Turn on debug.\n"); } else if(stricmp(argv[i], "-control") == 0) { IspEnvironment->ControlLines = 1; DebugPrintf( 3, "Use RTS/DTS to control target state.\n"); } else if(stricmp(argv[i], "-logfile") == 0) { IspEnvironment->LogFile = 1; DebugPrintf( 3, "Log terminal output.\n"); } else if( stricmp( argv[i], "-ADARM") == 0) { IspEnvironment->micro = ANALOG_DEVICES_ARM; DebugPrintf( 2, "Target: Analog Devices.\n"); } else if( stricmp( argv[i], "-PHILIPSARM") == 0) { IspEnvironment->micro = PHILIPS_ARM; DebugPrintf( 2, "Target: Philips.\n"); } else { DebugPrintf( 2, "Unknown command line option: \"%s\"\n", argv[i]); } } IspEnvironment->input_file = argv[argc - 4]; IspEnvironment->StringOscillator = argv[argc - 1]; IspEnvironment->serial_port = argv[argc - 3]; IspEnvironment->baud_rate = argv[argc - 2]; } if(argc < 5) { debug_level = (debug_level < 2) ? 2 : debug_level; } if(argc < 5) { DebugPrintf( 2, "\n"); DebugPrintf( 2, "Portable command line ISP for Philips LPC2000 family and \n"); DebugPrintf( 2, "Version 1.23 Analog Devices ADUC 70xx\n"); DebugPrintf( 2, "Compiled for %s: %s %s\n", COMPILED_FOR, __DATE__, __TIME__); DebugPrintf( 2, "Copyright (c) by Martin Maurer, 2003, 2004 Email: Martin.Maurer@clibb.de\n"); DebugPrintf( 2, "Portions Copyright (c) by Aeolus Development 2004\n"); DebugPrintf( 2, " http://www.aeolusdevelopment.com\n"); DebugPrintf( 2, "\n"); DebugPrintf( 1, "Syntax: lpc21isp [Options] file comport baudrate Oscillator_in_kHz\n\n"); DebugPrintf( 1, "Example: lpc21isp test.hex com1 115200 14746\n\n"); DebugPrintf( 1, "Options: -bin for uploading binary file\n"); DebugPrintf( 1, " -hex for uploading file in intel hex format (default)\n"); DebugPrintf( 1, " -term for starting terminal after upload\n"); DebugPrintf( 1, " -termonly for starting terminal without an upload\n"); DebugPrintf( 1, " -detectonly detect only used LPC chiptype (PHILIPSARM only)\n"); DebugPrintf( 1, " -debug for creating a lot of debug infos\n"); DebugPrintf( 1, " -control for controlling RS232 lines for easier booting\n"); DebugPrintf( 1, " (Reset = DTR, EnableBootLoader = RTS)\n"); DebugPrintf( 1, " -logfile for enabling logging of terminal output to lpc21isp.log\n"); DebugPrintf( 1, " -ADARM for downloading to an Analog Devices\n"); DebugPrintf( 1, " ARM microcontroller ADUC70xx\n"); DebugPrintf( 1, " -PHILIPSARM for downloading to a microcontroller from\n"); DebugPrintf( 1, " Philips LPC2000 family (default)\n"); exit(1); } if(IspEnvironment->micro == PHILIPS_ARM) { if (strlen(IspEnvironment->StringOscillator) > 5) { printf("Invalid crystal frequency %s",argv[argc - 1]); exit(1); } }}typedef enum{ PROGRAM_MODE, RUN_MODE} TARGET_MODE;/***************************** ResetTarget ******************************//** Resets the target leaving it in either download (program) mode orrun mode.\param [in] mode the mode to leave the target in.*/static void ResetTarget( ISP_ENVIRONMENT *IspEnvironment, TARGET_MODE mode){ if(IspEnvironment->ControlLines) { switch( mode) { /* Reset and jump to boot loader. */ case PROGRAM_MODE: ControlModemLines(IspEnvironment, 1, 1); Sleep(100); ClearSerialPortBuffers(IspEnvironment); Sleep(100); ControlModemLines(IspEnvironment, 0, 1); Sleep(100); // Clear the RTS line after having reset the micro // Needed for the "GO <Address> <Mode>" ISP command to work */ ControlModemLines(IspEnvironment, 0, 0); break; /* Reset and start uploaded program */ case RUN_MODE: ControlModemLines(IspEnvironment, 1, 0); Sleep(100); ClearSerialPortBuffers(IspEnvironment); Sleep(100); ControlModemLines(IspEnvironment, 0, 0); Sleep(100); break; } }}/***************************** LoadFile *********************************//** Loads the requested file to download into memory.\param [in] IspEnvironment structure containing input filename*/static void LoadFile(ISP_ENVIRONMENT *IspEnvironment){ int fd; int i; unsigned long Pos; unsigned long FileLength; BINARY *FileContent; /**< Used to store the content of a hex */ /* file before converting to binary. */ unsigned long BinaryMemSize; fd = open(IspEnvironment->input_file, O_RDONLY | O_BINARY); if(fd == -1) { DebugPrintf( 1, "Can't open file %s\n", IspEnvironment->input_file); exit(1); } 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->BinaryContent = malloc(BinaryMemSize); read(fd, FileContent, FileLength); close(fd); DebugPrintf( 2, "File %s loaded...\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; DebugPrintf( 2, "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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -