Official Blog of Silicon Labs

      • Helping Sengled Develop a Better Lightbulb

        Lance Looper | 02/54/2017 | 09:30 AM

        Sengled, known as an innovator in LED Lighting, recently showed off its new Element lightbulb during CES. We’re excited to have been part of bringing the element to life by providing our best-in-class zigbee® technology for the award-winning connected light bulb.


        Our wireless SoCs and zigbee stack make it possible for Element bulbs to connect to multi-node mesh networks deployed in smart homes. Using iOS and Android apps or popular smart home ecosystems, consumers can control Element bulbs individually or as groups, customize an array of smart lighting features, and schedule lights to turn on automatically in the evening or off during daylight hours to conserve energy.


        The Element bulb’s sleek, modern design fits easily into existing light sockets and complements contemporary home decor. And it combines the unmatched energy efficiency of an LED bulb with advanced features such as customizable scheduling, color temperature tuning (soft white 2700K to daylight 6500K) and energy tracking, all controlled through cloud-connected wireless technology. An Element bulb uses 80 percent less energy than traditional incandescent bulbs, offers a 60 W output equivalent while using only 9.8 W and is rated to last approximately 22 years. The Sengled Element bulb was selected as a 2017 CES Honoree in the Eco-Design and Sustainable Technologies category.


        Click on the video below and check out how Element works with Amazon Echo:

        Based on the widely adopted IEEE 802.15.4 standard and operating in the 2.4 GHz band, zigbee provides the scalability, interoperability, reliability, energy efficiency and security features required for wireless smart lighting control. Silicon Labs is the industry’s leading supplier of zigbee mesh networking technology for Internet of Things (IoT) applications including connected lighting. To date, Silicon Labs has shipped more than 100 million mesh networking SoCs and modules to customers worldwide.


        Screen Shot 2017-02-22 at 2.26.33 PM.pngFor more information on smart connected lighting, check out our whitepaper, “Flipping the Switch on Connected Lighting.”


      • How Much Do a Company’s Values Matter?

        Lance Looper | 02/52/2017 | 01:00 PM

        I asked myself that question earlier this month during a talk by Andy Fastow. You may recognize the name. He was the CFO at Enron. He spent 6 years in prison and is the only Enron executive to take full responsibility for his actions. Today, he spends much of his time lecturing on the situations and thinking that led to Enron’s downfall. A cautionary tale with insights on how every single decision sets a tone for the next decision.


        Think back to the year 2000. Enron was a $100B company that generated $1B in net profit. Fortune magazine included them on the list of Most Admired Companies due to their innovation and domination of new business categories. By 2001, however, Enron’s CEO had resigned and the SEC was investigating the company for fraud and Enron, one of the ten largest companies in America, was bankrupt.


        Enron was disciplined because it willfully misled investors and the public by creating “paper companies” to keep debt off the books and appear more profitable. While the formation of these paper entities was within the law, the overall picture of a profitable company was wholly misleading. Many made investment decisions based on this incomplete information and the consequences came crashing down.


        It’s important to remember that just because something is legal, does not mean it is ethical. Enron’s culture was one of greed and deception. Pushing the limits was the norm. Rules were overcome by finding loopholes that, while technically legal, violated the spirit of the rule. Do this enough times and you end up with deals made up of components that are right up against the red zone.


        Most companies have a set of values that govern how they do business which serve as a bulwark to reinforce ethical behavior. At Silicon Labs, we have four core values that we display in every conference room in each of our buildings. The fourth and final value is DO THE RIGHT THING. This core value pervades everything we do. Whether it’s how we treat a customer complaint, how we report our finances or how we structure a deal. That doesn’t mean mistakes are never made. But it does set the tone for what is expected, what is accepted and how mistakes should be handled.




        Good decisions are more likely to be made if the organization has set clear expectations on what is considered ethical behavior. Read our corporate values here and check out our Business Conduct Standards that serve as a company guide for ethical decision making. What experiences or feedback can you share with us on corporate best practices to set an ethical tone from the top?

      • Essential Best Practices and Debugging Tips for EFM32 Project Success - Part 4

        lynchtron | 02/46/2017 | 04:15 PM


        In the last section, you learned of some essential practices and tips for software development.  We continue those topics in this section, covering inline functions, reading and writing flash memory (including User Page flash), and how to avoid buffer overruns.  The potential issues of typcasting is discussed, and how configuration locks might help when things go really south.


        Code Well, and Everything Works Better -- Continued

        (See the prior section for parts 1 through 8.)


        9. The implications and limitations of inline functions
        If you define a function with the keyword “inline” in front of it, you are telling the compiler that you want that function to be copied into code as if it were typed into the code directly rather than as a function. As the programmer, you hope that this will speed up the code execution time. Whenever a function is called in C, the contents of the input parameters are placed onto the stack together with the return address where the code is supposed to jump back to when the function is done, and then the code jumps to execute the function. By making a function inline, you intend to bypass that time shuffling data to and from the stack. However, the C compiler takes this more or less as a suggestion, as small functions will be automatically inlined by the compiler. The compiler will ignore this inline suggestion for larger functions that the compiler has determined will see little benefit from the speed up.

        Inline functions cannot contain locally static variables. Since the function contents are intended to be replaced within the code, a static variable that is private to a function scope has no meaning. Inline functions have no scope.

        10. The difference between reading and writing flash memory
        To read data from any region of flash memory in EFM32 is very simple. Flash can be accessed with a pointer to a memory address like so:

        volatile uint8_t* address = 0x1000;
        uint8_t my_value = *address;

        By placing the asterisk in front of the address variable, you are dereferencing the pointer, which gives you the byte sized contents of system address 0x1000. The number of bytes retrieved from flash will vary based on the type of variable for my_value. For example, my_value defined as a uint64_t will fetch eight bytes at once from address 0x1000 to 0x1007. Therefore, executing my_value++ as a 64-bit unsigned integer points to 0x1008.

        Writing to flash memory is a much trickier business. All flash memory organizes memory into “pages” that group writeable cells together into big chucks that can only be erased together as a group. Therefore, if you want to write to a single byte of non-volatile memory, you have to erase the entire page first. To the programmer, that means that you have to first read the contents of memory for the whole page, store it in RAM, erase the page, then write back the whole page together with the modified byte, hoping that you don’t lose power in the middle of the operation or else you just lost that page of data forever. There are usually timing implications too, because erasing and writing a page takes a lot more time than reading a value. When a page of flash is erased, all of the contents of the page are reset to 1’s, or 0xFF’s in a byte-sized memory viewer. Therefore, when you write a byte to memory, you are simply clearing those bits that are not 1’s.

        To write to EFM32 flash, another requirement is that the function that is writing to flash must be resident in RAM, not in flash where normal executing code is located, while the same code is being executed. This requires that any function that intends to write to flash memory that is also being executed is declared with the RAMFUNC declaration as defined in the ramfunc.h library utility file.

        11. Store persistent data in flash User Page flash
        Main flash memory starts at address zero and is capped at different capacities based on the EFM32 model. See the Reference Manual for your specific chip to find out where main flash memory ends. In addition to the built-in flash, there is a memory region set aside for external flash expansion that resides just beyond the internal main memory, up to 24 MB. Any of the operations to read or write main flash memory covered in the previous section can be used to access main flash memory. However, every time that the chip is programmed, or if the device is erased, the data stored in the region used by your program will be overwritten by you new code. Therefore, reading or writing to main flash is typically used when performing a flash update procedure, for example, in a bootloader. You can of course feel free to use flash memory that is located above the program size as long as you realize that it will be erased if the chip is ever erased with a device erase operation or JTAG programming sequence.

        The EFM32 provides a separate page of flash memory that is not erased with a device erase operation or JTAG programming operation. This region of flash memory is called the User Page and starts at address 0x0FE00000. The amount of memory available is a single page, and the size of a flash page varies according to the model of EFM32 chip. Check the Data Sheet or Reference Manual for the size of a flash page. You can use this page for anything that you want to persist on the device from boot-to-boot that is safe from device erase operations, such as device serial numbers, device calibration data, or any data that is specific to each device.


        12. Avoid buffer overruns and the havoc those can cause
        When developing code with a desktop computer, you are lucky to be developing on a system that has an operating system, a built-in file system, and display screen. When you run into trouble with your software, the OS springs into action to rescue you and inform you that you tried to access memory that was outside the bounds of your program, or that you did something that created a fault. You have few luxuries when developing embedded code. There is no OS to watch over things to make sure that your program stays within some nicely defined boundary. If your code decides to write data to address zero or one million, the MCU will try to do what it is told. It cannot tell you that you don’t know what you are doing because there are no limits to what your program can do. You are all powerful, which is a good and a bad thing.

        A big problem that embedded developers face is buffer overruns. Working in embedded means lots of direct manipulation on memory addresses. If your program starts to behave erratically or you see a variable that seemingly changes its value without being set, a buffer overrun could be the culprit.

        The first thing to watch out for is obvious but still happens to the best of us. If you define an array that is x bytes long, don’t write beyond x-1. If there are x items in an array called foo, you can only address foo[0] to foo[x-1]. The bad thing is that if you address foo[x], foo[x+1], or so on, your code still works sometimes. The MCU will happily comply and write over whatever other variable happens to reside just beyond foo[x-1]. Then your project starts to act funky.  


        This can also get out of control whenever you are adjusting pointers, while casting the pointers to a different type. For example:

        void some_function()
        // Array of just 4 bytes
        uint8_t my_array[4];
        // Pointer to group of 4 bytes
        uint32_t * my_ptr = (uint32_t *) my_array;
        // foo is assigned all 4 bytes of my_array, 
        int foo = *my_ptr;
        // then my_ptr is incremented by one
        // which to my_ptr's type means 4 bytes
        // So my_ptr is now sitting out of bounds

        The above demonstrates how important it is to be careful when interpreting structures that are typed a one way at creation, but then later used by pointers that are typed differently.  Just because you can do the type cast, doesn't mean that you should do it.

        Another way that you can get into trouble with buffer overruns is by forgetting about the limitations of local scope. In C, most of the work done by functions is performed on pointers that are passed into the function. The return value from a C function is often limited to a “status” byte because simple values are easily returned from C functions on the stack, while other structures are trickier to return. Take for example a simple array that is local to a function:


        // This function will generate a compiler warning:
        // warning: function returns address of local variable
        int * some_function()
        int my_array[4];
        return my_array;
        // This function has no warning!
        int * some_other_function()
        int my_array[4];
        int * foo = my_array;
        return foo;

        As soon as the function returns, the memory allocated for my_array will be reclaimed by the system and allocated for the next thing that needs a chunk of memory. If you return a pointer to a local array from a C function, the compiler won’t warn you, and the MCU will happily do what you tell it to do. Once again, the code will work sometimes if there happens to be no new memory allocations immediately after the function returns. Your solution will be intermittent, and you will curse the day you ever decided to work on an embedded project!


        // This is a better way, pass pre-allocated pointers into the function
        // “int my_array[]” and “int * my_array” are identical for function parameters
        void some_new_function(int my_array[])
        my_array[0] = 1;

        13. Become a type-casting master
        When working “close to the metal” as you do in embedded development, you are constantly working with small bits of information, so you end up converting from one type to another often, with limited variable sizes such as 8-bit registers. Some of the examples of this section have shown how you must be aware of the impact on addresses when incrementing a pointer on a uint8_t type versus a uint32_t type. In addition, you must also be aware of how the C compiler interprets and converts types.

        The casting of types from one type to another doesn’t actually perform any conversion. It’s not a function, but is just a way to tell the compiler how data should be interpreted. It seems that the C compiler should warn you whenever you are assigning variables of different types to one another, but the compiler doesn’t always warn you of this. For example, consider the case of converting signed integers to unsigned integers as in the following:

        int8_t a = 0;   // Range is -128 to +127
        uint8_t b = 0;  // Range is 0 to 255
        long c = 0;     // Range is huge, both positive and negative
        a = -64;        // a can be negative
        b = 64;         // b can only be positive
        c = a + b;      // c is 0
        a = b;          // Converting a signed to unsigned is OK, in this case
        c = a - b;      // c is again 0
        b = 128;        // b is now bigger than a can represent
        a = b;          // a is now converted to -128
        c = a - b;      // c = -128 - 128 = -256!

        This example shows how you can get into trouble as your variables grow in size. Things work OK for a while, but then they can start to fail as the range of your variable is exceeded. Be sure you know what you want when converting types. A uint of size 8 can’t hold anything more than 0 to 255, and an int of 8 bits can’t hold anything beyond -128 to +127. Simply casting a large uint8_t as an int8_t doesn’t magically change your int8_t into a larger int. It is still limited to +127. You will have to use a larger type like int16_t if you want to increase its range.

        14. Use configuration locks to mitigate issues with malfunctioning code
        Sometimes when embedded engineers do math on pointers, we wander far off course and impact hardware with our lousy software. One way to protect your code from doing something downright awful thanks to buffer overruns and other lousy pointer arithmetic is to use configuration locks. The configuration locks available on many of EFM32’s peripherals require a special value to be written to a configuration lock register in order to allow changes to be made to the peripheral configuration. This prevents misbehaving code from changing the overall configuration of the device.

        Keys to Coding Success


        • Start with an existing example, then document your changes with well-named variables and lots of comments.
        • Learn more about the C language and understand where and how to declare variables and functions.
        • Don’t try to write to flash memory that hasn’t been erased or to memory that is outside the scope of what your variables can access.

        In the next section, we will learn how to better control software builds in the Simplicity Studio IDE.

      • IoT Hero Professor Sergei Bezrukov: Seeding the Next Generation of Innovators

        deirdrewalsh | 02/44/2017 | 05:29 PM


        We recently got to speak with Professor Sergei Bezrukov, faculty member of the Department of Math & Computer Science at the University of Wisconsin – Superior. An accomplished instructor fascinated with discrete mathematics, theoretical computer science, and electrical engineering, Sergei has influenced countless students during his career. As expected, the IoT has opened up a new avenue for encouraging his students to think outside the box and push the bounds of creative problem-solving with cutting-edge technology—as well as drawing more students to his discipline. We contacted him to gain insight into the modern classroom in the age of the IoT.


        Thanks for speaking with us, Professor. Tell us about your program and what you have your students up to at present.

        Our program here is pretty small and provides a personal touch; I often have 10 or even less students per class. We are a combined Computer Science and Mathematics department and don’t formally offer Electrical Engineering. But we do microcontroller development and emphasize solving related programming problems in several of my courses that I designed to entice more students to come over and explore the department. Of course, you cannot avoid an Electrical Engineering education if you want to design electronic circuits at the electrical level. However, for firmware development in many cases one does not need to know all the technical details about how the hardware works internally. This is my part in student projects. The students basically just need to understand how their devices work at the logic level, how to access registers for configuration, and collect data and process it by using some programming language. That’s closer to Computer Science, I would say.


        And to really encourage the students to put everything together on their own, what we do is have them complete one main individual design project that often involves wireless sensors, some kind of lighting control, sometimes radio controls, electrical, etc. Over the history of the course offerings, we’ve done about 40 projects—many of which are pushing into the realm of the IoT and addressing various problems the students are encountering.




        I really like that you are purposely seeking a more diverse student set to be part of your community and design exploration. What Silicon Labs devices are you having the students use in these individual projects, and why did you pick them?

        We use many Silicon Labs products, and many of them are our first-preference products. This includes low-power microcontrollers. I have intensive experience with your 8051 series and EFM32 series; they are very low power, actually the best in the market.


        Other Silicon Labs products that we intensively use are various USB bridges from the CP21xx series, temperature/humidity sensors from the Si70xx series, and the Sub-1G Si44xx radios. These are really easy to handle, and I like them a lot. This year, I also introduced your Bluetooth and WiFi modules from the Blue Gecko and Wizard Gecko series in my courses, wrote several forum articles on them, and we plan new projects based on them.



        What are some of your favorite student designs that come to mind since you started the projects in your class?

        Many come to mind. A recent one I like is done by a student who lives on a large piece of property in a rural area. He and his family can’t visually see when mail has been delivered; the mailbox is actually about a 10-minute walk from the house, and there are lots of trees. So he created a device that utilizes an accelerometer to detect the moment that the mailbox was opened and wirelessly alerts the family that something is waiting for them there.


        Another example is a Fraction Collector project we did for our Chemistry department. The device counts the amount of drops of solution collected in a tube and controls the carousel to bring the new tube under a sink according to the schedule set on a computer.


        Let me also mention several weather stations similar to the one I described here, a device for climate control in a bathroom, and a wireless vehicle control  based on  radio modules that use your EZRadioPRO chips. Last, but not least, a Bluetooth-controlled coffee machine project. A student whose kitchen and bedroom are located on different floors in his house turns on his coffee machine from bed with his smartphone upon waking up, so the coffee is ready and warm the moment he wants it.




        I always save my Bonus Question for the end. Where do you see the IoT going in the next 5–8 years given your unique experience as a researcher and educator?

        I think we will see a lot more simple devices will appear which are self-powered and deliver small data as needed for very specific applications. Also, more development will be done in the energy harvesting area for devices can self-power themselves from native power sources like sunlight, heat, or vibration and transmit some data wirelessly. And finally, just more wireless everything as the distance capacity for wireless transmission continues to multiply and forces designers to extend boundaries further in their problem-solving.

      • Connected Lighting Q&A

        Lance Looper | 02/38/2017 | 10:00 AM

        The connected lighting market is gaining serious momentum. The high expectations consumers have had for the industry are starting to materialize, and access to lighting development kits to simplify efforts is increasing. Product marketing engineer Alex Koepsel recently sat down to address some of the pressing questions facing the market, including taking a look at the different technologies and standards emerging, some of the most common applications, and a look at some of the design challenges facing developers.


        Connected Lighting.jpg


        Roughly how large is the wireless lighting market today?

        According to IHS Markit™ research data, the wireless lighting market is expected to increase from 17 million units shipped today to 52 million units in 2020. Other sources, such as Wireless Sensor Networks, are more bullish and forecast as much as 230 million units in 2020.


        What’s driving the market movement to wireless?

        For home lighting applications, quality of life and convenience are the most valuable reasons; for commercial use—such as retail and hotel applications—aesthetics is important; and for industrial applications, the main driver is cost savings.


        Is there one dominant wireless technology for lighting?

        Based on the answer above, it’s easy to see that there is not a one-size-fits-all solution. The right solution depends on the application and end-user requirements. For example, a family setting up lighting in their home would most likely prioritize ease of use and installation, while a multi-building manufacturing facility with thousands of lights and differently scheduled operational needs might require a more robust, secure system with scalable and long-range networking capability.


        What are some popular examples of wireless technologies?

        It depends on the specific environment and user needs, but some popular technologies are zigbee and Sub-GHz proprietary protocols, and others are growing in popularity, such as Thread and Bluetooth lighting. Presently, the zigbee PRO and its predecessor zigbee Light Link are the most widely used. Monitored by the zigbee Alliance, these specifications help to describe application-messaging protocols for lighting control and include mechanisms that make out-of-the-box operation simple, plus, for an engineering audience, make development simple. It’s worth noting that the zigbee 3.0 specification announced in 2016 is expected to replace the current specification in 2017, and as a part of market rebranding, the technology is now referred to as zigbee™ with the former application libraries becoming an IoT-centric application layer now called dotdot™.




        If Bluetooth is for streaming audio, why is this now being used in lighting?

        Bluetooth has actually expanded beyond just audio streaming, and it’s a popular technology because it connects to some of the most pervasive devices on the planet—smartphones. These newer and more user-friendly devices are perfect for setting up and controlling wireless lighting networks and offer some really cool applications, such as enabling light fixtures to send out Bluetooth Low Energy (BLE) beacons for advertising, geolocation, and other dual-purpose applications. That being said, Bluetooth lighting in scaled systems of many lights will most likely be joined by another wireless technology, due to the proven software and scalability of those accompanying technologies.


        Why not use Wi-Fi?

        Many people think of Wi-Fi because it is familiar and used all over the world, but Wi-Fi consumes a lot of power and has yet to have defined software for lighting—the “application layer” according to software developers. Having no app-layer or software toolbox to build from often adds months to a project development cycle. In addition, Wi-Fi hardware tends to be slightly higher cost than the alternative 802.15.4 solutions such as zigbee and Thread.


        What factors go into deciding the right wireless technology?

        A lot of factors come into play depending on your application. For example, systems can be as simple as a single on/off light switch or as complex as a fully featured lighting solution for a hotel/casino or manufacturing plant. Some considerations include the size and density of the network (how many lights or nodes will be controlled), the overall building environment, setup and installation requirements, installation budgets, and maintenance requirements.


        What are the biggest challenges or obstacles to developing wireless lighting?

        Some of the biggest challenges are cost pressures, time to market, and the associated learning curve of figuring out the wireless part of the design. For developers who are not well-versed in the inner workings of IoT (Internet of Things), it can be difficult. In terms of lighting specifically, an average zigbee light bulb has 15,000 lines of code. Compare that to a simple wired on/off light bulb that could be programmed on an MCU and can be coded in less than five minutes.


        Are there any plug-and-play solutions on the market (for developers to use)?

        There are some application notes and white papers that have been made available by both lighting experts and semiconductor companies. There are also some hardware and software reference designs that exist, and a few are available for purchase as open-source designs that can help developers solve some of the more difficult networking challenges.


        How do I pick which wireless protocol to use in my system?

        This question is difficult to answer due to all the variables mentioned so far. One thing to consider, though, to reduce the risk of future obsolescence is to find a solution that is flexible and can support many protocols. Innovation in the semiconductor market space has enabled that capability, to simplify hardware designs with a single chip solution.


        What about the networking software? Can I just license wireless lighting software to save myself time?

        Some companies have addressed that question and made efforts to better enable developers with wireless lighting software (“stacks”). zigbee, mentioned earlier, is a mature solution and a few companies have developed “Golden Unit” approved stacks that are available through low-cost kit purchases. Silicon Labs, TI, and NXP are a few examples of providers. Because zigbee is a mesh technology, some of those companies are now extending their leadership into Thread and Thread stack offerings, which adds Internet (IP) addressing.


        What is the best advice for development teams working on wireless lighting applications?

        Like most complex engineering projects, it is critical to understand and translate the consumers’ requirements as best as possible to design a great paper concept from the start. Then, from there, valuable resources are available to help cut development time and to deploy world-class wireless lighting products. I’ve seen engineering teams small and large take advantage of this. Examples of these resources include hardware reference designs, software design files, development plugin tools, networking debug tools, and training resources such as app notes.  Overall, leveraging the expertise and solutions that other industry leaders are providing will make a huge difference.


        For information about Silicon Labs’ lighting solutions, click here.

      • Essential Best Practices and Debugging Tips for EFM32 Project Success - Part 3

        lynchtron | 02/37/2017 | 03:17 PM



        In the last section, you learned about a few essential tips to help you develop your hardware prototype.  In this section, many hard-learned lessons in software development are shared.  What are the keywords extern, static and volatile all about?  Should you be using recursion or malloc() in your code?  Read on and find out.


        Code Well, and Everything Works Better

        1. Find existing software examples for your hardware devices
        The first step in developing any embedded solution is to find examples that can make your task easier. The software examples that you find for your specific parts in your custom solution will help you “see” the device in another light and help you reinterpret the device spec, even if those examples are for another computer architecture or software language.

        2. Code for the compiler
        There is no perfect computer software language. All languages have their strengths and weaknesses. The software language utilized in Simplicity Studio for the EFM32 family is C. The C language has been around long enough that it is well trusted and performs well on embedded designs, but it can be difficult to master the syntax and its idiosyncrasies. When you are coding in C, you are actually writing instructions that are meant for the compiler and other build tools. Keep that in mind. The C language is “close to the metal” in that your code has only a few steps between the code that you write in a human-readable format, the assembly code, and the binary image that is the result of the build process.

        The C code has strict typing that requires certain variables match well enough to perform safe assignment. This is there to protect you from doing stupid things, like comparing the address of a variable (i.e. a pointer) with the contents of a variable. But often in embedded development, you need to be able to convert pure numbers into addresses in order to specify a register address. This requires that you become well acquainted with type casts in order to tell the compiler that you really do know what you are doing.

        3. Use descriptive variable and function names
        The single best thing that you can do to help make sure that your code is well designed is to use descriptive variable and function names. There is no runtime performance penalty associated with long names in C code. All identifiers are removed when the build tools translate the C code into binary machine code. Consider the following snippet of code found in the FAT Filesystem (FF) library:

        	res = dir_sdi(dj, 0);
        	if (res == FR_OK) {
        		do {	/* Find a blank entry for the SFN */
        			res = move_window(dj->fs, dj->sect);
        			if (res != FR_OK) break;
        			c = *dj->dir;
        			if (c == DDE || c == 0) break;	/* Is it a blank entry? */
        			res = dir_next(dj, 1);			/* Next entry with table stretch */
        		} while (res == FR_OK);

        The above code has some comments, which certainly help and are a very good thing, but it’s hard to know the exact reason for this code by just looking at the variables, functions, enumerations and preprocessor symbols. Consider the following code as an alternative:

        // Load the first target_directory entry without table stretch
        result = set_directory_index(target_directory, NO_TABLE_STRETCH)
        if (result == FAT_RESULT_OK) { // Look for a blank entry for the Short File Name over all directories do
        { result = find_next_window_offset(target_directory->file_system_object, target_directory->current_sector); if (result != FAT_RESULT_OK) break; // Window offset was OK, check the entry short_file_name = *target_directory->short_file_name; // Is it a blank or unused entry? if (short_file_name[0] == DELETED_DIRECTORY_ENTRY_BYTE || short_file_name[0] == UNUSED_DIRECTORY) break; // Get the next entry with table stretch result = get_next_directory(target_directory, TABLE_STRETCH); } while (result == FAT_RESULT_OK);

        Yes, the code is a bit wider and harder to type, but Simplicity Studio offers code completion with the CTRL+Spacebar keyboard shortcut, and you can always cut and paste. What you will gain by this is readability that requires less hunting around for what the variable names are intended to do. We can tell just by looking at the second example that this code is intended to look through a target directory and break when it finds a deleted (previously populated but now available) or zero (never populated) Short File Name entry in the target directory. The descriptive names should allow you to read aloud the code as if it were a good story, telling you the purpose as you read along.

        4. Use comments religiously
        A good software developer adds lots of comments to the code in several key places. The comments, like long variable names, don’t add to the runtime file size of the resulting executable binary and are simply there to help document the purpose of code. The top of each file in the solution should state its purpose of that file, and there should be lengthy comments at the top of each function stating the purpose of the function as well as describe the inputs and outputs. Beyond these key places, comments should be used on a line-by-line basis wherever the intention of code isn’t clear. The use of descriptive variable names can help explain the purpose of code and make comments less necessary, causing the comments that are there to stand out. Trust me, even you won’t remember the purpose of the code a year after writing it, so comment liberally!

        5. Use the emlib library
        For the EFM32 programmer, the emlib library is your friend. Use these library calls wherever you can to interface with an EFM32 peripheral. These libraries are well-tested and have additional helper code to look for problems rather than just tweaking registers directly. For example, the following code uses the emlib library:

        TIMER_TopSet(TIMER3, 1000);

        The same thing can be done by addressing the registers of a memory-mapped peripheral by a preprocessor definition, which defines TIMER3 as 0x40010C00. We don’t use this address, which would be hard to remember, but that is where the TIMER3 is mapped in main memory.

        TIMER3->TOP = 1000;

        All peripherals are mapped to memory addresses in exactly the same way, so you will sometimes see examples using this pointer notation rather than the emlib library functions. If you will look inside of the TIMER_TopSet function definition in em_timer.h, you will see that the function does exactly the same thing as this example, so in this case the library function has provided no added value. However, with the emlib library, you will sometimes get much more functionality than the simple manipulation of a mapped register. For example, the CMU_ClockEnable function takes care to make a lot of decisions on your behalf before finally using a “bit band” command to ensure that a register bit is atomically set. Use these library functions as frequently as possible to gain the benefit of all of the EFM32 library designer’s hard work.

        6. Where and how to define variables to avoid problems with the stack and heap
        There are many facets of C that are not obvious to the casual programmer, but become important as you run your code in an embedded design. For starters, all locally-declared variables go on the stack. These are the variables that you define inside functions or any block of code.


        The stack is a region of memory that starts at the “top of memory” or the highest available address in physical RAM, and then counts downward until you hit the stack limit. If you define too many local variables or if your code dynamically creates those variables by using recursion or other nested functions, you can run out of stack space.


        Global variables are those that are defined outside of all functions and other blocks of code at the module level.   The compiler automatically allocates memory for your globally-declared variables on the heap, which is part of the main memory pool outside of the stackand will generate a compiler error if you try to allocate too much RAM.  However, the use of the malloc() command in your code allocates RAM on the heap at runtime, dynamically.


        The use of recursion or the malloc() command on an embedded processor with limited RAM is a risky business! You must understand how many recursive attempts (or malloc() calls) your code will ever require in order to resolve and then design a solution that will never run out of stack space.



        If you define all variables in your code and let the compiler determine how to manage memory automatically, you will run into fewer issues of overrunning the stack or heap.   Even with this precaution, if your code is nearly the size available RAM when you compile and build your code, you will need to learn how to monitor the size of the stack and heap, which is beyond the scope of this section.


        int foo;  			// Global variable, memory is on the heap
        void some_function()
        	int bar;		// Local variable, memory is on the stack

        7. The difference between global static variables and local static variables
        Variables that are defined using keyword “static” means different things at different scopes. Inside functions, the static keyword is used in front of a variable that is to remember its value in-between calls to the function. It’s sort of “sticky” in that you can initialize it at the first invocation of the function, and then it keeps its value rather than being reinitialized every time the function executes like non-static variables. At the global scope, all variables are “sticky” in that they only get initialized once at the start of runtime and then remember their values after that. However, the static keyword placed in front of global variable indicates to the compiler that the variable is local to that module and not to be used by outside modules. This is a totally different meaning for the same “static” keyword.

        int foo1 = 1;  	// Global variable, initialized only once
        static int foo2 = 2; 	// Global variable, initialized only once, private to this module
        void some_function()
        	int bar1 = 3;	// Local variable, initialized every time the function is called, 
        			// private to this function
        	static int bar2 = 4;// Local variable, initialized only the first time that this function
        			     // is called, private to this function
        	int foo1;	// This is a bad idea.  Local foo1 overrides global foo1 and makes the 
        			// global version unavailable inside this function


        8. The meaning of volatile and extern and how they impact each other
        As long as variables and functions are not declared as static within a module, they can then be used external to that module and used in other modules. In order to tell the compiler that you intend to use the same variable across modules, you define a variable the normal way in one module, and add the keyword “extern” in front of the definition in all other modules across the design. Now, all modules in your design can gain access to the same variable. However, if one of the other modules in the design intends to modify the value of a variable outside of the place where it is originally defined, you must add the keyword “volatile” in front of that variable. This volatile keyword tells the compiler that the variable can be changed outside the module’s knowledge and prevents the optimizer from removing statements that seem to have no effect.

        // Module A
        int foo;  		// Meant to be modified in this module only
        volatile int bar;	// Value can change unexpectedly outside of this module 
        // Optimizer must always evaluate the value of bar
        // Module B
        extern int foo;	// We can read this value defined in Module A, but should not modify it
        extern int bar;	// Since declared volatile in Module A, we can read and modify this variable

        In addition, the use of volatile is hugely important when you use a Release build versus a Debug build. The compiler will actively try to squash unnecessary code as the optimization settings increase. This means that you need to prevent the compiler from doing that by using the volatile keyword on any variable that can change outside of the current scope.


        In the next section, we will continue down the best practices for software path and learn about inline functions, how to work with flash memory, configuration locks and how you can get into trouble with buffer overruns.

      • A Focus on Simplicity Tops Our 2017 Resolutions

        Lance Looper | 02/33/2017 | 05:49 PM

        We’ve hit the ground running in 2017 and are dedicated to making this a year to remember.


        Our fundamental purpose as a company is to provide the silicon, software, and solutions for a smarter, more connected world. Beyond a tag line, this statement informs our primary purpose to help customers be successful. Looking ahead, there are two pillars that we’ll focus on in 2017 to help us deliver on the promise of simplicity


        Making things Simple

        We want to improve the way you discover, evaluate, and develop solutions in 2017. This means evaluation, setup, configuration, and installation is easy. You’ll see continued improvements on our website this year to enhance customer experience and make you more productive. Our 50,000-strong community is another area of focus. Explore our community and you’ll find more relevant content like knowledge base articles that provide answers to your most pressing questions in a matter of minutes.


         We also recognize the role that software plays in the success of your IoT applications; and we’ll continue to invest in best-in-class tools and stacks that give you more capabilities a competitive advantage. We take pride in understanding our customers’ business needs and doing things to help navigate a rapidly changing connectivity landscape. This year, we’ll continue to focus on things like pin compatibility, software reuse, multi-protocol wireless connectivity, and investing in modules that make it easier to validate concepts quicker and accelerate time to market. This approach will serve everyone from start-ups trying to get to market quickly to established companies trying to future proof designs.




        To provide a more comprehensive solution to designing IoT solutions, we recently acquired RTOS software leader Micrium and Zentri, an innovator in low-power, cloud-connected Wi-Fi technologies. These technologies are building blocks that make it easier to create cloud connected IoT devices.  As we build on our existing technology and integrate new capabilities, our aim will be to keep simplicity top of mind.


        Late last year, we performed in-depth market research, developer workshops, and stakeholder interviews with the goal of making Simplicity Studio 4 more efficient and easier to use. One of the first things we learned was the download and installation experience varied greatly depending on the customer’s geographic location. The Simplicity Studio team fixed this problem by letting the customer install only the portion of Simplicity Studio they wanted.  In some cases, this reduced the download size by a factor of 10. 


        This type of feedback was just the beginning. We’ll continue you to rely on ideas from you to help make our products better.


        I want to hear from you. What are your biggest professional resolutions this year?





      • February 2017 Member Spotlight: smalldevshack

        Siliconlabs | 02/33/2017 | 03:48 AM

        We are featuring one of the Silicon Labs Community members who is active or new in the community on a monthly basis to help members connect with each other.


        Meet our February member of the month: smalldevshack




        Q: Congrats on becoming our featured member of the month! Can you introduce yourself to our community members?


        Hi, my name is Patrick and I am a Product Developer at a Munich based startup. My background is chemistry and computer science, a rather interesting combination but it turns out as quite useful for prototyping Robot Happy

        When i studied computer science I quickly started doing Arduino projects like color scanning lamps or a remote controlled camera slider. I then joined a Start-up where I started working on the ARM-Cortex Chips (M0 and M4) for LED lighting systems control, and I was amazed by their power and compactness.

        I joined my current company one year ago. We have to develop a wearable device with strong space and power constraints, so I am currently looking forward to use the new BGM121 SIP for that job. I am fascinated with the low currents we can achieve now and how we are constantly reducing package / chip sizes.

        What's still on my bucket list is to develop a cyborg type implantable / wearable which can do energy harvesting from the human body and release pharmaceutical agents or support dysfunctional organs. I am highly interested in all gadgets / devices that combine (bio)chemistry and electronics.


        Q: How did you know about the Silicon Labs Community?


        Easy. I just saw it on the main Silabs site and signed up immediately. It's a very active community, I like that!


        Q: What features, products, services would you like to see in the future from Silicon Labs?


        Well, I really liked the AMAs in the forum, please make more of that. I think a quick support-chat function would be a great addition too. Also we NEED the EDIT button, please guys Robot wink


        Q: What advice would you give to someone new to the community?


        Ask anything you want to know if you want to grow better. If you have a problem/bug, always try to minimize the problem as radically as possible, i.e. make a new project where you just have that piece of functionality which causes the problem. Then take out a good old pen, write down all the possible causes you can think of with check boxes next to them and start debugging through the list. Solves 95 % of code problems...


        Q: Thanks for answering the questions. Any final comment?


        Thanks to all the employees and members on the forum. You are doing a great job!