Skip to end of metadata
Go to start of metadata

 

Purpose

This page is meant to help you get started with Giant Gecko microcontrollers which are part of the EFM32 device family from Silicon Labs.  The EFM32 family of microcontrollers are some of the lowest power 32-bit microcontrollers available.  The Giant Gecko device family implements an ARM Cortex-M3 core and is available with up to 1024KB program (flash) memory, up to 128KB RAM, and CPU speeds up to 48MHz.  This page will help you start a blank Giant Gecko project using IAR Embedded Workbench and provide some example code to familiarize you with the various peripherals available with this microcontroller at the register level. It also provides example code using emlib functions.  The EFM32GG-STK3700 was used as the development platform for these examples.

Reference Documentation
Downloads
  • Simplicity Studio  -  Provides extensive documentation for all EFM32 devices and example code using emlib libraries.  Also performs energy analysis.  Note: This is not a code development suite.
  • IAR Embedded Workbench  -  Firmware development environment (CD also included with kit).  Time-limited licenses, or code-limited licenses are available for free.  The 32KB code-limited version can be used for the examples found on this page.
  • Keil uVision5  -  Firmware development environment.  Similar free licenses are also available for this software.

Create an IAR Template Project for EFM32

Silicon Labs recommends using Simplicity Studio to locate example code and documentation.  They recommend cloning existing projects for IAR instead of starting a blank IAR project from scratch.  This is because all of the App Notes and example code written for these micros use a hierarchy that is non-typical for IAR projects.  The examples also setup your include file paths and setup your debug link for you.  You can then use CMSIS and em_lib libraries to call functions from your main.c file to develop your application.

Although it's not necessarily recommended, you can start a blank IAR project by using the following procedure.  This procedure parallels the example found here.  However, I setup my project in a unique project directory rather than the default location used by Simplicity Studio.

 

 Procedure for Starting a Template IAR Project for EFM32

This procedure outlines how to start a blank IAR project and setup the necessary project settings.  However, we will use this process to setup a template project.  Once we have a template created, we can simply copy&paste and rename the project whenever we wish to start a new EFM32 Giant Gecko project.  Even if you don't want to use the emlib libraries, you should still follow all of these steps to properly setup your project.

  1. Open IAR and navigate to Project -> Create New Project

  2. In the "Create New Project" dialog box, ensure 'ARM' is selected as the Toolchain.  Select 'Empty Project' and click 'OK'.

  3. Now a "Save As" dialog should pop up and you can select a location for your project.

    Silicon Labs recommends placing each of your projects in the application note (an) directory that gets created when you install Simplicity Studio.  However, we are going to create a unique location for all of our EFM32 projects. 

    For my personal use, I created a "My_EFM32_Projects" folder within an "Energy Micro" folder on my desktop.  This is where I store all of my new EFM32 projects.  For this demo, since we are using a Giant Gecko microcontroller, inside the "My_EFM32_Projects" folder, I've created a folder called "Template_EFM32GG".  You can name it whatever you wish.  However, I like to be able to sort my projects by micro type.  It's an easy identifier for me to recognize which specific micro I used for that project if I include it in the name of the project folder.  Alternatively, you could create another folder for individual micros if you wanted, but I like to keep my folder count down if possible.  My project directory now has the following hierarchy:

    <desktop> -> "Energy Micro" -> "My_EFM32_Projects" -> "Template_EFM32GG"

    Once you have your project directory setup, create an "iar" folder and save the project file as "Template_EFM32GG.ewp".

  4. Now that your project has been created, you can add some groups to the project.  Right-click the project in the workspace browser and select 'Add Group'.

  5. Let's name the first group 'source'.  This is standard for all EFM32 projects.

  6. Now we can create our 'main.c' file.  Navigate to File -> New -> File

  7. An untitled file should open.  Select File -> Save As

  8. Navigate to your project directory (one level above the 'iar' folder you saved the project file in) and save the file as 'main.c'.  In my case the project directory is: <desktop> -> "Energy Micro" -> "My_EFM32_Projects" -> "Template_EFM32GG"

  9. Now that the 'main.c' file has been created, we have to actually add it to our workspace.  Right-click on the 'source' group you created and select Add -> Add Files.

  10. Select the 'main.c' file you just created.


  11. Add two more groups to your workspace and call them 'CMSIS' and 'emlib'.  This is standard for EFM32 projects.
  12. Right-click the 'CMSIS' group and select Add -> Add File. 

  13. When Simplicity Studio is installed, it saves all documentation as well as CMSIS, emlib, and device files in:   C:\Users\<user name>\AppData\Roaming\energymicro
    In the 'energymicro' folder, navigate to Device -> EnergyMicro -> EFM32GG -> Source  (if you aren't using a Giant Gecko, navigate to the appropriate EFM32xx folder).

    Select the 'system_efm32gg.c' file and click 'Open' to add the file to your workspace.  This file is included for all standard EFM32 projects.

  14. Right-click the 'CMSIS' group and again select Add -> Add File.  Navigate to C:\Users\<user name>\App Data\Roaming\energymicro\Device\EnergyMicro\EFM32GG\Source\IAR and open the 'startup_efm32gg.s' file to add it to your workspace.  This file is needed in order to properly program the device.

  15. Now you can add source files to the 'emlib' group that you previously created.  You can add only the ones you need, or add all of them if you wish.  Navigate to the 'emlib' folder which is located at C:\Users\<user name>\AppData\Roaming\energymicro.
    Inside the 'emlib' folder you can open the 'src' folder and add any or all of the peripheral emlib libraries.  I would recommend adding all of them to your workspace for you to easily browse through the available functions.  That way you can view any file without having to navigate to each one using windows explorer.  Use 'Ctrl'+'left mouse button' to select individual files and click 'Open' to add them to your workspace.
    Note:  Even if you don't want to use the emlib libraries, you should still add the 'em_system.c' file to the emlib group so that you can call the Chip_Init() function at the beginning of your 'main.c' file.  Chip_Init() addresses any known errata for your device and applies any known software fixes.

  16. In order to use the functions located in these emlib files, you need to add #include for the respective header file in your 'main.c' file.  For example, if you wanted to use any of the prewritten ADC functions in your 'main.c' file, you would need to include the 'em_adc.h' header file as shown in the following example.  'em_system.h' and 'em_chip.h' should be added to every EFM32 project.  You can also add a blank main() function to your 'main.c' file.

  17. Now let's setup the project options.  Right-click on "Template_EFM32GG.ewp" in the workspace explorer and select 'Options'.

  18. In the 'General Options' category, under the 'Target' tab, make sure the 'Device' button is selected and click the 'list' icon on the right.  Navigate to EnergyMicro and select your specific device.  For this demo, I selected EFM32GG990F1024 which is loaded on the EFM32GG Starter Kit.

  19. In the 'C/C++ Compiler Settings' category, under the 'Preprocessor' tab, you can add include directories for your device.  You will need to add the paths to the include files for the CMSIS library and the emlib library if you wish to use the emlib API (recommended).  You will also need to link to the 'Include' folder for the specific device.  Example projects found in Energy Micro app notes use relative paths from the project directory to link to these directories.  You can use hard-coded paths if you know the location of these won't change.  For my personal use, I hard code the paths directly in the Project Options (rather than using relative path).  Silicon Labs recommends you use relative paths for portability.  It's completely up to you, but you need to always be aware of where the files are located and how you are linking to them. 

    In the 'Defined symbols' box, you also need to define your device symbol.  For my project, I've defined the symbol EFM32GG990F1024.  Here's an example of hard-coding the path to the default install directory.



  20. In the 'Output Converter' category, check 'Generate additional output' and select 'binary' for output format.

  21. In the 'Linker' category, select 'Override default' and navigate to the .icf file for your device.  The file should be located in the IAR install directory, not the Simplicity Studio install directory: 
    C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.x\arm\config\linker\EnergyMicro.

  22. In the 'Debugger' category, under the 'Setup' tab, select 'J-Link/J-Trace' as the Driver since we are using the J-link debugger included on the EFM32GG Starter Kit.  If you are using a different debugger, these settings may change.

  23. Still in the 'Debugger' category, under the 'Download' tab, check the 'Verify download' and 'Use flash loader(s)' boxes.

  24. In the 'J-Link' category, under the 'Connection' tab, select 'SWD' as the Interface.  Click 'OK' to apply the project options.

  25. Select File -> Save All.  Save the workspace in the 'iar' folder within your project directory.

  26. Right click on the project and click 'Make' to build the project

  27. Now we have a template project with all of the necessary project settings.  Whenever we wish to start a new EFM32 project for Giant Gecko, we can simply copy&paste the template project in whatever location we desire because we used hard-coded include paths.  Once you paste a copy of the template, simply rename the project folder to whatever you wish.  Also, I would recommend renaming the workspace file to match the project name.  All other files can keep "Template" in the file name and the project will still build properly.

            

 

You are on your way!  Now let's look at some code examples...


 

Code Examples

The following examples were written using IAR embedded work bench with a 32KB size-limited free license.  They are meant to help familiarize you with basic functionality of EFM32 Giant Gecko microcontrollers.  For all of the following projects, I followed the procedure above for creating a new project (copy&paste created template).  The examples are presented in order of difficulty and some build on previous examples.  If you are brand new to EFM32 microcontrollers, I would recommend starting from the beginning and going through each of the examples in order.  If you already have some experience with EFM32 microcontrollers, feel free to jump to any example you wish.

 

 GPIO Example

This example demonstrates how to set pins as inputs with pull-up resistors enabled, as well as how to set and clear digital outputs.  It also demonstrates how to adjust the drive strength of digital outputs.  The EFM32GG allows the user to set the drive strength of a digital output with the following values:

  • STANDARD  -  6mA drive current
  • LOWEST  -  0.5mA drive current
  • HIGH  -  20mA drive current
  • LOW  -  2mA drive current

However, the EFM32GG Starter Kit uses 3 kOhm resistors which limits LED current to a max of about 1mA.  Therefore, the HIGH and LOW drive settings show no effect.  The LOWEST drive mode does enable the user to see visible change in LED intensity as a direct result of the drive mode setting.  Therefore, LOWEST was used in the following example.

In the following example, LED0 is on by default with a standard drive strength of 6mA.  LED1 is off by default.  Pressing PB0 toggles LED1 and pressing PB1 toggles LED0.  LED1 uses the lowest drive mode setting of 0.5mA.  Even though the drive strength of LED0 is set to 6mA, the current limiting resistors reduce the current to approximately 1mA through LED0. 

 GPIO Example Using Direct Register Access

The following code demonstrates how basic GPIO functionality using direct register access.  For the following code to work, the 'em_system.c' file needs to be added to the workspace.

 GPIO Example Using emlib API

The following code demonstrates how the emlib libraries can be used to implement the same GPIO example.  For the following code to work, the following emlib source files must be added to the workspace:

  • em_cmu.c
  • em_gpio.c
  • em_system.c
 Timer with Interrupt

The following code uses a timer with interrupt to blink an LED.  It uses the default clock source which is the internal high speed RC oscillator.  It sets the RC oscillator to 1MHz and uses a timer to interrupt every millisecond.  After 500 ms, it toggles LED0. 

 Timer with Interrupt Using Direct Register Access

 The following code demonstrates how a basic timer can be implemented using direct register access.  For the following code to work, the 'em_system.c' file needs to be added to the workspace.

 Timer with Interrupt Using emlib API

The following code demonstrates how the emlib libraries can be used to implement the same Timer with Interrupt example.  For the following code to work, the following emlib source files must be added to the workspace:

  • em_cmu.c
  • em_gpio.c
  • em_timer.c
  • em_system.c
 Using the HF XTAL Oscillator

The following example is similar to the Timer with Interrupt example shown above.  However, this example uses the on-board 48MHz crystal as the High Frequency Clock source.  The code uses the HF clock divider to set the HF clock rate to 24MHz.  The High Frequency Peripheral clock and the High Frequency Core clock prescalers were left at /1.  Therefore, the Timer, GPIO peripherals along with the Core clocks all run at 24MHz in this example.  The TOP value of the counter was set to 24000 so that the overflow interrupt occurs every millisecond.  Every 500 ms, LED0 toggles.

 HF XTAL Example Using Direct Register Access

The following code block shows exactly which registers to write to in order to properly configure and use the HF XTAL oscillator.  For the following code to work, the 'em_system.c' file needs to be added to the workspace.

 HF XTAL Example Using emlib API

 The following code block achieves the exact same functionality as the above example using emlib functions.  The following files need to be added to the workspace for the code to work:

  • em_cmu.c
  • em_emu.c
  • em_gpio.c
  • em_timer.c
  • em_system.c

 


 

 

 PWM Example

This example demonstrates how to setup PWM output on the EFM32 Giant Gecko.  It uses Capture/Compare Channel 2 of Timer3 which is available on PortE, Pin2 of the microcontroller.  You may remember from the "GPIO Example" above, PE2 is connected externally to LED0 on the EFM32 Giant Gecko Starter Kit.  Therefore, we can use PWM output to control the intensity of LED0. 

This example uses 2 different timers.  Timer3 was used as the PWM generator.  The PWM period was set to 1ms (frequency of 1kHz) and the duty cycle was adjusted by updating the output compare register at a defined UPDATE_PERIOD.  The second timer – Timer0 – was used to generate the update period of 250ms.  This example uses Timer0 with its overflow interrupt just like in the "Timer with Interrupt" example above.

Whenever the Update Period is reached the intensity of LED0 is updated with the new compare value and LED1 toggles.

The system clock for this example was the High Frequency RC Oscillator, set to 1MHz.  The High Frequency Peripheral clock was used as the source for Timer0 and Timer3 with a prescaler of /1 for each timer.  Therefore, Timer0, Timer3, and the System Clock all share the same frequency.  The TOP value of each timer was set to 1000, so the overflow interrupt period for Timer0 and the PWM period for Timer3 were both 1ms (1kHz freq).

 PWM Example Using Direct Register Access

The following code block demonstrates how to achieve LED intensity control using PWM output functionality of Timer3 with direct register access.  For the following code to work, the 'em_system.c' file needs to be added to the workspace.

 PWM Example Using emlib API

The following code block demonstrates LED0 intensity control using PWM output capability of Timer3 (channel 2).  The following files need to be added to the workspace for the code to work:

  • em_cmu.c
  • em_gpio.c
  • em_timer.c
  • em_system.c

 


 

 

 UART Example

This example shows how to setup the USART in asynchronous mode (essentially a UART) for basic serial communication.  UART communication is very popular in embedded designs due to the low number of required pins (Transmit Data line, Receive Data line, and Ground).  There are even some "single-wire" UARTs available (shared TX/RX line), however these still require a common ground to operate properly.  UARTs work asynchronously, meaning there is no dedicated clock line between the 2 devices.  Therefore, each device needs to have a predefined matching data rate and frame format to actually communicate. 

The data rate is defined by the clock for each individual device.  Any error in the clock rate will effect the baud rate of the UART and could cause loss of sync between the devices.  Because of this, it's normally recommended to use a high accuracy clock source such as a crystal oscillator.  An RC oscillator may work, although it should involve some sort of calibration process to increase accuracy.

For this demo, the Giant Gecko was setup to use the 48MHz high frequency crystal oscillator.  The HF clock devider was set to /2 to achieve a system clock of 24 MHz just like in the "HF XTAL Oscillator" example above.

For this demo, the Giant Gecko UART port was setup with the following serial communication settings:

  • Baud Rate (bps):  38400
  • Data Bits:  8
  • Parity:  none
  • Stop Bits:  1

The code examples found below were tested using a custom expansion board which has USART1 available on an external connector.  The custom expansion board was connected to a PC using the TTL-232R-3V3 smart cable from FTDI.  A terminal emulator program (Tera Term) was used to display characters transmitted to and from the Giant Gecko.  The serial port of the terminal program was setup with the following settings:

  • Baud Rate (bps):  38400
  • Data Bits:  8
  • Parity:  none
  • Stop Bits:  1
  • Flow Control:  none

The following figure shows the printed characters in the terminal window while running the applications found below.

 

 UART Example Using Direct Register Access

The following example code shows how to use direct register access to implement this simple UART application.  For the following code to work, the 'em_system.c' file needs to be added to the workspace.

 UART Example Using emlib API

The following example code shows how to implement the UART example using emlib functions.  For the following code to work, the following files need to be added to the workspace:

  • em_cmu.c
  • em_emu.c
  • em_gpio.c
  • em_system.c
  • em_usart.c

 

 


 

 

 ADC Example

This example shows how to setup the Analog to Digital Converter (ADC) in the Giant Gecko using a custom expansion board that interfaces with the STK3700.

A potentiometer loaded on the expansion board was used as the analog source.  The potentiometer provided a controllable analog voltage source varying between 0~3.3V with the center tap connected to PD6 (ADC0 Channel 6) of the Giant Gecko.  Therefore, VDD (3.3V) was used as the reference voltage of the ADC.  The ADC was setup in single ended mode and provided single conversions at a predefined interval.  The results were set to 12-bit, right-justified within the 16-bit result register.  The ADC clock was set to 12MHz with x2 oversampling enabled.  An input filter was not implemented for this demo.

After the ADC completed each conversion, USART1 was used to transmit the results to a terminal program on a PC.  The USART was setup in asynchronous mode with the same serial communication settings as the "UART Example" shown above.

To provide a high accuracy clock for UART communication, the 48MHz crystal oscillator was used with a /2 prescaler to generate a 24MHz System Clock, just like the "HF XTAL Oscillator" example above. 

Timer0 was used as a general purpose timer to trigger single ADC conversions every 500ms, similar to the "Timer with Interrupt" example above.  The potentiometer value was updated onscreen every half second.

Below is a screenshot of the terminal window while running this demo application.

 

 ADC Example Using Direct Register Access

The following example code demonstrate how to setup the ADC in single conversion mode using direct register access.  For the following code to work, the 'em_system.c' file needs to be added to the workspace.

 SPI Example

This example shows how to setup the Serial Peripheral Interface (SPI) in the Giant Gecko using a custom expansion board that interfaces with the STK3700.

A flash memory IC (W25X20CL) loaded on the expansion board was used as the SPI target.  The flash IC SPI port (MOSI, MISO, SCLK, CS) was connected to USART1 (Location #1) through PortD - PD[3:0].  USART1 was configured in synchronous (SPI) master mode with the SCLK idle low, data setup on trailing edge of SCLK, and data sampled on the rising edge of SCLK.  The USART1 clock divider was left at 0 which generated a SCLK frequency of 12MHz.  Due to the requirements of the flash IC, USART1 was setup to transmit msb first and the CS pin was handled manually (although the Giant Gecko does offer automatic CS functionality).  The flash IC also has active low "Hold" and "Write Protect" pins connected to the Giant Gecko.  However, these pins are not used in this example, except to drive the "Hold" pin high and the "Write Protect" pin low.

For this demo, a simple 'Device ID' command was sent to the flash IC which returns a 2-byte response – the Manufacturer ID and the Device ID.  For the W24X20CL, these values were 0xEF and 0x11, respectively.

After the response was received, USART0 was used to transmit the response to a terminal program on a PC.  USART0 was setup in asynchronous mode with the same serial communication settings as the "UART Example" shown above.  However, for this example, PC0 (USART0 Location #5) was used as the transmit pin.  The receive pin at Location #5 is not available through the expansion port of the STK3700 while in full duplex mode.  This isn't a problem since we are simply transmitting results to the PC, not entering values from the PC.  USART0 TX pin and GND were connected to the RX and GND pins of TTL-232R-3V3 smart cable from FTDI which was then connected to the USB port of the PC.

To provide a high accuracy clock for UART communication, the 48MHz crystal oscillator was used with a /2 prescaler to generate a 24MHz System Clock, just like the "HF XTAL Oscillator" example above. 

Below is a screenshot of the terminal window while running this demo application.

 

 SPI Example Using Direct Register Access

The following example code demonstrate how to setup SPI communication using direct register access.  For the following code to work, the 'em_system.c' file needs to be added to the workspace.

 I2C Example

This example shows how to setup the Inter-Integrated Circuit (I2C) peripheral in the Giant Gecko using a custom expansion board that interfaces with the STK3700.

An EEPROM memory IC loaded on the expansion board was used as the I2C slave device.  The EEPROM was connected to I2C1 (Location #0) through PortC - PC[5:4].  I2C1 was configured in master mode using standard speed (100kHz).  The auto-acknowledge feature of the Giant Gecko I2C was used for this demo to simplify the code.  The EEPROM also has an active high "Write Protect" pin connected to PC3 which needs to be driven low to enable memory writes.

The example code below includes multiple functions involving interaction with the EEPROM:

  • read_byte()  -  reads the contents of the specified address in memory
  • write_byte()  -  writes a byte of data to a specific address in memory
  • read_block()  -  performs a sequential read of an entire block (256 bytes) of memory
  • write_page()  -  writes up to 16 bytes of memory in a single I2C transaction
  • chip_is_busy()  -  checks if the EEPROM is able to communicate

USART1 was setup to print responses in a terminal program.  USART1 was setup in asynchronous mode at Location #1 with the same serial settings as the examples above.  USART1 was connected to the PC using TTL-232R-3V3 smart cable from FTDI.

To provide a high accuracy clock for UART communication, the 48MHz crystal oscillator was used with a /2 prescaler to generate a 24MHz System Clock, just like the "HF XTAL Oscillator" example above. 

Below is a screenshot of the terminal window while running this demo application.  The following screenshot shows a portion of Block 1 after the write_byte() function was used to write 0x23 to address 0x02 of Block 1.  The page_write() function was used to write 0x00 to each byte of Page 1 as seen in the terminal window below.

 

 I2C Example Using Direct Register Access

The following code block demonstrates I2C communication using direct register access.  For the following code to work, the 'em_system.c' file needs to be added to the workspace.

Contact the Author

The code found in the examples above can be used freely.  I encourage you to build on the examples presented on this page and add functionality to the applications.  Take the Timer example code and try cascading multiple timers together.  See if you can combine the GPIO example and the Timer example to create a debounce function for the user buttons.  Try configuring different baud rates or setting up a software buffer for the UART example.  The goal of this page is to familiarize you with basic functions of EFM32 Giant Gecko microcontrollers so that you can apply each peripheral in more complex applications.  I hope you find it useful.  For questions, feedback, or if you would like to see a topic added to the eewiki, you can email me at eewiki@digikey.com.  I hope you are successful with Giant Gecko microcontrollers.

    -    Scott

 

Labels
  • No labels