Introduction

Many systems increasingly need to understand their environment. This maybe to optimize operating parameters for best operation given the environment. Alternatively, it may be to provide health and usage monitoring (HUMS) of the system such that the aging of the system can be monitored helping prognostics.

These systems need to be low power and compact, they also need to be able to interface with a range of sensors, for example, temperature, humidity, pressure, acceleration, magnetic field, etc.

Working with these sensors requires the ability to support interfaces such as SPI, UART, I2C etc.

In this project we are going to look at how we can create a simple environmental monitor which uses a cost optimized Xilinx FPGA containing an Arm Cortex-M1 soft core processor available as part of the Arm DesignStart FPGA.

Why the Cortex-M1

The Cortex-M1 is available for use in Xilinx FPGAs as part of the Arm DesignStart program. The Cortex-M1 is 32-bit RISC microprocessor based on the ARMv6-M architecture and intended for control, management and other constrained tasks.

Implementing the Cortex-M1 within our FPGA, is very simple and offers good code density so the implementation requires fewer Block RAMS over other embedded processing options.

Combined all of these features make it ideal for our environmental monitoring application.

Installing DesignStart FPGA

The first thing we need to do is create a DesignStart FPGA account, we can do this here.

Once registered you will receive an email, this email will contain the links to download Xilinx Vivado and crucially request an license key for Arm Keil

Registration Email Links

Clicking on the request key link will allow you to receive the Produce Serial Number, which is needed to generate a 90 day Arm Keil Essentials license.

With both Vivado and Arm Keil correctly installed and licensed, the next step is to download the reference M1 design for the Arty S7 which can be obtained here

DesignStart FPGA download

The downloaded Cortex-M1 will be contained within a compressed file, extract the compressed files until you see the following file structure.

File Structure for the extracted design

The next step is to set up Vivado such that we can work successfully with the example. The first step is to open Vivado and correctly set up a drive to enable Vivado to be able to work with the long path names in the directory strucutre.

Open Vivado and prior to opening the project in the TCL window enter the following commands. The installation directory is the path where you extracted the compressed file.

pwd cd <Installation Directory> exec subst V: .

This will map the installation directory to the drive V:\

With that we can open the Vivado project which you will find under

V:\hardware\m1_for_arty_s7\m1_for_arty_s7

Installing the IP Cores

For this project we are going to be working with Digilent Pmods. Rather helpfully, Digilent provide a range of Pmod IPs which can support Pmod use in both hardware and software development in Vivado and SDK.

If you do not have the Pmod libraries installed you can install these from here. Once you have them on your system the next step is to make them visible to our Vivado design.

To do this in our Vivado project select, project options

Project Options

This will open the dialog shown below

Vivado Project Setting Dialog

Under the project settings, select and expand IP, click on repository and then on the + button. This will enable you to map in the Digilent IP library.

Successfully mapped library

Creating the Vivado Design

With the IP cores now available we can create the Vivado design. To communicate with peripherals the Cortex-M1 uses a AXI interface.

In the reference design we are using as our starting point for this example, you will notice there already exists QSPI, UART, BRAM and GPIO interfaces connected to the AXI bus.

To create the hardware design for our application we are going to be adding in the following IP from the Digilent IP library.

PmodNAV

PmodHYGRO

These IP cores can be added in by opening the block diagram and clicking on the add IP button

Add IP Button

This will open up a dialog box which is used to add in IP. In the search window type in PmodHYGRO, double click on the IP block to add it into the block diagram. Once this is complete, do the same for the PmodNAV.

Searching for the IP block

Completing this will result in the two IP cores added to the block diagram, but not yet connected into the design. To connect them into the Cortex-M1 system we can use the connection assistant

Connection Automation

Click on Run Connection automation and then select all of the Pmod interfaces in the resulting dialog.

Selecting the Connection Interfaces

This will add in the Pmod IP into our design. The next thing we need to do is connect them to the Pmod ports on the Arty S7.

We can do this by selecting the Board tab in Vivado, scrolling down to the Pmod port section and then drag and drop connector JA on to the PmodNAV and JB to the PmodHYGRO

Connecting the IP to the Board Interfaces

The final step in the creation of this Vivado design is to ensure the EXT_SPI clock is connected on the PmodNAV interface.

Ensuring the EXT SPI CLK is connected

We can now generate the bitstream.

Creating the Output Products

The Cortex-M1 application is contained in the FPGAs BRAM.

Once the FPGA design has been implemented and the bitstream generated, we can still update the Cortex-M1 application without the need to re-implement the FPGA entirely.

To do this however each time we change the Vivado design we need to run a script which generates a file which contains information on the BRAMs used by the Cortex-M1 in the implementation.

Knowing this information allows just the contents of those BRAMs to be updated post bitstream generation.

We need to re-generate this file each time we implement the Vivado design as the BRAM structure could change during the implementation.

The reference design we downloaded, from the Arm website includes all of the necessary files to re-generate this BRAM information, including a script we can run in Vivado to generate this file.

However, to run this script we need to first open the implemented design in Vivado. You can open the implemented design by clicking on implementation under the Flow Navigator on the left hand side once the bitstream is available.

Vivado Design Implemented Design Opened

With the design is open, we use the TCL Console to run the provided script.

The script is available under

V:\hardware\m1_for_arty_s7\m1_for_arty_s7

To be able to run the script we need to change the current directory to the one above.

In the Vivado TCL window type in the following command

cd V:\\hardware\\m1_for_arty_s7\\m1_for_arty_s7

Once that command has been executed, we can run the command below to generate a updated MMI file.

source make_mmi_file.tcl

Now we know the BRAM organisation we are ready to export the hardware design and start creating our SW application.

We can export the hardware design by selecting in Vivado File->Export->Export Hardware

Exporting hardware

The location the Hardware design should be exported to is

V:\software

If you see a warning about an existing file, please select Yes to the overwrite question.

You should also use a file explorer to navigate to V:\software and ensure there is only one HDF (the exported hardware design) file present. This file should be named

m1_arty_s7_wrapper.hdf

Working in Xilinx SDK

Just like we do when we are creating MicroBlaze or Zynq based solutions, we need to use SDK to create a Board Support Package for the hardware design. This BSP will provide a number of APIs which we can use to work with the cortex peripherals.

We can open SDK from Vivado and this will import the hardware definition if we provide the correct information.

Launching SDK from Vivado

When Vivado asks for the location of the exported hardware and the SDK workspace use the settings in the diagram below

SDK Location Settings

Once in SDK, you will notice the hardware has been imported

Imported hardware

The next step is to create the BSP, to do this click on File->New->Board Support Package

Creating the BSP

Once the dialog opens, click on finish - leave the name as the default suggestion

BSP Dialog

In the BSP settings dialog also click OK to start the generation of the BSP

BSP settings dialog

Once the BSP is generated we have finished with SDK, and if desired you can close the program.

Before we can start creating our application however we need to use File Explorer to move some files into the BSP include directory and rename the BSP folder.

We need to copy the files

Xpsuedo_asm_rvct.c

Xpseudo_asm_rvct.h

From

V:\vivado\Arm_sw_repository\CortexM\bsp\standalone_v6_7\src\arm\cortexm1\armcc

Into

V:\software\m1_for_arty_s7\sdk_workspace\standalone_bsp_0\CORTEXM1_AXI_0\include

After we have copied these files we also need to rename the folder which contains the BSP located under

V:\software\m1_for_arty_s7\sdk_workspace\standalone_bsp_0

Ensure the folder is named CORTEX_M1_0 and not CORTEXM1_AXI_0

Creating the Application in Arm Keil

Arm Keil is the application that we will use to generate the application, to open the pre-existing project navigate to

V:/software/m1_for_arty_s7/Build_Keil/

Click on the file m1_for_arty_s7.uvprojx

Arm Keil Application

The next thing we need to do is ensure the compiler directives are set correctly for our application and the drivers we will be using. To open the options, click on the highlighted button

Opening the project options

Ensure C99 and GNU Extensions are enabled, if you want you can also adjust the optimization level.

Setting C99 and GNU Extensions

To work with the PmodHYGRO and the PmodNAV we need to add in the Pmod driver source code. To do this we right click on the project and select Manage Project Items.

Adding new project items

Under groups we can add in the PModHYGRO and thePModNAV as new groups, we need to add in the source code which can be found under the PmodXXXX drivers directory

You can find the drivers under

V:\software\m1_for_arty_s7\sdk_workspace\standalone_bsp_0\CORTEX_M1_0\libsrc

Do not include header files and ensure you do not declare the same file twice. This is especially true if SPI or IIC xilinx API drivers are included elsewhere in the project.

Adding the Pmod project items

To ensure we can time our the sensor reads, I am going to use the system tick interrupt to trigger a sensor read of both Pmods

The system tick is enabled in the Vivado design as the OS Extensions are enabled.

To use the System Tick in our code we need to define the following

#define STCTRL (*( ( volatile unsigned long *) 0xE000E010 )) #define STRELOAD (*( ( volatile unsigned long *) 0xE000E014 )) #define STCURR (*( ( volatile unsigned long *) 0xE000E018 )) #define SBIT_ENABLE 0 #define SBIT_TICKINT 1 #define SBIT_CLKSOURCE 2 #define RELOAD_VALUE 98999999

When we want to start the timer we need to use the code, once started it will free run.

STRELOAD = RELOAD_VALUE; STCTRL = (1<<SBIT_ENABLE) | (1<<SBIT_TICKINT) | (1<<SBIT_CLKSOURCE);

We also need to declare a interrupt handler, in this example each time a interrupt is triggered the sample boolean is set to true to trigger sampling of the Pmods.

void SysTick_Handler(void) { //print("Systick Int\r

"); sample=TRUE; }

The code to interface and work with the Pmod sensors is below

Definitions

#include "PmodHYGRO.h" #include "PmodNAV.h" #define TIMER_FREQ_HZ 100000000 PmodHYGRO myDevice; PmodNAV nav; bool sample; float temp_degc, hum_perrh, temp_degf;

Code Body

HYGRO_begin(&myDevice,XPAR_PMODHYGRO_0_AXI_LITE_IIC_BASEADDR,0x40,XPAR_PMODHYGRO_0_AXI_LITE_TMR_BASEADDR,1,TIMER_FREQ_HZ); NAV_begin (&nav,XPAR_PMODNAV_0_AXI_LITE_GPIO_BASEADDR,XPAR_PMODNAV_0_AXI_LITE_SPI_BASEADDR); NAV_Init(&nav); while ( 1 ) { if (sample == TRUE){ temp_degc = HYGRO_getTemperature(&myDevice); hum_perrh = HYGRO_getHumidity(&myDevice); sprintf (debugStr, "Temp is %f Humidity is %f\r



", temp_degc, hum_perrh ); print ( debugStr ); NAV_GetData(&nav); sprintf (debugStr, "X is %f Y is %f Z is %f\r



", nav.acclData.X, nav.acclData.Y, nav.acclData.Z ); print ( debugStr ); sample = FALSE; } }

We are now ready to implement the design in our Arty S7, click on rebuild the application.

Programming the Arty S7

Using a file browser to navigate to V:\hardware\m1_for_arty_s7\m1_for_arty_s7 you will see a file named bram_s7.elf and bram_s7.hex these should have a recent time stamp as they were just generated by Arm Keil.

Generated Files

Double click on the make_prog_files.bat this will create the bit file needed with the Cortex-M1 and application we just created to download into the Arty S7 board

To program the Arty S7 we need to use the hardware manager in Vivado

Opening the Hardware Manager

Once the hardware manager is opened select open target and auto connect, this will connect over JTAG to the Arty S7

Vivado Hardware Manager

Open a terminal program such as terra term or PuTTY so that we can see the output from the serial link – Set it for 115200, 1 Start, 1 Stop no Parity.

We are now ready to program the device, click on Program Device and select the bit file located at

V:/hardware/m1_for_arty_s7/m1_for_arty_s7/m1_for_arty_s7.bit

Programming the Device

Programming Dialog

Check the output in the your chosen terminal program and you will see the output of temperature, humidity and X, Y and Z information.

Move the board about and you will see the position change, while covering up the PmodHYGRO chip with your finger will change the temperature.

Terminal Output

Viceo of the resultant test

Wrapping Up

The Cortex-M1 is very simple to work with and offers a number of advantages for our applications including code density and resource utilization.

If you want to get hands on with the Arm DesignStart FPGA and create your own applications I am running a four-hour hands-on tutorial at ESC Boston in April.

Find out more below, it would be great to see you there!

https://ambo19.mapyourshow.com/7_0/sessions/session-details.cfm?ScheduleID=66

See previous projects here.

Additional Information on Xilinx FPGA / SoC Development can be found weekly on MicroZed Chronicles.

You can find the files associated with this project here:

https://github.com/ATaylorCEngFIET/Hackster