boards: arm: arty: add board definition Cortex-M1 on the Digilent Arty

Add board definition for the ARM DesignStart FPGA Cortex-M1 reference
design on the Digilent Arty FPGA development board.

Signed-off-by: Henrik Brix Andersen <henrik@brixandersen.dk>
This commit is contained in:
Henrik Brix Andersen 2020-07-29 00:17:16 +02:00 committed by Maureen Helm
commit 75713c39a1
10 changed files with 533 additions and 0 deletions

View file

@ -0,0 +1,26 @@
# SPDX-License-Identifier: Apache-2.0
if((CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1) AND (CONFIG_BUILD_OUTPUT_BIN))
# Generate zephyr.mem verilog memory hex dump file for initialising ITCM in
# Xilinx Vivado.
#
# This ought to be done using the objcopy verilog bfd, but it contains a bug
# affecting endianness: https://sourceware.org/bugzilla/show_bug.cgi?id=25202
#
# Instead we use bin2hex from the SiFive elf2hex package, if available.
# https://github.com/sifive/elf2hex
find_program(BIN2HEX ${CROSS_COMPILE_TARGET}-bin2hex)
if(NOT ${BIN2HEX} STREQUAL BIN2HEX-NOTFOUND)
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands
COMMAND ${BIN2HEX}
ARGS --bit-width 32
${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.bin
${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.mem
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
)
message(STATUS "Verilog memory hex dump will be written to: ${PROJECT_BINARY_DIR}/${CONFIG_KERNEL_BIN_NAME}.mem")
else()
message(STATUS "The bin2hex (${CROSS_COMPILE_TARGET}-bin2hex) utility was not found, verilog memory hex dump file cannot be generated")
endif()
endif()

View file

@ -0,0 +1,8 @@
# Digilent Arty board configuration
# Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
config BOARD_ARTY_A7_ARM_DESIGNSTART_M1
bool "Digilent Arty A7 ARM DesignStart Cortex-M1"
depends on SOC_SERIES_ARM_DESIGNSTART

View file

@ -0,0 +1,31 @@
# Digilent Arty board configuration
# Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
# SPDX-License-Identifier: Apache-2.0
if BOARD_ARTY_A7_ARM_DESIGNSTART_M1
config BOARD
default "arty_a7_arm_designstart_m1"
config CPU_CORTEX_M_HAS_SYSTICK
default y
config NUM_IRQS
default 8
if SERIAL
config UART_XLNX_UARTLITE
default y
endif # SERIAL
if GPIO
config GPIO_XLNX_AXI
default y
endif # GPIO
endif # BOARD_ARTY_A7_ARM_DESIGNSTART_M1

View file

@ -0,0 +1,225 @@
/*
* Copyright (c) 2020 Henrik Brix Andersen <henrik@brixandersen.dk>
*
* SPDX-License-Identifier: Apache-2.0
*/
/dts-v1/;
#include <arm/armv6-m.dtsi>
#include <dt-bindings/gpio/gpio.h>
#include <mem.h>
/ {
model = "Digilent Arty A7 ARM DesignStart Cortex-M1";
chosen {
zephyr,console = &uartlite0;
zephyr,shell-uart = &uartlite0;
zephyr,flash = &itcm;
/* Use DTCM as SRAM by default */
zephyr,sram = &dtcm;
};
aliases {
led0 = &led_ld4;
led1 = &led_ld5;
led2 = &led_ld6;
led3 = &led_ld7;
sw0 = &sw0;
sw1 = &sw1;
sw2 = &sw2;
sw3 = &sw3;
};
leds {
compatible = "gpio-leds";
led_ld0_red: led_ld0_red {
gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
label = "LED LD0 RED";
};
led_ld0_green: led_ld0_green {
gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
label = "LED LD0 GREEN";
};
led_ld0_blue: led_ld0_blue {
gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
label = "LED LD0 BLUE";
};
led_ld1_red: led_ld1_red {
gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
label = "LED LD1 RED";
};
led_ld1_green: led_ld1_green {
gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
label = "LED LD1 GREEN";
};
led_ld1_blue: led_ld1_blue {
gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
label = "LED LD1 BLUE";
};
led_ld2_red: led_ld2_red {
gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
label = "LED LD2 RED";
};
led_ld2_green: led_ld2_green {
gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>;
label = "LED LD2 GREEN";
};
led_ld2_blue: led_ld2_blue {
gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
label = "LED LD2 BLUE";
};
led_ld3_red: led_ld3_red {
gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
label = "LED LD3 RED";
};
led_ld3_green: led_ld3_green {
gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
label = "LED LD3 GREEN";
};
led_ld3_blue: led_ld3_blue {
gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
label = "LED LD3 BLUE";
};
led_ld4: led_ld4 {
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
label = "LED LD4";
};
led_ld5: led_ld5 {
gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
label = "LED LD5";
};
led_ld6: led_ld6 {
gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
label = "LED LD6";
};
led_ld7: led_ld7 {
gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
label = "LED LD7";
};
};
gpio_keys {
compatible = "gpio-keys";
sw0: sw0 {
gpios = <&gpio0_2 0 GPIO_ACTIVE_HIGH>;
label = "SW0";
};
sw1: sw1 {
gpios = <&gpio0_2 1 GPIO_ACTIVE_HIGH>;
label = "SW1";
};
sw2: sw2 {
gpios = <&gpio0_2 2 GPIO_ACTIVE_HIGH>;
label = "SW2";
};
sw3: sw3 {
gpios = <&gpio0_2 3 GPIO_ACTIVE_HIGH>;
label = "SW3";
};
btn0: btn0 {
gpios = <&gpio1_2 0 GPIO_ACTIVE_HIGH>;
label = "BTN0";
};
btn1: btn1 {
gpios = <&gpio1_2 1 GPIO_ACTIVE_HIGH>;
label = "BTN1";
};
btn2: btn2 {
gpios = <&gpio1_2 2 GPIO_ACTIVE_HIGH>;
label = "BTN2";
};
btn3: btn3 {
gpios = <&gpio1_2 3 GPIO_ACTIVE_HIGH>;
label = "BTN3";
};
};
soc {
itcm: memory@0 {
compatible = "arm,itcm";
reg = <0x00000000 DT_SIZE_K(64)>;
};
dtcm: memory@20000000 {
compatible = "arm,dtcm";
reg = <0x20000000 DT_SIZE_K(32)>;
};
uartlite0: uartlite@40100000 {
compatible = "xlnx,xps-uartlite-1.00.a";
interrupts = <0 0>;
reg = <0x40100000 0x10000>;
label = "UART_0";
};
gpio0: gpio@40110000 {
compatible = "xlnx,xps-gpio-1.00.a";
interrupts = <1 0>;
reg = <0x40110000 0x10000>;
label = "GPIO_0";
gpio-controller;
#gpio-cells = <2>;
xlnx,all-inputs = <0x0>;
xlnx,all-inputs-2 = <0x1>;
xlnx,all-outputs = <0x0>;
xlnx,all-outputs-2 = <0x0>;
xlnx,dout-default = <0x0>;
xlnx,dout-default-2 = <0x0>;
xlnx,gpio-width = <0x4>;
xlnx,gpio2-width = <0x4>;
xlnx,is-dual = <0x1>;
xlnx,tri-default = <0xffffffff>;
xlnx,tri-default-2 = <0xffffffff>;
gpio0_2: gpio2 {
compatible = "xlnx,xps-gpio-1.00.a-gpio2";
label = "GPIO_0_2";
gpio-controller;
#gpio-cells = <2>;
};
};
gpio1: gpio@40120000 {
compatible = "xlnx,xps-gpio-1.00.a";
interrupts = <2 0>;
reg = <0x40120000 0x10000>;
label = "GPIO_1";
gpio-controller;
#gpio-cells = <2>;
xlnx,all-inputs = <0x0>;
xlnx,all-inputs-2 = <0x1>;
xlnx,all-outputs = <0x0>;
xlnx,all-outputs-2 = <0x0>;
xlnx,dout-default = <0x0>;
xlnx,dout-default-2 = <0x0>;
xlnx,gpio-width = <0xc>;
xlnx,gpio2-width = <0x4>;
xlnx,is-dual = <0x1>;
xlnx,tri-default = <0xffffffff>;
xlnx,tri-default-2 = <0xffffffff>;
gpio1_2: gpio2 {
compatible = "xlnx,xps-gpio-1.00.a-gpio2";
label = "GPIO_1_2";
gpio-controller;
#gpio-cells = <2>;
};
};
bram0: memory@60000000 {
compatible = "mmio-sram";
reg = <0x60000000 DT_SIZE_K(64)>;
};
};
};
&nvic {
arm,num-irq-priority-bits = <2>;
};

View file

@ -0,0 +1,10 @@
identifier: arty_a7_arm_designstart_m1
name: Digilent Arty A7 ARM DesignStart Cortex-M1
type: mcu
arch: arm
toolchain:
- zephyr
- gnuarmemb
- xtools
ram: 32
flash: 64

View file

@ -0,0 +1,12 @@
# SPDX-License-Identifier: Apache-2.0
CONFIG_CORTEX_M_SYSTICK=y
CONFIG_SOC_SERIES_ARM_DESIGNSTART=y
CONFIG_SOC_ARM_DESIGNSTART_FPGA_CORTEX_M1=y
CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1=y
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=100000000
CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

View file

@ -0,0 +1,9 @@
# SPDX-License-Identifier: Apache-2.0
if(CONFIG_BOARD_ARTY_A7_ARM_DESIGNSTART_M1)
board_runner_args(openocd "--use-elf" "--config=${BOARD_DIR}/support/openocd_arty_a7_arm_designstart_m1.cfg")
board_runner_args(jlink "--device=Cortex-M1" "--reset-after-load")
include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake)
include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake)
endif()

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

View file

@ -0,0 +1,192 @@
.. _arty:
Digilent Arty
#############
Overview
********
The `Digilent Arty`_ is a line of FPGA-based development boards aimed for makers
and hobbyists. The Arty is available in several configurations, each with a
different Xilinx FPGA (Spartan-7, Artix-7, or Zynq-7000 series).
Each board is equipped with on-board JTAG for FPGA programming and debugging,
LEDs, switches, buttons, DDR3 RAM, and QSPI flash for storing the FPGA
bitstream.
.. figure:: ./arty_a7-35.png
:width: 500px
:align: center
:alt: Digilent Arty A7-35
Digilent Arty A7-35 (Credit: Digilent Inc)
The Spartan-7 and Artix-7 based Arty board do not contain a CPU, but require a
so-called soft processor to be instantiated within the FPGA in order to run
Zephyr. The Zynq-7000 based Arty boards are not yet supported by Zephyr.
ARM Cortex-M1 DesignStart FPGA
******************************
One such soft processor design is the Cortex-M1 `ARM DesignStart FPGA`_ Xilinx
edition reference design from ARM. This design targets the Spartan-7 or Artix-7
based Arty boards. Zephyr only supports the Artix-7 based boards for now.
For more information about the ARM Cortex-M1 DesignStart FPGA, see the following
websites:
- `Technical Resources for DesignStart FPGA`_
- `Technical Resources for DesignStart FPGA on Xilinx`_
- `ARM DesignStart FPGA Xilinx FAQs`_
Supported Features
==================
The ``arty_a7_arm_designstart_m1`` board configuration supports the following
hardware features:
+-----------+------------+-------------------------------------+
| Interface | Controller | Driver/Component |
+===========+============+=====================================+
| NVIC | on-chip | nested vector interrupt controller |
+-----------+------------+-------------------------------------+
| SYSTICK | on-chip | systick |
+-----------+------------+-------------------------------------+
| GPIO | on-chip | gpio, non-interrupt |
+-----------+------------+-------------------------------------+
| UART | on-chip | serial port-polling; |
| | | serial port-interrupt |
+-----------+------------+-------------------------------------+
The default configuration can be found in the defconfig file:
:file:`boards/arm/arty/arty_a7_arm_designstart_m1_defconfig`. Other hardware
features are not currently supported by the port.
System Clock
============
The reference design is configured to use the 100 MHz external oscillator on the
board as CPU system clock.
Serial Port
===========
The reference design contains one Xilinx UART Lite. This UART is configured as
console and is accessible through the on-board JTAG adapter via USB connector
``J10``.
Connecting the Debug Probes
===========================
Two different debug probes are needed in order to program the board; the
on-board Digilent JTAG connected to the FPGA, and an external Serial Wire Debug
(SWD) capable debug probe connected to the ARM Cortex-M1 CPU.
The on-board JTAG is used for configuring and debugging the Xilinx FPGA
itself. It is available on USB connector ``J10``.
The external SWD debug probe can be connected to connector ``J4`` (``nSRST`` on
``IO39``, ``SWDIO`` on ``IO40``, and ``SWCLK`` on ``IO41``).
Programming and Debugging
*************************
First, configure the FPGA with the reference design FPGA bitstream using Xilinx
Vivado as described in the ARM Cortex-M1 DesignStart FPGA Xilinx edition user
guide (available as part of the reference design download from `Technical
Resources for DesignStart FPGA on Xilinx`_).
Another option for configuring the FPGA with the reference design bitstream is
to use the :ref:`openocd-debug-host-tools`:
.. code-block:: console
openocd -f board/arty_s7.cfg -c "init;\
pld load 0 m1_for_arty_a7_reference.bit;\
shutdown"
Next, build and flash applications as usual (see :ref:`build_an_application` and
:ref:`application_run` for more details).
Configuring a Console
=====================
The UART console is available via the on-board JTAG on USB connector
``J10``. The on-board JTAG will enumerate as two USB serial ports. The UART is
typically available on the second serial port.
Use the following settings with your serial terminal of choice (minicom, putty,
etc.):
- Speed: 115200
- Data: 8 bits
- Parity: None
- Stop bits: 1
Flashing
========
Here is an example for the :ref:`hello_world` application.
.. zephyr-app-commands::
:zephyr-app: samples/hello_world
:board: arty_a7_arm_designstart_m1
:goals: flash
After flashing, you should see message similar to the following in the terminal:
.. code-block:: console
*** Booting Zephyr OS build zephyr-v2.3.99 ***
Hello World! arty_a7_arm_designstart_m1
Note, however, that the application was not persisted in flash memory by the
above steps. It was merely written to internal block RAM in the FPGA. It will
revert to the application stored in the block RAM within the FPGA bitstream
the next time the FPGA is configured.
The steps to persist the application within the FPGA bitstream are covered by
the ARM Cortex-M1 DesignStart FPGA Xilinx edition user guide. If the
:option:`CONFIG_BUILD_OUTPUT_BIN` is enabled and the `SiFive elf2hex`_ package
is available, the build system will automatically generate a Verilog memory hex
dump :file:`zephyr.mem` file suitable for initialising the block RAM using
`Xilinx Vivado`_.
Debugging
=========
Here is an example for the :ref:`hello_world` application.
.. zephyr-app-commands::
:zephyr-app: samples/hello_world
:board: arty_a7_arm_designstart_m1
:goals: debug
Step through the application in your debugger, and you should see a message
similar to the following in the terminal:
.. code-block:: console
*** Booting Zephyr OS build zephyr-v2.3.99 ***
Hello World! arty_a7_arm_designstart_m1
.. _Digilent Arty:
https://store.digilentinc.com/arty
.. _ARM DesignStart FPGA:
https://www.arm.com/resources/designstart/designstart-fpga
.. _Technical Resources for DesignStart FPGA:
https://developer.arm.com/ip-products/designstart/fpga
.. _Technical Resources for DesignStart FPGA on Xilinx:
https://developer.arm.com/ip-products/designstart/fpga/fpga-xilinx
.. _ARM DesignStart FPGA Xilinx FAQs:
https://developer.arm.com/ip-products/designstart/fpga/fpga-xilinx-faqs
.. _SiFive elf2hex:
https://github.com/sifive/elf2hex
.. _Xilinx Vivado:
https://www.xilinx.com/products/design-tools/vivado.html

View file

@ -0,0 +1,20 @@
source [find interface/cmsis-dap.cfg]
source [find target/swj-dp.tcl]
adapter_khz 5000
set _CHIPNAME cortex_m1
set _ENDIAN little
set _WORKAREASIZE 0x4000
set _CPUTAPID 0x411CC210
swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
if {![using_hla]} {
cortex_m reset_config sysresetreq
}