Пример #1
0
/**
 * \brief  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;

    uint32_t bytesToWrite, bufferAddr, memoryOffset;
    uint32_t l_start, l_end;
    uint32_t *pActualStart = NULL;
    uint32_t *pActualEnd = NULL;
    uint8_t error;

     /* Disable watchdog */
    WDT_Disable( WDT ) ;

    //TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK);

    // ----------------------------------------------------------
    // INIT:
    // ----------------------------------------------------------
    if (pMailbox->command == APPLET_CMD_INIT) {

        // Save communication link type
        comType = pMailbox->argument.inputInit.comType;

        if (comType == DBGU_COM_TYPE){
            USART_Configure(UART0, UART_MR_PAR_NONE, 115200, BOARD_MCK);
            USART_SetTransmitterEnabled(UART0, 1); 
            USART_SetReceiverEnabled(UART0, 1); 
        }

        flashBaseAddr       = AT91C_IFLASH;
        flashBaseAddrInit   = AT91C_IFLASH;
        flashSize           = AT91C_IFLASH_SIZE;
        flashPageSize       = AT91C_IFLASH_PAGE_SIZE;
        flashNbLockBits     = AT91C_IFLASH_NB_OF_LOCK_BITS;
        flashLockRegionSize = AT91C_IFLASH_LOCK_REGION_SIZE;

        TRACE_INFO("-- Internal Flash Applet %s --\n\r", SAM_BA_APPLETS_VERSION);
        TRACE_INFO("-- %s\n\r", BOARD_NAME);
        TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);

        // Initialize flash driver
        //FLASHD_Initialize(BOARD_MCK);

        // flash accesses must be 4 bytes aligned
        pMailbox->argument.outputInit.bufferAddress = ((uint32_t) &end);

        bufferSize = AT91C_ISRAM_SIZE                           // sram size
                     - ( ((uint32_t) &end) - AT91C_ISRAM )  // program size (romcode, code+data)
                     - STACK_SIZE;                              // stack size at the end
        // 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));
        pMailbox->argument.outputInit.bufferSize = bufferSize;

        pMailbox->argument.outputInit.memorySize = flashSize;
        pMailbox->argument.outputInit.memoryInfo.lockRegionSize = flashLockRegionSize;
        pMailbox->argument.outputInit.memoryInfo.numbersLockBits = flashNbLockBits;

        TRACE_INFO("bufferSize : %d  bufferAddr: 0x%x \n\r",
               pMailbox->argument.outputInit.bufferSize,
               (uint32_t) &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;

        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;
        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");

        // 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;
        }
        // Implement the erase all command
        if (FLASHD_Erase(flashBaseAddr) != 0) {

            TRACE_INFO("Full erase failed! \n\r");
            pMailbox->status = APPLET_ERASE_FAIL;
            goto exit;
        }

        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");
        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");
            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");
        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");
            pMailbox->status = APPLET_UNPROTECT_FAIL;
            goto exit;
        }

        TRACE_INFO("Unlock sector achieved\n\r");
        pMailbox->status = APPLET_SUCCESS;
    }

    // ----------------------------------------------------------
    // GPNVM :
    // ----------------------------------------------------------
    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;
    }

    // ----------------------------------------------------------
    // 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;
    }

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);
    if (comType == DBGU_COM_TYPE) {
        UART_PutChar(0x6);
    }

    return 0;
}
Пример #2
0
/**
 * \brief  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;

    uint32_t bytesToWrite, bufferAddr, memoryOffset;
    uint32_t l_start, l_end;
    uint32_t *pActualStart = NULL;
    uint32_t *pActualEnd = NULL;
    uint8_t error ;
    uint32_t writeSize;
    /* Save info of communication link */
    comType = pMailbox->argument.inputInit.comType;

    /*----------------------------------------------------------
     * INIT:
     *----------------------------------------------------------*/
    if (pMailbox->command == APPLET_CMD_INIT) {
        /*  Re-configurate UART   (MCK maybe change in LowLevelInit())  */
        UART_Configure(115200, BOARD_MCK);

        /* Set 6 WS for internal Flash writing (refer to errata) */
        EFC_SetWaitState(EFC0, 6);
#if defined (EFC1)
        EFC_SetWaitState(EFC1, 6);
#endif

#if (DYN_TRACES == 1)
        dwTraceLevel = pMailbox->argument.inputInit.traceLevel;
#endif

        flashBaseAddr       = IFLASH_ADDR;
        flashBaseAddrInit   = IFLASH_ADDR;
        flashSize           = IFLASH_SIZE;
        flashPageSize       = IFLASH_PAGE_SIZE;
        flashNbLockBits     = IFLASH_NB_OF_LOCK_BITS;
        flashLockRegionSize = IFLASH_LOCK_REGION_SIZE;

        TRACE_INFO("-- Internal Flash SAM-BA Applet %s --\n\r", SAM_BA_APPLETS_VERSION);
        TRACE_INFO("-- %s\n\r", BOARD_NAME);
        TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);

        /* Initialize flash driver */
        FLASHD_Initialize(BOARD_MCK, 1);

        /* flash accesses must be 4 bytes aligned */
        pMailbox->argument.outputInit.bufferAddress = ((uint32_t) &end);

        bufferSize = IRAM_SIZE                            /* sram size */
                     - ( ((uint32_t) &end) - IRAM_ADDR )  /* program size (romcode, code+data) */
                     - STACK_SIZE;                         /* stack size at the end */
        /* 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 > SECTOR_SIZE ? SECTOR_SIZE: bufferSize;
        pMailbox->argument.outputInit.bufferSize = bufferSize;

        pMailbox->argument.outputInit.memorySize = flashSize;
        pMailbox->argument.outputInit.memoryInfo.lockRegionSize = flashLockRegionSize;
        pMailbox->argument.outputInit.memoryInfo.numbersLockBits = flashNbLockBits;

        TRACE_INFO("bufferSize : %d  bufferAddr: 0x%x \n\r",
               (int)pMailbox->argument.outputInit.bufferSize,
               (unsigned int) &end );

        TRACE_INFO("memorySize : %d lockRegionSize : 0x%x numbersLockBits : 0x%x \n\r",
               (int)pMailbox->argument.outputInit.memorySize,
               (unsigned int)pMailbox->argument.outputInit.memoryInfo.lockRegionSize,
               (unsigned int)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;

        TRACE_INFO("WRITE at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes (flash base addr : 0x%x)\n\r",
                   (unsigned int)memoryOffset, (unsigned int)bufferAddr,
                   (unsigned int)bytesToWrite, (unsigned int)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;
        }

        if (memoryOffset % SECTOR_SIZE) {
            writeSize = SECTOR_SIZE - memoryOffset % SECTOR_SIZE;
            writeSize = writeSize > bufferSize ? bufferSize : writeSize;
        } else {
            writeSize = bytesToWrite;
        }
        TRACE_INFO("Write <%x> bytes from <#%x> \n\r", (unsigned int )writeSize, (unsigned int )memoryOffset );
        
        l_start = memoryOffset / SECTOR_SIZE;
        if ((memoryOffset % SECTOR_SIZE == 0) || 
              ((memoryOffset % SECTOR_SIZE != 0) && ( memoryOffset != (lastWrittenAddr + 1)))) {
            TRACE_INFO("Erase sector <#%d> \n\r", (unsigned int )l_start );
            TRACE_INFO("Unlock from <#%x> to <#%x> for sector erasing \n\r", 
                (unsigned int )(l_start * SECTOR_SIZE), (unsigned int)((l_start + 1) * SECTOR_SIZE -1));
            FLASHD_Unlock(flashBaseAddr + l_start * SECTOR_SIZE, flashBaseAddr + (l_start + 1) * SECTOR_SIZE -1 , pActualStart, pActualEnd);
#if defined (EFC1)
            if (memoryOffset < SECTOR_SIZE) {
                FLASHD_EraseSector(IFLASH_ADDR);             /* Small sector 0: 8K */
                FLASHD_EraseSector(IFLASH_ADDR + 1024 * 8);  /* Small sector 1: 8K */
                FLASHD_EraseSector(IFLASH_ADDR + 1024 * 16); /* Large sector  : 48K */

            } else if ((memoryOffset >= IFLASH_SIZE / 2) && (memoryOffset < (IFLASH_SIZE / 2 + SECTOR_SIZE))) {
                FLASHD_EraseSector(IFLASH_ADDR + IFLASH_SIZE / 2); /* Small sector 0: 8K */
                FLASHD_EraseSector(IFLASH_ADDR + IFLASH_SIZE / 2 + 1024 * 8);  /* Small sector 1: 8K */
                FLASHD_EraseSector(IFLASH_ADDR + IFLASH_SIZE / 2 + 1024 * 16); /* Large sector  : 48K */
            } else {
                /* Common erase Other sectors */
                FLASHD_EraseSector(flashBaseAddr + memoryOffset);
            }
#else
            if (memoryOffset < SECTOR_SIZE) {
                FLASHD_EraseSector(IFLASH_ADDR);             /* Small sector 0: 8K */
                FLASHD_EraseSector(IFLASH_ADDR + 1024 * 8);  /* Small sector 1: 8K */
                FLASHD_EraseSector(IFLASH_ADDR + 1024 * 16); /* Large sector  : 48K */
            } else {
                /* Common erase Other sectors */
                FLASHD_EraseSector(flashBaseAddr + memoryOffset);
            }
#endif
        }
        /* Write data */
        if (FLASHD_Write(flashBaseAddr + memoryOffset, (const void *)bufferAddr, writeSize) != 0) {

            TRACE_INFO("Error write operation\n\r");
            pMailbox->argument.outputWrite.bytesWritten = writeSize ;
            pMailbox->status = APPLET_WRITE_FAIL;
            goto exit;
        }
        lastWrittenAddr = memoryOffset + writeSize - 1;
        TRACE_INFO("Write achieved\n\r");
        pMailbox->argument.outputWrite.bytesWritten = writeSize;
        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 (flash base addr : 0x%x)\n\r",
                   (unsigned int)memoryOffset, (unsigned int)bufferAddr,
                   (unsigned int)bufferSize,
                   (unsigned int)flashBaseAddr);

        /* read data */
        memcpy((void *)bufferAddr, (void *)(flashBaseAddr + memoryOffset), bufferSize);
        /* workaound for sam4s-xpld */
        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");

        /* 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;
        }
        /* Implement the erase all command */
        /* Erase the flash */
        if (FLASHD_Erase(flashBaseAddr) != 0) {

            TRACE_INFO("Flash erase failed! \n\r");
            pMailbox->status = APPLET_ERASE_FAIL;
            goto exit;
        }
#if defined (EFC1)
        /* Erase the flash1 */
        if (FLASHD_Erase(flashBaseAddr + flashSize / 2) != 0) {

            TRACE_INFO("Full erase failed! \n\r");
            pMailbox->status = APPLET_ERASE_FAIL;
            goto exit;
        }
#endif
        lastWrittenAddr = 0;
        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");
        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");
            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");
        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");
            pMailbox->status = APPLET_UNPROTECT_FAIL;
            goto exit;
        }

        TRACE_INFO("Unlock sector achieved\n\r");
        pMailbox->status = APPLET_SUCCESS;
    }

    /*----------------------------------------------------------
     * GPNVM :
     *----------------------------------------------------------*/
    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;
    }

    /*----------------------------------------------------------
     * READ UNIQUE ID :
     *----------------------------------------------------------*/
    else if (pMailbox->command == APPLET_CMD_READ_UNIQUE_ID) {
        TRACE_INFO("READ UNIQUE ID command \n\r");

        if (FLASHD_ReadUniqueID ((uint32_t *)(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;
    }

exit:
    /* Acknowledge the end of command */
    TRACE_INFO("\tEnd of Applet %x %x.\n\r",
              (unsigned int)pMailbox->command,
              (unsigned int)pMailbox->status);
    /* Notify the host application of the end of the command processing */
    pMailbox->command = ~(pMailbox->command);

    if (comType == DBGU_COM_TYPE) {
        UART_PutChar(0x6);
    }

    return 0;
}
Пример #3
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;
}