static void FlushFlash( void ) { /* Erase flash sector */ NORFLASH_EraseSector( (uint32_t)flashStatus.pPageBase ); /* Program flash sector */ NORFLASH_Program( (uint32_t)flashStatus.pPageBase, flashPageBuf, flashPageSize ); }
//------------------------------------------------------------------------------ // 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; }