Example #1
0
static bool_t __SPI_DmaConfig(u32 BaseAddr)
{
    SpiDma *pSpiDma;
    SpiChannel *pSpiTx,*pSpiRx;
    u8 PeriId,port;

    if(BaseAddr == (u32)tg_SPI_Reg[CN_SPI0])
    {
        port = CN_SPI0;
        PeriId = ID_SPI0;
        pSpiDma = &Spid0;
        pSpiTx  = &Spi0Tx;
        pSpiRx  = &Spi0Rx;
    }
    else if(BaseAddr == (u32)tg_SPI_Reg[CN_SPI1])
    {
        port = CN_SPI1;
        PeriId = ID_SPI1;
        pSpiDma = &Spid1;
        pSpiTx  = &Spi1Tx;
        pSpiRx  = &Spi1Rx;
    }
    else
        return false;

    memset(pSpiTx, 0, sizeof(SpiChannel));
    memset(pSpiRx, 0, sizeof(SpiChannel));

    pSpiTx->BuffSize = SPI_DMA_BUF_LEN;
    pSpiTx->pBuff = pSpiDmaSendBuf[port];
    pSpiRx->BuffSize= SPI_DMA_BUF_LEN;
    pSpiRx->pBuff = pSpiDmaRecvBuf[port];
    pSpiTx->pArgument = (void*)pSpiDma;
    pSpiRx->pArgument = (void*)pSpiDma;
    pSpiTx->callback = (SpiCallback)SPI_DmaRxTxIntIsr;
    pSpiRx->callback = (SpiCallback)SPI_DmaRxTxIntIsr;

    pSpiDma->pRxChannel = pSpiRx;
    pSpiDma->pTxChannel = pSpiTx;
    pSpiDma->pXdmad = &dmad;
    pSpiDma->SpiId  = PeriId;
    pSpiDma->pSpiReg = (Spi *)BaseAddr;
    pSpiDma->sempaphore = 1;

    if(SPID_Configure(pSpiDma))
        return false;

    return true;
}
Example #2
0
int main(int argc, char **argv)
{
    struct _Mailbox *pMailbox = (struct _Mailbox *) argv;

    /* Communication type with SAM-BA GUI. */
    uint8_t comType;

    uint32_t jedecId;
    uint32_t bytesToWrite, bytesToRead, bufferAddr, startMemoryOffset, memoryOffset, packetSize;
    /* index on read/write buffer */
    uint8_t *pBuffer;
    /* Temporary buffer used for non block aligned read/write */
    uint32_t tempBufferAddr;
    /* Offset in destination buffer during buffer copy */
    uint32_t bufferOffset;
    /* INIT */  
    /* Save communication link type */
    comType = pMailbox->argument.inputInit.comType;

    if (pMailbox->command == APPLET_CMD_INIT) {
 

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

        TRACE_INFO("-- SerialFlash AT25/AT26 applet %s --\n\r", SAM_BA_APPLETS_VERSION);
        TRACE_INFO("-- %s\n\r", BOARD_NAME);
        TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
        /* Configure pins */
        PIO_Configure(pins, PIO_LISTSIZE(pins));
        /* Initialize DMA driver instance with polling mode */
        DMAD_Initialize( &dmad, 1 );
        
        /* Initialize the SPI and serial flash */
        SPID_Configure(&spid, SPI0, ID_SPI0, &dmad);
        AT25_Configure(&at25, &spid, SPI_CS, 1);
        TRACE_INFO("SPI and AT25/AT25 drivers initialized\n\r");
        pMailbox->argument.outputInit.bufferAddress = (uint32_t) &_end ;
        /* Read the JEDEC ID of the device to identify it */
        jedecId = AT25D_ReadJedecId(&at25);
        if (AT25_FindDevice(&at25, jedecId) == 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 {
            /* Get device parameters */
            pMailbox->status = APPLET_SUCCESS;
            pageSize = AT25_PageSize(&at25);
            blockSize = AT25_BlockSize(&at25);

            /* Program page */
            if (AT25_ManId(&at25) == SST_SPI_FLASH) {
                /* SST Flash write is slower, we reduce buffer size to avoid USB timeout */
                bufferSize = 10 * pageSize;
            }
            else {
                bufferSize = 4 * blockSize;
            }
            /* integer number of pages can be contained in each buffer */
            bufferSize -= bufferSize % pageSize; 
            if ( bufferSize < pageSize) {
                TRACE_INFO("No enought memory to load buffer.\n\r");
                goto exit;
            } 
            pMailbox->argument.outputInit.bufferSize = bufferSize;
            pMailbox->argument.outputInit.memorySize = AT25_Size(&at25);
            TRACE_INFO("%s blockSize : 0x%lx bufferAddr : 0x%lx\n\r",
                   at25.pDesc->name, blockSize, pMailbox->argument.outputInit.bufferAddress);
        }
    }

    // ----------------------------------------------------------
    // WRITE:
    // ----------------------------------------------------------
    else if (pMailbox->command == APPLET_CMD_WRITE) {
        startMemoryOffset = pMailbox->argument.inputWrite.memoryOffset;
        memoryOffset      = startMemoryOffset;
        bufferAddr        = pMailbox->argument.inputWrite.bufferAddr;
        tempBufferAddr    = bufferAddr + bufferSize;
        bytesToWrite      = pMailbox->argument.inputWrite.bufferSize;
        TRACE_INFO("WRITE at offset: 0x%lx buffer at : 0x%lx of: 0x%lx Bytes\n\r",
               memoryOffset, bufferAddr, bytesToWrite);
        /* Check word alignment */
        if (memoryOffset % 4) {

            pMailbox->status = APPLET_ALIGN_ERROR;
            goto exit;
        }

        if (AT25D_Unprotect(&at25)) {

            TRACE_INFO("Can not unprotect the flash\n\r");
            pMailbox->status = APPLET_UNPROTECT_FAIL;
            goto exit;
        }
        pBuffer = (uint8_t *) bufferAddr;

        if ((memoryOffset % pageSize) != 0) {

            /*  We are not page aligned, retrieve first page content to update it*/
            if (memoryOffset < writtenAddress) {
                lastErasedBlock = 0xFFFF;
            }
            /*  Flush temp buffer */
            memset((uint32_t *)tempBufferAddr, 0xFF, pageSize);

            bufferOffset = (memoryOffset % pageSize);
            packetSize = pageSize - bufferOffset;
            memoryOffset -= bufferOffset;
            /*  Read page to be updated*/
            AT25D_Read(&at25, (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
            /* Fill retrieved page with data to be programmed */
            memcpy((uint8_t *)(tempBufferAddr + bufferOffset), pBuffer, packetSize);

             if (((memoryOffset / blockSize) > lastErasedBlock) || (lastErasedBlock == 0xFFFF)) {
                /* Erase the block to be updated */
                AT25D_EraseBlock(&at25, memoryOffset);
                lastErasedBlock = (memoryOffset / blockSize);
            }

            /*  Write the page contents */
            AT25D_Write(&at25, (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
            bytesToWrite = (bytesToWrite > packetSize) ? (bytesToWrite - packetSize) : 0;
            pBuffer += packetSize;
            memoryOffset += pageSize;
            writtenAddress = memoryOffset;
        }

        /*  If it remains more than one page to write */
        while (bytesToWrite >= pageSize) {
            if (memoryOffset < writtenAddress) {
                lastErasedBlock = 0xFFFF;
            }
             if (((memoryOffset / blockSize) > lastErasedBlock) || (lastErasedBlock == 0xFFFF)) {
                 /* Erase the block to be updated */
                AT25D_EraseBlock(&at25, memoryOffset);
                 lastErasedBlock = (memoryOffset / blockSize);
            }
            /*  Write the page contents */
            AT25D_Write(&at25, (uint8_t *) pBuffer, pageSize, memoryOffset);
            pBuffer += pageSize;
            memoryOffset += pageSize;
            bytesToWrite -= pageSize;
            writtenAddress = memoryOffset;
        }

        /*  Write remaining data */
        if (bytesToWrite > 0) {

            /*  Read previous content of page */
            AT25D_Read(&at25, (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
            /*  Fill retrieved block with data to be programmed */
            memcpy((uint8_t *)tempBufferAddr, pBuffer, bytesToWrite);
            if (((memoryOffset / blockSize) > lastErasedBlock) || (lastErasedBlock == 0xFFFF)) {
                 /*  Erase the block to be updated */
                AT25D_EraseBlock(&at25, memoryOffset);
                 lastErasedBlock = (memoryOffset / blockSize);
            }
            /*  Write the page contents */;
            AT25D_Write(&at25, (uint8_t *) tempBufferAddr, pageSize, memoryOffset);
            writtenAddress = memoryOffset + bytesToWrite;
            /*  No more bytes to write */
            bytesToWrite = 0;
        }

        TRACE_INFO("WRITE return byte written : 0x%lx 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%lx buffer at : 0x%lx of: 0x%lx Bytes\n\r",
               memoryOffset, bufferAddr, bytesToRead);
        /*  Check word alignment */
        if (memoryOffset % 4) {

            pMailbox->status = APPLET_ALIGN_ERROR;
            goto exit;
        }
        pBuffer = (uint8_t *) bufferAddr;

        /* Read packet after packets */
        while (((uint32_t)pBuffer < (bufferAddr + bufferSize)) && (bytesToRead > 0)) {

            packetSize = min(MAX_COUNT, bytesToRead);
            AT25D_Read(&at25, pBuffer, packetSize, memoryOffset);
            pBuffer += packetSize;
            bytesToRead -= packetSize;
            memoryOffset += packetSize;
        }

        TRACE_INFO("READ return byte read : 0x%lx 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\n\r");

        /* Unprotected the flash */
        if (AT25D_Unprotect(&at25)) {

            TRACE_INFO("Can not unprotect the flash\n\r");
            pMailbox->status = APPLET_UNPROTECT_FAIL;
            goto exit;
        }

        TRACE_INFO("Flash unprotected\n\r");

        /* Erase the chip */
        TRACE_INFO("Chip is being erased...\n\r");

        if (AT25D_EraseChip(&at25)) {

            TRACE_INFO("Erasing error\n\r");
            pMailbox->status = APPLET_ERASE_FAIL;
            goto exit;
        }

        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 \n\r");
         /*  Unprotected the flash */
        if (AT25D_Unprotect(&at25)) {

            TRACE_INFO("Can not unprotect the flash\n\r");
            pMailbox->status = APPLET_UNPROTECT_FAIL;
            goto exit;
        }

         memoryOffset = pMailbox->argument.inputBufferErase.memoryOffset;

           if (AT25D_EraseBlock(&at25, memoryOffset)) {
            pMailbox->status = APPLET_ERASE_FAIL;
            TRACE_INFO("Block erasing error\n\r");
            goto exit;
        }
        pMailbox->argument.outputBufferErase.bytesErased = AT25_BlockSize(&at25);

        TRACE_INFO("Buffer Erase achieved\n\r");
        pMailbox->status = APPLET_SUCCESS;
    }
exit:
    /* Acknowledge the end of command */
    TRACE_INFO("\tEnd of applet (command : %lx --- status : %lx)\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) {
         /* Wait for the transmitter to be ready */
        while ( (DBGU->DBGU_SR & DBGU_SR_TXEMPTY) == 0 ) ;
        /* Send character */
         DBGU->DBGU_THR= 0x06 ;
    }
    return 0;
}
Example #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;
    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;
}
Example #4
0
int main(int argc, char **argv)
{
    struct _Mailbox *pMailbox = (struct _Mailbox *) argv;

    const At45Desc *pDesc = 0;
    uint32_t bytesToWrite, bytesToRead, bufferAddr, memoryOffset, packetSize;
    /* index on read/write buffer */
    uint8_t *pBuffer;
    /* Temporary buffer used for non block aligned read/write */
    uint32_t tempBufferAddr;
    /* Offset in destination buffer during buffer copy */
    uint32_t bufferOffset;

    /* Configure pins */
    PIO_Configure(pins, PIO_LISTSIZE(pins));

    if (pMailbox->command == APPLET_CMD_INIT) {
        /* Save communication link type */
        comType = pMailbox->argument.inputInit.comType;

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

        TRACE_INFO("-- DataFlash AT45 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 DMA driver instance with polling mode */
        DMAD_Initialize( &dmad, 1 );
        /* Initialize the SPI and serial flash */
        SPID_Configure(&spid, SPI0, ID_SPI0, &dmad);
        AT45_Configure(&at45, &spid, SPI_CS, 1);
        TRACE_INFO("SPI and at45 drivers initialized\n\r");
        pMailbox->argument.outputInit.bufferAddress = (uint32_t) &_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("Device Unknown\n\r");
            goto exit;
        }
        else {
            /* Get device parameters */
            pMailbox->status = APPLET_SUCCESS;
            pageSize = AT45_PageSize(&at45);
            numPages = AT45_PageNumber(&at45);
            /* Program page */
            bufferSize = BUFFER_NB_PAGE * pageSize;
            pMailbox->argument.outputInit.bufferSize = bufferSize;
            pMailbox->argument.outputInit.memorySize = numPages * pageSize;
            TRACE_INFO("%s numPages : 0x%x bufferAddr : 0x%x\n\r",
                   at45.pDesc->name, (unsigned int)numPages, (unsigned int)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",
               (unsigned int)memoryOffset, (unsigned int)bufferAddr,(unsigned int) bytesToWrite);

        pBuffer = (unsigned char *) bufferAddr;
        tempBufferAddr = bufferAddr + bufferSize;

        if ((memoryOffset % pageSize) != 0) {

            /* We are not page aligned, retrieve first page content to update it */
            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",
               (unsigned int)(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",
               (unsigned int)memoryOffset, (unsigned int)bufferAddr, (unsigned int)bytesToRead);

        pBuffer = (unsigned char *) bufferAddr;

        /* Read packet after packets */
        while (((unsigned int)pBuffer < (bufferAddr + bufferSize)) && (bytesToRead > 0)) {

            packetSize = min(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",
               (unsigned int)(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", (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) {
        DBGU_PutChar(0x6);
    }
    return 0;
}