Esempio n. 1
0
static void flashEraseCallback(void)
{
    // Disable global interrupts
    IntMasterDisable();

    // Erase Flash CCA page
    FlashMainPageErase(CC2538_FLASH_CCA_ADDRESS);

    // Reset the board
    SysCtrlReset();
}
Esempio n. 2
0
//*****************************************************************************
//
// Configure the device, erase an page and the program the page.
//
//*****************************************************************************
int
main(void)
{
    int32_t i32Res;
    uint32_t i;
    char pcStrInRam[16] = "Hello ... world!";    

    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // (no ext 32k osc, no internal osc)
    //
    SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);

    //
    // Set IO clock to the same as system clock
    //
    SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);
       
    //
    // Erase a page
    //
    i32Res = FlashMainPageErase(PAGE_TO_ERASE_START_ADDR);
    ASSERT(i32Res==0);
    
    //
    // Program a page in chunks
    //
    for(i=0; i<PAGE_SIZE; i+=sizeof(pcStrInRam))
    {
        i32Res = FlashMainPageProgram((uint32_t*) pcStrInRam, 
                                      PAGE_TO_ERASE_START_ADDR+i,
                                      sizeof(pcStrInRam));
        ASSERT(i32Res==0);
    }
    
    //
    // Loop forever
    //
    while(1)
    {
    }
}
Esempio n. 3
0
/**************************************************************************************************
 * @fn          sbCmnd
 *
 * @brief       Act on the SB command and received buffer.
 *
 * input parameters
 *
 * @param 		sbCmd - Received SBL command.
 * @param		payload_len - Length of command payload
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE to indicate that the SB_ENABLE_CMD command was successful; FALSE otherwise.
 **************************************************************************************************
 */
static uint8 sbCmnd(uint8 sbCmd, uint32 payload_len)
{
    uint32        firstAddr;
    uint32        lastAddr;
    uint32        operationLength;
    uint32        writeLength;
    uint32        respPayloadLen = 0;
    uint32        pageNumber;
    uint32        i;
    uint32        actual_number_of_data_bytes_to_send;
    uint8         paddingLength;
    uint8         rsp = SB_SUCCESS;
    uint8         imageEnabledSuccessfully = FALSE;
    uint8         *pBuf;

    pBuf = sbBuf;

    switch (sbCmd)
    {
    case SB_HANDSHAKE_CMD:
        /* Mark all pages as not-deleted-yet */
        memset(pageDeleted, 0, sizeof(pageDeleted));

        UINT32_TO_BUF_LITTLE_ENDIAN(pBuf, SB_BOOTLOADER_REVISION);
        *pBuf++ = SB_DEVICE_TYPE_2538;
        UINT32_TO_BUF_LITTLE_ENDIAN(pBuf, SB_RW_BUF_LEN );
        UINT32_TO_BUF_LITTLE_ENDIAN(pBuf, SB_DEVICE_PAGE_SIZE);
        respPayloadLen = pBuf - sbBuf;
        break;

    case SB_WRITE_CMD:
        firstAddr = BUF_TO_UINT32_LITTLE_ENDIAN(pBuf);
        operationLength = BUF_TO_UINT32_LITTLE_ENDIAN(pBuf);

        /* The payload_len includes the addr_offset
         * and the operationLength fields. The value
         * (pBuf - sbBuf) gives the number of bytes
         * used by those firelds. The remaining bytes
         *  are the actual data bytes to be written.
         */
        writeLength = payload_len - (pBuf - sbBuf);
        lastAddr = firstAddr + operationLength - 1;
        if ((firstAddr < FLASH_BASE) ||
                (lastAddr > CC2538_CODE_FLASH_END_ADDRESS) ||
                (writeLength > operationLength))
        {
            rsp = SB_FAILURE;
            break;
        }

        /* Before writing to a flash page for the first time during a bootloading session, the
         * page must be erased. The following section makes sure that every page being written
         * to have already been erased, otherwise, it erases it (before writing to it).
         * Note that the write command may span over more than a single page.
         */
        for (pageNumber = GET_PAGE_NUMBER(firstAddr); pageNumber <= GET_PAGE_NUMBER(lastAddr); pageNumber++)
        {
            if (!IS_PAGE_ERASED(pageNumber))
            {
                if (FlashMainPageErase(GET_PAGE_ADDRESS(pageNumber)) != 0)
                {
                    rsp = SB_FAILURE;
                    break;
                }

                MARK_PAGE_ERASED(pageNumber);
            }
        }

        /* Note that the start address (firstAddr) and the byte count (writeLength) must be
         * word aligned. The start address is expected to be already aligned (by the SBL server),
         * since aligning it here would require padding the buffer's start, which would require
         * shifting the buffer content (as the buffer is passesd as (uint32_t *pui32Data) so it
         * should be aligned by itself. The byte count is aligned below.
         */
        paddingLength = ((4 - (writeLength & 0x00000003)) % 4);
        for (i = 0; i < paddingLength; i++)
        {
            pBuf[writeLength + i] = 0xFF;
        }
        writeLength += paddingLength;


        /* If the page was successfully erased (or was previously erased), perform the write action.
         * Note that pBuf must point to a uint32-aligned address, as required by FlashMainPageProgram().
         * This is the case now (the prefixing field are total of 8 bytes), and _sbBuf is 32bit aligned.
         */
        if ((rsp == SB_SUCCESS) && (writeLength > 0) &&
                (FlashMainPageProgram((uint32_t *)(pBuf), firstAddr, writeLength) != 0))
        {
            rsp = SB_FAILURE;
        }

        break;

    case SB_READ_CMD:
        firstAddr = BUF_TO_UINT32_LITTLE_ENDIAN(pBuf);
        operationLength = BUF_TO_UINT32_LITTLE_ENDIAN(pBuf);
        lastAddr = firstAddr + operationLength - 1;

        if ((firstAddr < FLASH_BASE) ||
                (lastAddr > CC2538_CODE_FLASH_END_ADDRESS) ||
                (operationLength > sizeof(_sbBuf)))
        {
            rsp = SB_FAILURE;
            break;
        }

#if !MT_SYS_OSAL_NV_READ_CERTIFICATE_DATA
#if (HAL_IMG_A_BEG > HAL_NV_START_ADDR)
#warning This check assumes NV PAGES located at the end of the program flash memory
#endif
        if (GET_PAGE_NUMBER(lastAddr) >= HAL_NV_PAGE_BEG)
        {
            rsp = SB_FAILURE;
            break;
        }
#endif

        /* If the end of the buffer is made only of 0xFF characters, no need to
         *  send them. Find out the number of bytes that needs to be sent:
         */
        for (actual_number_of_data_bytes_to_send = operationLength;
                (actual_number_of_data_bytes_to_send > 0) && ((*(uint8 *)(firstAddr + actual_number_of_data_bytes_to_send - 1)) == 0xFF);
                actual_number_of_data_bytes_to_send--);

        /* As a future upgrade, memcopy can be avoided. Instead,
         * may pass a pointer to the actual flash address
         */
        (void)memcpy(pBuf, (const void *)firstAddr, actual_number_of_data_bytes_to_send);
        respPayloadLen = (pBuf - sbBuf) + actual_number_of_data_bytes_to_send;
        break;

    case SB_ENABLE_CMD:
        if (enableImg())
        {
            imageEnabledSuccessfully = TRUE;
        }
        else
        {
            rsp = SB_VALIDATE_FAILED;
        }
        break;

    default:
        break;
    }

    sbResp(sbCmd, rsp, respPayloadLen);
    return imageEnabledSuccessfully;
}
Esempio n. 4
0
void flash_erase_page(uint32_t address) {
    FlashMainPageErase(address);
}
Esempio n. 5
0
/**
 * GPIO_C ISR handler. User button is GPIO_C_3
 * Erases a Flash sector to trigger the bootloader backdoor
 */
void GPIO_C_Isr_Handler(){
    IntMasterDisable();
    FlashMainPageErase(CC2538_FLASH_ADDRESS);
    SysCtrlReset();
}
Esempio n. 6
0
//*****************************************************************************
//
// Main function, setup DMA and perform flash write. Verify the transaction.
//
//*****************************************************************************
int
main(void)
{
    uint16_t i;
    int32_t i32Res;
  
    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // (no ext 32k osc, no internal osc)
    //
    SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);

    //
    // Set IO clock to the same as system clock
    //
    SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);
    
    
    //
    // Set up the serial console to use for displaying messages.  This is
    // just for this example program and is not needed for Systick operation.
    //
    InitConsole();

    //
    // Display the setup on the console.
    //
    UARTprintf("Example - Write to Flash using DMA.\n");
    
    //
    // Erase Flash page that will hold our transferred data
    //
    i32Res = FlashMainPageErase(PAGE_TO_ERASE_START_ADDR);
    ASSERT(i32Res==0);
    
    //
    // Fill Source buffer (to be copied to flash) with some data
    //
    for(i=0; i<256; i++)
    {
        ucSourceBuffer[i] = '0' + (i % 10);
    }
    
    //
    // Enable the uDMA controller.
    //
    uDMAEnable();
    
    //
    // Disable the uDMA channel to be used, before modifications are done.
    //
    uDMAChannelDisable(UDMA_CH2_FLASH);

    //
    // Set the base for the channel control table.
    //
    uDMAControlBaseSet(&ucDMAControlTable[0]);

    //
    // Assign the DMA channel
    //
    uDMAChannelAssign(UDMA_CH2_FLASH);
    
    //
    // Set attributes for the channel.
    //
    uDMAChannelAttributeDisable(UDMA_CH2_FLASH, UDMA_ATTR_HIGH_PRIORITY);

    //
    // Now set up the characteristics of the transfer.
    // 32-bit data size, with source increments in words (32 bits), 
    // no destination increment.
    // A bus arbitration size of 1 must be used.
    //
    uDMAChannelControlSet(UDMA_CH2_FLASH, UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                          UDMA_DST_INC_NONE | UDMA_ARB_1);

    //
    // Set transfer parameters. 
    // Source address is the location of the data to write
    // and destination address is the FLASH_CTRL_FWDATA register.
    //
    uDMAChannelTransferSet(UDMA_CH2_FLASH, UDMA_MODE_BASIC, ucSourceBuffer, 
                           (void *) FLASH_CTRL_FWDATA, sizeof(ucSourceBuffer));

    //
    // Asure that the flash controller is not busy.
    //
    while(HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_BUSY)
    {
    }
    
    //
    // Initialize Flash control register without changing the cache mode.
    //
    HWREG(FLASH_CTRL_FCTL) &= FLASH_CTRL_FCTL_CM_M;
    
    //
    // Setup Flash Address register to address of first data word (32-bit)
    //
    HWREG(FLASH_CTRL_FADDR) = PAGE_TO_ERASE_START_ADDR;
    
    //
    // Finally, the DMA channel must be enabled.
    //
    uDMAChannelEnable(UDMA_CH2_FLASH);
    
    //
    // Set FCTL.WRITE, to trigger flash write
    //
    HWREG(FLASH_CTRL_FCTL) |= FLASH_CTRL_FCTL_WRITE;
    
    //
    // Wait until all words has been programmed.
    //
    while( HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_FULL )
    {
    }
    
    // 
    // Check if flash write was successfull
    //
    if (HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_ABORT)
    {
        UARTprintf("Write not successful!\n");
    }
    else
    {
        UARTprintf("Write success!\n");
    }
    
    //
    // Set control register back to reset value without changing the cache mode.
    //
    HWREG(FLASH_CTRL_FCTL) &= FLASH_CTRL_FCTL_CM_M;
    

    //
    // Compare source buffer and destination flash page
    //
    if(memcmp(ucSourceBuffer, (void*) PAGE_TO_ERASE_START_ADDR, 256)==0)
    {
        UARTprintf("Buffer compares to flash page!\n");
    }
    else
    {
        UARTprintf("Buffer does not compare to flash page!\n");
    }
    
    //
    // We are done, loop forever
    //
    while(1)
    {
    }
}