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-M1The 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 FPGAThe 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
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
The downloaded Cortex-M1 will be contained within a compressed file, extract the compressed files until you see the following file structure.
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
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
This will open the dialog shown below
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.
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
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.
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
Click on Run Connection automation and then select all of the Pmod interfaces in the resulting dialog.
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
The final step in the creation of this Vivado design is to ensure the EXT_SPI clock is connected on the PmodNAV interface.
We can now generate the bitstream.
Creating the Output ProductsThe 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.
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
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
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.
When Vivado asks for the location of the exported hardware and the SDK workspace use the settings in the diagram below
Once in SDK, you will notice the hardware has been imported
The next step is to create the BSP, to do this click on File->New->Board Support Package
Once the dialog opens, click on finish - leave the name as the default suggestion
In the BSP settings dialog also click OK to start the generation of the BSP
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 KeilArm 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
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
Ensure C99 and GNU Extensions are enabled, if you want you can also adjust the optimization level.
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.
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.
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\n");
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\n\n", temp_degc, hum_perrh );
print ( debugStr );
NAV_GetData(&nav);
sprintf (debugStr, "X is %f Y is %f Z is %f\r\n\n", 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 S7Using 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.
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
Once the hardware manager is opened select open target and auto connect, this will connect over JTAG to the Arty S7
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
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.
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:
Comments