/* * @brief Edit the bootloader state words (subnet and bootloader state) * @param state The value of the bootloader state * @return void */ void writeBootloaderState(unsigned long state) { uint32 tempBootloaderSubnet = bootloaderSubnet; // address of the last word (4 bytes) of state flash = 0x0003FFFC // address of last 1kb block = 0x0003FC00 FlashErase(BL_STATE_BLOCK_ADDRESS); FlashProgram(&state, BL_STATE_WORD_ADDRESS, sizeof(uint32)); // address of the second to the last word in state flash FlashProgram(&tempBootloaderSubnet, BL_STATE_SUBNET_ADDRESS, sizeof(uint32)); }
bool Persistent::setPageActive(uint8_t* ptr) { uint32_t data = 0; if (FlashProgram(&data, (uint32_t) ptr, 4)) return false; _pageActive = ptr; return true; }
static uint32_t ProgramApplicationCode(void) { uint32_t ret = FTFx_OK; uint32_t dest; uint32_t size; uint8_t i; /* Erase upper half of Pflash */ for (i = P_BLOCK_NUM/2 ; i < P_BLOCK_NUM; i++) { dest = P_FLASH_BASE + i*(P_FLASH_SIZE/P_BLOCK_NUM); ret |= FlashEraseBlock(&flashSSDConfig, dest, g_FlashLaunchCommand); if (FTFx_OK != ret) { PRINTF("\r\nFlash Erase Upper Block Error, Address: 0x%x", (int)dest); return ret; } } /******************************************************************* Program upper block with exact same data from lower half except the last sector ( for swap inficator). This includes security information, for use when we swap blocks *******************************************************************/ dest = P_FLASH_BASE + P_FLASH_SIZE/2; size = P_FLASH_SIZE/2 - 2*P_SECTOR_SIZE; ret = FlashProgram(&flashSSDConfig, dest, size, P_FLASH_BASE, g_FlashLaunchCommand); if (FTFx_OK != ret) { PRINTF("\r\nFlashProgram Error, Pflash half program, Address: 0x%x", (int)dest); return ret; } /* program data to upper Pflash half for verification */ ret |= FlashProgram(&flashSSDConfig, PSWAP_UPPERDATA_ADDR, PGM_SIZE_BYTE, pgmData, g_FlashLaunchCommand); /* Program data to lower Pflash half*/ for (i = 0; i < PGM_SIZE_BYTE; i ++) { pgmData[i] = (i+0x10); } ret |= FlashEraseSector(&flashSSDConfig,PSWAP_LOWERDATA_ADDR, P_SECTOR_SIZE,g_FlashLaunchCommand); ret |= FlashProgram(&flashSSDConfig, PSWAP_LOWERDATA_ADDR, PGM_SIZE_BYTE, pgmData, g_FlashLaunchCommand); return (ret); }
bool Persistent::pagePutTag(uint8_t* page, uint8_t tag, uint8_t* data, uint8_t length) { uint8_t* address = pageFreeBegin(page); Header hdr = { 0xFF, ROUNDUP4(length), length, tag }; if (FlashProgram((uint32_t*) &hdr, (uint32_t) address, 4)) return false; union { uint32_t i32; uint8_t b[4]; } v; int l; for (int i = 0; i < ROUNDUP4(length); i += 4) { if (i < length - 4) { l = 4; } else l = length - i; memcpy(v.b, data + i, l); FlashProgram(&v.i32, (uint32_t) (address + 4 + i), 4); } return true; }
/********************************************************************* * @fn OADTarget_writeFlash * * @brief Write data to flash. * * @param page - page to write to in flash * @param offset - offset into flash page to begin writing * @param pBuf - pointer to buffer of data to write * @param len - length of data to write in bytes * * @return None. */ void OADTarget_writeFlash(uint8_t page, uint32_t offset, uint8_t *pBuf, uint16_t len) { uint8_t cacheState; cacheState = OADTarget_disableCache(); FlashProgram(pBuf, (uint32_t)FLASH_ADDRESS(page, offset), len); OADTarget_enableCache(cacheState); }
unsigned long massStorageWrite(void * drive,unsigned char *data,unsigned long blockNumber,unsigned long numberOfBlocks) { //FlashProgram((unsigned long*)data,USER_PROGRAM_START+counter,BLOCK_SIZE*numberOfBlocks); //counter+=BLOCK_SIZE*numberOfBlocks; #ifdef DEBUG UARTprintf("Write block: %d, no. of blocks: %d\n",blockNumber,numberOfBlocks); int i,j; for (j=0;j<BLOCK_SIZE*numberOfBlocks;j+=16){ for (i=0;i<16;i++) UARTprintf("%x ",data[j+i]); UARTprintf("\n"); } #endif if (blockNumber==0){ memcpy(bootSector,data,BOOT_LEN); } else if (blockNumber==1||blockNumber==2){ memcpy(fat,data,FAT_LEN); firmware_start_cluster=directory[58];//sometimes the system will move the firmware to a different cluster } else if (blockNumber==3){ memcpy(directory,data,DIRECTORY_LEN); } //new firmware is being uploaded else if (blockNumber>=FIRMWARE_START_SECTOR&&blockNumber<FIRMWARE_START_SECTOR+USER_PROGRAM_LENGTH/BLOCK_SIZE){ unsigned long address=(blockNumber-FIRMWARE_START_SECTOR)*BLOCK_SIZE+USER_PROGRAM_START; if (blockNumber==FIRMWARE_START_SECTOR){ for (counter=0;counter<239;counter++) FlashErase(USER_PROGRAM_START+counter*1024); } FlashProgram((unsigned long*)data,address,BLOCK_SIZE*numberOfBlocks); return BLOCK_SIZE*numberOfBlocks; } return BLOCK_SIZE*numberOfBlocks; }
//***************************************************************************** // //! Writes a word to an EEPROM page. //! //! This function is called to write a word (32 bits) to an EEPROM page. It //! verifies that the write was successful by reading the location and comparing //! against the value written. //! //! \param pulData is the pointer to the data to be written. //! //! \param pucPgAddr is the pointer to the target address. //! //! \param ucByteCount is the number of bytes to be written. //! //! \return A value of 0 indicates that the write was successful. A non-zero //! value indicates a failure. // //***************************************************************************** static long PageDataWrite(unsigned long* pulData, unsigned char* pucPgAddr, unsigned char ucByteCount) { unsigned char ucCount; // // Write the supplied data to the supplied address. // if(FlashProgram(pulData, (unsigned long)pucPgAddr, ucByteCount)) { // // A error occurred. // return(-1); } // // Loop through and verify the program operation // for(ucCount = 0; ucCount < ucByteCount; ucCount += 4) { // // Verify that the data was programmed correctly. // if(*(unsigned long *)pucPgAddr != *pulData) { // // An error occurred. // return(-1); } // // Increment the pointers. // pucPgAddr += 4; pulData++; } // // The program operation was successful, so return 0. // return(0); }
//***************************************************************************** // //! Programs unprotected main bank flash sectors // //***************************************************************************** uint32_t FlashsafeProgram(uint8_t *pui8DataBuffer, uint32_t ui32Address, uint32_t ui32Count) { uint32_t ui32ErrorReturn; // // Check the arguments. // ASSERT((ui32Address + ui32Count) <= (FLASHMEM_BASE + FlashsafeSizeGet())); if(FlashsafeSMPHTryAcquire()) { ui32ErrorReturn = FlashProgram(pui8DataBuffer, ui32Address, ui32Count); FlashsafeSMPHRelease(); return(ui32ErrorReturn); } return(FLASHSAFE_ACCESS_DENIED); }
//***************************************************************************** // //! Save sector protection to make it permanent // //***************************************************************************** uint32_t FlashProtectionSave(uint32_t ui32SectorAddress) { uint32_t ui32ErrorReturn; uint32_t ui32SectorNumber; uint32_t ui32CcfgSectorAddr; uint32_t ui32ProgBuf; ui32ErrorReturn = FAPI_STATUS_SUCCESS; // // Check the arguments. // ASSERT(ui32SectorAddress <= (FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet())); ASSERT((ui32SectorAddress & (FlashSectorSizeGet() - 1)) == 00); if(FlashProtectionGet(ui32SectorAddress) == FLASH_WRITE_PROTECT) { // // Find sector number for specified sector. // ui32SectorNumber = (ui32SectorAddress - FLASHMEM_BASE) / FlashSectorSizeGet(); ui32CcfgSectorAddr = FLASHMEM_BASE + FlashSizeGet() - FlashSectorSizeGet(); // // Adjust CCFG address to the 32-bit CCFG word holding the // protect-bit for the specified sector. // ui32CcfgSectorAddr += (((ui32SectorNumber >> 5) * 4) + CCFG_OFFSET_SECT_PROT); // // Find value to program by setting the protect-bit which // corresponds to specified sector number, to 0. // Leave other protect-bits unchanged. // ui32ProgBuf = (~(1 << (ui32SectorNumber & 0x1F))) & *(uint32_t *)ui32CcfgSectorAddr; ui32ErrorReturn = FlashProgram((uint8_t*)&ui32ProgBuf, ui32CcfgSectorAddr, CCFG_SIZE_SECT_PROT); }
/************************************************************************************//** ** \brief Programs FLASH_WRITE_BLOCK_SIZE bytes to flash from the block->data ** array. ** \param block Pointer to flash block info structure to operate on. ** \return BLT_TRUE if successful, BLT_FALSE otherwise. ** ****************************************************************************************/ static blt_bool FlashWriteBlock(tFlashBlockInfo *block) { blt_int8u sector_num; blt_bool result = BLT_TRUE; blt_addr prog_addr; blt_int32u prog_data; blt_int32u word_cnt; /* check that address is actually within flash */ sector_num = FlashGetSector(block->base_addr); if (sector_num == FLASH_INVALID_SECTOR) { return BLT_FALSE; } /* program all words in the block one by one */ for (word_cnt=0; word_cnt<(FLASH_WRITE_BLOCK_SIZE/sizeof(blt_int32u)); word_cnt++) { prog_addr = block->base_addr + (word_cnt * sizeof(blt_int32u)); prog_data = *(volatile blt_int32u*)(&block->data[word_cnt * sizeof(blt_int32u)]); /* keep the watchdog happy */ CopService(); /* program the word to flash */ if (FlashProgram((unsigned long *)&prog_data, prog_addr, sizeof(blt_int32u)) != 0) { result = BLT_FALSE; break; } /* verify that the written data is actually there */ if (*(volatile blt_int32u*)prog_addr != prog_data) { result = BLT_FALSE; break; } } /* still here so all is okay */ return result; } /*** end of FlashWriteBlock ***/
void Persistent::pageInit(uint8_t* address, uint32_t sequence) { FlashErase((uint32_t) address); FlashProgram(&sequence, (uint32_t) address, 4); }
//***************************************************************************** // // This is called each time there is a new data record to log to the flash // storage area. A simple algorithm is used which rotates programming // data log records through an area of flash. It is assumed that the current // page is blank. Records are stored on the current page until a page // boundary is crossed. If the page boundary is crossed and the new page // is not blank (testing only the first location), then the new page is // erased. Finally the entire record is programmed into flash and the // storage pointers are updated. // // While storing and when crossing to a new page, if the flash page is not // blank it is erased. So this algorithm overwrites old data. // // The data is stored in flash as a record, with a flash header prepended, // and with the record length padded to be a multiple of 4 bytes. The flash // header is a 3-byte magic number and one byte of record length. // //***************************************************************************** int FlashStoreWriteRecord(tLogRecord *pRecord) { unsigned long ulIdx; unsigned long ulItemCount; unsigned long *pulRecord; // // Check the arguments // ASSERT(pRecord); if(!pRecord) { return(1); } // // Determine how many channels are to be logged // ulIdx = pRecord->usItemMask; ulItemCount = 0; while(ulIdx) { if(ulIdx & 1) { ulItemCount++; } ulIdx >>= 1; } // // Add 16-bit count equivalent of record header, time stamp, and // selected items mask. This is the total number of 16 bit words // of the record. // ulItemCount += 6; // // Convert the count to bytes, be sure to pad to 32-bit alignment. // ulItemCount = ((ulItemCount * 2) + 3) & ~3; // // Create the flash record header, which is a 3-byte signature and a // one byte count of bytes in the record. Save it at the beginning // of the write buffer. // ulIdx = 0x53554100 | (ulItemCount & 0xFF); g_ulRecordBuf[0] = ulIdx; // // Copy the rest of the record to the buffer, and get a pointer to // the buffer. // memcpy(&g_ulRecordBuf[1], pRecord, ulItemCount - 4); pulRecord = g_ulRecordBuf; // // Check to see if the record is going to cross a page boundary. // if(((g_ulStoreAddr & 0x3FF) + ulItemCount) > 0x3FF) { // // Find number of bytes remaining on this page // ulIdx = 0x400 - (g_ulStoreAddr & 0x3FF); // // Program part of the record on the space remaining on the current // page // FlashProgram(pulRecord, g_ulStoreAddr, ulIdx); // // Increment the store address by the amount just written, which // should make the new store address be at the beginning of the next // flash page. // g_ulStoreAddr += ulIdx; // // Adjust the remaining bytes to program, and the pointer to the // remainder of the record data. // ulItemCount -= ulIdx; pulRecord = &g_ulRecordBuf[ulIdx / 4]; // // Check to see if the new page is past the end of store and adjust // if(g_ulStoreAddr >= FLASH_STORE_END_ADDR) { g_ulStoreAddr = FLASH_STORE_START_ADDR; } // // If new page is not blank, then erase it // if(HWREG(g_ulStoreAddr) != 0xFFFFFFFF) { FlashErase(g_ulStoreAddr); } } // // Now program the remaining part of the record (if we crossed a page // boundary above) or the full record to the current location in flash // FlashProgram(pulRecord, g_ulStoreAddr, ulItemCount); // // Increment the storage address to the next location. // g_ulStoreAddr += ulItemCount; // // Return success indication to caller. // return(0); }
/* * @brief Grabs binary file (robot software) via XMODEM and writes to flash starting at address OS_START_ADDRESS. * It uses XMODEM 1024 protocol through secureCRT. * @returns 0 if the binary is successfully installed. For other error values, see bootloader.h */ uint8 xmodemDownalodBinary(void) { int c; uint32 i, j, totalErrors, osMemeoryLocation; uint16 dataPacketSize; uint8 checkSum, packetNumer, tempByte, error; uint8 dataPacket[MAX_PACKET_SIZE]; boolean packetError, endOfFile, gotEOT; totalErrors = 0; endOfFile = FALSE; osMemeoryLocation = (uint32)OS_START_ADDRESS; // For every packet while (!(endOfFile) && (totalErrors < RX_MAX_ERRORS)) { dataPacketSize = 0; checkSum = 0; error = 0; packetError = FALSE; gotEOT = FALSE; // Send a NAK every 1/2 second until the transmission starts. if ((c = getSerialByteWithTimeout(RX_TIMEOUT_US)) >= 0) { // First byte determines the packet type tempByte = (uint8)c; switch (tempByte) { case SOH: // This is the beginning of a 128 byte packet dataPacketSize = 128; break; case STX: // This is the beginning of a 1024 byte packet dataPacketSize = 1024; break; case EOT: // This transmission is finished. gotEOT = TRUE; endOfFile = TRUE; break; case CAN: // This transmission has been canceled. packetError = TRUE; endOfFile = TRUE; error = ERROR_CANCEL; break; default: // Unknown error. Abort. packetError = TRUE; endOfFile = TRUE; error = ERROR_UNKOWN; break; } // EOT if (gotEOT) { sendByte(ACK); break; } // Get packet data if there's no error if (error == 0) { // Get packet number, inverse Packet number, payload[dataBytesInPacket], checksum for (i = 0; i < dataPacketSize + 3; i++) { // Poll interrupt pin until the FIFO reaches the triggering level. while (!GPIOPinRead(UART0_BASE, UART_INT_RX)); c = getSerialByteNonblocking(); dataPacket[i] = (uint8)c; } packetNumer = dataPacket[0]; if (packetNumer != (uint8)(~dataPacket[1])) { // Mismatch in packet ID and inverse packet ID packetError = TRUE; } for (j = 2; j < dataPacketSize + 2; j++) { checkSum += dataPacket[j]; } // The last byte is the checksum byte if (checkSum != dataPacket[dataPacketSize + 2]) { packetError = TRUE; } } if (packetError) { // Some kind of packet error. Flush RX buffer and retry. totalErrors++; error = ERROR_TIMEOUT; sendByte(NAK); } else if (dataPacketSize > 0) { // Received a complete xmodem packet, program flash, and signal the sender. FlashErase(osMemeoryLocation); FlashProgram((uint32 *)(dataPacket + 2), osMemeoryLocation, dataPacketSize); osMemeoryLocation += dataPacketSize; blinkyLedToggle(); sendByte(ACK); } } else { // Received nothing. Signal NAK. sendByte(NAK); } } // Give SecureCRT some time to close the dialog box systemDelay(300); return error; }
/******************************************************************************* Function: ReturnType Flash( InstructionType insInstruction, ParameterType *fp ) Arguments: insInstruction is an enum which contains all the available Instructions of the SW driver. fp is a (union) parameter struct for all Flash Instruction parameters Return Value: The function returns the following conditions: Flash_AddressInvalid, Flash_MemoryOverflow, Flash_PageEraseFailed, Flash_PageNrInvalid, Flash_SectorNrInvalid, Flash_FunctionNotSupported, Flash_NoInformationAvailable, Flash_OperationOngoing, Flash_OperationTimeOut, Flash_ProgramFailed, Flash_SpecificError, Flash_Success, Flash_WrongType Description: This function is used to access all functions provided with the current Flash device. Pseudo Code: Step 1: Select the right action using the insInstruction parameter Step 2: Execute the Flash memory Function Step 3: Return the Error Code *******************************************************************************/ ReturnType Flash( InstructionType insInstruction, ParameterType *fp ) { ReturnType rRetVal; ST_uint8 ucStatusRegister; ST_uint16 ucDeviceIdentification; #ifdef USE_JEDEC_STANDARD_TWO_BYTE_SIGNATURE ST_uint8 ucManufacturerIdentification; #endif switch (insInstruction) { case WriteEnable: rRetVal = FlashWriteEnable( ); break; case WriteDisable: rRetVal = FlashWriteDisable( ); break; case ReadDeviceIdentification: rRetVal = FlashReadDeviceIdentification(&ucDeviceIdentification); (*fp).ReadDeviceIdentification.ucDeviceIdentification = ucDeviceIdentification; break; #ifdef USE_JEDEC_STANDARD_TWO_BYTE_SIGNATURE case ReadManufacturerIdentification: rRetVal = FlashReadManufacturerIdentification(&ucManufacturerIdentification); (*fp).ReadManufacturerIdentification.ucManufacturerIdentification = ucManufacturerIdentification; break; #endif case ReadStatusRegister: rRetVal = FlashReadStatusRegister(&ucStatusRegister); (*fp).ReadStatusRegister.ucStatusRegister = ucStatusRegister; break; case WriteStatusRegister: ucStatusRegister = (*fp).WriteStatusRegister.ucStatusRegister; rRetVal = FlashWriteStatusRegister(ucStatusRegister); break; case Read: rRetVal = FlashRead( (*fp).Read.udAddr, (*fp).Read.pArray, (*fp).Read.udNrOfElementsToRead ); break; case FastRead: rRetVal = FlashFastRead( (*fp).Read.udAddr, (*fp).Read.pArray, (*fp).Read.udNrOfElementsToRead ); break; case PageProgram: rRetVal = FlashProgram( (*fp).PageProgram.udAddr, (*fp).PageProgram.pArray, (*fp).PageProgram.udNrOfElementsInArray ); break; case SectorErase: rRetVal = FlashSectorErase((*fp).SectorErase.ustSectorNr ); break; case SubSectorErase: rRetVal = FlashSubSectorErase((*fp).SubSectorErase.ustSectorNr ); break; case BulkErase: rRetVal = FlashBulkErase( ); break; #ifndef NO_DEEP_POWER_DOWN_SUPPORT case DeepPowerDown: rRetVal = FlashDeepPowerDown( ); break; case ReleaseFromDeepPowerDown: rRetVal = FlashReleaseFromDeepPowerDown( ); break; #endif case Program: rRetVal = FlashProgram( (*fp).Program.udAddr, (*fp).Program.pArray, (*fp).Program.udNrOfElementsInArray); break; default: rRetVal = Flash_FunctionNotSupported; break; } /* EndSwitch */ return rRetVal; } /* EndFunction Flash */
//***************************************************************************** // // This function processes a packet received from the UART. // //***************************************************************************** void ProcessPacket(void) { unsigned long ulIdx, ulCheckSum, *pulData; // // Compute the checksum of the packet data. // for(ulIdx = 3, ulCheckSum = 0; ulIdx < (g_ulUpdateSize + 3); ulIdx++) { ulCheckSum += g_pucUpdateData[ulIdx]; } // // If the checksum does not match, NAK the packet and return without any // further processing. // if((ulCheckSum & 0xff) != g_ulUpdateCheckSum) { UARTCharPut(UART0_BASE, 0x00); UARTCharPut(UART0_BASE, COMMAND_NAK); return; } // // Determine the command in this packet. // switch(g_pucUpdateData[3]) { // // The PING command. // case COMMAND_PING: { // // Set the command status to success. // g_ulUpdateStatus = COMMAND_RET_SUCCESS; // // ACK this command. // UARTCharPut(UART0_BASE, 0x00); UARTCharPut(UART0_BASE, COMMAND_ACK); // // This command has been handled. // break; } // // The DOWNLOAD command. // case COMMAND_DOWNLOAD: { // // Set the command status to success. If a failure is detected // during the processing of this command, the status will be // updated. // g_ulUpdateStatus = COMMAND_RET_SUCCESS; // // A simple do/while(0) loop that is executed once (because of the // while(0) at the end) but can be easily exited with a break. // This allows a common cleanup at the end (after the loop) while // not having increasingly deep nesting of the intervening code. // do { // // This command is invalid if there are not 8 data bytes in // addition to the command. // if(g_ulUpdateSize != 9) { g_ulUpdateStatus = COMMAND_RET_INVALID_CMD; break; } // // Ignore the image offset from the command, but extract the // image size. // g_ulImageOffset = 0; g_ulImageSize = ((g_pucUpdateData[8] << 24) | (g_pucUpdateData[9] << 16) | (g_pucUpdateData[10] << 8) | g_pucUpdateData[11]); // // Make sure that the image is not too large. // if(g_ulImageSize > 0x1f000) { g_ulUpdateStatus = COMMAND_RET_INVALID_ADR; break; } // // Loop through the pages used to store the image. // for(ulIdx = 0; ulIdx < (g_ulImageSize + 4); ulIdx += 0x400) { // // Erase this page of the image storage, setting the status // if a failure occurs. // if(FlashErase(IMAGE_BASE + ulIdx) != 0) { g_ulUpdateStatus = COMMAND_RET_FLASH_FAIL; } } // // Save the image size as the first word of the flash. // g_pulFirstWords[0] = g_ulImageSize; // // Indicate that a serial download command has been received. // HWREGBITW(&g_ulFlags, FLAG_SERIAL_BOOTLOADER) = 1; } while(0); // // If an error was encountered, reset the image size to zero to // indicate that there is no active download. // if(g_ulUpdateStatus != COMMAND_RET_SUCCESS) { g_ulImageSize = 0; } // // ACK this command. // UARTCharPut(UART0_BASE, 0x00); UARTCharPut(UART0_BASE, COMMAND_ACK); // // This command has been handled. // break; } // // The RUN command. // case COMMAND_RUN: { // // This command is ignored, so treat it as an invalid command. // g_ulUpdateStatus = COMMAND_RET_INVALID_CMD; // // ACK this command. // UARTCharPut(UART0_BASE, 0x00); UARTCharPut(UART0_BASE, COMMAND_ACK); // // This command has been handled. // break; } // // The GET_STATUS command. // case COMMAND_GET_STATUS: { // // ACK this command. // UARTCharPut(UART0_BASE, 0x00); UARTCharPut(UART0_BASE, COMMAND_ACK); // // Send a status packet. // UARTCharPut(UART0_BASE, 0x03); UARTCharPut(UART0_BASE, g_ulUpdateStatus); UARTCharPut(UART0_BASE, g_ulUpdateStatus); // // Set the UART state to ACK/NAK so that it will look for the ACK // or NAK packet that should be received in response to the status // packet. // g_ulUARTState = UART_STATE_ACK_NAK; // // This command has been handled. // break; } // // The SEND_DATA command. // case COMMAND_SEND_DATA: { // // Set the command status to success. If a failure is detected // during the processing of this command, the status will be // updated. // g_ulUpdateStatus = COMMAND_RET_SUCCESS; // // Decrement the packet size by one (which is the command byte). // g_ulUpdateSize--; // // Only process this data if it is part of the download image. // if((g_ulImageOffset + g_ulUpdateSize) <= g_ulImageSize) { // // Get a pointer to the first word of the download data. // pulData = (unsigned long *)(g_pucUpdateData + 4); // // Round the data size up to a word-sized quantity. // g_ulUpdateSize = (g_ulUpdateSize + 3) & ~3; // // See if this is the first word of the image. // if(g_ulImageOffset == 0) { // // Save away the first word of the image so it can be // programmed after the remainder of the image. // g_pulFirstWords[1] = *pulData++; g_ulImageOffset += 4; g_ulUpdateSize -= 4; } // // See if this is the second word of the image. // if((g_ulImageOffset == 4) && (g_ulUpdateSize != 0)) { // // Save away the second word of the image so it can be // programmed after the remainder of the image. // g_pulFirstWords[2] = *pulData++; g_ulImageOffset += 4; g_ulUpdateSize -= 4; } // // See if there is any data to be programmed. // if(g_ulUpdateSize != 0) { // // Program the data into flash, setting the status if a // failure occurs. // if(FlashProgram(pulData, IMAGE_BASE + g_ulImageOffset + 4, g_ulUpdateSize) != 0) { g_ulUpdateStatus = COMMAND_RET_FLASH_FAIL; } // // Increment the image offset by the number of words // programmed. // g_ulImageOffset += g_ulUpdateSize; } // // See if the end of the image has been reached. // if(g_ulImageOffset >= g_ulImageSize) { // // Program the first three words of the image, setting the // status if a failure occurs. // if(FlashProgram(g_pulFirstWords, IMAGE_BASE, 12) != 0) { g_ulUpdateStatus = COMMAND_RET_FLASH_FAIL; } // // Set the image size to zero to indicate that the download // has completed. // g_ulImageSize = 0; } // // Indicate that a serial download command has been received. // HWREGBITW(&g_ulFlags, FLAG_SERIAL_BOOTLOADER) = 1; } else { // // Data was received that is outside the bounds of the download // image, so set the status to indicate an error. // g_ulUpdateStatus = COMMAND_RET_INVALID_ADR; } // // ACK this command. // UARTCharPut(UART0_BASE, 0x00); UARTCharPut(UART0_BASE, COMMAND_ACK); // // This command has been handled. // break; } // // The RESET command. // case COMMAND_RESET: { // // This command is ignored, so treat it as an invalid command. // g_ulUpdateStatus = COMMAND_RET_INVALID_CMD; // // ACK this command. // UARTCharPut(UART0_BASE, 0x00); UARTCharPut(UART0_BASE, COMMAND_ACK); // // This command has been handled. // break; } // // An unknown command was received. // default: { // // Set the status to indicate an unknown command. // g_ulUpdateStatus = COMMAND_RET_UNKNOWN_CMD; // // ACK this command. // UARTCharPut(UART0_BASE, 0x00); UARTCharPut(UART0_BASE, COMMAND_ACK); // // This command has been handled. // break; } } }
/************************************************************************************************** * @fn HalFlashWrite * * @brief This function reads 'cnt' bytes from the internal flash. * * input parameters * * @param addr - Valid HAL flash write address: actual addr / 4 and quad-aligned. * @param buf - Valid buffer space at least as big as the 'cnt' parameter. * @param cnt - Valid number of bytes to write: a write cannot cross into the next 32KB bank. * * output parameters * * None. * * @return None. ************************************************************************************************** */ void HalFlashWrite(uint32 addr, uint8 *buf, uint16 cnt) { FlashProgram( buf, addr, cnt ); }
//***************************************************************************** // //! Writes a new parameter block to flash. //! //! \param pucBuffer is the address of the parameter block to be written to //! flash. //! //! This function will write a parameter block to flash. Saving the new //! parameter blocks involves three steps: //! //! - Setting the sequence number such that it is one greater than the sequence //! number of the latest parameter block in flash. //! - Computing the checksum of the parameter block. //! - Writing the parameter block into the storage immediately following the //! latest parameter block in flash; if that storage is at the start of an //! erase block, that block is erased first. //! //! By this process, there is always a valid parameter block in flash. If //! power is lost while writing a new parameter block, the checksum will not //! match and the partially written parameter block will be ignored. This is //! what makes this fault-tolerant. //! //! Another benefit of this scheme is that it provides wear leveling on the //! flash. Since multiple parameter blocks fit into each erase block of flash, //! and multiple erase blocks are used for parameter block storage, it takes //! quite a few parameter block saves before flash is re-written. //! //! \return None. // //***************************************************************************** void FlashPBSave(unsigned char *pucBuffer) { unsigned char *pucNew; unsigned long ulIdx, ulSum; // // Check the arguments. // ASSERT(pucBuffer != (void *)0); // // See if there is a valid parameter block in flash. // if(g_pucFlashPBCurrent) { // // Set the sequence number to one greater than the most recent // parameter block. // pucBuffer[0] = g_pucFlashPBCurrent[0] + 1; // // Try to write the new parameter block immediately after the most // recent parameter block. // pucNew = g_pucFlashPBCurrent + g_ulFlashPBSize; if(pucNew == g_pucFlashPBEnd) { pucNew = g_pucFlashPBStart; } } else { // // There is not a valid parameter block in flash, so set the sequence // number of this parameter block to zero. // pucBuffer[0] = 0; // // Try to write the new parameter block at the beginning of the flash // space for parameter blocks. // pucNew = g_pucFlashPBStart; } // // Compute the checksum of the parameter block to be written. // for(ulIdx = 0, ulSum = 0; ulIdx < g_ulFlashPBSize; ulIdx++) { ulSum -= pucBuffer[ulIdx]; } // // Store the checksum into the parameter block. // pucBuffer[1] += ulSum; // // Look for a location to store this parameter block. This infinite loop // will be explicitly broken out of when a valid location is found. // while(1) { // // See if this location is at the start of an erase block. // if(((unsigned long)pucNew & 1023) == 0) { // // Erase this block of the flash. This does not assume that the // erase succeeded in case this block of the flash has become bad // through too much use. Given the extremely low frequency that // the parameter blocks are written, this will likely never fail. // But, that assumption is not made in order to be safe. // FlashErase((unsigned long)pucNew); } // // Loop through this portion of flash to see if is all ones (i.e. it // is an erased portion of flash). // for(ulIdx = 0; ulIdx < g_ulFlashPBSize; ulIdx++) { if(pucNew[ulIdx] != 0xff) { break; } } // // If all bytes in this portion of flash are ones, then break out of // the loop since this is a good location for storing the parameter // block. // if(ulIdx == g_ulFlashPBSize) { break; } // // Increment to the next parameter block location. // pucNew += g_ulFlashPBSize; if(pucNew == g_pucFlashPBEnd) { pucNew = g_pucFlashPBStart; } // // If every possible location has been checked and none are valid, then // it will not be possible to write this parameter block. Simply // return without writing it. // if((g_pucFlashPBCurrent && (pucNew == g_pucFlashPBCurrent)) || (!g_pucFlashPBCurrent && (pucNew == g_pucFlashPBStart))) { return; } } // // Write this parameter block to flash. // FlashProgram((unsigned long *)pucBuffer, (unsigned long)pucNew, g_ulFlashPBSize); // // Compare the parameter block data to the data that should now be in // flash. Return if any of the data does not compare, leaving the previous // parameter block in flash as the most recent (since the current parameter // block failed to properly program). // for(ulIdx = 0; ulIdx < g_ulFlashPBSize; ulIdx++) { if(pucNew[ulIdx] != pucBuffer[ulIdx]) { return; } } // // The new parameter block becomes the most recent parameter block. // g_pucFlashPBCurrent = pucNew; }
/*----------------------------------------------------------------------------- * Verarbeitung der Bustelegramme */ static void ProcessBus(UINT8 ret) { TBusMsgType msgType; UINT16 *pData; UINT16 wordAddr; BOOL rc; BOOL msgForMe = FALSE; if (ret == BUS_MSG_OK) { msgType = spRxBusMsg->type; switch (msgType) { case eBusDevReqReboot: case eBusDevReqUpdEnter: case eBusDevReqUpdData: case eBusDevReqUpdTerm: if (spRxBusMsg->msg.devBus.receiverAddr == MY_ADDR) { msgForMe = TRUE; } default: break; } if (msgForMe == FALSE) { return; } if (msgType == eBusDevReqReboot) { /* Über Watchdog Reset auslösen */ /* Watchdogtimeout auf kurzeste Zeit (14 ms) stellen */ cli(); wdt_enable(WDTO_15MS); /* warten auf Reset */ while (1); } else { switch (sFwuState) { case WAIT_FOR_UPD_ENTER_TIMEOUT: case WAIT_FOR_UPD_ENTER: if (msgType == eBusDevReqUpdEnter) { /* Applicationbereich des Flash löschen */ FlashErase(); /* Antwort senden */ SetMsg(eBusDevRespUpdEnter, spRxBusMsg->senderAddr); BusSend(&sTxBusMsg); sFwuState = WAIT_FOR_UPD_DATA; } break; case WAIT_FOR_UPD_DATA: if (msgType == eBusDevReqUpdData) { wordAddr = spRxBusMsg->msg.devBus.x.devReq.updData.wordAddr; pData = spRxBusMsg->msg.devBus.x.devReq.updData.data; /* Flash programmieren */ rc = FlashProgram(wordAddr, pData, sizeof(spRxBusMsg->msg.devBus.x.devReq.updData.data) / 2); /* Antwort senden */ SetMsg(eBusDevRespUpdData, spRxBusMsg->senderAddr); if (rc == TRUE) { /* Falls Programmierung des Block OK: empfangene wordAddr zurücksenden */ sTxBusMsg.msg.devBus.x.devResp.updData.wordAddr = wordAddr; } else { /* Problem bei Programmierung: -1 als wordAddr zurücksenden */ sTxBusMsg.msg.devBus.x.devResp.updData.wordAddr = -1; } BusSend(&sTxBusMsg); } else if (msgType == eBusDevReqUpdTerm) { /* programmiervorgang im Flash abschließen (falls erforderlich) */ rc = FlashProgramTerminate(); /* Antwort senden */ SetMsg(eBusDevRespUpdTerm, spRxBusMsg->senderAddr); if (rc == TRUE) { /* Falls Programmierung OK: success auf 1 setzen */ sTxBusMsg.msg.devBus.x.devResp.updTerm.success = 1; } else { /* Problem bei Programmierung: -1 als wordAddr zurücksenden */ sTxBusMsg.msg.devBus.x.devResp.updTerm.success = 0; } BusSend(&sTxBusMsg); } break; default: break; } } } }
int TAP_Main (void) { AddTime(0, 0); BMP_WriteHeader(NULL, 0, 0); BootReason(); BuildWindowBorder(); BuildWindowInfo(); BuildWindowLine(); BuildWindowLineSelected(); BuildWindowScrollBar(); BuildWindowTitle(); busyWait(); CalcAbsSectorFromFAT(NULL, 0); CalcPrepare(); CalcTopIndex(0, 0); Callback(0, NULL, 0, 0, 0, 0); CallbackHelper(NULL, NULL, 0, 0, 0, 0); CallBIOS(0, 0, 0, 0, 0); CallFirmware(0, 0, 0, 0, 0); CallTraceEnable(FALSE); CallTraceEnter(NULL); CallTraceExit(NULL); CallTraceInit(); CaptureScreen(0, 0, 0, NULL, 0, 0); ChangeDirRoot(); CheckSelectable(0, 0); combineVfdData(NULL, NULL); compact(NULL, 0); CompressBlock(NULL, 0, NULL); CompressedTFDSize(NULL, 0, NULL); CompressTFD(NULL, 0, NULL, 0, 0, NULL); CRC16(0, NULL, 0); CRC32 (0, NULL, 0); Delay(0); DialogEvent(NULL, NULL, NULL); DialogMsgBoxButtonAdd(NULL, FALSE); DialogMsgBoxExit(); DialogMsgBoxInit(NULL, NULL, NULL, NULL); DialogMsgBoxShow(); DialogMsgBoxShowInfo(0); DialogMsgBoxShowOK(); DialogMsgBoxShowOKCancel(0); DialogMsgBoxShowYesNo(0); DialogMsgBoxShowYesNoCancel(0); DialogMsgBoxTitleSet(NULL, NULL); DialogProfileChange(NULL); DialogProfileCheck(NULL, NULL, FALSE); DialogProfileLoad(NULL); DialogProfileLoadDefault(); DialogProfileLoadMy(NULL, FALSE); DialogProfileSave(NULL); DialogProfileSaveDefault(); DialogProfileScrollBehaviourChange(FALSE, FALSE); DialogProgressBarExit(); DialogProgressBarInit(NULL, NULL, 0, 0, NULL, 0, 0); DialogProgressBarSet(0, 0); DialogProgressBarShow(); DialogProgressBarTitleSet(NULL); DialogWindowChange(NULL, FALSE); DialogWindowCursorChange(FALSE); DialogWindowCursorSet(0); DialogWindowExit(); DialogWindowHide(); DialogWindowInfoAddIcon(0, 0, NULL); DialogWindowInfoAddS(0, 0, 0, NULL, 0, 0, 0, 0, 0); DialogWindowInfoDeleteAll(); DialogWindowInit(NULL, NULL, 0, 0, 0, 0, NULL, NULL, NULL, 0, 0, 0); DialogWindowItemAdd(NULL, 0, NULL, 0, FALSE, FALSE, 0, NULL); DialogWindowItemAddSeparator(); DialogWindowItemChangeFlags(0, FALSE, FALSE); DialogWindowItemChangeIcon(0, 0, NULL); DialogWindowItemChangeParameter(0, NULL, 0); DialogWindowItemChangeValue(0, NULL, 0); DialogWindowItemDelete(0); DialogWindowItemDeleteAll(); DialogWindowRefresh(); DialogWindowReInit(0, 0, 0, 0, 0, 0); DialogWindowScrollDown(); DialogWindowScrollDownPage(); DialogWindowScrollUp(); DialogWindowScrollUpPage(); DialogWindowShow(); DialogWindowTabulatorSet(0, 0); DialogWindowTitleChange(NULL, NULL, NULL); DialogWindowTypeChange(0); DrawMsgBoxButtons(); DrawMsgBoxTitle(); DrawOSDLine(0, 0, 0, 0, 0, 0); DrawProgressBarBar(0, 0); DrawProgressBarTitle(); DrawWindowBorder(); DrawWindowInfo(); DrawWindowLine(0); DrawWindowLines(); DrawWindowScrollBar(); DrawWindowTitle(); EndMessageWin(); exitHook(); ExtractLine(NULL, NULL); FileSelector(NULL, NULL, NULL, 0); FileSelectorKey(0, 0); FindDBTrack(); FindInstructionSequence(NULL, NULL, 0, 0, 0, 0); findSendToVfdDisplay(0, 0); FlashAddFavourite(NULL, 0, FALSE); FlashDeleteFavourites(); FlashFindEndOfServiceNameTableAddress(); FlashFindEndOfServiceTableAddress(0); FlashFindServiceAddress(0, 0, 0, 0); FlashFindTransponderIndex(0, 0, 0); FlashGetBlockStartAddress(0); FlashGetChannelNumber(0, 0, 0, 0); FlashGetSatelliteByIndex(0); FlashGetServiceByIndex(0, FALSE); FlashGetServiceByName (NULL, FALSE); FlashGetTransponderCByIndex(0); FlashGetTransponderSByIndex(0, 0); FlashGetTransponderTByIndex(0); FlashGetTrueLocalTime(0, 0); FlashGetType(); FlashInitialize(0); FlashProgram(); FlashReindexFavourites(0, 0, 0); FlashReindexTimers(0, 0, 0); FlashRemoveCASServices(FALSE); FlashRemoveServiceByIndex(0, FALSE); FlashRemoveServiceByIndexString(NULL, FALSE); FlashRemoveServiceByLCN(NULL, FALSE); FlashRemoveServiceByName(NULL, FALSE); FlashRemoveServiceByPartOfName(NULL, FALSE); FlashRemoveServiceByUHF(NULL, FALSE, FALSE); FlashServiceAddressToServiceIndex(NULL); FlashWrite(NULL, NULL, 0, NULL); FlushCache(NULL, 0); FreeOSDRegion(0); fwHook(0); GetAudioTrackPID(0, NULL); GetClusterPointer(0); GetCurrentEvent(NULL); GetEEPROMAddress(); GetEEPROMPin(); GetFrameBufferPixel(0, 0); GetFrameSize(0, 0); GetFWInfo(0, 0, 0, 0, 0, 0, 0, 0); GetHeapParameter(NULL, 0); GetLine(NULL, 0); GetOSDMapAddress(); GetOSDRegionHeight(0); GetOSDRegionWidth(0); GetPinStatus(); GetPIPPosition(NULL, NULL, NULL, NULL); getRECSlotAddress(); GetSysOsdControl(0); GetToppyString(0); HasEnoughItemMemory(); HDD_AAM_Disable(); HDD_AAM_Enable(0); HDD_APM_Disable(); HDD_APM_Enable(0); HDD_BigFile_Read(NULL, 0, 0, NULL); HDD_BigFile_Size(NULL); HDD_BigFile_Write(NULL, 0, 0, NULL); HDD_ChangeDir(NULL); HDD_DecodeRECHeader(NULL, NULL); HDD_EncodeRECHeader(NULL, NULL, 0); HDD_FappendOpen(NULL); HDD_FappendWrite(NULL, NULL); HDD_FindPCR(NULL, 0); HDD_FindPMT(NULL, 0, NULL); HDD_FreeSize(); HDD_GetClusterSize(); HDD_GetFileDir(NULL, 0, NULL); HDD_GetFirmwareDirCluster(); HDD_GetHddID(NULL, NULL, NULL); HDD_IdentifyDevice(NULL); HDD_isAnyRecording(); HDD_isCryptedStream(NULL, 0); HDD_isRecording(0); HDD_LiveFS_GetChainLength(0); HDD_LiveFS_GetFAT1Address(); HDD_LiveFS_GetFAT2Address(); HDD_LiveFS_GetFirstCluster(0); HDD_LiveFS_GetLastCluster(0); HDD_LiveFS_GetNextCluster(0); HDD_LiveFS_GetPreviousCluster(0); HDD_LiveFS_GetRootDirAddress(); HDD_LiveFS_GetSuperBlockAddress(); HDD_MakeNewRecName(NULL, 0); HDD_Move(NULL, NULL, NULL); HDD_ReadClusterDMA(0, NULL); HDD_ReadSector(0, 0); HDD_ReadSectorDMA(0, 0, NULL); HDD_RECSlotGetAddress(0); HDD_RECSlotIsPaused(0); HDD_RECSlotPause(0, FALSE); HDD_RECSlotSetDuration(0, 0); HDD_SetCryptFlag(NULL, 0); HDD_SetFileDateTime(NULL, 0, 0, 0); HDD_SetSkipFlag (NULL, FALSE); HDD_SetStandbyTimer(0); HDD_Smart_DisableAttributeAutoSave(); HDD_Smart_DisableOperations(); HDD_Smart_EnableAttributeAutoSave(); HDD_Smart_EnableOperations(); HDD_Smart_ExecuteOfflineImmediate(0); HDD_Smart_ReadData(0); HDD_Smart_ReadThresholdData(0); HDD_Smart_ReturnStatus(); HDD_Stop(); HDD_TAP_Callback(0, NULL, 0, 0, 0, 0); HDD_TAP_Disable(0, 0); HDD_TAP_DisableAll(0); HDD_TAP_DisabledEventHandler(0, 0, 0); HDD_TAP_GetCurrentDir(NULL); HDD_TAP_GetCurrentDirCluster(); HDD_TAP_GetIDByFileName(NULL); HDD_TAP_GetIDByIndex(0); HDD_TAP_GetIndexByID(0); HDD_TAP_GetInfo(0, NULL); HDD_TAP_GetStartParameter(); HDD_TAP_isAnyRunning(); HDD_TAP_isBatchMode(); HDD_TAP_isDisabled(0); HDD_TAP_isDisabledAll(); HDD_TAP_isRunning(0); HDD_TAP_SendEvent(0, FALSE, 0, 0, 0); HDD_TAP_SetCurrentDirCluster(0); HDD_TAP_Start(NULL, FALSE, NULL, NULL); HDD_TAP_StartedByTAP(); HDD_TAP_Terminate(0); HDD_TouchFile(NULL); HDD_TranslateDirCluster(0, NULL); HDD_TruncateFile(NULL, 0); HDD_Write(NULL, 0, NULL); HDD_WriteClusterDMA(0, NULL); HDD_WriteSectorDMA(0, 0, NULL); HookEnable(0, 0); HookExit(); HookIsEnabled(0); HookMIPS_Clear(0, 0, 0); HookMIPS_Set(0, 0, 0); HookSet(0, 0); IMEM_Alloc(0); IMEM_Init(0); IMEM_isInitialized(); IMEM_Compact(); IMEM_Free(NULL); IMEM_GetInfo(NULL, NULL); IMEM_Kill(); InfoTestGrid(); INICloseFile(); INIFindStartEnd(NULL, NULL, NULL, 0); INIGetARGB(NULL, NULL, NULL, NULL, NULL, 0); INIGetHexByte(NULL, 0, 0, 0); INIGetHexDWord(NULL, 0, 0, 0); INIGetHexWord(NULL, 0, 0, 0); INIGetInt(NULL, 0, 0, 0); INIGetString(NULL, NULL, NULL, 0); INIKillKey(NULL); INIOpenFile(NULL); INISaveFile(NULL); INISetARGB(NULL, 0, 0, 0, 0); INISetComment(NULL); INISetHexByte(NULL, 0); INISetHexDWord(NULL, 0); INISetHexWord(NULL, 0); INISetInt(NULL, 0); INISetString(NULL, NULL); initCodeWrapper(0); InitTAPAPIFix(); InitTAPex(); InteractiveGetStatus(); InteractiveSetStatus(FALSE); intLock(); intUnlock(0); isAnyOSDVisible(0, 0, 0, 0); isLegalChar(0, 0); isMasterpiece(); isMPMenu(); iso639_1(0); isOSDRegionAlive(0); isValidChannel(NULL); LangGetString(0); LangLoadStrings(NULL, 0, 0); LangUnloadStrings(); Log(NULL, NULL, FALSE, 0, NULL); LowerCase(NULL); MakeValidFileName(NULL, 0); MHEG_Status(); MPDisplayClearDisplay(); MPDisplayClearSegments(0, 0); MPDisplayDisplayLongString(NULL); MPDisplayDisplayShortString(NULL); MPDisplayGetDisplayByte(0); MPDisplayGetDisplayMask(0); MPDisplayInstallMPDisplayFwHook(); MPDisplaySetAmFlag(0); MPDisplaySetColonFlag(0); MPDisplaySetDisplayByte(0, 0); MPDisplaySetDisplayMask(0, 0); MPDisplaySetDisplayMemory(NULL); MPDisplaySetDisplayMode(0); MPDisplaySetPmFlag(0); MPDisplaySetSegments(0, 0); MPDisplayToggleSegments(0, 0); MPDisplayUninstallMPDisplayFwHook(); MPDisplayUpdateDisplay(); Now(NULL); OSDCopy(0, 0, 0, 0, 0, 0, 0); OSDLinesForeDirty(FALSE); ParseLine(NULL, NULL, 0); ProfileDirty(); ProfileInit(); ProfileLoad(NULL, FALSE); ProfileMayReload(); ReadEEPROM(0, 0, NULL); ReadIICRegister(0, 0, 0, 0, NULL); Reboot(0); ReceiveSector(0); RTrim(NULL); SaveBitmap(NULL, 0, 0, NULL); SendEvent(0, 0, 0, 0); SendEventHelper(NULL, 0, 0, 0); SendHDDCommand(0, 0, 0, 0, 0, 0, 0); SendToFP(NULL); SeparatePathComponents(NULL, NULL, NULL, NULL); SetCrashBehaviour(0); setSymbol14(0, 0); setSymbol17(0, 0); ShowMessageWin(NULL, NULL, NULL, 0); ShowMessageWindow(NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0); Shutdown(0); SoundSinus(0, 0, 0); StrEndsWith(NULL, NULL); stricstr(NULL, NULL); SubtitleGetStatus(); SubtitleSetStatus(FALSE); SuppressedAutoStart(); SwapDWords(0); SwapWords(0); TAP_Osd_PutFreeColorGd(0, 0, 0, NULL, FALSE, 0); TAPCOM_CloseChannel(NULL); TAPCOM_Finish(NULL, 0); TAPCOM_GetChannel(0, NULL, NULL, NULL, NULL); TAPCOM_GetReturnValue(NULL); TAPCOM_GetStatus(NULL); TAPCOM_LastAlive(NULL); TAPCOM_OpenChannel(0, 0, 0, NULL); TAPCOM_Reject(NULL); TAPCOM_StillAlive(NULL); TFDSize(NULL); TimeDiff(0, 0); TimeFormat(0, 0, 0); TunerGet(0); TunerSet(0); UncompressBlock(NULL, 0, NULL, 0); UncompressedFirmwareSize(NULL); UncompressedLoaderSize(NULL); UncompressedTFDSize(NULL); UncompressFirmware(NULL, NULL, NULL); UncompressLoader(NULL, NULL, NULL); UncompressTFD(NULL, NULL, NULL); UpperCase(NULL); ValidFileName(NULL, 0); WindowDirty(); WriteIICRegister(0, 0, 0, 0, NULL); YUV2RGB(0, 0, 0, NULL, NULL, NULL); YUV2RGB2(0, 0, 0, NULL, NULL, NULL); return 0; }