Skip to main content
Indian medical-device engineer designing a custom SEGGER emWin widget for a patient monitor HMI on an STM32H7 development board

Building Custom emWin Widgets for Indian Medical Devices and HMI: STM32H7 and i.MX RT1170 in Production

GSAS Editorial · · 9 min read

Indian medical-device OEMs, industrial HMI vendors, and high-end consumer-appliance teams all end up at the same question about six weeks into a GUI project: “The stock progress bar, gauge, and slider widgets are not enough, how do we build our own?” The question usually arrives the moment the industrial designer sends back a mockup with a circular vitals dial, a segmented signal-strength indicator, or a multi-ring temperature chart that does not match anything in a standard widget library.

On Cortex-M, the answer most Indian GUI teams converge on is SEGGER emWin. It dominates Indian Cortex-M GUI work because STMicroelectronics ships it free for STM32 under a restricted licence (STemWin), Renesas ships it free for specific RA and RZ silicon, and NXP ships it free for the i.MX RT crossover family. For any other target, or for Indian OEMs who want full source, commercial redistribution rights, and the royalty-free per-product licence, SEGGER Microcontroller GmbH sells commercial emWin source via GSAS Micro Systems in India.

This post is the Indian engineering-context version of SEGGER’s Application Note AN03002, Custom emWin Widget Type Creation Guide, aimed specifically at medical-device and HMI teams building patient monitors, infusion pumps, ventilator UIs, cold-chain controllers, and industrial touch panels out of Bengaluru, Chennai, Hyderabad, Pune, Mumbai, and Delhi NCR.

Why emWin dominates Indian Cortex-M GUI work

Three reasons Indian teams keep picking emWin:

  • Silicon-vendor free tiers cover the largest Indian Cortex-M target families. An STM32H7 project uses STemWin at no extra licence cost. An i.MX RT1170 project uses the NXP-bundled emWin at no extra licence cost. A Renesas RA6M4 project uses the Renesas-bundled variant. This covers a big fraction of the Cortex-M HMI work Indian ODMs take on.
  • Mature drawing primitives with antialiasing, rotation, and memory-device buffering. Rolling your own GUI library is a two-year project that nobody in India wants to price into an RFQ. emWin’s primitive library (lines, polygons, arcs, gradients, font rendering, JPEG/PNG/GIF decode) is what saves the calendar.
  • Commercial source licensing for the remaining cases. When the target is not an STM32, RA, or i.MX RT, for example, a custom ASIC-plus-Cortex-M design, or an older NXP Kinetis part, or a TI Sitara R5F cluster, the same codebase is available as a commercial source licence from SEGGER via GSAS on a royalty-free per-product basis. The Indian OEM pays once per product line and ships without per-unit runtime fees.

None of this is marketing copy, it reflects what Indian GUI teams are actually doing in 2026, and it is the reason the widget creation workflow below is worth learning.

The emWin widget model in three paragraphs

Every emWin widget is a specialization of the base window object. It inherits window behavior (position, size, parent/child hierarchy, invalidation) and adds three things that make it a widget: a _Create function that allocates the widget and its per-instance data, a _Paint callback that redraws the widget when it is invalidated, and a _Callback function that handles messages routed to the widget by emWin’s window manager.

Messages come from several sources. The window manager sends WM_PAINT when the widget becomes dirty. The touch input layer sends PID_STATE_CHANGED messages wrapped in WM_TOUCH with hit-test coordinates. The application sends custom messages via WM_SendMessage to change the widget’s state (a new vitals reading, a new setpoint, a theme change). Each message type gets a case in the _Callback switch statement.

Per-instance state, the value the gauge is showing, the min/max range, the colour theme, the current user-visible label, lives in a struct the _Create function allocates. emWin stores a pointer to it in the widget’s window-manager extra-data slot (WM_SetUserData). Every call into _Paint or _Callback starts by retrieving that pointer and reading the current state from it. This is the same object-lifetime model as Win32 controls, which is deliberate, emWin’s API was explicitly modelled on it.

Worked example: a circular vitals dial for a patient-monitor HMI

Indian medical-device OEMs build a lot of patient-monitoring equipment. A patient monitor typically displays heart rate, SpO2, non-invasive blood pressure, respiratory rate, and temperature on a single screen, and each value is shown in a mix of a numeric readout and a circular dial or waveform strip. The circular dial is a good worked example for a custom widget because no stock emWin control matches it directly.

The widget’s per-instance state for a vitals dial looks roughly like this:

  • Current numeric value.
  • Min/max range of the dial.
  • Warning and critical thresholds (the dial needs to change colour when the value crosses them).
  • Current theme (day or night, more on this below).
  • A label string (“HR”, “SpO2”, “NIBP”) drawn in the dial centre.
  • A cached “previous value” for smooth arc animation when the value updates.

The _Paint callback runs through a fixed sequence: draw the background ring in the theme’s track colour, draw the foreground arc from the start angle to the angle computed from (value - min) / (max - min), draw tick marks around the ring at every nth integer, draw the numeric value in a large font in the dial centre, draw the label in a smaller font below the numeric value, and draw a warning icon if the value has crossed a threshold. Every drawing call uses emWin primitives, GUI_AA_DrawArc, GUI_AA_FillPolygon, GUI_DispStringAt, not raw framebuffer writes. This matters for two reasons: antialiasing and display rotation continue to work automatically, and the same widget code compiles and runs on any emWin target without per-board tweaks.

The _Callback handles three things: WM_PAINT (calls _Paint), a custom MSG_SET_VALUE application message (updates the per-instance value, invalidates the widget), and MSG_SET_THEME (swaps the theme pointer, invalidates the widget).

Handling touch input on a non-rectangular widget

The circular dial is a non-rectangular hit area. A touch event at coordinates inside the widget’s rectangular bounding box is only a real hit on the dial if it falls inside the ring’s annulus. emWin’s default window hit-testing treats every widget as a rectangle, so the custom widget needs to reject touches that fall outside the annulus.

The trick AN03002 documents is to handle WM_TOUCH inside the widget’s _Callback, compute the Euclidean distance from the touch point to the widget centre, and only treat the event as a valid hit if that distance is between the inner and outer ring radius. If it is not, the callback returns without marking the event consumed, and emWin will route the event to whatever widget is behind the dial, which is usually the background panel, where the application has a “no-op” behaviour.

This is the same pattern you use for any non-rectangular widget: pie chart slices, segmented gauges, custom-shaped buttons. The point is that emWin’s window manager makes the routing decision for you; the widget’s only job is to classify its own touch events correctly.

For a patient monitor, the gesture vocabulary on a vitals dial is usually minimal, a single-tap to bring up detail, a long-press to silence an alarm associated with that parameter. Both of those are handled by inspecting the PID_STATE_CHANGED message’s timing and coordinate deltas inside the widget’s touch handler.

Day mode and night mode skinning without duplicating code

Indian hospital wards run 24/7 and patient monitors need a low-luminance “night mode” so nursing staff can read values at the bedside without waking patients. The widget therefore needs two themes, and the rule you want to enforce from day one is that the themes are data, not code.

A theme is a struct of colours, fonts, and optionally stroke widths:

  • Background colour.
  • Track (unfilled arc) colour.
  • Normal-range foreground colour.
  • Warning-range foreground colour.
  • Critical-range foreground colour.
  • Label font.
  • Value font.

The widget’s per-instance state stores a pointer to the active theme. The application switches themes by sending MSG_SET_THEME with a pointer to the new theme struct, the widget updates its pointer, and the next paint uses the new colours and fonts. No widget code is duplicated, the _Paint function reads everything it needs out of the theme struct.

This is the discipline that keeps a medical-device GUI maintainable across regulatory-driven change requests. When the clinical team says “the critical-range colour must be more orange, less red, for colour-blind accessibility”, the change is a single hex value in one theme struct, not a code edit inside _Paint, which means the change does not trigger a re-test of the widget’s drawing logic during DHF documentation.

Performance: drawing primitives, not raw framebuffer writes

The single most common emWin performance mistake Indian teams make is reaching for raw framebuffer writes (memcpy into the LTDC front buffer, custom pixel loops, bypassing GUI_DrawPixel) on the assumption that it is faster than the emWin primitive. On any modern Cortex-M7 or Cortex-M33 with a DMA2D / PXP / Chrom-ART accelerator, the emWin primitive is faster because it uses the accelerator, and the raw write does not.

The two target families Indian HMI teams ship most:

  • STM32H7 + LTDC + Chrom-ART (DMA2D). STemWin’s LTDC driver already programs Chrom-ART for block fills, alpha blending, and image copies. A GUI_FillRect goes through Chrom-ART automatically. A hand-written framebuffer fill loop burns CPU and blocks the scheduler.
  • NXP i.MX RT1170 + eLCDIF + PXP. The i.MX RT1170 has a PXP 2D accelerator that the NXP-bundled emWin driver uses for the same operations. On the RT1170 dual-display configuration (a primary LVDS panel plus a secondary HDMI port for clinical dashboard use), PXP is the only reasonable way to hit the frame rate budget on both panels at once.

The rule: let emWin call into the accelerator. Do not bypass it. Profile with SystemView (next section) to confirm the accelerator is actually being used.

Debugging paint artefacts with SystemView

When a custom widget paints incorrectly, flicker, tearing, partial updates, colour bleed, the fastest path to root cause is SEGGER SystemView. SystemView shows the exact timeline of every task switch, every interrupt, and every user event on the target, streamed over RTT to the host at nanosecond resolution.

For emWin paint debugging specifically, Indian teams instrument the widget’s _Paint function with SystemView SEGGER_SYSVIEW_OnUserStart/_OnUserStop markers around each drawing phase: background, arc, tick marks, numeric value, label. When SystemView visualizes the result, you see exactly where the frame-time budget is going and where the accelerator is or is not being used. If the widget is running too close to the vertical-blank interval of the LTDC controller, it shows up in the timeline immediately, usually before you would have spotted it visually.

This is the same workflow the SystemView v4 ELF-integration post describes for general Indian firmware debug; custom emWin widgets are one of the best cases for it because GUI bugs are fundamentally timing bugs wearing a costume.

Commercial emWin licensing in India

STemWin, NXP’s emWin bundle, and Renesas’s emWin bundle are free for their respective silicon targets, but every Indian OEM should read the licence text before shipping. The silicon-vendor variants are restricted to that vendor’s chips, do not come with source for the renderer, and are not redistributable outside a shipping product on that silicon.

For any of the following cases, Indian OEMs need a commercial emWin source licence from SEGGER, and GSAS Micro Systems is the authorized partner for that licence in India:

  • The target silicon is not STM32, RA, RZ, or i.MX RT.
  • The team needs full renderer source for in-house modification or regulatory traceability.
  • The product is being built by an Indian design house for redistribution to multiple OEMs.
  • The team wants a single unified licence that covers every future product line on any Cortex-M target, so that a hardware re-spin to a different silicon vendor does not trigger a GUI-stack re-licensing discussion.

The commercial model is royalty-free per product. You pay once for the product, ship as many units as you like over its lifetime, and there are no per-unit runtime fees. For Indian medical-device and HMI programs with five-to-ten-year production runs, this is materially cheaper than any per-unit alternative.

Further reading

To scope a custom emWin widget set for your medical-device, HMI, or consumer-appliance GUI project, or to licence emWin source commercially for a non-STM32 / non-i.MX RT target, contact GSAS Micro Systems in Bengaluru, Chennai, Hyderabad, Pune, Mumbai, or Delhi NCR and our engineering team will walk you through the widget design, the accelerator tuning on your specific silicon, and the commercial licensing.

Interested in SEGGER tools?

Talk to our application engineers for personalized tool recommendations.

Stay in the Loop

Get monthly compliance updates, product insights, and engineering best practices delivered to your inbox.