//------------------------------------------------------------------------------ /// Bootstrap main application. /// Transfer data from media to main memory and return the next application entry /// point address. //------------------------------------------------------------------------------ int main() { #if defined(BOOT_RECOVERY) unsigned char shallEraseBootstrap = 0; // Flag used to activate the boot recovery procedure #endif #if defined(at91cap9) && defined (FPGAINIT) unsigned int ret = 0; #endif // Enable User Reset AT91C_BASE_RSTC->RSTC_RMR |= AT91C_RSTC_URSTEN | (0xA5<<24); //------------------------------------------------------------------------- // ROM Code Fixes //------------------------------------------------------------------------- // at91sam9261 with ROM code 1.4 fix : Disable USB pull-up #ifdef at91sam9261 AT91C_BASE_MATRIX->MATRIX_USBPCR = ~AT91C_MATRIX_USBPCR_PUON; #endif //------------------------------------------------------------------------- // Test if at91bootstrap shall be erased (button pressed by user) //------------------------------------------------------------------------- #if defined(BOOT_RECOVERY) shallEraseBootstrap = ShallEraseBootstrap(); #endif //------------------------------------------------------------------------- // Configure traces //------------------------------------------------------------------------- TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); TRACE_INFO_WP("\n\r"); TRACE_INFO_WP("-- AT91bootstrap Project %s --\n\r", BOOTSTRAP_VERSION); TRACE_INFO_WP("-- %s\n\r", BOARD_NAME); TRACE_INFO_WP("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); TRACE_INFO("Setting: MCK = %dMHz\n\r", (int)(BOARD_MCK/1000000)); //------------------------------------------------------------------------- // Enable I-Cache //------------------------------------------------------------------------- CP15_Enable_I_Cache(); //------------------------------------------------------------------------- // Configure MPBLOCK //------------------------------------------------------------------------- #if defined(at91cap9) && defined(FPGAINIT) ret = BOARD_FPGA_InitMPBlock(); TRACE_INFO("return value BOARD_InitMPBlock() = 0x%x\n\r", ret); #endif //------------------------------------------------------------------------- // Configure External memories supply //------------------------------------------------------------------------- #if defined (at91cap9) // EBI 1V8 //------------------------------------------------------------------------- #if defined(VDDMEMSEL_EBI1V8) BOARD_ConfigureVddMemSel(VDDMEMSEL_1V8); #endif // EBI 3V3 //------------------------------------------------------------------------- #if defined(VDDMEMSEL_EBI3V3) BOARD_ConfigureVddMemSel(VDDMEMSEL_3V3); #endif #if !defined(VDDMEMSEL_EBI1V8) && !defined(VDDMEMSEL_EBI3V3) #error No external memories power supply selected #endif // VDDMEMSEL #endif // at91cap9 //------------------------------------------------------------------------- // Configure external RAM where the application will be transfered //------------------------------------------------------------------------- // SDRAM //------------------------------------------------------------------------- #if defined(DESTINATION_sdram) TRACE_INFO("Init SDRAM\n\r"); BOARD_ConfigureSdram(BOARD_SDRAM_BUSWIDTH); #endif // DDRAM //------------------------------------------------------------------------- #if defined(DESTINATION_ddram) TRACE_INFO("Init DDRAM\n\r"); BOARD_ConfigureDdram(0, BOARD_DDRAM_BUSWIDTH); #endif // BCRAM //------------------------------------------------------------------------- #if defined(DESTINATION_bcram) TRACE_INFO("Init BCRAM\n\r"); BOARD_ConfigureBcram(BOARD_BCRAM_BUSWIDTH); #endif // Check that a destination memory has be selected #if !defined(DESTINATION_sdram) && \ !defined(DESTINATION_ddram) && \ !defined(DESTINATION_bcram) #error No destination memory selected #endif //------------------------------------------------------------------------- // Configure access to memory and transfer data from memory to external RAM //------------------------------------------------------------------------- // DataFlash //------------------------------------------------------------------------- #if defined(ORIGIN_dataflash) #if defined(BOOT_RECOVERY) if (shallEraseBootstrap) BOOT_AT45_EraseBoot(); else #endif //BOOT_RECOVERY BOOT_AT45_CopyBin(tabDesc, TDESC_LISTSIZE(tabDesc)); #endif // SerialFlash //------------------------------------------------------------------------- #if defined(ORIGIN_serialflash) BOOT_AT26_CopyBin(tabDesc, TDESC_LISTSIZE(tabDesc)); #endif // NandFlash //------------------------------------------------------------------------- #if defined(ORIGIN_nandflash) #if defined(BOOT_RECOVERY) if (shallEraseBootstrap) BOOT_NAND_EraseBoot(); else #endif //BOOT_RECOVERY BOOT_NAND_CopyBin(tabDesc, TDESC_LISTSIZE(tabDesc)); #endif // SDcard //------------------------------------------------------------------------- #if defined(ORIGIN_sdcard) BOOT_SDcard_CopyFile(tabDesc, TDESC_LISTSIZE(tabDesc)); #endif // NorFlash //------------------------------------------------------------------------- #if defined(ORIGIN_norflash) BOOT_NOR_CopyBin(tabDesc, TDESC_LISTSIZE(tabDesc)); #endif // Eeprom //------------------------------------------------------------------------- #if defined(ORIGIN_eeprom) BOOT_EEPROM_CopyBin(tabDesc, TDESC_LISTSIZE(tabDesc)); #endif // Check that an origin memory has be selected #if !defined(ORIGIN_dataflash) && \ !defined(ORIGIN_serialflash) && \ !defined(ORIGIN_nandflash) && \ !defined(ORIGIN_sdcard) && \ !defined(ORIGIN_norflash) && \ !defined(ORIGIN_eeprom) #error No origin memory selected #endif //------------------------------------------------------------------------- // Jump to external RAM //------------------------------------------------------------------------- #ifdef DEBUG_DUMP_MEMORY UTIL_DbguDumpMemory(tabDesc[0].dest, 0x200); #endif TRACE_INFO("Jump to 0x%08x\n\r", tabDesc[0].dest); GoToJumpAddress(tabDesc[0].dest, MACH_TYPE); return 0;//never reach }
//------------------------------------------------------------------------------ /// Applet main entry. This function decodes received command and executes it. /// \param argc always 1 /// \param argv Address of the argument area. //------------------------------------------------------------------------------ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; const At45Desc *pDesc = 0; unsigned int bytesToWrite, bytesToRead, bufferAddr, memoryOffset, packetSize; // index on read/write buffer unsigned char *pBuffer; // Temporary buffer used for non page aligned read/write unsigned int tempBufferAddr; // Offset in destination buffer during buffer copy unsigned int bufferOffset; // Configure the DBGU TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); // Configure pins (must be done each time because of some old ROM codes that reset PIO usage) if (at45Select[at45Index].pSpiHw != 0) { PIO_Configure(at45Select[at45Index].pPinsSpi, at45Select[at45Index].numPinsSpi); PIO_Configure(at45Select[at45Index].pPinCs, 1); } // ---------------------------------------------------------- // INIT: // ---------------------------------------------------------- if (pMailbox->command == APPLET_CMD_INIT) { // Save info of communication link comType = pMailbox->argument.inputInit.comType; at45Index = pMailbox->argument.inputInit.at45Idx; #if (DYN_TRACES == 1) traceLevel = pMailbox->argument.inputInit.traceLevel; #endif TRACE_INFO("-- DataFlash AT45 Applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); if (at45Select[at45Index].pSpiHw == 0) { pMailbox->status = APPLET_NO_DEV; pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = 0; pMailbox->argument.outputInit.bufferAddress = (unsigned int) &end; TRACE_INFO("INIT command: No Dataflash %d defined for this board\n\r", \ pMailbox->argument.inputInit.at45Idx); pMailbox->status = APPLET_NO_DEV; goto exit; } TRACE_INFO("INIT command: Dataflash %d : SPI 0x%x SPI_NPCS 0x%x (0x%x)\n\r", \ pMailbox->argument.inputInit.at45Idx, at45Select[at45Index].spiIndex, at45Select[at45Index].cs, (unsigned int) &(pMailbox->argument.inputInit.at45Idx)); // Initialize the SPI and serial flash SPID_Configure(&spid, at45Select[at45Index].pSpiHw, at45Select[at45Index].spiId); PIO_Configure(at45Select[at45Index].pPinsSpi, at45Select[at45Index].numPinsSpi); PIO_Configure(at45Select[at45Index].pPinCs, 1); TRACE_INFO("\tSPI NCSR 0x%x\n\r", (int)AT45_CSR(BOARD_MCK, SPCK)); SPID_ConfigureCS(&spid, at45Select[at45Index].cs, AT45_CSR(BOARD_MCK, SPCK)); AT45_Configure(&at45, &spid, at45Select[at45Index].cs); TRACE_INFO("\tSPI and AT45 drivers initialized\n\r"); pMailbox->argument.outputInit.bufferAddress = (unsigned int) &end; // Read the JEDEC ID of the device to identify it pDesc = AT45_FindDevice(&at45, AT45D_GetStatus(&at45)); if (!pDesc) { pMailbox->status = APPLET_DEV_UNKNOWN; pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = 0; TRACE_INFO("\tDevice Unknown\n\r"); goto exit; } // Get device parameters pMailbox->status = APPLET_SUCCESS; numPages = AT45_PageNumber(&at45); pageSize = AT45_PageSize(&at45); #if defined(sram) || defined(at91sam7se) bufferSize = ((unsigned int) &_sstack) - ((unsigned int) &end) // user area - STACK_SIZE // stack size (if same area of applet code) - pageSize; // tempbuffer size to to make not aligned write operations bufferSize -= bufferSize % pageSize; // integer number of pages can be contained in each buffer //Buffer size can't be too big, otherwise COM will be timeout. if ( bufferSize < pageSize) { TRACE_INFO("\t No enought memory to load buffer.\n\r"); goto exit; } #else bufferSize = BUFFER_NB_PAGE * pageSize; #endif // Limit buffer size for tranfsert via COM. if (bufferSize > BUF_MAX_SIZE) { bufferSize = BUF_MAX_SIZE; bufferSize -= bufferSize % pageSize; // integer number of pages can be contained in each buffer } pMailbox->argument.outputInit.bufferSize = bufferSize; pMailbox->argument.outputInit.memorySize = numPages * pageSize; TRACE_INFO("\t%s numPages : 0x%x pageSize : 0x%x bufferAddr : 0x%x\n\r", at45.pDesc->name, numPages, pageSize, pMailbox->argument.outputInit.bufferAddress); } // ---------------------------------------------------------- // WRITE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; bytesToWrite = pMailbox->argument.inputWrite.bufferSize; TRACE_INFO("WRITE at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes\n\r", memoryOffset, bufferAddr, bytesToWrite); pBuffer = (unsigned char *) bufferAddr; tempBufferAddr = bufferAddr + bufferSize; if ((memoryOffset % pageSize) != 0) { // We are not page aligned, retrieve first page content to update it // Flush temp buffer memset((unsigned int *)tempBufferAddr, 0xFF, pageSize); bufferOffset = (memoryOffset % pageSize); if( (bytesToWrite + bufferOffset) < pageSize) { packetSize = bytesToWrite; } else { packetSize = pageSize - bufferOffset; } memoryOffset -= bufferOffset; // Read page to be updated AT45D_Read(&at45, (unsigned char *) tempBufferAddr, pageSize, memoryOffset); // Fill retrieved page with data to be programmed memcpy((unsigned char *)(tempBufferAddr + bufferOffset), pBuffer, packetSize); // Write the page contents AT45D_Write(&at45, (unsigned char *) tempBufferAddr, pageSize, memoryOffset); bytesToWrite -= packetSize; pBuffer += packetSize; memoryOffset += pageSize; } // If it remains more than one page to write while (bytesToWrite >= pageSize) { // Write the page contents AT45D_Write(&at45, pBuffer, pageSize, memoryOffset); pBuffer += pageSize; memoryOffset += pageSize; bytesToWrite -= pageSize; } // Write remaining data if (bytesToWrite > 0) { // Read previous content of page AT45D_Read(&at45, (unsigned char *) tempBufferAddr, pageSize, memoryOffset); // Fill retrieved block with data to be programmed memcpy((unsigned char *)tempBufferAddr, pBuffer, bytesToWrite); // Write the page contents AT45D_Write(&at45, (unsigned char *) tempBufferAddr, pageSize, memoryOffset); // No more bytes to write bytesToWrite = 0; } TRACE_INFO("WRITE return byte written : 0x%x Bytes\n\r", pMailbox->argument.inputWrite.bufferSize - bytesToWrite); pMailbox->argument.outputWrite.bytesWritten = pMailbox->argument.inputWrite.bufferSize - bytesToWrite; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // READ: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ) { memoryOffset = pMailbox->argument.inputRead.memoryOffset; bufferAddr = pMailbox->argument.inputRead.bufferAddr; bytesToRead = pMailbox->argument.inputRead.bufferSize; TRACE_INFO("READ at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes\n\r", memoryOffset, bufferAddr, bytesToRead); pBuffer = (unsigned char *) bufferAddr; // Read packet after packets while (((unsigned int)pBuffer < (bufferAddr + bufferSize)) && (bytesToRead > 0)) { packetSize = min(PDC_MAX_COUNT, bytesToRead); AT45D_Read(&at45, pBuffer, packetSize, memoryOffset); pBuffer += packetSize; bytesToRead -= packetSize; memoryOffset += packetSize; } TRACE_INFO("READ return byte read : 0x%x Bytes\n\r", pMailbox->argument.inputRead.bufferSize - bytesToRead); pMailbox->argument.outputRead.bytesRead = pMailbox->argument.inputRead.bufferSize - bytesToRead; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // FULL ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_FULL_ERASE) { TRACE_INFO("FULL ERASE command\n\r"); memoryOffset = 0; while (memoryOffset < (pageSize * numPages)) { // Erase the page AT45D_Erase(&at45, memoryOffset); memoryOffset += pageSize; } TRACE_INFO("Full Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // BUFFER ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_BUFFER_ERASE) { TRACE_INFO("BUFFER ERASE command\n\r"); memoryOffset = pMailbox->argument.inputBufferErase.memoryOffset; while (memoryOffset < (pMailbox->argument.inputBufferErase.memoryOffset + bufferSize)) { // Erase the page AT45D_Erase(&at45, memoryOffset); memoryOffset += pageSize; } TRACE_INFO("Buffer Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // CONFIGURE IN BINARY MODE (power of two page size): // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_BINARY_PAGE) { TRACE_INFO("BINARY PAGE SET command\n\r"); // Configure power-of-2 binary page size. AT45D_BinaryPage(&at45); TRACE_INFO("Binary Page achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } exit : // Acknowledge the end of command TRACE_INFO("\tEnd of applet (command : %x --- status : %x)\n\r", pMailbox->command, pMailbox->status); // Notify the host application of the end of the command processing pMailbox->command = ~(pMailbox->command); // Send ACK character if (comType == DBGU_COM_TYPE) { DBGU_PutChar(0x6); } return 0; }
//------------------------------------------------------------------------------ // Global functions //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ /// Applet main entry. This function decodes received command and executes it. /// \param argc always 1 /// \param argv Address of the argument area. //------------------------------------------------------------------------------ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; unsigned int bufferSize, bufferAddr, memoryOffset; unsigned int eraseStartSector, eraseEndSector, bytesToErase; unsigned int i; const unsigned char busWidth[3] = {FLASH_CHIP_WIDTH_8BITS, FLASH_CHIP_WIDTH_16BITS, FLASH_CHIP_WIDTH_32BITS}; unsigned int comType = 0; TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); PIO_Configure(pPinsNf, PIO_LISTSIZE(pPinsNf)); // ---------------------------------------------------------- // INIT: // ---------------------------------------------------------- if (pMailbox->command == APPLET_CMD_INIT) { // Save info of communication link comType = pMailbox->argument.inputInit.comType; #if (DYN_TRACES == 1) traceLevel = pMailbox->argument.inputInit.traceLevel; #endif TRACE_INFO("-- NorFlash Applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); TRACE_INFO("INIT command\n\r"); norFlash.norFlashInfo.baseAddress = BOARD_NORFLASH_ADDR; // Check device CFI and get Vendor setting from it. TRACE_INFO("\t Common Flash Interface detecting...\n\r"); for (i = 0; i < 3; i++) { // Configure SMC for Norflash accesses TRACE_INFO("\t Try bus width %d bits\n\r", busWidth[i] * 8); BOARD_ConfigureNorFlash(busWidth[i] * 8); if (!NorFlash_CFI_Detect(&norFlash, busWidth[i])) break; } if (norFlash.norFlashInfo.cfiCompatible == 0) { pMailbox->status = APPLET_DEV_UNKNOWN; pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = 0; TRACE_INFO("Device Unknown\n\r"); goto exit; } else { TRACE_INFO("manufactureID : 0x%08x, deviceID : 0x%08x\n\r", NORFLASH_ReadManufactoryID(&norFlash), NORFLASH_ReadDeviceID(&norFlash)); NORFLASH_ReadManufactoryID(&norFlash); // Get device parameters memSize = NorFlash_GetDeviceSizeInBytes(&(norFlash.norFlashInfo)); pMailbox->argument.outputInit.bufferAddress = ((unsigned int) &end); #if defined (at91sam7se) pMailbox->argument.outputInit.bufferAddress = 0x21000000; #endif bufferSize = NorFlash_GetDeviceMaxBlockSize(&(norFlash.norFlashInfo)); if (bufferSize > MAX_BUFFER_SIZE) bufferSize = MAX_BUFFER_SIZE; pMailbox->argument.outputInit.bufferSize = bufferSize; pMailbox->argument.outputInit.memorySize = memSize; TRACE_INFO("bufferSize : %d memorySize : %d bufferAddr: 0x%x \n\r", pMailbox->argument.outputInit.bufferSize, pMailbox->argument.outputInit.memorySize, (unsigned int) &end); } } // ---------------------------------------------------------- // WRITE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; bufferSize = pMailbox->argument.inputWrite.bufferSize; TRACE_INFO("WRITE at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes\n\r", memoryOffset, bufferAddr, bufferSize); if (memoryOffset < lastErasedOffset) { lastErasedSector = 0xFFFF; } lastErasedOffset = memoryOffset + bufferSize - 1; eraseStartSector = NorFlash_GetDeviceSectorInRegion(&(norFlash.norFlashInfo), memoryOffset); eraseEndSector = NorFlash_GetDeviceSectorInRegion(&(norFlash.norFlashInfo), lastErasedOffset); do { TRACE_INFO("lastErasedSector %d \n\r", lastErasedSector); if (eraseStartSector > lastErasedSector || lastErasedSector == 0xFFFF) { TRACE_INFO("Sector Erase in sector %d \n\r", eraseStartSector); if (NORFLASH_EraseSector( &norFlash, NorFlash_GetDeviceSectorAddress(&(norFlash.norFlashInfo),eraseStartSector))) { TRACE_INFO("Sector Erase failed in sector %d \n\r", eraseStartSector); pMailbox->status = APPLET_FAIL; goto exit; } lastErasedSector = eraseStartSector; } eraseStartSector++; } while (eraseStartSector <= eraseEndSector); // Write the buffer contents. if (NORFLASH_WriteData(&norFlash, memoryOffset, (unsigned char *)bufferAddr, bufferSize)) { TRACE_INFO("Program failed \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } pMailbox->argument.outputWrite.bytesWritten = bufferSize; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // READ: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ) { memoryOffset = pMailbox->argument.inputRead.memoryOffset; bufferAddr = pMailbox->argument.inputRead.bufferAddr; bufferSize = pMailbox->argument.inputRead.bufferSize; TRACE_INFO("READ at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes\n\r", memoryOffset, bufferAddr, bufferSize); NORFLASH_ReadData(&norFlash, memoryOffset, (unsigned char *) bufferAddr, bufferSize); pMailbox->argument.outputRead.bytesRead = bufferSize; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // BUFFER ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_BUFFER_ERASE) { TRACE_INFO("BUFFER ERASE command\n\r"); memoryOffset = pMailbox->argument.inputBufferErase.memoryOffset; bytesToErase = NorFlash_GetDeviceMaxBlockSize(&(norFlash.norFlashInfo)) * 2; bytesToErase = ((memoryOffset + bytesToErase) > memSize) ? (memSize - memoryOffset): bytesToErase; lastErasedOffset = memoryOffset + bytesToErase; eraseStartSector = NorFlash_GetDeviceSectorInRegion(&(norFlash.norFlashInfo), memoryOffset); eraseEndSector = NorFlash_GetDeviceSectorInRegion(&(norFlash.norFlashInfo), lastErasedOffset); for (i = eraseStartSector; i <= eraseEndSector; i++) { if (NORFLASH_EraseSector( &norFlash, NorFlash_GetDeviceSectorAddress(&(norFlash.norFlashInfo),i))) { TRACE_INFO("Sector Erase failed in sector %d \n\r", i); pMailbox->status = APPLET_FAIL; goto exit; } lastErasedSector = i; } pMailbox->argument.outputBufferErase.bytesErased = bytesToErase; TRACE_INFO("Buffer Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // FULL ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_FULL_ERASE) { TRACE_INFO("FULL ERASE command\n\r"); if (NORFLASH_EraseChip(&norFlash)) { TRACE_INFO("Full Erase failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("Full Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } exit : // Acknowledge the end of command TRACE_INFO("\tEnd of applet (command : %x --- status : %x)\n\r", pMailbox->command, pMailbox->status); // Notify the host application of the end of the command processing pMailbox->command = ~(pMailbox->command); // Send ACK character if (comType == DBGU_COM_TYPE) { DBGU_PutChar(0x6); } return 0; }
//------------------------------------------------------------------------------ /// Applet main entry. This function decodes received command and executes it. /// \param argc always 1 /// \param argv Address of the argument area. //------------------------------------------------------------------------------ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; unsigned int bufferSize, bufferAddr, memoryOffset; unsigned int bytesToWrite; unsigned int bytesRead = 0; unsigned int nbBadBlocks = 0; unsigned int nbBlocks = 0; // Temporary buffer used for non block aligned read / write unsigned int tempBufferAddr; unsigned short block, page, offset, i; // Index in source buffer during buffer copy unsigned int offsetInSourceBuff; // Index in destination buffer during buffer copy unsigned int offsetInTargetBuff; // Errors returned by SkipNandFlash functions unsigned char error = 0; // Configure the DBGU TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); // Configure SMC for Nandflash accesses (done each time applet is launched because of old ROM codes) BOARD_ConfigureNandFlash(nfBusWidth); PIO_Configure(pPinsNf, PIO_LISTSIZE(pPinsNf)); // ---------------------------------------------------------- // INIT: // ---------------------------------------------------------- if (pMailbox->command == APPLET_CMD_INIT) { // Save info of communication link comType = pMailbox->argument.inputInit.comType; #if (DYN_TRACES == 1) traceLevel = pMailbox->argument.inputInit.traceLevel; #endif TRACE_INFO("-- NandFlash applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); TRACE_INFO("INIT command\n\r"); if (pPinsNf->pio == 0) { pMailbox->status = APPLET_NO_DEV; pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = 0; pMailbox->argument.outputInit.bufferAddress = (unsigned int) &end; TRACE_INFO("INIT command: No Nandflash defined for this board\n\r"); } else { memset(&skipBlockNf, 0, sizeof(skipBlockNf)); NandDisableInternalEcc(((struct RawNandFlash *) &skipBlockNf)); if (SkipBlockNandFlash_Initialize(&skipBlockNf, 0, cmdBytesAddr, addrBytesAddr, dataBytesAddr, nfCePin, nfRbPin)) { pMailbox->status = APPLET_DEV_UNKNOWN; pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = 0; TRACE_INFO("\tDevice Unknown\n\r"); } else { // Check the data bus width of the NandFlash nfBusWidth = NandFlashModel_GetDataBusWidth((struct NandFlashModel *)&skipBlockNf); // Reconfigure bus width BOARD_ConfigureNandFlash(nfBusWidth); TRACE_INFO("\tNandflash driver initialized\n\r"); #if defined (at91sam3u) pMailbox->argument.outputInit.bufferAddress = 0x60000000; #elif defined (at91sam7se) pMailbox->argument.outputInit.bufferAddress = 0x21000000; #else pMailbox->argument.outputInit.bufferAddress = (unsigned int) &end; #endif // Get device parameters memSize = NandFlashModel_GetDeviceSizeInBytes(&skipBlockNf.ecc.raw.model); blockSize = NandFlashModel_GetBlockSizeInBytes(&skipBlockNf.ecc.raw.model); numBlocks = NandFlashModel_GetDeviceSizeInBlocks(&skipBlockNf.ecc.raw.model); pageSize = NandFlashModel_GetPageDataSize(&skipBlockNf.ecc.raw.model); numPagesPerBlock = NandFlashModel_GetBlockSizeInPages(&skipBlockNf.ecc.raw.model); pMailbox->status = APPLET_SUCCESS; pMailbox->argument.outputInit.bufferSize = blockSize; pMailbox->argument.outputInit.memorySize = memSize; TRACE_INFO("\t pageSize : 0x%x blockSize : 0x%x blockNb : 0x%x bus width : %d\n\r", pageSize, blockSize, numBlocks, nfBusWidth); TRACE_INFO("\t bufferAddr : 0x%x\n\r", (unsigned int) &end); } } } // ---------------------------------------------------------- // WRITE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; tempBufferAddr = bufferAddr + blockSize; bytesToWrite = pMailbox->argument.inputWrite.bufferSize; TRACE_INFO("WRITE arguments : offset 0x%x, buffer at 0x%x, of 0x%x Bytes\n\r", memoryOffset, bufferAddr, bytesToWrite); pMailbox->argument.outputWrite.bytesWritten = 0; // Check word alignment if (memoryOffset % 4) { pMailbox->status = APPLET_ALIGN_ERROR; goto exit; } // Retrieve page and block addresses if (NandFlashModel_TranslateAccess(&(skipBlockNf.ecc.raw.model), memoryOffset, bytesToWrite, &block, &page, &offset)) { pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("WRITE at block 0x%x, page 0x%x, offset in page 0x%x\n\r", block, page, offset); if (page || offset || (bytesToWrite < blockSize)) { // We are not block aligned, retrieve block content to update it memset((unsigned int *)tempBufferAddr, 0xFF, blockSize); error = SkipBlockNandFlash_ReadBlock(&skipBlockNf, block, (unsigned int *)tempBufferAddr); if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } // Fill retrieved block with data to be programmed offsetInTargetBuff = (page * pageSize) + offset; offsetInSourceBuff = 0; while ((offsetInTargetBuff < blockSize) && (bytesToWrite > 0)) { *(unsigned int *)(tempBufferAddr + offsetInTargetBuff) = *(unsigned int *)(bufferAddr + offsetInSourceBuff); offsetInSourceBuff += 4; offsetInTargetBuff += 4; bytesToWrite -= 4; } } else { // Write a full and aligned block tempBufferAddr = bufferAddr; bytesToWrite = 0; } // Erase target block error = SkipBlockNandFlash_EraseBlock(&skipBlockNf, block, NORMAL_ERASE); if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } // Write target block error = SkipBlockNandFlash_WriteBlock(&skipBlockNf, block, (unsigned int *)tempBufferAddr); if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } pMailbox->argument.outputWrite.bytesWritten = pMailbox->argument.inputWrite.bufferSize - bytesToWrite; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // READ: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ) { memoryOffset = pMailbox->argument.inputRead.memoryOffset; bufferAddr = pMailbox->argument.inputRead.bufferAddr; tempBufferAddr = bufferAddr + blockSize; bufferSize = pMailbox->argument.inputRead.bufferSize; TRACE_INFO("READ at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes\n\r", memoryOffset, bufferAddr, bufferSize); pMailbox->argument.outputRead.bytesRead = 0; // Check word alignment if (memoryOffset % 4) { pMailbox->status = APPLET_ALIGN_ERROR; goto exit; } // Retrieve page and block addresses if (NandFlashModel_TranslateAccess(&(skipBlockNf.ecc.raw.model), memoryOffset, bufferSize, &block, &page, &offset)) { pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("READ at block 0x%x, page 0x%x, offset in page 0x%x\n\r", block, page, offset); if (page || offset) { memset((unsigned int *)tempBufferAddr, 0xFF, blockSize); error = SkipBlockNandFlash_ReadBlock(&skipBlockNf, block, (unsigned int *)tempBufferAddr); if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } // Fill dest buffer with read data offsetInSourceBuff = (page * pageSize) + offset; offsetInTargetBuff = 0; while ((offsetInSourceBuff < blockSize) && (offsetInTargetBuff < blockSize) && (bytesRead < bufferSize)) { *(unsigned int *)(bufferAddr + offsetInTargetBuff) = *(unsigned int *)(tempBufferAddr + offsetInSourceBuff); offsetInSourceBuff += 4; offsetInTargetBuff += 4; bytesRead += 4; } pMailbox->argument.outputRead.bytesRead = bytesRead; pMailbox->status = APPLET_SUCCESS; } else { memset((unsigned int *)bufferAddr, 0xFF, blockSize); error = SkipBlockNandFlash_ReadBlock(&skipBlockNf, block, (unsigned int *)bufferAddr); if (error == NandCommon_ERROR_BADBLOCK) { pMailbox->status = APPLET_BAD_BLOCK; goto exit; } if (error) { pMailbox->status = APPLET_FAIL; goto exit; } pMailbox->argument.outputRead.bytesRead = bufferSize; pMailbox->status = APPLET_SUCCESS; } } // ---------------------------------------------------------- // FULL ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_FULL_ERASE) { TRACE_INFO("FULL ERASE command\n\r"); TRACE_INFO("\tForce erase flag: 0x%x\n\r", pMailbox->argument.inputFullErase.eraseType); for (i = 0; i < numBlocks; i++) { // Erase the block if (SkipBlockNandFlash_EraseBlock(&skipBlockNf, i, pMailbox->argument.inputFullErase.eraseType)) { TRACE_INFO("Found block #%d BAD, skip it\n\r", i); } } TRACE_INFO("Full Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // BATCH FULL ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_BATCH_ERASE) { TRACE_INFO("BATCH ERASE command\n\r"); block = pMailbox->argument.inputBatchErase.batch * (numBlocks / ERASE_BATCH); TRACE_INFO("Erase block from #%d to #%d\n\r", block, block + (numBlocks / ERASE_BATCH)); for (i = block ; i < block + (numBlocks / ERASE_BATCH) ; i++) { // Erase the block if (SkipBlockNandFlash_EraseBlock(&skipBlockNf, i, pMailbox->argument.inputBatchErase.eraseType)) { TRACE_INFO("Found block #%d BAD, skip it\n\r", i); } } if ((pMailbox->argument.inputBatchErase.batch + 1) == ERASE_BATCH) { TRACE_INFO("Full Erase achieved, erase type is %d\n\r", pMailbox->argument.inputBatchErase.eraseType); pMailbox->argument.outputBatchErase.nextBatch = 0; } else { pMailbox->argument.outputBatchErase.nextBatch = pMailbox->argument.inputBatchErase.batch + 1; TRACE_INFO("Batch Erase achieved\n\r"); } pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // FULL ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_ERASE_BLOCKS) { TRACE_INFO("BLOCKS ERASE command\n\r"); memoryOffset = pMailbox->argument.inputBlocksErase.memoryOffsetStart; if ((pMailbox->argument.inputBlocksErase.memoryOffsetEnd > memSize) || (pMailbox->argument.inputBlocksErase.memoryOffsetEnd < memoryOffset) ) { TRACE_INFO("Out of memory space\n\r"); pMailbox->status = APPLET_ERASE_FAIL; goto exit; } nbBlocks = ((pMailbox->argument.inputBlocksErase.memoryOffsetEnd- memoryOffset)/ blockSize) + 1; TRACE_INFO("Erase blocks from %d to %d \n\r", memoryOffset / blockSize, (memoryOffset / blockSize)+ nbBlocks ); // Erase blocks for (i = memoryOffset / blockSize; i < memoryOffset / blockSize + nbBlocks ; i++) { if (SkipBlockNandFlash_EraseBlock(&skipBlockNf, i , NORMAL_ERASE)) { TRACE_INFO("Found block #%d BAD, skip it\n\r", i); } } TRACE_INFO("Blocks Erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // LIST BAD BLOCKS: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_LIST_BAD_BLOCKS) { TRACE_INFO("LIST BAD BLOCKS command\n\r"); nbBadBlocks = 0; bufferAddr = (unsigned int) &end; pMailbox->argument.outputListBadBlocks.bufferAddress = bufferAddr; for (i = 0; i < numBlocks; i++) { // Erase the page if (SkipBlockNandFlash_CheckBlock(&skipBlockNf, i) == BADBLOCK) { nbBadBlocks++; *((unsigned int *)bufferAddr) = i; bufferAddr += 4; TRACE_INFO("Found block #%d BAD\n\r", i); } } TRACE_INFO("LIST BAD BLOCKS achieved\n\r"); pMailbox->argument.outputListBadBlocks.nbBadBlocks = nbBadBlocks; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // TAG BLOCK: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_TAG_BLOCK) { TRACE_INFO("TAG BLOCK command\n\r"); bufferAddr = (unsigned int) &end; block = pMailbox->argument.inputTagBlock.blockId; // To tag the block as good, just erase it without bad block check if ((unsigned char)pMailbox->argument.inputTagBlock.tag == 0xFF) { if (SkipBlockNandFlash_EraseBlock(&skipBlockNf, block, SCRUB_ERASE)) { TRACE_INFO("Cannot erase block %d\n\r", block); pMailbox->status = APPLET_FAIL; goto exit; } } else { for (i = 0; i < 2; i++) { // Start by reading the spare memset((unsigned char *)bufferAddr, 0xFF, NandCommon_MAXSPAREECCBYTES); TRACE_INFO("Tag to write : 0x%x\n\r", (unsigned char)pMailbox->argument.inputTagBlock.tag); NandSpareScheme_WriteBadBlockMarker((struct NandSpareScheme *)(NandFlashModel_GetScheme((struct NandFlashModel *)(&skipBlockNf))), (unsigned char *)bufferAddr, ((unsigned char)pMailbox->argument.inputTagBlock.tag)); if (RawNandFlash_WritePage((struct RawNandFlash *)(&skipBlockNf), block, i, 0, (unsigned char *)bufferAddr)) { TRACE_ERROR("Failed to write spare data of page %d of block %d\n\r", i, block); pMailbox->status = APPLET_FAIL; goto exit; } } } TRACE_INFO("TAG BLOCK achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } exit : // Acknowledge the end of command TRACE_INFO("\tEnd of applet (command : %x --- status : %x)\n\r", pMailbox->command, pMailbox->status); // Notify the host application of the end of the command processing pMailbox->command = ~(pMailbox->command); // Send ACK character if (comType == DBGU_COM_TYPE) { DBGU_PutChar(0x6); } return 0; }
//------------------------------------------------------------------------------ /// Applet code for initializing the external RAM. //------------------------------------------------------------------------------ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; unsigned int ramType = 0; unsigned int bufferSize, bufferAddr, memoryOffset; unsigned int bytesToWrite; unsigned int tempBufferAddr; unsigned int dataBusWidth = 0; unsigned int ddrModel = 0; LowLevelInit(); TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); /* *AT91C_PMC_PCER = AT91C_ID_PIOA; *AT91C_PIOA_PDR = (1<<31); *AT91C_PIOA_OER = (1<<31); *AT91C_PIOA_BSR = (1<<31); *AT91C_PIOA_PER = (1<<0); *AT91C_PIOA_OER = (1<<0); *AT91C_PMC_PCKR = (1<<8); // select master clock *AT91C_PMC_SCER = (1<<8); // ENABLE PCK0*/ TRACE_INFO("Statup: PMC_MCKR %x MCK = %d command = %d\n\r", *AT91C_PMC_MCKR, BOARD_MCK, pMailbox->command); // ---------------------------------------------------------- // INIT: // ---------------------------------------------------------- if (pMailbox->command == APPLET_CMD_INIT) { // Initialize PMC // BOARD_RemapRam(); // Enable User Reset AT91C_BASE_RSTC->RSTC_RMR |= AT91C_RSTC_URSTEN | (0xA5<<24); ramType = pMailbox->argument.inputInit.ramType; dataBusWidth = pMailbox->argument.inputInit.dataBusWidth; ddrModel = pMailbox->argument.inputInit.ddrModel; //#if (DYN_TRACES == 1) // traceLevel = pMailbox->argument.inputInit.traceLevel; //#endif TRACE_INFO("-- EXTRAM ISP Applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); TRACE_INFO("-- Compiled: %s %s %s --\n\r", __DATE__, __TIME__, __GIT__); TRACE_INFO("INIT command:\n\r"); TRACE_INFO("\tCommunication link type : %d\n\r", pMailbox->argument.inputInit.comType); TRACE_INFO("\tData bus width : %d bits\n\r", dataBusWidth); if (ramType == TYPE_SDRAM) { TRACE_INFO("\tExternal RAM type : %s\n\r", "SDRAM"); } else { if (ramType == TYPE_DDRAM) { TRACE_INFO("\tExternal RAM type : %s\n\r", "DDRAM"); } else { TRACE_INFO("\tExternal RAM type : %s\n\r", "PSRAM"); } } #if defined(at91cap9) || defined(at91sam9m10) || defined(at91sam9g45) TRACE_INFO("\tInit EBI Vdd : %s\n\r", (pMailbox->argument.inputInit.VddMemSel)?"3.3V":"1.8V"); BOARD_ConfigureVddMemSel(pMailbox->argument.inputInit.VddMemSel); #endif //defined(at91cap9) if (pMailbox->argument.inputInit.ramType == TYPE_SDRAM) { // Configure SDRAM controller TRACE_INFO("\tInit SDRAM...\n\r"); #if defined(PINS_SDRAM) BOARD_ConfigureSdram(dataBusWidth); #endif } else if (pMailbox->argument.inputInit.ramType == TYPE_PSRAM) { TRACE_INFO("\tInit PSRAM...\n\r"); #if defined(at91sam3u4) BOARD_ConfigurePsram(); #endif } else { // Configure DDRAM controller #if defined(at91cap9dk) || defined(at91sam9m10) || defined(at91sam9g45) TRACE_INFO("\tInit DDRAM ... (model : %d)\n\r", ddrModel); BOARD_ConfigureVddMemSel(VDDMEMSEL_1V8); BOARD_ConfigureDdram(0, dataBusWidth); // ddramc_hw_init(); #endif } TRACE_INFO("\tInit successful.\n\r"); } // ---------------------------------------------------------- // LIST_BAD_BLOCK: (Check DDR) // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_LIST_BAD_BLOCKS) { // Test external RAM access if (ExtRAM_TestOk()) { pMailbox->status = APPLET_SUCCESS; } else { pMailbox->status = APPLET_FAIL; } pMailbox->argument.outputInit.bufferAddress = ((unsigned int) &end); pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = EXTRAM_SIZE; } // ---------------------------------------------------------- // WRITE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; bytesToWrite = pMailbox->argument.inputWrite.bufferSize; tempBufferAddr = bufferAddr+memoryOffset; TRACE_INFO("WRITE arguments : offset 0x%x, run 0x%x, of 0x%x Bytes\n\r", memoryOffset, tempBufferAddr, bytesToWrite); pMailbox->argument.outputWrite.bytesWritten = 0; /* * We must define the following * - MACH_TYPE_xxx * - Setup the kernel tagged list (http://www.arm.linux.org.uk/developer/booting.php#4) * first 16KiB of RAM. * * we recommend to load at 32KiB into RAM */ //Fake the end of the applet because we will not be able to do anything after this step if (bytesToWrite < EXTRAM_SIZE) { pMailbox->status = APPLET_SUCCESS; } else { pMailbox->status = APPLET_FAIL; } pMailbox->command = ~(pMailbox->command); //Going to ((VFptr *)(EXTRAM_ADDR+memoryOffset))(); } exit : // Acknowledge the end of command TRACE_INFO("\tEnd of applet (command : %x --- status : %x)\n\r", pMailbox->command, pMailbox->status); // Notify the host application of the end of the command processing pMailbox->command = ~(pMailbox->command); return 0; }
//------------------------------------------------------------------------------ /// Applet main entry. This function decodes received command and executes it. /// \param argc always 1 /// \param argv Address of the argument area. //------------------------------------------------------------------------------ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; unsigned int bytesToWrite, bufferAddr, memoryOffset; unsigned int l_start; unsigned int l_end; unsigned int *pActualStart = NULL; unsigned int *pActualEnd = NULL; unsigned char error; TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); // ---------------------------------------------------------- // INIT: // ---------------------------------------------------------- if (pMailbox->command == APPLET_CMD_INIT) { // Save info of communication link comType = pMailbox->argument.inputInit.comType; #if (DYN_TRACES == 1) traceLevel = pMailbox->argument.inputInit.traceLevel; #endif switch (pMailbox->argument.inputInit.bank) { default: case 0: flashBaseAddr = AT91C_IFLASH; flashBaseAddrInit = AT91C_IFLASH; #if defined (at91sam3u4) flashSize = AT91C_IFLASH_SIZE + AT91C_IFLASH1_SIZE; #else flashSize = AT91C_IFLASH_SIZE; #endif flashPageSize = AT91C_IFLASH_PAGE_SIZE; pMailbox->argument.outputInit.memoryInfo.numbersLockBits = AT91C_IFLASH_NB_OF_LOCK_BITS; flashLockRegionSize = AT91C_IFLASH_LOCK_REGION_SIZE; break; #if defined (at91sam3u4) case 1: flashBaseAddr = AT91C_IFLASH1; flashBaseAddrInit = AT91C_IFLASH1; flashSize = AT91C_IFLASH1_SIZE; flashPageSize = AT91C_IFLASH1_PAGE_SIZE; pMailbox->argument.outputInit.memoryInfo.numbersLockBits = AT91C_IFLASH1_NB_OF_LOCK_BITS; flashLockRegionSize = AT91C_IFLASH1_LOCK_REGION_SIZE; break; #endif } TRACE_INFO("-- Internal Flash Applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); // Initialize flash driver FLASHD_Initialize(BOARD_MCK); // flash accesses must be 4 bytes aligned pMailbox->argument.outputInit.bufferAddress = ((unsigned int) &end); #if defined (at91sam7s161) || defined (at91sam3u1) bufferSize = flashPageSize * 2; #elif defined (at91sam7s32) || defined (at91sam7s321) || defined (at91sam7l) bufferSize = flashPageSize; #else bufferSize = AT91C_ISRAM_SIZE // sram size - ( ((unsigned int) &end) - AT91C_ISRAM ) // program size (romcode, code+data) - STACK_SIZE; // stack size at the end #endif // integer number of pages can be contained in each buffer // operation is : buffersize -= bufferSize % flashPageSize // modulo can be done with a mask since flashpagesize is a power of two integer bufferSize -= (bufferSize & (flashPageSize - 1)); if (bufferSize > MAX_BUF_SIZE && (comType == DBGU_COM_TYPE)) bufferSize = MAX_BUF_SIZE; pMailbox->argument.outputInit.bufferSize = bufferSize; pMailbox->argument.outputInit.memorySize = flashSize; pMailbox->argument.outputInit.memoryInfo.lockRegionSize = flashLockRegionSize; TRACE_INFO("bufferSize : %d bufferAddr: 0x%x \n\r", pMailbox->argument.outputInit.bufferSize, (unsigned int) &end ); TRACE_INFO("memorySize : %d lockRegionSize : 0x%x numbersLockBits : 0x%x \n\r", pMailbox->argument.outputInit.memorySize, pMailbox->argument.outputInit.memoryInfo.lockRegionSize, pMailbox->argument.outputInit.memoryInfo.numbersLockBits); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // WRITE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; bytesToWrite = pMailbox->argument.inputWrite.bufferSize; #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { if ((memoryOffset < AT91C_IFLASH_SIZE) && ((memoryOffset + bytesToWrite) > AT91C_IFLASH_SIZE)) { flashBaseAddr = AT91C_IFLASH; bytesToWrite = AT91C_IFLASH_SIZE - memoryOffset; } else if (memoryOffset >= AT91C_IFLASH_SIZE) { flashBaseAddr = AT91C_IFLASH1; memoryOffset -= AT91C_IFLASH_SIZE; } } #endif TRACE_INFO("WRITE at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes (flash base addr : 0x%x)\n\r", memoryOffset, bufferAddr, bytesToWrite, flashBaseAddr); // Check the giving sector have been locked before. if (FLASHD_IsLocked(flashBaseAddr + memoryOffset, flashBaseAddr + memoryOffset + bytesToWrite) != 0) { TRACE_INFO("Error page locked\n\r"); pMailbox->argument.outputWrite.bytesWritten = 0; pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } // Write data if (FLASHD_Write(flashBaseAddr + memoryOffset, (const void *)bufferAddr, bytesToWrite) != 0) { TRACE_INFO("Error write operation\n\r"); pMailbox->argument.outputWrite.bytesWritten = 0; pMailbox->status = APPLET_WRITE_FAIL; goto exit; } TRACE_INFO("Write achieved\n\r"); pMailbox->argument.outputWrite.bytesWritten = bytesToWrite; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // READ: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ) { memoryOffset = pMailbox->argument.inputRead.memoryOffset; bufferAddr = pMailbox->argument.inputRead.bufferAddr; bufferSize = pMailbox->argument.inputRead.bufferSize; #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { flashBaseAddr = AT91C_IFLASH; if ((memoryOffset < AT91C_IFLASH_SIZE) && ((memoryOffset + bufferSize) > AT91C_IFLASH_SIZE)) { bufferSize = AT91C_IFLASH_SIZE - memoryOffset; } else if (memoryOffset >= AT91C_IFLASH_SIZE) { flashBaseAddr = AT91C_IFLASH1; memoryOffset -= AT91C_IFLASH_SIZE; } } #endif TRACE_INFO("READ at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes (flash base addr : 0x%x)\n\r", memoryOffset, bufferAddr, bufferSize, flashBaseAddr); // read data memcpy((void *)bufferAddr, (void *)(flashBaseAddr + memoryOffset), bufferSize); TRACE_INFO("Read achieved\n\r"); pMailbox->argument.outputRead.bytesRead = bufferSize; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // FULL ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_FULL_ERASE) { TRACE_INFO("FULL ERASE command \n\r"); #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { flashBaseAddr = AT91C_IFLASH; // Check if at least one page has been locked if (FLASHD_IsLocked(flashBaseAddr, flashBaseAddr + AT91C_IFLASH_SIZE - 1) != 0) { TRACE_INFO("Error page locked \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } } else { // Check if at least one page has been locked if (FLASHD_IsLocked(flashBaseAddr, flashBaseAddr + AT91C_IFLASH1_SIZE - 1) != 0) { TRACE_INFO("Error page locked \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } } #else // Check if at least one page has been locked if (FLASHD_IsLocked(flashBaseAddr, flashBaseAddr + flashSize) != 0) { TRACE_INFO("Error page locked \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } #endif // Implement the erase all command if (FLASHD_Erase(flashBaseAddr) != 0) { TRACE_INFO("Full erase failed! \n\r"); pMailbox->status = APPLET_ERASE_FAIL; goto exit; } #if defined (at91sam7xc512) || (at91sam7x512) if (FLASHD_Erase(flashBaseAddr + FLASH_SECOND_BANK_OFFSET) != 0) { TRACE_INFO("Full erase failed! \n\r"); pMailbox->status = APPLET_ERASE_FAIL; goto exit; } #endif TRACE_INFO("Full erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // LOCK SECTOR: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_LOCK) { TRACE_INFO("LOCK command \n\r"); #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { flashBaseAddr = AT91C_IFLASH; if (pMailbox->argument.inputLock.sector >= AT91C_IFLASH_NB_OF_LOCK_BITS) { flashBaseAddr = AT91C_IFLASH1; pMailbox->argument.inputLock.sector -= AT91C_IFLASH_NB_OF_LOCK_BITS; } } #endif l_start = (pMailbox->argument.inputLock.sector * flashLockRegionSize) + flashBaseAddr; l_end = l_start + flashLockRegionSize; if( FLASHD_Lock(l_start, l_end, pActualStart, pActualEnd) != 0) { TRACE_INFO("Lock failed! \n\r"); // ASSERT( *pActualStart == l_start, "-F- Lock failed! \n\r"); // ASSERT( *pActualEnd == (l_start + flashLockRegionSize), "-F- Lock failed! \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } TRACE_INFO("Lock sector achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // UNLOCK SECTOR: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_UNLOCK) { TRACE_INFO("UNLOCK command \n\r"); #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { flashBaseAddr = AT91C_IFLASH; if (pMailbox->argument.inputLock.sector >= AT91C_IFLASH_NB_OF_LOCK_BITS) { flashBaseAddr = AT91C_IFLASH1; pMailbox->argument.inputLock.sector -= AT91C_IFLASH_NB_OF_LOCK_BITS; } } #endif l_start = (pMailbox->argument.inputLock.sector * flashLockRegionSize) + flashBaseAddr; l_end = l_start + flashLockRegionSize; if( FLASHD_Unlock(l_start, l_end, pActualStart, pActualEnd) != 0) { TRACE_INFO("Unlock failed! \n\r"); //ASSERT( *pActualStart == l_start, "-F- Unlock failed! \n\r"); //ASSERT( *pActualEnd == (l_start + flashLockRegionSize), "-F- Unock failed! \n\r"); pMailbox->status = APPLET_UNPROTECT_FAIL; goto exit; } TRACE_INFO("Unlock sector achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // GPNVM : // ---------------------------------------------------------- #if !defined (at91sam7a3) else if (pMailbox->command == APPLET_CMD_GPNVM) { if( pMailbox->argument.inputGPNVM.action == 0) { TRACE_INFO("DEACTIVATES GPNVM command \n\r"); error = FLASHD_ClearGPNVM(pMailbox->argument.inputGPNVM.bitsOfNVM); } else { TRACE_INFO("ACTIVATES GPNVM command \n\r"); error = FLASHD_SetGPNVM(pMailbox->argument.inputGPNVM.bitsOfNVM); } if(error != 0) { TRACE_INFO("GPNVM failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("GPNVM achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } #endif // #if !defined (at91sam7a3) // ---------------------------------------------------------- // SET SECURITY : // ---------------------------------------------------------- #if defined(CHIP_FLASH_EFC) && !defined (at91sam7a3) else if (pMailbox->command == APPLET_CMD_SECURITY) { TRACE_INFO("SET SECURITY BIT command \n\r"); if (FLASHD_SetSecurityBit() != 0) { TRACE_INFO("SET SECURITY BIT failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("SET SECURITY BIT achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } #endif #if defined(at91sam3u4) // ---------------------------------------------------------- // READ UNIQUE ID : // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ_UNIQUE_ID) { TRACE_INFO("READ UNIQUE ID command \n\r"); if (FLASHD_ReadUniqueID (pMailbox->argument.inputReadUniqueID.bufferAddr) != 0) { TRACE_INFO("Read Unique ID failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("Read Unique ID achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } #endif exit: // Acknowledge the end of command TRACE_INFO("\tEnd of Applet %x %x.\n\r", pMailbox->command, pMailbox->status); // Notify the host application of the end of the command processing pMailbox->command = ~(pMailbox->command); // Send ACK character if (comType == DBGU_COM_TYPE) { DBGU_PutChar(0x6); } return 0; }
//------------------------------------------------------------------------------ /// Applet code for initializing the external RAM. //------------------------------------------------------------------------------ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; unsigned int ramType = 0; unsigned int dataBusWidth = 0; unsigned int ddrModel = 0; unsigned int baseAddress = 0; unsigned int *ramAddr = (unsigned int *) EXTRAM_ADDR; unsigned int comType = 0; TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); // ---------------------------------------------------------- // INIT: // ---------------------------------------------------------- if (pMailbox->command == APPLET_CMD_INIT) { // Save info of communication link comType = pMailbox->argument.inputInit.comType; #if (TRACE_LEVEL==0) && (DYN_TRACES==0) if (comType == DBGU_COM_TYPE){ // Function TRACE_CONFIGURE_ISP wiil be bypass due to the 0 TRACE_LEVEL. We shall reconfigure the baut rate. DBGU_Configure(DBGU_STANDARD, 115200, BOARD_MCK); } #endif // Enable User Reset AT91C_BASE_RSTC->RSTC_RMR |= AT91C_RSTC_URSTEN | (0xA5<<24); ramType = pMailbox->argument.inputInit.ramType; dataBusWidth = pMailbox->argument.inputInit.dataBusWidth; ddrModel = pMailbox->argument.inputInit.ddrModel; baseAddress = pMailbox->argument.inputInit.baseAddress; #if (DYN_TRACES == 1) traceLevel = pMailbox->argument.inputInit.traceLevel; #endif TRACE_INFO("-- EXTRAM Applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); TRACE_INFO("INIT command:\n\r"); TRACE_INFO("\tCommunication link type : %d\n\r", pMailbox->argument.inputInit.comType); TRACE_INFO("\tData bus width : %d bits\n\r", dataBusWidth); if (ramType == TYPE_SDRAM) { TRACE_INFO("\tExternal RAM type : %s\n\r", "SDRAM"); } else { if (ramType == TYPE_DDRAM) { TRACE_INFO("\tExternal RAM type : %s\n\r", "DDRAM"); } else { TRACE_INFO("\tExternal RAM type : %s\n\r", "PSRAM"); } } #if defined(at91cap7) || defined(at91cap9) || defined(at91sam9m10) || defined(at91sam9g45) TRACE_INFO("\tInit EBI Vdd : %s\n\r", (pMailbox->argument.inputInit.VddMemSel)?"3.3V":"1.8V"); BOARD_ConfigureVddMemSel(pMailbox->argument.inputInit.VddMemSel); #endif //defined(at91cap9) if (pMailbox->argument.inputInit.ramType == TYPE_SDRAM) { // Configure SDRAM controller TRACE_INFO("\tInit SDRAM...\n\r"); #if defined(PINS_SDRAM) BOARD_ConfigureSdram(dataBusWidth); #endif } else if (pMailbox->argument.inputInit.ramType == TYPE_PSRAM) { TRACE_INFO("\tInit PSRAM...\n\r"); #if defined(at91sam3u) BOARD_ConfigurePsram(); #endif } else { // Configure DDRAM controller #if defined(at91sam9m10) || defined(at91sam9g45) TRACE_INFO("\tInit DDRAM ... (model : %d)\n\r", ddrModel); BOARD_ConfigureDdram(baseAddress, ddrModel, dataBusWidth); if (baseAddress != (unsigned int)AT91C_BASE_DDR2C) { ramAddr = (unsigned int *)EXTRAM_ADDR_2; } #elif defined(at91cap9dk) TRACE_INFO("\tInit DDRAM ... (model : %d)\n\r", ddrModel); BOARD_ConfigureDdram(ddrModel, dataBusWidth); #endif } // Test external RAM access if (ExtRAM_TestOk(ramAddr)) { pMailbox->status = APPLET_SUCCESS; } else { pMailbox->status = APPLET_FAIL; } pMailbox->argument.outputInit.bufferAddress = ((unsigned int) &end); pMailbox->argument.outputInit.bufferSize = 0; pMailbox->argument.outputInit.memorySize = EXTRAM_SIZE; TRACE_INFO("\tInit successful.\n\r"); } // Acknowledge the end of command TRACE_INFO("\tEnd of applet (command : %x --- status : %x)\n\r", pMailbox->command, pMailbox->status); // Notify the host application of the end of the command processing pMailbox->command = ~(pMailbox->command); // Send ACK character if (comType == DBGU_COM_TYPE) { DBGU_PutChar(0x6); } return 0; }
//------------------------------------------------------------------------------ /// Bootstrap main application. /// Transfer data from media to main memory and return the next application entry /// point address. //------------------------------------------------------------------------------ int main() { int i=0; //, j=0; // int Dc=0, Dp=0; // Enable User Reset AT91C_BASE_RSTC->RSTC_RMR |= AT91C_RSTC_URSTEN | (0xA5<<24); //------------------------------------------------------------------------- // Configure traces //------------------------------------------------------------------------- TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, MASTERCLK); printf("\n\r"); printf("-- Acme Test version %s --\n\r", ACME_TEST_VERSION); printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); printf("Setting: masterclk = %d Hz\n\r",MASTERCLK); printf(" CPU Clock = %d Hz\n\r", MASTERCLK*3); printf("AT91C_BASE_DBGU->DBGU_BRGR = %d\n\r", (int)AT91C_BASE_DBGU->DBGU_BRGR); printf("BOARD_MULA = 0x%0x\n\r", (int)BOARD_MULA>>16); printf("BOARD_DIVA = 0x%0x\n\r", (int)BOARD_DIVA); printf("AT91C_BASE_PMC->PMC_PLLAR = %0x\n\r", (int)AT91C_BASE_PMC->PMC_PLLAR); printf("MULA = 0x%0x OUTA = 0x%0x PLLACOUNT = 0x%0x DIVA = 0x%0x \n\r", (AT91C_BASE_PMC->PMC_PLLAR&0x00ff0000)>>16, (AT91C_BASE_PMC->PMC_PLLAR&0x0000c000)>>14, (AT91C_BASE_PMC->PMC_PLLAR&0x00003f00)>>8, (AT91C_BASE_PMC->PMC_PLLAR&0x000000ff)); printf("BOARD_OSCOUNT = %0x; AT91C_CKGR_MOSCEN = %0x \n\r",BOARD_OSCOUNT,AT91C_CKGR_MOSCEN); // Configure FoxG20 LED PIO_Configure(&FoxLED, 1); // configure it as an output with level = logical 1. It should start with red led ON. /* init_Daisy1(); init_Daisy2(); init_Daisy3(); init_Daisy4(); init_Daisy5(); init_Daisy6(); init_Daisy7(); init_Daisy8(); */ //------------------------------------------------------------------------- // Enable I-Cache //------------------------------------------------------------------------- CP15_EnableIcache(); //------------------------------------------------------------------------- // Configure external RAM where the application will be transfered //------------------------------------------------------------------------- // SDRAM #if defined(DESTINATION_sdram) printf("Init SDRAM\n\r"); BOARD_ConfigureSdram(BOARD_SDRAM_BUSWIDTH); #endif printf("1"); printf("2"); printf("3"); printf("4"); printf("5"); printf("6"); printf("8\n"); printf("LED toggles every 300000 cycles\n\r"); #if 0 while(1) { for (Dc=1; Dc<9; Dc++) { for (Dp=2; Dp<9; Dp++) { DaisyClear(Dc, Dp); DaisySet(Dc, Dp); } } } #endif while(1) { i++; if (i%300000 == 0) { if (stateFoxLED == 1) { PIO_Clear(&FoxLED); stateFoxLED = 0; } else { PIO_Set(&FoxLED); stateFoxLED = 1; } } /* j++; switch(j) { case 1: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 3); DaisySet(Dc, 2); } break; case 2: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 2); DaisySet(Dc, 3); } break; case 3: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 3); DaisySet(Dc, 4); } break; case 4: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 4); DaisySet(Dc, 5); } break; case 5: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 5); DaisySet(Dc, 6); } break; case 6: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 6); DaisySet(Dc, 7); } break; case 7: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 7); DaisySet(Dc, 8); } break; case 8: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 8); DaisySet(Dc, 9); } break; case 9: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 9); DaisySet(Dc, 8); } break; case 10: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 8); DaisySet(Dc, 7); } break; case 11: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 7); DaisySet(Dc, 6); } break; case 12: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 6); DaisySet(Dc, 5); } break; case 13: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 5); DaisySet(Dc, 4); } break; case 14: for (Dc=1; Dc<9; Dc++) { DaisyClear(Dc, 4); DaisySet(Dc, 3); } j=0; } } */ } // printf("Jump to the Kernel image at %x\n\r",entry_point); // GoToJumpAddress(entry_point, MACH_TYPE); return 0; }