示例#1
0
uint32_t dfu_transport_update_start(void)
{
    uint32_t err_code;

    m_antfs_dfu_state = ANTFS_DFU_STATE_RESET;

    err_code = softdevice_ant_evt_handler_set(ant_evt_dispatch);

    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    // DFU flash activity call back.
    dfu_register_callback(dfu_cb_handler);

    // initialize mem_pools
    m_mem_pool_1.size       = 0;
    m_mem_pool_2.size       = 0;

    // It is expected that there was no ANTFS related activities before this point.
    // Check if flash is busy pre-initializing.
    // If Flash is still initializing wait until it is done.
    if (flash_busy())
    {
        // Postpone services init and ANTFS init until flash is done.
        m_antfs_dfu_state = ANTFS_DFU_STATE_INIT_DELAYED;
        return NRF_SUCCESS;
    }

    // Start services right away if flash not busy
    services_init();

    return NRF_SUCCESS;
}
示例#2
0
//Byte Page Program allows 1 to 256 bytes of data to be programmed into previously erased memory locations
//Erased locations have a logical state fo 1
void flash_program(uint8_t address[3], uint8_t *data, int len) {

	int i;

	//First we need to enable write
	write_enable();
	
	//Bring CSN low
	flash_csn_low();

	//Write OPCODE
	flash_transfer_byte(BP_PROGRAM);

	//Write the three addresses
	flash_transfer_byte(address[2]);
	flash_transfer_byte(address[1]);
	flash_transfer_byte(address[0]);

	for(i=0;i<len;i++) {
		flash_transfer_byte(data[i]);
	}

	//Bring CSN high
	flash_csn_high();

	//Loop until write actually has taken place.
	while(flash_busy() == 1);

}
示例#3
0
/**@brief Function for processing ANTFS download request event.
 *
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void antfs_event_download_request_handle(const antfs_event_return_t * p_event)
{
    uint8_t response = RESPONSE_MESSAGE_OK;

    // Grab request info.
    m_current_file_index = p_event->file_index;

    // We only have one file in the directory.
    if (m_current_file_index == 0) // directory download
    {
        // Set response parameters.
        m_response_info.file_index.data           = 0;
        // File size (per directory).
        m_response_info.file_size.data            = sizeof(m_directory);
        // File is being read, so maximum size is the file size.
        m_response_info.max_file_size             = sizeof(m_directory);
        // Send the entire file in a single block if possible.
        m_response_info.max_burst_block_size.data = sizeof(m_directory);

    }
    else if (m_current_file_index == ANTFS_FILE_INDEX_OTA_UPDATE_INFO)
    {
        // Set response parameters.
        m_response_info.file_index.data           = ANTFS_FILE_INDEX_OTA_UPDATE_INFO;
        // File size (per directory).
        m_response_info.file_size.data            = OTA_UPDATE_INFO_FILE_SIZE;
        // File is being read, so maximum size is the file size.
        m_response_info.max_file_size             = OTA_UPDATE_INFO_FILE_SIZE;
        // Send the entire file in a single block if possible.
        m_response_info.max_burst_block_size.data = OTA_UPDATE_INFO_FILE_SIZE;
    }
    // Index not found.
    else
    {
        response                                  = RESPONSE_MESSAGE_NOT_EXIST;
        m_response_info.file_index.data           = 0;
        m_response_info.file_size.data            = 0;
        m_response_info.max_file_size             = 0;
        m_response_info.max_burst_block_size.data = 0;
    }

    if (response == RESPONSE_MESSAGE_OK)
    {
        // Check if there was scheduled in Flash.
        // TODO need to track flash activity better
        if (flash_busy())
        {
            m_download_request_in_progress = 1;
            m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_ERASE;
            return;
        }
        antfs_download_req_resp_prepare(response, &m_response_info);
    }
    else
    {
        antfs_download_req_resp_prepare(response, &m_response_info);
    }
}
示例#4
0
static void antfs_event_upload_complete_handle(const antfs_event_return_t * p_event)
{
    uint32_t err_code;

    if (m_antfs_dfu_state == ANTFS_DFU_STATE_VALIDATED)
    {
       // only send this response if we have validated the upload
       UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));
    }
    else if (m_antfs_dfu_state == ANTFS_DFU_STATE_READY)
    {
        if (flash_busy())
        {
            m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;                  //  Image completed but still busy writing, postpone it on flash call back.
            return;
        }

        if (m_image_data_complete == true)
        {
            err_code = dfu_image_validate(m_header_crc_seed);
            if (err_code == NRF_SUCCESS)
            {
                m_antfs_dfu_state = ANTFS_DFU_STATE_VALIDATED;
                UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));
            }
            else
            {
                upload_data_response_fail_reset();
            }
        }
        else
        {
            UNUSED_VARIABLE(antfs_upload_data_resp_transmit(true));             // This is expected on block transfers.
        }
    }
    else
    {
        // no implementation
    }
}
示例#5
0
void block_erase(uint8_t address[3], uint8_t byte) {
	//First we need to enable write
	write_enable();
	
	//Bring CSN low
	flash_csn_low();

	//Write OPCODE
	flash_transfer_byte(byte);

	//Write the three addresses
	flash_transfer_byte(address[2]);
	flash_transfer_byte(address[1]);
	flash_transfer_byte(address[0]);

	//Bring CSN high
	flash_csn_high();

	//Loop until erase actually has taken place.
	while(flash_busy() == 1);

}
示例#6
0
/**@brief Function for processing ANTFS upload request data event.
 *
 * @param[in] p_event The event extracted from the queue to be processed.
 */
static void antfs_event_upload_request_handle(const antfs_event_return_t * p_event)
{
    uint32_t    err_code = RESPONSE_MESSAGE_OK;
    uint8_t     new_request = false;

    if ((m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_ERASE) || (m_antfs_dfu_state == ANTFS_DFU_STATE_FLASH_PENDING))
    {
        return;
    }

    /*reset*/
    m_response_info.file_index.data           = p_event->file_index;
    m_response_info.max_burst_block_size.data = 0;
    m_response_info.max_file_size             = 0;
    m_response_info.file_size.data            = 0;
    m_response_info.file_crc                  = 0;

    // Evaluate File Index first
    if (m_current_file_index != p_event->file_index )
    {
        m_current_file_index = p_event->file_index;
        m_current_offset                        = 0;
        m_current_crc                           = 0;
    }

    if (p_event->offset == MAX_ULONG)
    {
        // This is a request to continue upload.
    }
    else if (p_event->offset == 0x00)
    {
        new_request = true;
    }
    else if(p_event->offset != m_current_offset)
    {
        // Something is wrong.
        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_INVALID_OPERATION, &m_response_info));
        m_antfs_dfu_state = ANTFS_DFU_STATE_STALL;
    }
    else
    {
        // no implementation.
    }

    switch (m_current_file_index)
    {
#if !defined (S210_V3_STACK)
        case ANTFS_FILE_INDEX_UPDATE_STACK:
        case ANTFS_FILE_INDEX_UPDATE_BOOTLOADER:
        case ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER:
#endif // S210_V3_STACK
        case ANTFS_FILE_INDEX_UPDATE_APPLICATION:
        {
            // Current valid file size is the last offset written to the file.
            m_response_info.file_size.data            = m_current_offset;
            // Intentionally report maximum allowed upload file size as max writeable file size + header and crc.
            // Writeable size check will be performed by dfu_start_pkt_handle() after parsing uploaded header
            m_response_info.max_file_size             = ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX;
            // Maximum burst block should be maximum allowable downloadable file size.
            m_response_info.max_burst_block_size.data = ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX;
            // Last valid CRC.
            m_response_info.file_crc                  = m_current_crc;

            // Will only handle upload request while at ANTFS_DFU_STATE_READY
            if (m_antfs_dfu_state == ANTFS_DFU_STATE_VALIDATED)
            {
                if (new_request)
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_AVAILABLE, &m_response_info));
                }
                else
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));                 // To handle resume at end of data.
                }
                return;
            }
            else if (m_antfs_dfu_state != ANTFS_DFU_STATE_READY)
            {
                UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_AVAILABLE, &m_response_info));
                return;
            }

            // Check File Size if it can still fit. Uploaded file size may be larger than the total writeable space because it includes header
            // and CRC that do not get written to flash. Writeable size check will be performed by dfu_start_pk_handle() after
            // parsing uploaded header
            if ((p_event->offset + p_event->bytes) > (ANTFS_FILE_SIZE_MAX_DFU_IMAGE + OTA_IMAGE_HEADER_SIZE_MAX + OTA_IMAGE_CRC_SIZE_MAX))
            {
                UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_ENOUGH_SPACE, &m_response_info));
                return;
            }

            m_data_buffered         = 0;

            if (new_request)
            {
                m_current_offset    = 0;
                m_current_crc       = 0;
                m_pending_offset    = 0;

                antfs_ota_init();

                // Only supports offset starting at 0;
                if (p_event->offset != 0)
                {
                    UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_FAIL, &m_response_info));
                    return;
                }

//                boot_return_set(PARAM_RETURN_BOOT_STATUS_Entered);

                // Store file size,
                m_current_file_size     = p_event->bytes;

                if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_STACK)
                {
                    m_update_mode = DFU_UPDATE_SD;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_BOOTLOADER)
                {
                    m_update_mode = DFU_UPDATE_BL;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_APPLICATION)
                {
                    m_update_mode = DFU_UPDATE_APP;
                }
                else if (m_current_file_index == ANTFS_FILE_INDEX_UPDATE_STACK_BOOTLOADER)
                {
                    m_update_mode = DFU_UPDATE_SD;
                    m_update_mode |= DFU_UPDATE_BL;//lint !e655 suppress Lint Warning 655: Bit-wise operations
                }

                m_dfu_pkt.packet_type = INIT_PACKET;

                if ((*ANT_BOOT_APP_SIZE > DFU_IMAGE_MAX_SIZE_BANKED)    ||
                    (*ANT_BOOT_APP_SIZE == 0xFFFFFFFF)                  ||
                    (*ANT_BOOT_APP_SIZE == 0x00000000)                  ||
                    (m_update_mode & DFU_UPDATE_SD))/*lint !e655 suppress Lint Warning 655: Bit-wise operations*/
                {
                    m_dfu_pkt.params.init_packet.total_image_size = DFU_IMAGE_MAX_SIZE_FULL;
                }
                else
                {
                    m_dfu_pkt.params.init_packet.total_image_size = m_current_file_size;
                }

                if (m_upload_swap_space_prepared == true)
                {
                    // Prepare no flash, except the states
                    m_dfu_pkt.params.init_packet.total_image_size = 0;
                }

                err_code = dfu_init_pkt_handle(&m_dfu_pkt);
                if (err_code)
                {
                    if (err_code == NRF_ERROR_INVALID_STATE)
                    {
                        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_INVALID_OPERATION, &m_response_info));
                    }
                    else
                    {
                        UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_FAIL, &m_response_info));
                    }
                    return;
                }

                m_ota_image_header_parsed   = false;
                m_image_data_complete       = false;
                m_image_data_offset         = 0;

                m_data_buffered             = 0;

                // A flash erase is expected at this time. postpone response if there is.
                if (flash_busy())
                {
                    m_upload_request_in_progress = true;
                    m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_ERASE;
                    return;
                }
            }
            else
            {
                // Check if there are still pending writes scheduled in Flash.
                if (flash_busy())
                {
                    m_upload_request_in_progress = true;
                    m_antfs_dfu_state = ANTFS_DFU_STATE_FLASH_PENDING;
                    return;
                }
            }

            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_OK, &m_response_info));
        }
            break;
        default:
            m_antfs_dfu_state = ANTFS_DFU_STATE_READY;
            UNUSED_VARIABLE(antfs_upload_req_resp_transmit(RESPONSE_MESSAGE_NOT_EXIST, &m_response_info));
    }
}