Close
0%
0%

Electronic Ornament 2025 with EFM8SB1 Sleepy Bee

Working on porting code for my PIC16LF1823-based ornament to a new design using an 8051-based EFM8SB1 MCU

Similar projects worth following
179 views
0 followers
2-layer PCB with HASL finish, fabricated and assembled by JLCPCB
Board designed with KiCAD 7.0.
Firmware developed in C with Simplicity Studio 5, compiled with Keil 8051 C compiler.

2-layer PCB design with HASL finish, fabricated and assembled by JLCPCB.

Firmware developed in C using Simplicity Studio 5 and compiled with the Keil 8051 C compiler.

PCB designed with KiCAD 7.0.

Custom adapter used during development: https://hackaday.io/project/202798-breakout-board-for-third-party-8051-debugger

ornament2.hex

HEX file for ornament, product of C51/A51 with ornament2.c as input

hex - 6.47 kB - 05/15/2025 at 02:13

Download

ornament2.c

C source file, compiled with Keil 8051 C compiler (C51) for EFM8SB1 MCU. Compiled with level 8 optimization. Implements a bug fix for ornament.c involving clearing PMU flags on wake-up.

text/x-csrc - 9.17 kB - 05/15/2025 at 02:11

Download

ornament.hex

HEX file for ornament, product of C51/A51 with ornament.c as input

hex - 5.51 kB - 05/10/2025 at 12:05

Download

ornament.c

C source file, compiled with Keil 8051 C compiler (C51) for EFM8SB1 MCU. Compiled with level 8 optimization.

x-csrc - 8.41 kB - 05/10/2025 at 12:05

Download

main-unoptimized.c

C source file, compiled with Keil 8051 C compiler for EFM8SB1 MCU. This program is written to use the idle mode for power savings.

x-csrc - 7.39 kB - 04/13/2025 at 15:08

Download

View all 7 files

  • 1 × PTS647SM38SMTR2LFS SW2
  • 1 × Q13FC13500004 Y1
  • 1 × CL21A106KAYNNNE C1
  • 1 × CL10B102KB8NNNC C2
  • 1 × SHF-105-01-L-D-SM-K-TR J1

View all 11 components

  • Bug fixes and code optimization

    Zachary Murtishi6 days ago 0 comments

    I decided to finally install 2032 cell holders for the boards and went to test them, only to realize that the timing of the EFM8's RTC was off. I dug into the code and ended up cleaning up / optimizing a lot of it while trying to figure out why the RTC was acting up, only to end up investigating the ISR for the RTC wakeup.

    I noticed that upon the RTC alarm interrupt firing, the EFM8 would often "forget" to execute code after its ISR. This all began when I cleaned up the ISR to remove excess code (it's not great to have bloated ISRs) - turns out, some excess code in there was generating a delay that we seem to need. The EFM8 reference manual does suggest 4 NOP instructions following a wakeup, but it doesn't seem as the 4 instrinic NOPs I have in the code are working, so I threw in a uint8_t i; for(i=0; i<16; i++); to generate this delay.

    The RTC now seems to work well now with that delay in place...wondering why the delay needs to be longer than the reference manual suggests.

  • Bug fix: interrupt priority

    Zachary Murtishi04/14/2025 at 22:49 0 comments

    I noticed that the RTC alarms were failing to put the ornament into sleep mode whenever light patterns that depended on Timer0 interrupts were on. I figured that this may be due to the fact that the Timer0 held priority over the RTC alarm interrupt and consequently it could not be pre-empted by an RTC alarm interrupt if they coincided.

    I updated the program to shift the Timer0 interrupt to a low priority and the RTC alarm to a high priority.

    Initial tests show that this solution seems to work, but I have yet to test it with the intended time sequence (4 hours on, 20 hours off).

    I have a few other optimizations I can perform left, such as getting rid of the modulo operations and replacing them with conditionals. This would decrease the program size at the expense of data memory, which I have plenty of left.

  • Optimized firmware build

    Zachary Murtishi04/13/2025 at 21:39 0 comments

    I went and improved on the firmware build I put together earlier today by reorganizing my program to make use of the sleep mode to save power during periodic inactive periods, much like my PIC16LF1823-based design was implemented. The last build used the Timer2 peripheral for timekeeping, which I used because it is much easier to access than the RTC registers (which require indirect memory access to read/write). The use of Timer2 made the use of sleep mode impossible, as Timer2 cannot wake up the CPU from sleep mode (only idle mode).

    I disabled Timer2 as it would no longer be used for timekeeping - instead, I enabled the RTC timer and set the alarm function to periodically trigger an interrupt and wake the CPU from sleep. Like the previous PIC16LF1823 design, these intervals were set to the following:

    • Put the CPU to sleep after 4 fourhours of continuous use and turn off all LEDs
    • After twenty-four hours of sleep, wake the CPU and turn all LEDs back on

    In order to use the button to wake up the CPU from sleep mode, I enabled the port mismatch function for my button pin (P0.1) in addition to the existing use of the INT0 interrupt. This allows the button to wake the MCU from its sleep mode, much like how it works on my previous designs. This is required as only the port mismatch function can wake up the CPU from sleep mode.

    The use of sleep mode seems to have paid off, as I am now recording only a 3.2uA current draw from the EFM8SB1 when the CPU is in sleep mode:

    On the other hand, I recorded a 1.35 mA current draw from the EFM8SB1 when the CPU was in idle mode:

    Seems like sleep mode results in power consumption nearly 422 times lower than the idle mode!

  • Unoptimized firmware build #1

    Zachary Murtishi04/13/2025 at 15:08 0 comments

    I banged out an unoptimized firmware build for implementing some light patterns and the power-saving mode. So far, we have for light patterns:

    1. Candlelight: bottom LEDs off, top LED flickers
    2. Solid: bottom LEDs on at 100% brightness, top LED flickers
    3. Blink (slow): bottom LEDs blink at a 1 Hz rate, top LED flickers
    4. Blink (fast): bottom LEDs blink at a 2 Hz rate, top LED flickers
    5. LED chaser
    6. Software flicker: all LEDs flicker at different offsets from the source RNG array; bottom LEDs flicker in software, top LED flickers in hardware with PCA0-based PWM generator
    7. Half-brightness: bottom LEDs are set to a reduced brightness through software PWM, top LED flickers

    So far, I've implemented a crude power saving function that shuts off all LEDs and places the CPU in idle mode, where all interrupts may wake the CPU. Unfortunately, this is not ideal as the way I implement timekeeping is through Timer2 driven by the RTC crystal divided by 8, so the CPU will wake up every 1 second and need to be put back to sleep.

    Ideally, I can place the CPU into sleep mode, where all peripherals and the core are both off. This would cut power consumption even more, but require me to re-implement several features:

    • The button interfaces with the CPU through the INT0 interrupt, which is disabled during sleep mode. However, I can re-map the button to a port match interrupt on P0 and allow it to wake the CPU during sleep mode.
    • Timekeeping is not implemented through the RTC timer right now, but I will have to do so if I want to allow the CPU to wake itself through RTC alarms.

    This will require some re-writing of the code, so I'm going to dump what I have in my files for now.

  • Development Log 1

    Zachary Murtishi04/08/2025 at 22:44 0 comments

    Last year, I developed a PIC16LF1823-based ornament that had several programmable LED patterns, had built-in timekeeping through a 32.768 kHz crystal, and was powered by a CR2032 coin cell. These things were cool and the PIC16LF1823 was an awesome device for this application, but I've always wanted to experiment with Silicon Labs' 8051-based microcontrollers. I'm very familiar with the 8051 architecture as I've done some work with the original Intel devices - I thought it would be pretty cool to work with modernized versions of them with modern peripherals so I thought a good test bed for them would be my battery-powered ornament concept. I already have a set of design files and C firmware for them, so it shouldn't be too much of an effort to port them to the EFM8. On top of that, the EFM8 had several features on paper that would allow me to reduce the component count on the PCB and retain much of the same functionality.

    I based my design around the EFM8SB1 "Sleepy Bee" MCU, which has a very small QFN-20 package and boasts some great power consumption specifications, which is huge for an application relying on battery power. This time, I individually connected each LED to an MCU digital pin to directly drive them (the EFM8 is more than capable of this). Like last time, I hooked up a 32.768 kHz crystal for the RTC - but this time, I was able to omit the loading capacitors as the EFM8 as it has internal loading capacitors that can be configured to 16 different values. This time, I decided to use an SWD-style 1.27mm header for programming with my J-Link. The rest of the board used the old design - same button, same switch, same battery holder, more or less the same LEDs (though I added a few more).

    I've been working on getting this thing working for a bit. I received two assembled PCBs last month but couldn't start development immediately for two reasons: 1) my development tools on hand wouldn't work and 2) I had to leave for a trip almost immediately upon receiving the boards.



    More on the development tools issue: originally, I planned on debugging/programming these boards with a J-Link EDU I had on hand as it advertised the ability to program the EFM8/C8051-family devices from SiLabs. Unfortunately, this seemed to be inaccurate marketing as further investigation shows that the J-Link EDU does not support the C2 protocol used for flashing these devices. This left me in some trouble, as I had designed the pinout of the programming header to mate with a J-Link's interface. Unfortunately, I came to this conclusion after spending the better part of a night fiddling with Simplicity Studio, exasperated at its inability to work with the J-Link EDU to find my EFM8s.

    I decided to try out a third-party programmer for Silicon Lab's 8051 devices. (from "Silicom Labs") as they were only $10 on eBay. However, these things come with a 2.54mm IDC header, which isn't exactly easy to mate these boards to. I had an issue: I had two complete PCBs that were otherwise fine and had an improper programming port pinout for this new debugger.

    I had two options: design a custom cable using a larger 2.54mm IDC header on one side and a smaller SWD-style 1.27mm header on the other to mate with my PCB, or design a breakout board. I briefly investigated option 1 before deciding that building a breakout board might actually be cheaper and easier for me - and have more consistent results as I am not very confident in my handiwork when it comes to cables.

    Before I left for my trip, I quickly designed and ordered a breakout board designed to interface the output of my third-party EC6 debugger with the programming port on my ornament PCBs. I decided to include two headers: one that was a simple 1-to-1 mapping of the larger IDC header to a smaller IDC header to allow me to use a 1-to-1 pinout on future designs and a second header that would allow me to program my ornament boards with an improper pinout. I also included breakouts of the 3.3V and...

    Read more »

View all 5 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates