📄 lpc21isp.c
字号:
/** Erase the Analog Devices micro. We take the simple way out andjust erase the whole thing.*/static void AnalogDevicesErase(ISP_ENVIRONMENT *IspEnvironment){ BINARY pages; AD_PACKET packet; pages = 0; DebugPrintf( 2, "Erasing .. "); AnalogDevicesFormPacket( IspEnvironment, 'E', 1, 0, &pages, &packet); AnalogDevicesSendPacket( IspEnvironment, &packet); DebugPrintf( 2, "Erased\n");}#define AD_PACKET_SIZE (250)/***************************** AnalogDevicesWrite ***********************//** Write the program.\param [in] data the program to download to the micro.\param [in] address where to start placing the program.\param [in] bytes the size of the progrm to download.*/static void AnalogDevicesWrite( ISP_ENVIRONMENT *IspEnvironment, const void *data, long address, size_t bytes){ AD_PACKET packet; const BINARY *prog_data; DebugPrintf( 2, "Writing %d bytes ", bytes); prog_data = data; while( bytes > AD_PACKET_SIZE) { AnalogDevicesFormPacket( IspEnvironment, 'W', AD_PACKET_SIZE, address, prog_data, &packet); AnalogDevicesSendPacket( IspEnvironment, &packet); address += AD_PACKET_SIZE; prog_data += AD_PACKET_SIZE; bytes -= AD_PACKET_SIZE; DebugPrintf( 2, "."); } if( bytes > 0) { AnalogDevicesFormPacket( IspEnvironment, 'W', bytes, address, prog_data, &packet); AnalogDevicesSendPacket( IspEnvironment, &packet); DebugPrintf( 2, "."); }}/***************************** AnalogDevicesDownload ********************//** Perform the download into an Analog Devices micro. As a quick and * dirty hack against flash relocations at 0x80000 * \return 0 if ok, error code else * \ToDo: possible to implement the return value instead of calling * exit() in sub-functions */static int AnalogDevicesDownload(ISP_ENVIRONMENT *IspEnvironment){ AnalogDevicesSync(IspEnvironment); AnalogDevicesErase(IspEnvironment); if( IspEnvironment->BinaryLength > 0x80000) { DebugPrintf( 2, "Note: Flash remapped 0x80000 to 0.\n"); AnalogDevicesWrite( IspEnvironment, IspEnvironment->BinaryContent + 0x80000, 0, IspEnvironment->BinaryLength-0x80000); } else { AnalogDevicesWrite( IspEnvironment, IspEnvironment->BinaryContent, 0, IspEnvironment->BinaryLength); } return(0);}/* note -- need to rationalize timeouts, use define?similarly for the number of sync attempts*/#endif // !defined COMPILE_FOR_LPC21/***************************** Download *********************************//** Download the file from the internal memory image to the philips microcontroller. * This function is visible from outside if COMPILE_FOR_LPC21 */#if !defined COMPILE_FOR_LPC21static#endifint PhilipsDownload(ISP_ENVIRONMENT *IspEnvironment){ unsigned long realsize; char Answer[128]; char temp[128]; char *strippedAnswer, *endPtr; int strippedsize; int nQuestionMarks; int found; unsigned long Sector; unsigned long SectorLength; unsigned long SectorStart, SectorOffset; char tmpString[128]; char uuencode_table[64]; int Line; unsigned long tmpStringPos; unsigned long BlockOffset; unsigned long Block; unsigned long Pos; unsigned long CopyLength; int c,k=0,i; unsigned long ivt_CRC; // CRC over interrupt vector table unsigned long block_CRC; time_t tStartUpload, tDoneUpload; long WatchDogSeconds = 0; int WaitForWatchDog = 0; if(!IspEnvironment->DetectOnly) { // Build up uuencode table uuencode_table[0] = 0x60; // 0x20 is translated to 0x60 ! for(i = 1; i <= 64; i++) { uuencode_table[i] = (char)(0x20 + i); } // Patch 0x14, otherwise it is not running and jumps to boot mode ivt_CRC = 0; /* Clear the vector at 0x14 so it doesn't affect the checksum: */ for(i = 0; i < 4; i++) { IspEnvironment->BinaryContent[i + 0x14] = 0; } /* Calculate a native checksum of the little endian vector table: */ for(i = 0; i < (4 * 8);) { ivt_CRC += IspEnvironment->BinaryContent[i++]; ivt_CRC += IspEnvironment->BinaryContent[i++] << 8; ivt_CRC += IspEnvironment->BinaryContent[i++] << 16; ivt_CRC += IspEnvironment->BinaryContent[i++] << 24; } /* Negate the result and place in the vector at 0x14 as little endian * again. The resulting vector table should checksum to 0. */ ivt_CRC = (unsigned long)-ivt_CRC; for(i = 0; i < 4; i++) { IspEnvironment->BinaryContent[i + 0x14] = (unsigned char)(ivt_CRC >> (8 * i)); } DebugPrintf( 3, "Position 0x14 patched: ivt_CRC = 0x%08lX\n", ivt_CRC); } DebugPrintf( 2, "Synchronizing\n"); for(nQuestionMarks = found = 0; !found && nQuestionMarks < 100; nQuestionMarks++) { SendComPort( IspEnvironment, "?"); memset(Answer,0,sizeof(Answer)); ReceiveComPort( IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,100); strippedAnswer = Answer; strippedsize = realsize; while((strippedsize > 0) && ((*strippedAnswer == '?') || (*strippedAnswer == 0))) { strippedAnswer++; strippedsize--; } DumpString( 3, strippedAnswer, strippedsize, "StrippedAnswer(Length=%ld): '", strippedsize); if(strcmp(strippedAnswer, "Bootloader\r\n") == 0 && IspEnvironment->TerminalOnly == 0) { long chars, xtal; unsigned long ticks; chars = (17 * IspEnvironment->BinaryLength + 1) / 10; WatchDogSeconds = (10 * chars + 5) / atol(IspEnvironment->baud_rate) + 10; xtal = atol(IspEnvironment->StringOscillator) * 1000; ticks = (unsigned long)WatchDogSeconds * ((xtal + 15) / 16); DebugPrintf( 2, "Entering ISP; re-synchronizing (watchdog = %ld seconds)\n", WatchDogSeconds); sprintf(temp, "T %lu\r\n", ticks); SendComPort( IspEnvironment, temp); ReceiveComPort( IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 1,100); if(strcmp(Answer, "OK\r\n") != 0) { printf("No answer on 'watchdog timer set'\n"); return(4); } SendComPort( IspEnvironment, "G 10356\r\n"); Sleep(200); nQuestionMarks = 0; WaitForWatchDog = 1; continue; } tStartUpload = time(NULL); if(strcmp(strippedAnswer, "Synchronized\r\n") == 0) { found = 1; }#if !defined COMPILE_FOR_LPC21 else { ResetTarget(IspEnvironment, PROGRAM_MODE ); }#endif } if(!found) { DebugPrintf( 1, "No answer on '?'\n"); return(4); } DebugPrintf( 3, "Synchronized 0\n"); SendComPort( IspEnvironment, "Synchronized\r\n"); ReceiveComPort( IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,1000); if(strcmp(Answer, "Synchronized\r\nOK\r\n") != 0) { printf("No answer on 'Synchronized'\n"); return(4); } DebugPrintf( 3, "Synchronized 1\n"); DebugPrintf( 2, "Setting oscillator\n"); sprintf( temp, "%s\r\n", IspEnvironment->StringOscillator); SendComPort( IspEnvironment, temp); ReceiveComPort( IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,1000); sprintf( temp, "%s\r\nOK\r\n", IspEnvironment->StringOscillator); if(strcmp(Answer, temp) != 0) { DebugPrintf( 1, "No answer on Oscillator-Command\n"); return(4); } DebugPrintf( 2, "Unlock\n"); SendComPort( IspEnvironment, "U 23130\r\n"); ReceiveComPort( IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000); if(strcmp(Answer, "U 23130\r\n0\r\n") != 0) { DebugPrintf( 1, "Unlock-Command:\n"); PhilipsOutputErrorMessage(GetErrorNumber(Answer)); return(4); } DebugPrintf( 2, "Read bootcode version: "); SendComPort( IspEnvironment, "K\r\n"); ReceiveComPort( IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 4,5000); if(strncmp(Answer, "K\r\n", 3) != 0) { DebugPrintf( 1, "no answer on Read Boot Code Version\n"); return(4); } if(strncmp(Answer, "K\r\n0\r\n", 6) == 0) { int maj, min, build; strippedAnswer = Answer + 6; if (sscanf(strippedAnswer, "%d %d %d", &build, &min, &maj) == 2) { maj = min; min = build; build = 0; } /* if */ DebugPrintf( 2, "%d.%d.%d\n", maj, min, build); } else { DebugPrintf( 2, "unknown\n"); } DebugPrintf( 2, "Read part ID: "); SendComPort( IspEnvironment, "J\r\n"); ReceiveComPort( IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 3,5000); if(strncmp(Answer, "J\r\n", 3) != 0) { DebugPrintf( 1, "no answer on Read Part Id\n"); return(4); } strippedAnswer = (strncmp(Answer, "J\r\n0\r\n", 6) == 0) ? Answer + 6 : Answer; Pos = strtoul(strippedAnswer, &endPtr, 10); *endPtr = '\0'; /* delete \r\n */ for (i = sizeof LPCtypes / sizeof LPCtypes[0] - 1; i > 0 && LPCtypes[i].id != Pos; i--) /* nothing */; IspEnvironment->DetectedDevice = i; if (IspEnvironment->DetectedDevice == 0) DebugPrintf( 2, "unknown"); else DebugPrintf( 2, "LPC%d, %d kiB ROM / %d kiB SRAM", LPCtypes[IspEnvironment->DetectedDevice].Product, LPCtypes[IspEnvironment->DetectedDevice].FlashSize, LPCtypes[IspEnvironment->DetectedDevice].RAMSize); DebugPrintf( 2, " (%s)\n", strippedAnswer); if (IspEnvironment->DetectOnly) return(0); for(SectorStart = Sector = 0; ; SectorStart += LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector++]) { if (Sector >= LPCtypes[IspEnvironment->DetectedDevice].FlashSectors) { DebugPrintf( 1, "Programm too large; running out of Flash sectors.\n"); return(4); } DebugPrintf( 3, "Writing Sector %ld: ", Sector); fflush(stdout); sprintf(tmpString, "P %ld %ld\r\n", Sector, Sector); SendComPort( IspEnvironment, tmpString); ReceiveComPort( IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000); sprintf(tmpString, "P %ld %ld\r\n0\r\n", Sector, Sector); if(strcmp(Answer, tmpString) != 0) { DebugPrintf( 1, "Wrong answer on Prepare-Command (1) (Sector %ld)\n", Sector); PhilipsOutputErrorMessage(GetErrorNumber(Answer)); return(4); } DebugPrintf( 2, "."); fflush(stdout); sprintf(tmpString, "E %ld %ld\r\n", Sector, Sector); SendComPort( IspEnvironment, tmpString); ReceiveComPort( IspEnvironment, Answer, sizeof(Answer)-1, &realsize, 2,5000); sprintf(tmpString, "E %ld %ld\r\n0\r\n", Sector, Sector); if(strcmp(Answer, tmpString) != 0) { DebugPrintf( 1, "Wrong answer on Erase-Command (Sector %ld)\n", Sector); PhilipsOutputErrorMessage(GetErrorNumber(Answer)); return(4); } DebugPrintf( 2, "."); fflush(stdout); SectorLength = LPCtypes[IspEnvironment->DetectedDevice].SectorTable[Sector]; if(SectorLength > IspEnvironment->BinaryLength - SectorStart) { SectorLength = IspEnvironment->BinaryLength - SectorStart; } // Write multiple of 45 * 4 Byte blocks to RAM, but copy maximum of on sector to Flash // In worst case we transfer up to 180 byte to much to RAM // but then we can always use full 45 byte blocks an
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -