Skip to content

Commit

Permalink
Merge pull request #552 from xmos/feature/dfu
Browse files Browse the repository at this point in the history
Feature/dfu
  • Loading branch information
xmos-jmccarthy authored Nov 17, 2022
2 parents df8d571 + 8f6a6d2 commit 68dd860
Show file tree
Hide file tree
Showing 28 changed files with 1,985 additions and 133 deletions.
1 change: 1 addition & 0 deletions doc/tutorials/freertos/examples/dfu.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.. include:: ../../../../examples/freertos/dfu/README.rst
1 change: 1 addition & 0 deletions examples/examples.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL XCORE_XS3A)
include(${CMAKE_CURRENT_LIST_DIR}/bare-metal/explorer_board/explorer_board.cmake)

## FreeRTOS examples
include(${CMAKE_CURRENT_LIST_DIR}/freertos/dfu/dfu.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/freertos/device_control/device_control.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/freertos/dispatcher/dispatcher.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/freertos/explorer_board/explorer_board.cmake)
Expand Down
249 changes: 249 additions & 0 deletions examples/freertos/dfu/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
##############
DFU
##############

This example application demonstrates a method to add DFU to a FreeRTOS application on XCORE.

**********************
Preparing the host
**********************

This application supports any host host application that is capable of USB DFU Class V1.1.

The application was verified using dfu-util.

Installation instructions for respective operating system can be found `here <https://dfu-util.sourceforge.net/>`__

If on Linux the user may need to add the USB device to their udev rules. This example defaults to Vendor ID 0xCAFE with Product ID 0x4000.

If on Windows the user may need to use a tool such as Zadig to install USB drivers.

*********************
Building the firmware
*********************

Run the following commands in the xcore_sdk root folder to build the firmware:

.. tab:: Linux and Mac

.. code-block:: console
cmake -B build -DCMAKE_TOOLCHAIN_FILE=xmos_cmake_toolchain/xs3a.cmake
cd build
make example_freertos_dfu_v1
make example_freertos_dfu_v2
.. tab:: Windows

.. code-block:: console
cmake -G "NMake Makefiles" -B build -DCMAKE_TOOLCHAIN_FILE=xmos_cmake_toolchain/xs3a.cmake
cd build
nmake example_freertos_dfu_v1
nmake example_freertos_dfu_v2
**********************
Preparing the hardware
**********************

It is recommended to begin from an erased flash. To erase flash run:

.. tab:: Linux and Mac

.. code-block:: console
make erase_all_example_freertos_dfu_v1
.. tab:: Windows

.. code-block:: console
nmake erase_all_example_freertos_dfu_v1
This target will use `xflash` to erase the flash of the device specified by the provided target XN file.

After building the firmware and erasing the flash, the factory image must be flashed. From the xcore_sdk build folder run:

.. tab:: Linux and Mac

.. code-block:: console
make flash_app_example_freertos_dfu_v1
.. tab:: Windows

.. code-block:: console
nmake flash_app_example_freertos_dfu_v1
This target will use `xflash` to flash the application as a factory image with a boot partition size specified in dfu.cmake.

The board may then be power cycled and will boot up the application.

.. tab:: Linux and Mac

.. code-block:: console
make create_upgrade_img_example_freertos_dfu_v2
.. tab:: Windows

.. code-block:: console
nmake create_upgrade_img_example_freertos_dfu_v2
This target will use `xflash` to create an upgrade image for the specified target.

********************
Running the firmware
********************

After flashed, the factory image will run by default. The user may opt to manually run via xrun to see debug messages.

From the xcore_sdk build folder run:

.. tab:: Linux and Mac

.. code-block:: console
make run_example_freertos_dfu_v1
.. tab:: Windows

.. code-block:: console
nmake run_example_freertos_dfu_v1
********************
Upgrading the firmware via DFU
********************

Once the application is running, a USB DFU v1.1 tool can be used to perform various actions. This example will demonstrate with dfu-util commands.

MacOS users may need to sudo the following commands.

To verify the device is running run:

.. code-block:: console
dfu-util -l
The output of this command will very based on which image is running.
For example_freertos_dfu_v1, the output should contain:

.. code-block:: console
Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=2, name="DFU dev DATAPARTITION v1", serial="123456"
Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=1, name="DFU dev UPGRADE v1", serial="123456"
Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=0, name="DFU dev FACTORY v1", serial="123456"
For example_freertos_dfu_v2, the output should contain:

.. code-block:: console
Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=2, name="DFU dev DATAPARTITION v2", serial="123456"
Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=1, name="DFU dev UPGRADE v2", serial="123456"
Found DFU: [cafe:4000] ver=0100, devnum=53, cfg=1, intf=0, path="3-4.1", alt=0, name="DFU dev FACTORY v2", serial="123456"
The factory image can be read back by running:

.. code-block:: console
dfu-util -e -d 4000 -a 0 -U readback_factory_img.bin
From the xcore_sdk build folder, the upgrade image can be written by running:

.. code-block:: console
dfu-util -e -d 4000 -a 1 -D example_freertos_dfu_v2_upgrade.bin
After updating the upgrade image it may be necessary to unplug the USB device to initiate a host re-enumeration.

The upgrade image can be read back by running:

.. code-block:: console
dfu-util -e -d 4000 -a 1 -U readback_upgrade_img.bin
The data partition image can be read back by running:

.. code-block:: console
dfu-util -e -d 4000 -a 2 -U readback_data_partition_img.bin
The data partition image can be written by running:

.. code-block:: console
dfu-util -e -d 4000 -a 2 -D readback_data_partition_img.bin
If running the application with the run_example_freertos_dfu_v1 target, information is printed to verify behavior.

Initially, the debug prints will contain:

.. code-block:: console
DFU Image Info
Factory:
Addr:0x1C70
Size:103108
Version:0
Upgrade:
Addr:0x1B000
Size:0
Version:0
Data Partition
Addr:0x100000
First word at data partition start is: 0xFFFFFFFF
After writing an upgrade image the debug prints will contain:

.. code-block:: console
DFU Image Info
Factory:
Addr:0x1C70
Size:103108
Version:0
Upgrade:
Addr:0x1B000
Size:103108
Version:0
Data Partition
Addr:0x100000
First word at data partition start is: 0xFFFFFFFF
The debug prints include the value of the first word at the start of the data partition. Writing a text file containing "XMOS" will result in:

.. code-block:: console
DFU Image Info
Factory:
Addr:0x1C70
Size:103108
Version:0
Upgrade:
Addr:0x1B000
Size:103108
Version:0
Data Partition
Addr:0x100000
First word at data partition start is: 0x534F4D58
********************************
Debugging the firmware with xgdb
********************************

From the xcore_sdk build folder run:

.. tab:: Linux and Mac

.. code-block:: console
make debug_example_freertos_dfu_v1
.. tab:: Windows

.. code-block:: console
nmake debug_example_freertos_dfu_v1
109 changes: 109 additions & 0 deletions examples/freertos/dfu/XCORE-AI-EXPLORER.xn
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<Network xmlns="http://www.xmos.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.xmos.com http://www.xmos.com">
<Type>Board</Type>
<Name>xcore.ai Explorer Kit</Name>

<Declarations>
<Declaration>tileref tile[2]</Declaration>
</Declarations>

<Packages>
<Package id="0" Type="XS3-UnA-1024-FB265">
<Nodes>
<Node Id="0" InPackageId="0" Type="XS3-L16A-1024" Oscillator="24MHz" SystemFrequency="600MHz" ReferenceFrequency="100MHz">
<Boot>
<Source Location="bootFlash"/>
</Boot>
<Extmem sizeMbit="1024" Frequency="100MHz">
<!-- Attributes for Padctrl and Lpddr XML elements are as per equivalently named 'Node Configuration' registers in datasheet -->

<Padctrl clk="0x30" cke="0x30" cs_n="0x30" we_n="0x30" cas_n="0x30" ras_n="0x30" addr="0x30" ba="0x30" dq="0x31" dqs="0x31" dm="0x30"/>
<!--
Attributes all have the same meaning, which is:
[6] = Schmitt enable, [5] = Slew, [4:3] = drive strength, [2:1] = pull option, [0] = read enable
Therefore:
0x30: 8mA-drive, fast-slew output
0x31: 8mA-drive, fast-slew bidir
-->

<Lpddr emr_opcode="0x20" protocol_engine_conf_0="0x2aa"/>
<!--
Attributes have various meanings:
emr_opcode[7:5] = LPDDR drive strength to xcore.ai
protocol_engine_conf_0[23:21] = tWR clock count at the Extmem Frequency
protocol_engine_conf_0[20:15] = tXSR clock count at the Extmem Frequency
protocol_engine_conf_0[14:11] = tRAS clock count at the Extmem Frequency
protocol_engine_conf_0[10:0] = tREFI clock count at the Extmem Frequency
Therefore:
0x20: Half drive strength
0x2aa: tREFI 7.79us, tRAS 0us, tXSR 0us, tWR 0us
-->
</Extmem>
<Tile Number="0" Reference="tile[0]">
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS"/>
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK"/>
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO"/>

<Port Location="XS1_PORT_1N" Name="PORT_I2C_SCL"/>
<Port Location="XS1_PORT_1O" Name="PORT_I2C_SDA"/>

<Port Location="XS1_PORT_4C" Name="PORT_LEDS"/>
<Port Location="XS1_PORT_4D" Name="PORT_BUTTONS"/>

<Port Location="XS1_PORT_1I" Name="WIFI_WIRQ"/>
<Port Location="XS1_PORT_1J" Name="WIFI_MOSI"/>
<Port Location="XS1_PORT_4E" Name="WIFI_WUP_RST_N"/>
<Port Location="XS1_PORT_4F" Name="WIFI_CS_N"/>
<Port Location="XS1_PORT_1L" Name="WIFI_CLK"/>
<Port Location="XS1_PORT_1M" Name="WIFI_MISO"/>
</Tile>
<Tile Number="1" Reference="tile[1]">
<!-- Mic related ports -->
<Port Location="XS1_PORT_1G" Name="PORT_PDM_CLK"/>
<Port Location="XS1_PORT_1F" Name="PORT_PDM_DATA"/>

<!-- Audio ports -->
<Port Location="XS1_PORT_1D" Name="PORT_MCLK_IN"/>
<Port Location="XS1_PORT_1C" Name="PORT_I2S_BCLK"/>
<Port Location="XS1_PORT_1B" Name="PORT_I2S_LRCLK"/>
<Port Location="XS1_PORT_1A" Name="PORT_I2S_DAC_DATA"/>
<Port Location="XS1_PORT_1N" Name="PORT_I2S_ADC_DATA"/>
<Port Location="XS1_PORT_4A" Name="PORT_CODEC_RST_N"/>
</Tile>
</Node>
</Nodes>
</Package>
</Packages>
<Nodes>
<Node Id="2" Type="device:" RoutingId="0x8000">
<Service Id="0" Proto="xscope_host_data(chanend c);">
<Chanend Identifier="c" end="3"/>
</Service>
</Node>
</Nodes>
<Links>
<Link Encoding="2wire" Delays="5clk" Flags="XSCOPE">
<LinkEndpoint NodeId="0" Link="XL0"/>
<LinkEndpoint NodeId="2" Chanend="1"/>
</Link>
</Links>
<ExternalDevices>
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="16384">
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
<Attribute Name="QE_REGISTER" Value="flash_qe_location_status_reg_0"/>
<Attribute Name="QE_BIT" Value="flash_qe_bit_6"/>
</Device>
</ExternalDevices>
<JTAGChain>
<JTAGDevice NodeId="0"/>
</JTAGChain>

</Network>

Loading

0 comments on commit 68dd860

Please sign in to comment.