I saw Nuvoton introducing the NUC1262/NUC1263 MCU on their forum weeks ago. In addition to the ARMv8 Cortex-M23 CPU, it features Nuvoton's patented hardware peripheral, LLSI. Moreover, a friend from Everlight gave me their newly developed “magical” product, and some brilliant ideas immediately came to my mind. Therefore, I ordered a NuMaker-NUC1263SD development board and five chips from Nuvoton's online store. To my surprise, they arrived the very next day!
Nuvoton NUC1263 Series: Vibrant ARGB Lighting Control with Easy LLSI Interface Design
However, the project is still under design, so stay tuned. For now, let’s experiment with the NUC1263 MCU and its LLSI using the Adafruit NeoPixel Ring. The complete test code will also be shared on GitHub and in the comment section! (Looking at the project name, can you guess what I’m going to do again? lol)
https://github.com/danchouzhou/LLSIClock/blob/main/firmware/LLSI_RGBW/main.cKey Features of the NUC1263:- Arm Cortex-M23, 72 MHz, based on ARMv8-M architecture
- Built-in 64 KB Flash and 20 KB SRAM
- Operating voltage: 2.5 V ~ 5.5 V
- In addition to common peripherals such as UART, SPI, I2C, ADC, and PWM, it also supports I3C, USB, and 4 DACs
- It features a built-in level shifter which has independent VDDIO pin, enabling I3C to support a minimum voltage of 0.95 V
- The most notable feature is its patented and exclusive hardware function – LLSI
First Time Hearing about LLSI?LLSI, which is LED Light Strip Interface. It’s a control interface specifically designed for addressable LEDs (ARGB LED). Common models include WS2812B, SK6812, or Adafruit's NeoPixel series. The advantage of this interface lies in its simplicity: a single signal wire connects to the D
IN input of the first LED, and its D
OUT output chains to the D
IN of the next LED, allow us to control the entire strip of full-color LEDs.

Since it only uses a single wire, the ARGB LED control interface encodes ‘0’ and ‘1’ in the timing of the high and low signal durations. Nuvoton has implemented this control timing in hardware, giving it the cool name - LLSI and integrating it into the MCU. This makes Nuvoton the first company to launch an MCU with hardware capabilities for controlling ARGB LEDs, also it’s an exclusive function only available on Nuvoton MCUs.
Trends of RGB Dynamic Lighting EffectsRGB dynamic lighting effects have become increasingly popular. They can now be seen in countless gaming peripherals, including keyboards, mice, motherboards, graphics cards, PC cases, fans, power supplies, coolers, and headsets. Even Windows 11 has built-in options to adjust lighting effects. RGB LEDs are also appearing behind TV and decorative lighting to create various ambient effects in homes.
Controlling ARGB LEDsIn the past, controlling ARGB LEDs with an MCU involved manually changing the GPIO output state, relying on NOP instructions or timer delays to generate the timing sequences by the software. To meet the precision requirements of timing, the CPU couldn’t perform other tasks during transmission, and interrupts had to be disabled to ensure complete data transmission. This method, such as the
Adafruit NeoPixel Library, and
the porting of NeoPixel Library to Nuvoton MCUs.
As RGB dynamic effects gain popularity, the number and complexity of LEDs are increasing, making software-generated timing sequences less feasible. This has caused significant challenges for firmware designers.
World’s First, Exclusive Feature, Latest Patent! What’s the Advantages of LLSI?Fortunately, Nuvoton has introduced LLSI. With LLSI, all you need to do is fill the buffer with the color data for each LED, and the hardware automatically sends out the content by the ARGB LED timing sequence. It operates similarly to some serial communication interfaces.
The NUC1263's LLSI provides a 16-byte-depth FIFO buffer, supports transmit threshold interrupt and DMA transfers, design to free up CPU resources. This allows the CPU to focus on its primary tasks or compute complex lighting effects. Thanks to the built-in 64 KB Flash and 20 KB SRAM ensure ample memory, even as the number of LEDs increases!
ImplementationAfter introducing LLSI, let’s deep into the technical, what you will realize the benefits of LLSI. Whether you’re accustomed to Keil MDK, IAR, or Nuvoton’s own NuEclipse development environment, you can refer to the NuMaker-NUC1263SD manual to set up the development environment:
https://www.nuvoton.com/export/resource-files/en-us--UM_NuMaker-NUC1263SD_EN_Rev1.00.pdfThe LLSI can also Control RGBW “Four-Color” Addressable LEDsThe NUC1263 manual reveals that LLSI is designed for three-color addressable LEDs (RGB). Data is sent 3-byte in a units, supporting both RGB and GRB arrangements. While controlling standard ARGB are obviously, today we’ll test whether LLSI can control the four-color ARGB variant, “ARGBW”!
To test the NUC1263’s LLSI, I pulled out a treasured, never-used
Adafruit NeoPixel Ring - 24 x RGBW Natural White (~4500K). I remember get this for over 20 USD at Micro Center during my studies in the US years ago. In addition to the common RGB three colors, it includes an extra white LED, offering better color rendering (CRI) than the white light created by mixing RGB.
Lighting Up Each Color (RGBW) with LLSIBefore creating effects, you must first determine the arrangement of R, G, B, W in each LED and how to control them individually. Let’s start by lighting up a single color:
The use of LLSI is straightforward and can be activated with these three lines of code. I used PC.5 on the NUC1263 as the LLSI0 output. Since we’re using 24 x four-color RGBW LEDs, not the originally designed three-color RGB LEDs, you’ll need to adjust the LED quantity field manually and can be calculated like this:
LLSI_PCNT = 24 / 3 x 4 = 32 |
CLK_EnableModuleClock(LLSI0_MODULE); // Enable LLSI0 module clock
// T_Period = 1250ns; T_T0H = 400ns; T_T1H = 850ns; T_ResetPeriod = 50000ns; LED count = 32
LLSI_Open(LLSI0, LLSI_MODE_SW, LLSI_FORMAT_RGB, HCLK_CLK, 1250, 400, 850, 50000, 0, LLSI_IDLE_LOW);
SET_LLSI0_OUT_PC5(); // Set PC.5 multi-function pins for LLSI0
Here are the respective codes for lighting up R, G, B, and W in four LEDs, each occupying 8 bits. Testing reveals the arrangement order is 0xWWBBRRGG. But why is there an extra 0x00000000 sent at the end? As mentioned earlier,
LLSI is designed for RGB three-color addressable LEDs, and data is sent in 3-byte units.
Since four RGBW LEDs total 16 bytes, which isn’t divisible by 3, LLSI assumes the data is incomplete and won’t send the last byte which light up the white LED. Thus, adding an additional dummy data field “tricks” it into sending the last LED’s data.
// 0xWWBBRRGG
LLSI_WRITE_DATA(LLSI0, 0x000000FF);
LLSI_WRITE_DATA(LLSI0, 0x0000FF00);
LLSI_WRITE_DATA(LLSI0, 0x00FF0000);
LLSI_WRITE_DATA(LLSI0, 0xFF000000);
LLSI_WRITE_DATA(LLSI0, 0x00000000);

Fortunately, the NeoPixel Ring used here has 24 x RGBW LEDs, which is a common multiple of 3 and 4. When initializing LLSI with `LLSI_Open()` and setting the LED count to 32, creating an RGBW marquee effect doesn’t require additional handling. The program flow will become like this, instead of lighting up one by one:
- Create an array `g_au32frameBuffer[]` as a “frame.”
- Enable Threshold Interrupt to notify the CPU to fill up the FIFO when the content drops below the set threshold.
- Enable frame end interrupts, which trigger when all LED data has been transmitted, setting the flag `g_u32FrameEnd` to ‘1’ and updating the pattern style `g_u32PatternToggle`.
- In the main program, check the flag, and once the previous “frame” has been sent, calculate new pattern to update the “frame.”
This example clearly demonstrates the convenience of controlling ARGB LEDs with LLSI. After filling `g_au32frameBuffer` with the pattern, the hardware automatically generates the timing sequences. When the FIFO falls below the lower limit, the hardware triggers an interrupt to notify the CPU to “reload the cartridge,” conserving significant CPU resources.
Below are three lines of code to enable the two interrupt functions mentioned above:
/* Set TX FIFO threshold */
LLSI_SetFIFO(LLSI0, 2);
NVIC_EnableIRQ(LLSI0_IRQn);
/* Enable Transmit FIFO Threshold Interrupt and Frame End Interrupt */
LLSI_EnableInt(LLSI0, LLSI_TXTH_INT_MASK | LLSI_FEND_INT_MASK);
The ISR code:
void LLSI0_IRQHandler()
{
if (LLSI_GetIntFlag(LLSI0, LLSI_TXTH_INT_MASK))
{
while(LLSI_GET_TX_FIFO_FULL_FLAG(LLSI0) == 0) // Fill up the TX FIFO
{
if (g_u32DataCount == (TEST_COUNT - 1))
LLSI_SET_LAST_DATA(LLSI0); // Before writing last word data to LLSI_DATA, user must write LDT = 1
if (g_u32DataCount < TEST_COUNT)
LLSI_WRITE_DATA(LLSI0, g_au32frameBuffer[g_u32DataCount++]);
else
break;
}
if(g_u32DataCount >= TEST_COUNT)
{
LLSI_DisableInt(LLSI0, LLSI_TXTH_INT_MASK);
}
}
if (LLSI_GetIntFlag(LLSI0, LLSI_FEND_INT_MASK)) // FENDIF will be set to 1 when LLSI transfer last pixel data.
{
g_u32FrameEnd = 1;
g_u32PatternToggle++;
LLSI_ClearIntFlag(LLSI0, LLSI_FEND_INT_MASK);
}
}
The algorithm to update the pattern:
if (g_u32FrameEnd == 1) // Wait for FEND_INT
{
u32Tmp = g_u32PatternToggle % 4;
/* Generate a new frame */
for (int i=0; i<TEST_COUNT; i++)
{
if (i % 4 == u32Tmp)
g_au32frameBuffer[i] = 0xFF000000 >> (u32Tmp * 8);
else
g_au32frameBuffer[i] = 0x00000000;
}
g_u32FrameEnd = 0;
g_u32DataCount = 0;
LLSI_EnableInt(LLSI0, LLSI_TXTH_INT_MASK);
CLK_SysTickDelay(50000);
}
The result
Wanna try the latest patented LLSI technology? Don’t miss this! By joining Nuvoton’s forum, you can engage in technical exchanges and also receive a 10% coupon for Nuvoton’s official online store. Tap the link below for event details.
https://forum.nuvoton.com/en/programs-events/seminars-events/14355