Intel® Quark™ SE with Intel® System Studio for Microcontrollers
GPIO: Programming Guide
Overview
The purpose of this lab is to provide an introduction to the programming of the Intel® Quark SE (Atlas Hills) using Intel® System Studio 2016 for Microcontrollers Update 1 ( ISSM ). The project used in this lab is a GPIO sample. This sample demonstrates using Quark SE GPIO and Pin Interrupt capabilities. When a rising edge signal comes in to the pin with interrupt, it triggers ISR which sends a message through the UART.
Prerequisites
- Host machine:
- PC running Microsoft Windows 7 or later with an available USB ports.
- Software:
- Intel® System Studio for Microcontrollers 2016 Update 1.
- Hardware:
- Intel® Quark™ SE board (Atlas Hills).
- 2 USB Type A to Micro USB Type B cables.
Lab Workflow
- Connect the Intel® Quark™ SE board to the host PC
- Check that USB driver is properly installed
- Run ISSM
- Update Boot ROM (once per board)
- Create a new project with the provided source code.
- Build the project.
- Flash and Run the project.
- Observe the result.
- Debugging.
- Review the source code
Lab Instructions
Step 1: Connect the Intel® Quark™ SE board (Atlas Hills).
Connect the board to your PC using the USB Type A to Micro USB Type B cables.
- Make sure that your Jumpers and Power Switch are properly set like in the picture below. They will be properly set by default out-of-the-box
- Connect to your host machine with the micro-USB cable B to power up your board, to connect with JTAG and to get serial output
- Use micro-USB cable C to fully power up the board
Step 2: Check the USB driver and COM port
Open Zadig (http://zadig.akeo.ie/) to replace the drivers of Intel Quark SE so they will work properly with ISSM.
Check Options -> List All Devices.
Then you can see Atlas Hills Rev-x (… ) ( Interface 0 ). Choose it and replace driver with WinUSB as you can see in the picture below.
Now open Windows Device Manager and make sure there you see a new USB Serial Port under Port (COM & LPT) and Atlas Hills Rev – X (IPN: … ) under Universal Serial Bus Devices.
If the Atlas Hills Rev device does not appear or the Universal Serial Bus devices category is missing, the USB driver needs to be installed. To install the driver, navigate to C:\IntelSWTools\ISSM_2016.1.0xx\tools\debugger\driver directory using File Explorer, run the install.bat as Administrator, and answer ‘y’ in the window that will appear[AM2] [KJ3] .
Step 3: Run Intel® System Studio for Microcontrollers
Using File Explorer navigate to C:\IntelSWTools\ISSM_2016.1.0xx directory, and double click on the iss_mcu_ide_eclipse-launcher.bat.
The Intel® System Studio for Microcontrollers will prompt for the workspace location:
It is recommended to click Browse… button here and change the workspace location to your user directory, for example C:\Users\username\Documents\workspace. Click OK button to confirm workspace selection. The Intel® System Studio for Microcontrollers windows will appear as shown on the screenshot below.
Step 4: Update boot ROM
Note: This step needs to be performed only once per board.
From Intel ISSM menu select Update target ROM… entry as shown on the screenshot below.
The Update target ROM dialog will appear. Make sure that you select the board and project type accordingly. Click Update button to program the ROM to the microcontroller.
Step 5: Create a new project
From the Intel ISSM menu select New Intel ® Project. The Create new Project will appear. Choose Atlas Hills and click Next.
You can choose between Intel® QMSI(Intel® Quark™ Microcontroller Software Interface) and Zephyr but this time we will try Intel® QMSI.
Select Intel® Quark as the selected core since this project runs on Intel® Quark core. There are projects run on Arc[AM4] core particularly.
Now, name your project as you wish and choose gpio, then click Finish.
In the Project Explorer window on the left side of Intel® System Studio for Microcontrollers click on the gpio project. Find main.c file and double click on it to open it the editor.
Step 6: Build the project
Click on the Build button (“hammer” icon) on the toolbar to build the project. Alternatively it is possible to select the build configuration using the drop down menu next to that button. Intel® Systems Studio for Microcontrollers provides two configurations: debug and release. The debug configuration includes symbols in the generated binary files to facilitate debugging. It is the default configuration. The release configuration optimizes code for deployment.
Step 7: Flash and run the project
Click on the drop down menu next to the Run button (“play” icon). Select gpio_new (flashing) from the menu. The Intel® Systems Studio for Microcontrollers [AM5] [DCI6] will recompile the code, and flash it to the microcontroller.
Note: Intel® System Studio for Microcontrollers offers two ways to run the code: The first – gpio_new option assumes that the code had been already programmed to the microcontroller. The second – gpio_new (flashing) option will recompile and re-flash the code. Use this option if the source code had been changed since the last time microcontroller was programmed. This is the option used in this lab step.
Note: The flashing process takes some time. Look for the progress bar at the bottom right corner of the Intel® Systems Studio for Microcontrollers window:
Step 8: Test the project
Set up a jumper cable connecting pin 42 and 40 on header P4. Pin 42 is an output pin which triggers an interrupt on the input pin and pin 40 is configured as an input pin with interrupts enabled.
Open Terminals view (Window -> Show View -> Terminals ) and open a terminal by clicking on a monitor icon in Terminals view. Choose the right COM port of the board which can be found in Windows Device Manager. See the following configuration for the rest of the configuration for the terminal connection.
In the terminal , you should see messages as the following when you run the example
Congratulations, you just had completed your first Intel® Quark™ SE project!
Step 9: Debug the project
Click on the drop down menu next to the Debug button (“bug” icon). Select gpio_new from the menu.
Note: Intel® System Studio for Microcontrollers offers two ways to start debugging: The first – gpio_new option assumes that the code had been already programmed to the microcontroller (In this lab it was done in the “Flashing and running the project” step). The second – gpio_new (flashing) option will recompile and re-flash the code. Use this option if the source code had been changed since the last time microcontroller was programmed.
The Intel® Systems Studio for Microcontrollers will ask you about switching to the Debug perspective. Click the Yes button here.
Tip: It is possible to switch between perspectives using the Window -> Open Perspective menu, or by clicking C/C++ or Debug buttons on the Quick Access toolbar:
The Debug perspective will open.
Try using the debug functions described below:
Toggling breakpoints
Right click on the bar on the left from the code line where you want to set or remove a breakpoint, and select the Toggle Breakpoint menu item.
Follow the next steps for this lab:
- Find the following line in the main.c (line 102):
QM_PRINTF("GPIO callback - status register = 0x%u\n", status); |
- Right click on the bar from the left of this line, and select the Toggle Breakpoint menu item, as shown on the screenshot below.
Controlling the code execution
Use the toolbar buttons shown on the screenshot below, their corresponding shortcut keystrokes (for example F5 – Step Into, F6 – Step Over, F8 – Resume), or the commands from the Run menu to control the code execution.
Follow the next steps for this lab:
- Click Resume button once. Observe code running till the breakpoint set in the previous step.
- Press Resume button again to continue running the code.
- Push Suspend button to stop the code.
These commands also accessible using right click inside the Debug window.
Adding a conditional breakpoint
Conditional breakpoints are useful for suspending the code execution when certain conditions are met. Right click on the bar on the left from the code line where you want to add a conditional breakpoint and select the Add Breakpoint... menu item. The Properties for C/C++ Line Breakpoint dialog will appear. Enter the condition expression in the Condition text box.
Follow the next steps for this lab:
- Find the following line in the main.c (line 83):
while (!callback_invoked) { |
- Right click on the bar from the left of this line, and select the Add Breakpoint… menu item
- Set the condition to callback_invoked as shown on the screenshot below, and click OK button.
- Press Resume button to continue running the code.
- Press run during the debug session, you will see it stops at line 83 when callback_invoked becomes true and the process escapes from the while loop.
Using EmbSys Registers view
The EmbSys Registers view allows viewing and modifying Intel® Quark™ Microcontroller SE peripheral registers. This feature is useful when debugging on-chip peripherals and their interaction with the external hardware.
Follow the next steps for this lab:
- Locate the EmbSys Registers window. You might need to enlarge it, so that all fields are visible.
- In the EmbSys Registers view click on the Peripherals item to open it.
- Next find and click on the fst_periph_GPIO_reg_i to open the list of GPIO registers.
- Locate the GPIO_SWPORTA_DDR register and click on it to show the bit fields in this register. This register is the data register for GPIO ports. Bits number 0 to 31 of this register map to the GPIO pins of the microcontroller.
- Double click on GPIO_SWPORTA_DDR again to activate it. The register will be colored green, and the current value of the register will be shown.
- In case the current value is not shown it might be necessary to Resume and Suspend the code.
- Click in the Bin value of the GPIO_SWPORTA_DDR (bits 31-0) bit field. The buttons for each pin indicating the current bits values and the Set button will appear, as shown on the screenshot below.
- Click on the 6th and 7th from the left bits to change their value to 1. Click on the Set button to send the updated value to the microcontroller. Observe that the LEDs on the board (LED0 and LED1) will light up. This happens because bit 25 and 26 are connected to the on-board LEDs, and setting it to 1 turns on the LEDs.
- Click on those bits again to change their value back to 0. Click on the Set button to send the updated value to the microcontroller. The LEDs will turn off.
Other debug views
There are multiple other debug views are available – feel free to explore them on your own. Here are just some of them:
- Disassembly view
- Registers view
- Memory view
Use Windows -> Show View menu to select the views. Note that the view selection will vary depending on the active perspective.
OpenOCD view
The Intel® System Studio for Microcontroller uses OpenOCD software to interface to the Intel® Quark™ SE through JTAG interface. This software is running in the OpenOCD view. In some cases, for example when board is disconnected and reconnected, it might be necessary to restart OpenOCD. This can be done by clicking the Stop OpenOCD (red “stop” icon) button, and then clicking the Start OpenOCD (green “play” icon) button at the top right corner of the OpenOCD view. It is necessary to restart the debugging session after OpenOCD had been restarted.
Lab Source Code
How it works
This sample code enables a pin interrupt on a GPIO pin number 40 and gets an input signal from another GPIO pin, pin number 42, through a jumper. Then the interrupt runs the IRS which makes the process escapes a while loop to finally finish its task and print out “Finished : GPIO“.
The GPIO sample configures those I/O pins as following:
- PIN_OUT is configured for the output mode:
cfg.direction = BIT(PIN_OUT); |
- PIN_INTR is configured as the following
cfg.int_en = BIT(PIN_INTR); /* Interrupt enabled */ cfg.int_type = BIT(PIN_INTR); /* Edge sensitive interrupt */ cfg.int_polarity = BIT(PIN_INTR); /* Rising edge */ cfg.int_debounce = BIT(PIN_INTR); /* Debounce enabled */ cfg.int_bothedge = 0x0; /* Both edge disabled */ cfg.callback = gpio_example_callback; |
- The sample sets the gpio_example_callback function as the interrupt callback:
cfg.callback = gpio_example_callback; cfg.callback_data = NULL; |
- Requesting the given IRQ and register Interrupt Service Routine to interrupt vector and applying the pin configuration:
qm_irq_request(QM_IRQ_GPIO_0, qm_gpio_isr_0); qm_gpio_set_config(QM_GPIO_0, &cfg); |
Source Code
#include"qm_gpio.h" #include"qm_interrupt.h" #include"qm_isr.h"
#include<inttypes.h>
/* QMSI GPIO app example * * This app requires a board to be set up with a jumper cable connecting the * pins listed below so the output pin can trigger an interrupt on the * input pin. PIN_OUT will be configured as an output pin and PIN_INTR will be * configured as an input pin with interrupts * enabled. * * On the Intel(R) Quark(TM) Microcontroller D2000 Development Platform PIN_OUT * and PIN_INTR are marked "SSO 10" and "A0". * On Quark SE development board, PIN_OUT and PIN_INTR are located on header P4 * PIN 42 and 40. */ #define PIN_OUT 0 #define PIN_INTR 3
/* Example callback function */ staticvoidgpio_example_callback(void *, uint32_t);
volatile bool callback_invoked;
intmain(void) { qm_gpio_port_config_t cfg; qm_gpio_state_t state;
QM_PUTS("Starting: GPIO\n");
/* Request IRQ and write GPIO port config */ cfg.direction = BIT(PIN_OUT); cfg.int_en = BIT(PIN_INTR); /* Interrupt enabled */ cfg.int_type = BIT(PIN_INTR); /* Edge sensitive interrupt */ cfg.int_polarity = BIT(PIN_INTR); /* Rising edge */ cfg.int_debounce = BIT(PIN_INTR); /* Debounce enabled */ cfg.int_bothedge = 0x0; /* Both edge disabled */ cfg.callback = gpio_example_callback; cfg.callback_data = NULL; callback_invoked = false;
qm_irq_request(QM_IRQ_GPIO_0, qm_gpio_isr_0);
qm_gpio_set_config(QM_GPIO_0, &cfg);
/* Set PIN_OUT to trigger PIN_INTR interrupt */ qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT); qm_gpio_set_pin(QM_GPIO_0, PIN_OUT);
while (!callback_invoked) { }
if (qm_gpio_read_pin(QM_GPIO_0, PIN_OUT, &state)) { QM_PUTS("Error: read pin failed\n"); return -EIO; } if (state != QM_GPIO_HIGH) { QM_PUTS("Error: pin comparison failed\n"); return -EIO; } qm_gpio_clear_pin(QM_GPIO_0, PIN_OUT); QM_PUTS("Finished: GPIO\n"); return 0; }
voidgpio_example_callback(void *data, uint32_t status) { callback_invoked = true; QM_PRINTF("GPIO callback - status register = 0x%u\n", status); } |