SegLCD (Segment LCD)

group group_seglcd

The Segment LCD Driver provides an API to configure and operate the MXLCD hardware block.

The MXLCD block can be flexibly configured to drive a variety of LCD glass at different voltage levels with multiplex ratios.

Features:

  • Digital Correlation and PWM at 1/2, 1/3, 1/4 and at 1/5 bias modes are supported

  • Drives STN/TN LCD-glass with up to eight COMs (device specific)

  • 30 to 150 Hz refresh rate

  • Supports both type A (standard) and type B (low-power) waveforms

  • The display pixel state can be inverted for a negative image

  • Operation in Deep Sleep Mode from ILO/MFO

  • All-digital contrast control using “Dead Period” digital modulation

  • A set of basic standard displays and fonts

  • The customizable display and font structures.

Glossary

  • LCD - Liquid Crystal Display

  • Glass - An LCD glass with one or more displays (e.g. one 7-segment display and one bar-graph display).

  • TN - A twisted nematic LCD glass.

  • STN - A super-twisted nematic LCD glass.

  • Display - A block of the same type of symbols on an LCD glass to indicate a multi-digital number or character string. There may be one or more displays on a single LCD glass.

  • Symbol - A block of pixels on an LCD glass to indicate a single digit or character.

  • Pixel - A basic displaying item. This can be a segment of a 7-segment symbol (thus called a “segment”), a pixel of a dot-matrix display, or a stand-alone arbitrarily-shaped display element. Each pixel has a unique set of common and segment lines within one LCD glass. The API offers pixel identifiers - the 32-bit items of the display pixel map (to use in the display structure definition, see cy_stc_seglcd_disp_t), created by the CY_SEGLCD_PIXEL macro.

  • Common line (Com/COM for short) - A common wire/signal from the PSoC chip to the LCD glass. The API offers common line identifiers - the 32-bit items of the commons array (to use in Cy_SegLCD_ClrFrame and Cy_SegLCD_InvFrame), created by the CY_SEGLCD_COMMON macro.

  • Segment line (Seg/SEG for short) - A segment wire/signal from the PSoC chip to the LCD glass.

  • Octet - A bunch of subsequent eight MXLCD terminals. Octets may not match GPIO ports.

  • Frame buffer - An array of registers to control the MXLCD signal generation for all the MXLCD terminals.

SegLCD Solution

The Segment LCD Driver can be used either as a standalone library to manage the MXLCD hardware or as a part of the more complex software solution delivered within ModusToolbox: the Device Configurator SegLCD personality and the SegLCD Configurator tools.

The SegLCD solution provides an easy method to configure an MXLCD block to drive your standard or custom LCD glass:

The SegLCD solution includes:

  • The SegLCD Configurator tool, which is a display configuration wizard to create and configure displays and generate commons array and display structures cy_stc_seglcd_disp_t.

  • The ModusToolbox Device Configurator contains a SegLCD personality, which is an MXLCD block configuration wizard. It helps to easily tune all the timing settings, operation modes, provides a flexible GPIO pin assignment capability and generates the cy_stc_seglcd_config_t structure and the rest of accompanying definitions.

  • The SegLCD Driver API itself, which uses all the mentioned above generated code.

../../../_images/seglcd_solution.png

Configuration Considerations

To start working with an LCD, first initialize the MXLCD block, then initialize the frame buffer, and then enable the block:

/* Scenario: Enable an LCD block */

cy_stc_seglcd_config_t config =
{
    .speed = CY_SEGLCD_SPEED_HIGH,
    .wave = CY_SEGLCD_TYPE_B,
    .drive = CY_SEGLCD_PWM,
    .bias = CY_SEGLCD_BIAS_FOURTH,
    .lsClk = CY_SEGLCD_LSCLK_LF,
    .comNum = 8,
    .frRate = 70,
    .contrast = 70,
  /*.clkFreq is unknown here */
};

const uint32_t commons[8] =
{
    CY_SEGLCD_COMMON(LCD_COM_0, 0UL),
    CY_SEGLCD_COMMON(LCD_COM_1, 1UL),
    CY_SEGLCD_COMMON(LCD_COM_2, 2UL),
    CY_SEGLCD_COMMON(LCD_COM_3, 3UL),
    CY_SEGLCD_COMMON(LCD_COM_4, 4UL),
    CY_SEGLCD_COMMON(LCD_COM_5, 5UL),
    CY_SEGLCD_COMMON(LCD_COM_6, 6UL),
    CY_SEGLCD_COMMON(LCD_COM_7, 7UL)
};

note

If you use ModusToolbox Device Configurator, a SegLCD configuration structure is generated automatically into the GeneratedSource/cycfg_peripherals.h/.c files. All you need is just to call Cy_SegLCD_Init with a pointer to the structure.

    /* Then in executable code: */

    /* Get the frequency of the assigned peripheral clock divider */
    config.clkFreq  = Cy_SysClk_PeriphGetFrequency(CY_SYSCLK_DIV_8_BIT, 0U);

    if (CY_SEGLCD_SUCCESS == Cy_SegLCD_Init(LCD0, &config))
    {
        if (CY_SEGLCD_SUCCESS == Cy_SegLCD_ClrFrame(LCD0, commons))
        {
            Cy_SegLCD_Enable(LCD0);
            
           /* Now the block generates LCD signals (all the pixels are off) and is ready to turn on any pixel
            * (or many pixels) using any of the frame/pixel/character/display management API functions.
            */
        }
        else
        {
            /* error handling */
        }
    }
    else
    {
        /* error handling */
    }
Contrast vs. Frame Rate (cy_stc_seglcd_config_t::contrast vs. cy_stc_seglcd_config_t::frRate)

Some combinations of a frame rate and input frequency can restrict the valid contrast range because of the limited dividers size (for Low Speed mode - 8 bit, and for High Speed mode - 16 bit). For small values of contrast at small frame rates, the required divider values may be beyond permissible limits of the dividers size. For large High Speed clock frequencies, certain ratios between the contrast and frame rate cannot be achieved due to the limited divider size. The

Cy_SegLCD_Init function automatically restricts such incorrect combinations (returns CY_SEGLCD_BAD_PARAM). The peripheral clock divider can be adjusted to clock the LCD block with proper clock frequency:
    /* Scenario: Enable peripheral clock divider for LCD operation with 
     * the 2MHz clock frequency at the PeriClk frequency 50MHz
     */
    Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT, 0U, 24U);
    Cy_SysClk_PeriphAssignDivider(PCLK_LCD_CLOCK, CY_SYSCLK_DIV_8_BIT, 0U);
    Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, 0U);
Speed Mode Switching (cy_stc_seglcd_config_t::speed)

The High Speed and Low Speed generators mostly duplicate each other, except that for MXLCD_ver1, the High Speed version has larger frequency dividers to generate the frame and sub-frame periods. This is because the clock of the High Speed block typically has a frequency 30-100 times bigger than the 32 KHz clock fed to the Low Speed block. For MXLCD_ver2, both High Speed and Low Speed generators have similar 16-bit dividers, because a possibility exists to source a Low Speed generator with a Medium Frequency clock (see

Medium Frequency Domain Clock) that may be much higher than 32 KHz ILO:
    /* Scenario: Enable MFO for LCD operation with the 2MHz clock frequency
     * in Deep Sleep power mode 
     */
    Cy_SysClk_MfoEnable(true);
    Cy_SysClk_ClkMfSetDivider(1UL);
    Cy_SysClk_ClkMfEnable();
Switching between High Speed and Low Speed modes via the Cy_SegLCD_Init function causes the dividers to reconfigure. Under possible restrictions related to certain ratios between contrast and frame rates (see Contrast vs. Frame Rate section above), switching between High Speed and the Low Speed modes via the Cy_SegLCD_Init function may set new dividers values that don’t give the same contrast value.

Driving Modes (cy_stc_seglcd_config_t::drive)

SegLCD supports the following operating modes:

  • Digital Correlation - preferred for low clock speeds, low common lines count and low supply voltages.

  • PWM at 1/2, 1/3, 1/4 or 1/5 Bias - preferred for high clock speeds (e.g. over 1MHz), many common lines (e.g. over 4), and high voltages (e.g. 3.3V or higher). More precise preferences depend on a certain set of an LCD glass, power modes, the number of terminals, desired contrast/frame rate settings, etc.

Conventional Waveforms (cy_stc_seglcd_config_t::wave)

Conventional LCD drivers apply waveforms to COM and SEG electrodes generated by switching between multiple different voltages. The following terms are used to define these waveforms:

  • Duty: A driver operates in the 1/M-th duty when it drives M COM electrodes. Each COM electrode is effectively driven for the 1/M of the frame time.

  • Bias: A driver uses the 1/B-th bias when its waveforms use the voltage steps of (1/B)*VDRV.

  • Frame: A frame is the time length to address all segments. During a frame, the driver cycles through the commons in sequence. All segments receive 0V DC when measured over the length of an entire frame.

  • Type-A Waveform: The driver structures the frame into M sub-frames. COMi is addressed in sub-frame i.

  • Type-B Waveform: The driver structures the frame into 2M sub-frames. COMi is addressed in sub-frames i and M+i. The two sub-frames are inverse of each other. Typically, type-B waveforms are slightly more power-efficient because they contain fewer transitions.

The following figures show the conventional waveforms for COM and SEG electrodes for the 1/3rd bias and 1/4th duty. Only COM0/COM1 and SEG0/SEG1 are drawn. Conventional Type-A Waveform Example: ../../../_images/seglcd_waveA.png

Conventional Type-B Waveform Example:

../../../_images/seglcd_waveB.png

The generalized waveforms for individual sub-frames for any duty and bias are illustrated in the following figure. Note that these use 6 different voltages at most(including VSS and VDRV). Conventional Waveforms - Generalized:

../../../_images/seglcd_waveGen.png

The effective RMS voltage for on and off segments can be calculated using these waveforms:

../../../_images/seglcd_Voff.png../../../_images/seglcd_Von.png

The resulting Discrimination Ratio (D) for various bias and duty combinations is illustrated in the following table. The bias choice (B) for each duty (M) with the highest possible value for D is colored green:

../../../_images/seglcd_descr.png

Digital Correlation (CY_SEGLCD_CORRELATION)

The principles of operation are illustrated by the example waveforms shown in the following figures. Digital Correlation Example - Type-A:

../../../_images/seglcd_DCA.png

Digital Correlation Example - Type-B:

As illustrated, instead of generating bias voltages between the rails, this approach takes advantage of the LCD displays characteristic: the LCD segments’ on-ness and off-ness degree is determined by the RMS voltage across the segments. In this approach, the correlation coefficient between any given pair of COM and SEG signals determines whether the corresponding LCD segment is On or Off. Thus, by doubling the base drive frequency of the COM signals in their inactive sub-frame intervals, the phase relationship of the COM and SEG drive signals can be varied to turn segments on and off - rather than varying the DC levels of the signals as is used in the conventional approaches.

../../../_images/seglcd_DCB.png

PWM Drive (CY_SEGLCD_PWM)

This approach duplicates the multi-voltage drive signals of the conventional method with bias B using a PWM output signal together with the intrinsic resistance and capacitance of the LCD display to create a simple PWM DAC. This is illustrated in the following figure:

../../../_images/seglcd_PWM.png

To drive a low-capacitance display with an acceptable ripple and rise/fall time, using a 32-kHz PWM an additional external series resistance of 100 k - 1 M ohm is required. External Resistors are not required for PWM frequencies of greater than ~1 MHz. The exact frequency depends on the display capacitance, the internal ITO resistance of the ITO routing traces, and the drive impedance of the I/O pins. The PWM method works for any bias value (B). NOTE As B gets higher, a higher PWM step frequency is required to maintain the same PWM output frequency (the RC response of the LCD depends on the PWM output frequency, NOT the step frequency). The PWM approach may also be used to drive a 1/2-bias display. This has the advantage that PWM is only required on the COM signals, as SEG signals of a 1/2-bias display use only logic levels. Therefore, PWM 1/2-bias can be supported at 32 kHz using just four external resistors. The power consumption of the approach (even for 1/2 bias) is substantially higher than that of other methods. Therefore, it is recommended power-sensitive customers use Digital Correlation drive in Deep Sleep mode, and change to PWM mode to gain the advantage of better contrast/viewing angle on TN displays in Active or Sleep mode.

PWM1/2 LCD drive waveform: ../../../_images/seglcd_PWM2.png

PWM1/3 LCD drive waveform:

../../../_images/seglcd_PWM3.png

Digital Contrast Control

In all modes, digital contrast control is available using the duty cycle/dead time method illustrated in the following figure:

../../../_images/seglcd_contrast.png

This illustration shows the principle for 1/3 bias and 1/4 duty implementation, but the general approach of reducing contrast by reducing the percentage of time the glass is driven can be generalized and applied to any drive method. In all cases, during the dead time, all COM and SEG signals are set to a logic “1” state.

When the block is configured, for further work with display, a display structure is needed:

const uint32_t displayPixMap[4][CY_SEGLCD_7SEG] =
{
    {
        CY_SEGLCD_PIXEL(LCD_P11_2, 0UL), /* Seg: P11_2, Com: 0, symbol 0, pixel A */
        CY_SEGLCD_PIXEL(LCD_P11_2, 2UL), /* Seg: P11_2, Com: 2, symbol 0, pixel B */
        CY_SEGLCD_PIXEL(LCD_P11_2, 5UL), /* Seg: P11_2, Com: 5, symbol 0, pixel C */
        CY_SEGLCD_PIXEL(LCD_P11_2, 6UL), /* Seg: P11_2, Com: 6, symbol 0, pixel D */
        CY_SEGLCD_PIXEL(LCD_P11_2, 4UL), /* Seg: P11_2, Com: 4, symbol 0, pixel E */
        CY_SEGLCD_PIXEL(LCD_P11_2, 1UL), /* Seg: P11_2, Com: 1, symbol 0, pixel F */
        CY_SEGLCD_PIXEL(LCD_P11_2, 3UL), /* Seg: P11_2, Com: 3, symbol 0, pixel G */
    },
    {
        CY_SEGLCD_PIXEL(LCD_P10_3, 0UL), /* Seg: P10_3, Com: 0, symbol 1, pixel A */
        CY_SEGLCD_PIXEL(LCD_P10_3, 2UL), /* Seg: P10_3, Com: 2, symbol 1, pixel B */
        CY_SEGLCD_PIXEL(LCD_P10_3, 5UL), /* Seg: P10_3, Com: 5, symbol 1, pixel C */
        CY_SEGLCD_PIXEL(LCD_P10_3, 6UL), /* Seg: P10_3, Com: 6, symbol 1, pixel D */
        CY_SEGLCD_PIXEL(LCD_P10_3, 4UL), /* Seg: P10_3, Com: 4, symbol 1, pixel E */
        CY_SEGLCD_PIXEL(LCD_P10_3, 1UL), /* Seg: P10_3, Com: 1, symbol 1, pixel F */
        CY_SEGLCD_PIXEL(LCD_P10_3, 3UL), /* Seg: P10_3, Com: 3, symbol 1, pixel G */
    },
    {
        CY_SEGLCD_PIXEL(LCD_P11_1, 0UL), /* Seg: P11_1, Com: 0, symbol 2, pixel A */
        CY_SEGLCD_PIXEL(LCD_P11_1, 2UL), /* Seg: P11_1, Com: 2, symbol 2, pixel B */
        CY_SEGLCD_PIXEL(LCD_P11_1, 5UL), /* Seg: P11_1, Com: 5, symbol 2, pixel C */
        CY_SEGLCD_PIXEL(LCD_P11_1, 6UL), /* Seg: P11_1, Com: 6, symbol 2, pixel D */
        CY_SEGLCD_PIXEL(LCD_P11_1, 4UL), /* Seg: P11_1, Com: 4, symbol 2, pixel E */
        CY_SEGLCD_PIXEL(LCD_P11_1, 1UL), /* Seg: P11_1, Com: 1, symbol 2, pixel F */
        CY_SEGLCD_PIXEL(LCD_P11_1, 3UL), /* Seg: P11_1, Com: 3, symbol 2, pixel G */
    },
    {
        CY_SEGLCD_PIXEL(LCD_P11_0, 0UL), /* Seg: P11_0, Com: 0, symbol 3, pixel A */
        CY_SEGLCD_PIXEL(LCD_P11_0, 2UL), /* Seg: P11_0, Com: 2, symbol 3, pixel B */
        CY_SEGLCD_PIXEL(LCD_P11_0, 5UL), /* Seg: P11_0, Com: 5, symbol 3, pixel C */
        CY_SEGLCD_PIXEL(LCD_P11_0, 6UL), /* Seg: P11_0, Com: 6, symbol 3, pixel D */
        CY_SEGLCD_PIXEL(LCD_P11_0, 4UL), /* Seg: P11_0, Com: 4, symbol 3, pixel E */
        CY_SEGLCD_PIXEL(LCD_P11_0, 1UL), /* Seg: P11_0, Com: 1, symbol 3, pixel F */
        CY_SEGLCD_PIXEL(LCD_P11_0, 3UL), /* Seg: P11_0, Com: 3, symbol 3, pixel G */
    }
};

cy_stc_seglcd_disp_t display =
{
    .type   = CY_SEGLCD_7SEG,
    .symNum = 4,
    .invert = false,
    .pixMap = (uint32_t*)displayPixMap,
    .font   = &cy_segLCD_7SegFont
};

note

Using the SegLCD Configurator, display structures and the commons array are generated automatically into the GeneratedSource/cycfg_seglcd.h/.c files. All you need is just to include cycfg_seglcd.h into your application code.

And now you can write multi-digit decimal and hexadecimal numbers and strings onto the initiated 7-segment display:

        /* Scenario: Write a decimal number starting at the most right symbol on display: */
        if (CY_SEGLCD_SUCCESS != Cy_SegLCD_WriteNumber(LCD0, 12, 3, &display, false, false))
        {
            /* error handling */
        }
after which the next image on the glass appears: ../../../_images/seglcd_12.png

        /* Scenario: Write a hexadecimal number with trailing zeroes: */
        if (CY_SEGLCD_SUCCESS != Cy_SegLCD_WriteNumber(LCD0, 12, 3, &display, true, true))
        {
            /* error handling */
        }
../../../_images/seglcd_oooc.png

Or even manage separate LCD pixels:

/* Scenario: There is a heart-shaped sign on an LCD glass: */
#define HEART (CY_SEGLCD_PIXEL(LCD_P11_6, 7UL)) /* Seg: P11_6, Com: 7 */
    /* Scenario: Set a pixel (write a true value) */
    if (CY_SEGLCD_SUCCESS != Cy_SegLCD_SetPixel(LCD0, HEART))
    {
        /* error handling */
    }
after which the next image on the glass appears: ../../../_images/seglcd_heart.png

    /* Scenario: Clear a pixel (write a false value) */
    if (CY_SEGLCD_SUCCESS != Cy_SegLCD_ClrPixel(LCD0, HEART))
    {
        /* error handling */
    }
    /* Scenario: Invert a pixel (change the value to opposite) */
    Cy_SegLCD_InvPixel(LCD0, HEART);
    /* Scenario: Read a pixel value, do some action with it and write it back into the frame */
    bool pixelValue = Cy_SegLCD_ReadPixel(LCD0, HEART);
    Cy_SegLCD_WritePixel(LCD0, HEART, !pixelValue);
The basic use case of the bar-graph display type:
/* Scenario: There is a battery-shaped frame on an LCD glass: */
#define FRAME (CY_SEGLCD_PIXEL(LCD_P12_6, 7UL)) /* Seg: P12_6, Com: 7 */
#define BAR_LENGTH (4)
const uint32_t barGraphPixMap[BAR_LENGTH] =
{
    CY_SEGLCD_PIXEL(LCD_SEG_6,  7UL),
    CY_SEGLCD_PIXEL(LCD_SEG_5,  7UL),
    CY_SEGLCD_PIXEL(LCD_SEG_4,  7UL),
    CY_SEGLCD_PIXEL(LCD_SEG_2,  7UL)
};

const cy_stc_seglcd_disp_t barGraph =
{
    .type   = CY_SEGLCD_BAR,
    .symNum = BAR_LENGTH,
    .invert = false,
    .pixMap = (uint32_t*)barGraphPixMap,
    .font   = NULL
};
    uint32_t barGraphValue = 3UL; /* the value from 0 to barGraph.symNum */
    /* Scenario: Set a frame for the battery-shaped bar-graph display */
    if (CY_SEGLCD_SUCCESS != Cy_SegLCD_SetPixel(LCD0, FRAME))
    {
        /* error handling */
    }
    /* Scenario: Write a bar graph starting from the first pixel of the barGraph display */
    if (CY_SEGLCD_SUCCESS != Cy_SegLCD_BarGraph(LCD0, barGraphValue, 0UL, &barGraph))
    {
        /* error handling */
    }
after which the next image on the glass appears: ../../../_images/seglcd_bargraph.png

Also, you can customize basic fonts, for example:

/* This is a customized ASCII-coded font for the basic 7-segment display: */
const uint8_t customAsciiFontMap7Seg[] =
{
  /*space*/         /* Zeroes for all the unused symbols */                     /*  -  */
    0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x40U,0x00U,0x00U,
  /*  0     1     2     3     4     5     6     7     8     9  */
    0x3FU,0x06U,0x5BU,0x4FU,0x66U,0x6DU,0x7DU,0x07U,0x7FU,0x6FU,0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,
        /*  A     B     C     D     E     F     G     H     I     J     K     L     M     N     O  */
    0x00U,0x77U,0x7CU,0x39U,0x1FU,0x79U,0x71U,0x3DU,0x76U,0x06U,0x1EU,0x75U,0x38U,0x15U,0x37U,0x3FU,
  /*  P     Q     R     S     T     U     V     W     X     Y     Z  */
    0x73U,0x67U,0x33U,0x6DU,0x07U,0x3EU,0x72U,0x2AU,0x64U,0x66U,0x5BU,0x00U,0x00U,0x00U,0x00U,0x00U,
        /*  a     b     c     d     e     f     g     h     i     j     k     l     m     n     o  */
    0x00U,0x5FU,0x7CU,0x58U,0x5EU,0x7BU,0x71U,0x6FU,0x74U,0x04U,0x0EU,0x7AU,0x38U,0x15U,0x54U,0x5CU,
  /*  p     q     r     s     t     u     v     w     x     y     z  */
    0x73U,0x67U,0x50U,0x6DU,0x78U,0x1CU,0x62U,0x2AU,0x52U,0x6EU,0x5BU
};

const cy_stc_seglcd_font_t customAsciiFont7Seg =
{
    .first   = ' ',
    .last    = 'z',
    .ascii   = true,
    .fontMap = customAsciiFontMap7Seg
};
And now you can write characters and strings on a standard 7-segment display:
        /* Scenario: Write characters so that there the word 'char' is created */
        /* Set up the custom alphanumerical font for 7-segment display */
        display.font = &customAsciiFont7Seg; /* Set up the alphanumerical font */
        (void) Cy_SegLCD_WriteChar(LCD0, 'c', 0, &display);
        (void) Cy_SegLCD_WriteChar(LCD0, 'h', 1, &display);
        (void) Cy_SegLCD_WriteChar(LCD0, 'a', 2, &display);
        (void) Cy_SegLCD_WriteChar(LCD0, 'r', 3, &display);
after which the next image on the glass appears: ../../../_images/seglcd_char.png

        /* Scenario: Write a string starting at the most left symbol on display */
        char_t * string = "Font";
        /* Set up the custom alphanumerical font for 7-segment display */
        display.font = &customAsciiFont7Seg;
        if (CY_SEGLCD_SUCCESS != Cy_SegLCD_WriteString(LCD0, string, 0, &display))
        {
            /* error handling */
        }
../../../_images/seglcd_font.png

Also, you can customize or create your own displays, for example:

/* This is a custom 3x5 dot matrix display
 * (which is made from the standard 5x8 dot matrix just cutting all the redundant pixels):
 */

#define CUSTOM_DISP_3x5DM_TYPE                (3 * 5) /* Amount of pixels in single 3x5 symbol */
 
const uint32_t commonsDm[] =
{
    CY_SEGLCD_COMMON(LCD_P11_3, 0UL),
    CY_SEGLCD_COMMON(LCD_P11_4, 1UL),
    CY_SEGLCD_COMMON(LCD_P11_5, 2UL),
    CY_SEGLCD_COMMON(LCD_P11_6, 3UL),
    CY_SEGLCD_COMMON(LCD_P11_0, 4UL),
    CY_SEGLCD_COMMON(LCD_P11_1, 5UL),
    CY_SEGLCD_COMMON(LCD_P10_3, 6UL),
    CY_SEGLCD_COMMON(LCD_P11_2, 7UL)
};

const uint32_t display3x5PixMap[4][CUSTOM_DISP_3x5DM_TYPE] =
{
    {
        CY_SEGLCD_PIXEL(LCD_DM_1,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_1,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_1,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_1,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_1,  5UL),
        CY_SEGLCD_PIXEL(LCD_DM_2,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_2,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_2,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_2,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_2,  5UL),
        CY_SEGLCD_PIXEL(LCD_DM_3,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_3,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_3,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_3,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_3,  5UL)
    },
    {
        CY_SEGLCD_PIXEL(LCD_DM_6,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_6,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_6,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_6,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_6,  5UL),
        CY_SEGLCD_PIXEL(LCD_DM_7,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_7,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_7,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_7,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_7,  5UL),
        CY_SEGLCD_PIXEL(LCD_DM_8,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_8,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_8,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_8,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_8,  5UL)
    },
    {
        CY_SEGLCD_PIXEL(LCD_DM_11,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_11,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_11,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_11,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_11,  5UL),
        CY_SEGLCD_PIXEL(LCD_DM_12,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_12,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_12,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_12,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_12,  5UL),
        CY_SEGLCD_PIXEL(LCD_DM_13,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_13,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_13,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_13,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_13,  5UL)
    },
    {
        CY_SEGLCD_PIXEL(LCD_DM_16,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_16,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_16,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_16,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_16,  5UL),
        CY_SEGLCD_PIXEL(LCD_DM_17,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_17,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_17,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_17,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_17,  5UL),
        CY_SEGLCD_PIXEL(LCD_DM_18,  1UL),
        CY_SEGLCD_PIXEL(LCD_DM_18,  2UL),
        CY_SEGLCD_PIXEL(LCD_DM_18,  3UL),
        CY_SEGLCD_PIXEL(LCD_DM_18,  4UL),
        CY_SEGLCD_PIXEL(LCD_DM_18,  5UL)
    }
};

const cy_stc_seglcd_disp_t display3x5 =
{
    .type   = CUSTOM_DISP_3x5DM_TYPE,
    .symNum = 4,
    .invert = false,
    .pixMap = (uint32_t*)display3x5PixMap,
    .font   = &customNumericFont3x5
};
And also different fonts for them:
#define CUSTOM_DISP_3x5DM_FONT_SYM_SIZE       (CY_SYSLIB_DIV_ROUNDUP(CUSTOM_DISP_3x5DM_TYPE, CY_SEGLCD_OCTET)) /* Size of the 3x5 font map array item in bytes */

/* Numeric font (numbers 0...F and blank symbol) */
const uint8_t customNumericFontMap3x5[][CUSTOM_DISP_3x5DM_FONT_SYM_SIZE] =
{
    /*    0             1             2             3             4             5             6             7     */
    {0x2EU,0x3AU},{0xF2U,0x43U},{0xB9U,0x4AU},{0xB1U,0x2AU},{0x87U,0x7CU},{0xB7U,0x26U},{0xAEU,0x26U},{0xA1U,0x0FU},
    /*    8             9             A             B             C             D             E             F           space  */
    {0xAAU,0x2AU},{0xB2U,0x3AU},{0x3EU,0x79U},{0xBFU,0x2AU},{0x2EU,0x2AU},{0x3FU,0x3AU},{0xBFU,0x46U},{0xBFU,0x04U},{0x00U,0x00U}
};

const cy_stc_seglcd_font_t customNumericFont3x5 =
{
    .first   = 0,
    .last    = CY_SEGLCD_NUM_BLANK,
    .ascii   = false,
    .fontMap = (uint8_t*)customNumericFontMap3x5
};

/* ASCII-coded limited font (symbols 0...9, A...F and space) */
const uint8_t customAsciiFontMap3x5[][CUSTOM_DISP_3x5DM_FONT_SYM_SIZE] =
{
    /*  space  */ /*         All zeroes (essentially the 'space' characters) for all the unused symbols          */
    {0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},
    {0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},
    /*    0             1             2             3             4             5             6             7     */
    {0x2EU,0x3AU},{0xF2U,0x43U},{0xB9U,0x4AU},{0xB1U,0x2AU},{0x87U,0x7CU},{0xB7U,0x26U},{0xAEU,0x26U},{0xA1U,0x0FU},
    /*    8             9    */
    {0xAAU,0x2AU},{0xB2U,0x3AU},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},{0x00U,0x00U},
                  /*    A             B             C             D             E             F    */
    {0x00U,0x00U},{0x3EU,0x79U},{0xBFU,0x2AU},{0x2EU,0x2AU},{0x3FU,0x3AU},{0xBFU,0x46U},{0xBFU,0x04U}
};

const cy_stc_seglcd_font_t customAsciiFont3x5 =
{
    .first   = ' ',
    .last    = 'F',
    .ascii   = true,
    .fontMap = (uint8_t*)customAsciiFontMap3x5
};
And now use all that together:
    /* Scenario: Write a hexadecimal number 43 981 (0xABCD): */
    if (CY_SEGLCD_SUCCESS != Cy_SegLCD_WriteNumber(LCD0, 43981, 3, &display3x5, false, true))
    {
        /* error handling */
    }
../../../_images/seglcd_3x5.png

There are LCD-GPIO terminal mapping definitions for different device families used in the mentioned above commons and display pixel arrays:

#if defined P13_0_PORT
    #define LCD_P10_3 11UL
    #define LCD_P10_4 12UL
    #define LCD_P10_7 15UL
    #define LCD_P11_0 16UL
    #define LCD_P11_1 17UL
    #define LCD_P11_2 18UL
    #define LCD_P11_3 19UL
    #define LCD_P11_4 20UL
    #define LCD_P11_5 21UL
    #define LCD_P11_6 22UL
    #define LCD_P12_0 23UL
    #define LCD_P12_1 24UL
    #define LCD_P12_2 25UL
    #define LCD_P12_3 26UL
    #define LCD_P12_4 27UL
    #define LCD_P12_5 28UL
    #define LCD_P12_6 29UL
    #define LCD_P12_7 30UL
    #define LCD_P13_0 31UL
    #define LCD_P13_1 32UL
    #define LCD_P13_2 33UL
    #define LCD_P13_3 34UL
    #define LCD_P13_4 35UL
    #define LCD_P13_5 36UL
    #define LCD_P13_6 37UL
    #define LCD_P13_7 38UL

    #define LCD_COM_0 LCD_P13_0
    #define LCD_COM_1 LCD_P13_1
    #define LCD_COM_2 LCD_P13_2
    #define LCD_COM_3 LCD_P13_3
    #define LCD_COM_4 LCD_P13_4
    #define LCD_COM_5 LCD_P13_5
    #define LCD_COM_6 LCD_P13_6
    #define LCD_COM_7 LCD_P13_7

    #define LCD_SEG_6 LCD_P12_1
    #define LCD_SEG_5 LCD_P12_2
    #define LCD_SEG_4 LCD_P12_3
    #define LCD_SEG_3 LCD_P12_4
    #define LCD_SEG_2 LCD_P12_5

    #define LCD_DM_2  LCD_P12_2
    #define LCD_DM_3  LCD_P12_3
    #define LCD_DM_12 LCD_P13_0
    #define LCD_DM_13 LCD_P13_1
    #define LCD_DM_16 LCD_P13_4
    #define LCD_DM_17 LCD_P13_5
    #define LCD_DM_18 LCD_P13_6
#else /* Another LCD-GPIO mapping for CY8C62x5 device family */
    #define LCD_P2_0   6UL
    #define LCD_P2_1   7UL
    #define LCD_P2_2   8UL
    #define LCD_P2_3   9UL
    #define LCD_P2_4  10UL
    #define LCD_P2_5  11UL
    #define LCD_P2_6  12UL
    #define LCD_P2_7  13UL
    #define LCD_P10_3 47UL
    #define LCD_P10_4 48UL
    #define LCD_P10_7 51UL
    #define LCD_P11_0 52UL
    #define LCD_P11_1 53UL
    #define LCD_P11_2 54UL
    #define LCD_P11_3 55UL
    #define LCD_P11_4 56UL
    #define LCD_P11_5 57UL
    #define LCD_P11_6 58UL
    #define LCD_P12_0  0UL
    #define LCD_P12_1  1UL
    #define LCD_P12_6  2UL
    #define LCD_P12_7  3UL
    #define LCD_P6_0  20UL
    #define LCD_P6_1  21UL
    #define LCD_P6_2  22UL
    #define LCD_P6_3  23UL

    #define LCD_COM_0 LCD_P2_0
    #define LCD_COM_1 LCD_P2_1
    #define LCD_COM_2 LCD_P2_2
    #define LCD_COM_3 LCD_P2_3
    #define LCD_COM_4 LCD_P2_4
    #define LCD_COM_5 LCD_P2_5
    #define LCD_COM_6 LCD_P2_6
    #define LCD_COM_7 LCD_P2_7

    #define LCD_SEG_6 LCD_P12_1
    #define LCD_SEG_5 LCD_P6_0
    #define LCD_SEG_4 LCD_P6_1
    #define LCD_SEG_3 LCD_P6_2
    #define LCD_SEG_2 LCD_P6_3

    #define LCD_DM_2  LCD_P6_0
    #define LCD_DM_3  LCD_P6_1
    #define LCD_DM_12 LCD_P2_0
    #define LCD_DM_13 LCD_P2_1
    #define LCD_DM_16 LCD_P2_4
    #define LCD_DM_17 LCD_P2_5
    #define LCD_DM_18 LCD_P2_6
#endif

    #define LCD_DM_1  LCD_P12_1
    #define LCD_DM_6  LCD_P12_6
    #define LCD_DM_7  LCD_P12_7
    #define LCD_DM_8  LCD_P10_4
    #define LCD_DM_11 LCD_P10_7

More Information

Refer to the technical reference manual (TRM) and the device datasheet.

Changelog

Version

Changes

Reason for Change

1.10

Fixed/Documented MISRA 2012 violations.

MISRA 2012 compliance.

1.0.1

Code snippets are extended to support the CY8C62x5 device family

User experience improvement

1.0

Initial version