PSoC 6 Peripheral Driver Library
SegLCD (Segment LCD)

General Description

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:

Glossary

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:

seglcd_solution.png

The SegLCD solution includes:

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 */
{
.drive = CY_SEGLCD_PWM,
.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 */
if (CY_SEGLCD_SUCCESS == Cy_SegLCD_Init(LCD0, &config))
{
if (CY_SEGLCD_SUCCESS == Cy_SegLCD_ClrFrame(LCD0, commons))
{
/* 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
*/

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
*/

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:

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:

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:

seglcd_waveA.png

Conventional Type-B Waveform Example:

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:

seglcd_waveGen.png

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

seglcd_Voff.png
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:

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:

seglcd_DCA.png

Digital Correlation Example - Type-B:

seglcd_DCB.png

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.

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:

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:

seglcd_PWM2.png

PWM1/3 LCD drive waveform:

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:

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 */
}
};
{
.symNum = 4,
.invert = false,
.pixMap = (uint32_t*)displayPixMap,
};
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:

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 */
}
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) */
{
/* error handling */
}

after which the next image on the glass appears:

seglcd_heart.png
/* Scenario: Clear a pixel (write a false value) */
{
/* 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 =
{
.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 */
{
/* 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:

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:

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 */
}
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,
.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 */
}
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.

MISRA-C Compliance

MISRA Rule Rule Class (Required/Advisory) Rule Description Description of Deviation(s)
10.3 R The value of a complex expression of integer type shall only be cast to a type of the same signedness that is no wider than the underlying type of the expression. The value got from the bitfield physically cannot exceed the enumeration that describes this bitfield. So, the code is safe by design.
11.4 A A cast should not be performed between a pointer to object type and a different pointer to object type. This is a fix for the GCC compiler warning.
14.1 R There shall be no unreachable code. This is the HOBTO parameter reading for future features support.

Changelog

VersionChangesReason for Change
1.0.1 Code snippets are extended to support the CY8C62x5 device family User experience improvement
1.0 Initial version

API Reference

 Macros
 
 Functions
 
 Data Structures
 
 Global Data
 
 Enumerated Types