Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Peripheral.canfd:
- CONFIG_RT_CANSND_MSG_TIMEOUT=100
- CONFIG_RT_CAN_NB_TX_FIFO_SIZE=1024

Peripheral.slcd:
kconfig:
- CONFIG_BSP_USING_SLCD=y

# ------ utest CI ------
utest.pin:
<<: *scons
Expand Down
6 changes: 6 additions & 0 deletions bsp/nxp/mcx/mcxa/frdm-mcxa366/board/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ menu "On-chip Peripheral Drivers"
endmenu

menu "Onboard Peripheral Drivers"
config BSP_USING_SLCD
bool "Enable onboard SLCD display"
default n
help
Enable FRDM-MCXA366 onboard segment LCD (6 digits).

config BSP_USING_ARDUINO
bool "Compatible with Arduino Ecosystem (RTduino)"
select PKG_USING_RTDUINO
Expand Down
28 changes: 28 additions & 0 deletions bsp/nxp/mcx/mcxa/frdm-mcxa366/board/MCUX_Config/board/pin_mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,3 +489,31 @@ void BOARD_InitPins(void)
PORT_SetPinConfig(PORT1, 17U, &port1_17_pin10_config);
#endif /* BSP_USING_CAN1 */
}

void BOARD_InitSLCDPins(void)
{
uint8_t pin;

/* LCD_P16~LCD_P31 are routed on PORT0_12~PORT0_27 (Alt9). */
const port_pin_config_t slcd_pin_config = {
.pullSelect = kPORT_PullDisable,
.pullValueSelect = kPORT_LowPullResistor,
.slewRate = kPORT_FastSlewRate,
.passiveFilterEnable = kPORT_PassiveFilterDisable,
.openDrainEnable = kPORT_OpenDrainDisable,
.driveStrength = kPORT_LowDriveStrength,
.driveStrength1 = kPORT_NormalDriveStrength,
.mux = kPORT_MuxAlt9,
.inputBuffer = kPORT_InputBufferEnable,
.invertInput = kPORT_InputNormal,
.lockRegister = kPORT_UnlockRegister,
};

CLOCK_EnableClock(kCLOCK_GatePORT0);
RESET_ReleasePeripheralReset(kPORT0_RST_SHIFT_RSTn);

for (pin = 12U; pin <= 27U; pin++)
{
PORT_SetPinConfig(PORT0, pin, &slcd_pin_config);
}
}
30 changes: 18 additions & 12 deletions bsp/nxp/mcx/mcxa/frdm-mcxa366/board/MCUX_Config/board/pin_mux.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,41 @@
*/

/* Symbols to be used with GPIO driver */
#define BOARD_INITLEDSPINS_LED_RED_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_RED_GPIO_PIN 18U /*!<@brief GPIO pin number */
#define BOARD_INITLEDSPINS_LED_RED_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_RED_GPIO_PIN 18U /*!<@brief GPIO pin number */
#define BOARD_INITLEDSPINS_LED_RED_GPIO_PIN_MASK (1U << 18U) /*!<@brief GPIO pin mask */

/* Symbols to be used with PORT driver */
#define BOARD_INITLEDSPINS_LED_RED_PORT PORT3 /*!<@brief PORT peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_RED_PIN 18U /*!<@brief PORT pin number */
#define BOARD_INITLEDSPINS_LED_RED_PORT PORT3 /*!<@brief PORT peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_RED_PIN 18U /*!<@brief PORT pin number */
#define BOARD_INITLEDSPINS_LED_RED_PIN_MASK (1U << 18U) /*!<@brief PORT pin mask */
/* @} */

/*! @name PORT3_19 (number 85), LED_GREEN
@{ */

/* Symbols to be used with GPIO driver */
#define BOARD_INITLEDSPINS_LED_GREEN_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_GREEN_GPIO_PIN 19U /*!<@brief GPIO pin number */
#define BOARD_INITLEDSPINS_LED_GREEN_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_GREEN_GPIO_PIN 19U /*!<@brief GPIO pin number */
#define BOARD_INITLEDSPINS_LED_GREEN_GPIO_PIN_MASK (1U << 19U) /*!<@brief GPIO pin mask */

/* Symbols to be used with PORT driver */
#define BOARD_INITLEDSPINS_LED_GREEN_PORT PORT3 /*!<@brief PORT peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_GREEN_PIN 19U /*!<@brief PORT pin number */
#define BOARD_INITLEDSPINS_LED_GREEN_PORT PORT3 /*!<@brief PORT peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_GREEN_PIN 19U /*!<@brief PORT pin number */
#define BOARD_INITLEDSPINS_LED_GREEN_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */
/* @} */

/*! @name PORT3_21 (number 82), LED_BLUE
@{ */

/* Symbols to be used with GPIO driver */
#define BOARD_INITLEDSPINS_LED_BLUE_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_BLUE_GPIO_PIN 21U /*!<@brief GPIO pin number */
#define BOARD_INITLEDSPINS_LED_BLUE_GPIO GPIO3 /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_BLUE_GPIO_PIN 21U /*!<@brief GPIO pin number */
#define BOARD_INITLEDSPINS_LED_BLUE_GPIO_PIN_MASK (1U << 21U) /*!<@brief GPIO pin mask */

/* Symbols to be used with PORT driver */
#define BOARD_INITLEDSPINS_LED_BLUE_PORT PORT3 /*!<@brief PORT peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_BLUE_PIN 21U /*!<@brief PORT pin number */
#define BOARD_INITLEDSPINS_LED_BLUE_PORT PORT3 /*!<@brief PORT peripheral base pointer */
#define BOARD_INITLEDSPINS_LED_BLUE_PIN 21U /*!<@brief PORT pin number */
#define BOARD_INITLEDSPINS_LED_BLUE_PIN_MASK (1U << 21U) /*!<@brief PORT pin mask */
/* @} */

Expand All @@ -77,6 +77,12 @@ void BOARD_InitBootPins(void);
*/
void BOARD_InitPins(void);

/*!
* @brief Configures PORT0_12~PORT0_27 as LCD_P16~LCD_P31 for onboard SLCD.
*
*/
void BOARD_InitSLCDPins(void);

#if defined(__cplusplus)
}
#endif
Expand Down
7 changes: 5 additions & 2 deletions bsp/nxp/mcx/mcxa/frdm-mcxa366/board/ports/SConscript
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from building import *
import os

cwd = GetCurrentDir()
# add the general drivers.
src = Glob('*.c')
src = []
CPPPATH = [cwd]

if GetDepend(['BSP_USING_SLCD']):
src += ['drv_slcd.c']

group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)

list = os.listdir(cwd)
Expand Down
234 changes: 234 additions & 0 deletions bsp/nxp/mcx/mcxa/frdm-mcxa366/board/ports/drv_slcd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
/*
* Copyright (c) 2006-2026, RT-Thread Development Team
* Copyright 2024-2025 NXP
*
* SPDX-License-Identifier: Apache-2.0
*
* Board-level SLCD helper for FRDM-MCXA366, built on NXP fsl_slcd.
*
* Segment mapping (8 bits per front-plane pair in num_matrix):
* 7 6 5 4 | 3 2 1 0
* E G F P | D C B A
*
* Front plane: digit6..digit1 use LCD_P27/P26 .. LCD_P17/P16
* Back plane: COM1..COM4 use LCD_P28..LCD_P31
*/

#include <rtthread.h>

#ifdef BSP_USING_SLCD

#include "drv_slcd.h"
#include "pin_mux.h"
#include "fsl_clock.h"
#include "fsl_reset.h"
#include "fsl_slcd.h"

#define BOARD_SLCD LCD0

#define SEGA 0x0001u
#define SEGB 0x0002u
#define SEGC 0x0004u
#define SEGD 0x0008u
#define SEGP 0x0100u
#define SEGF 0x0200u
#define SEGG 0x0400u
#define SEGE 0x0800u

/* Low byte -> pin_lo (A/B/C/D), high byte -> pin_hi (P/F/G/E). */
static const uint16_t num_matrix[] = {
SEGA | SEGB | SEGC | SEGD | SEGE | SEGF, /* 0 */
SEGB | SEGC, /* 1 */
SEGA | SEGB | SEGG | SEGE | SEGD, /* 2 */
SEGA | SEGB | SEGG | SEGC | SEGD, /* 3 */
SEGF | SEGG | SEGB | SEGC, /* 4 */
SEGA | SEGF | SEGG | SEGC | SEGD, /* 5 */
SEGA | SEGF | SEGE | SEGD | SEGC | SEGG, /* 6 */
SEGA | SEGB | SEGC, /* 7 */
SEGA | SEGB | SEGC | SEGD | SEGE | SEGF | SEGG, /* 8 */
SEGA | SEGF | SEGG | SEGB | SEGC | SEGD, /* 9 */
0 /* space / blank */
};

/* digit 1..6 -> low front-plane pin (high pin is low+1) */
static const uint8_t digit_pin_lo[] = { 0, 16, 18, 20, 22, 24, 26 };

/* SLCD_Px point -> front-plane pin (phase A / SEGP) */
static const uint8_t point_pin[] = {
23, /* P1 */
21, /* P2 */
19, /* P3 */
25, /* P4 */
27, /* P5 */
17, /* P6 */
};

static rt_bool_t g_slcd_inited = RT_FALSE;

static void slcd_set_digit_segments(uint8_t digit, uint16_t seg)
{
uint8_t pin_lo;

if ((digit < 1U) || (digit > 6U))
{
return;
}

pin_lo = digit_pin_lo[digit];
SLCD_SetFrontPlaneSegments(BOARD_SLCD, pin_lo, (uint8_t)(seg & 0xFFU));
SLCD_SetFrontPlaneSegments(BOARD_SLCD, pin_lo + 1U, (uint8_t)((seg >> 8) & 0xFFU));
}

int rt_hw_slcd_init(void)
{
slcd_config_t config;

if (g_slcd_inited)
{
return RT_EOK;
}

BOARD_InitSLCDPins();

/* SLCD function clock on MCXA366. */
CLOCK_SetupFRO16KClocking(kCLKE_16K_COREMAIN);
RESET_ReleasePeripheralReset(kSLCD0_RST_SHIFT_RSTn);

SLCD_GetDefaultConfig(&config);
config.dutyCycle = kSLCD_1Div4DutyCycle;
config.slcdLowPinEnabled = 0xFFFF0000U; /* LCD_P16~P31 */
config.slcdHighPinEnabled = 0U;
config.backPlaneLowPin = 0xF0000000U; /* LCD_P28~P31 */
config.backPlaneHighPin = 0U;
config.faultConfig = RT_NULL;
SLCD_Init(BOARD_SLCD, &config);

SLCD_SetBackPlanePhase(BOARD_SLCD, 28U, kSLCD_PhaseAActivate);
SLCD_SetBackPlanePhase(BOARD_SLCD, 29U, kSLCD_PhaseBActivate);
SLCD_SetBackPlanePhase(BOARD_SLCD, 30U, kSLCD_PhaseCActivate);
SLCD_SetBackPlanePhase(BOARD_SLCD, 31U, kSLCD_PhaseDActivate);

SLCD_StartDisplay(BOARD_SLCD);

g_slcd_inited = RT_TRUE;
return RT_EOK;
}

void rt_hw_slcd_display_all(void)
{
uint8_t pin;

for (pin = 16U; pin <= 27U; pin++)
{
SLCD_SetFrontPlaneSegments(BOARD_SLCD, pin,
(uint8_t)(kSLCD_PhaseAActivate | kSLCD_PhaseBActivate |
kSLCD_PhaseCActivate | kSLCD_PhaseDActivate));
}
}

void rt_hw_slcd_clear(void)
{
uint8_t pin;

for (pin = 16U; pin <= 27U; pin++)
{
SLCD_SetFrontPlaneSegments(BOARD_SLCD, pin, (uint8_t)kSLCD_NoPhaseActivate);
}
}

void rt_hw_slcd_display_num(uint8_t digit, uint8_t num)
{
uint16_t seg = (num <= 9U) ? num_matrix[num] : num_matrix[10];

slcd_set_digit_segments(digit, seg);
}

void rt_hw_slcd_display_string(const char *str)
{
uint8_t digit;
uint8_t num;
uint8_t points = 0U;

if (str == RT_NULL)
{
return;
}

for (digit = 6U; digit >= 1U; digit--)
{
while ((*str == ':') || (*str == '.'))
{
if (*str == ':')
{
points |= SLCD_COLON;
}
else
{
points |= SLCD_DOT;
}
str++;
}

if (*str == '\0')
{
num = 10U;
}
else if (*str == ' ')
{
num = 10U;
str++;
}
else
{
num = (uint8_t)(*str - '0');
str++;
if (num > 9U)
{
num = 10U;
}
}
rt_hw_slcd_display_num(digit, num);
if (digit == 1U)
{
break;
}
}

if (points != 0U)
{
rt_hw_slcd_display_point(points);
}
}

void rt_hw_slcd_display_time(uint8_t hour, uint8_t minute)
{
char buf[8];

if (hour > 99U)
{
hour = 99U;
}
if (minute > 99U)
{
minute = 99U;
}

rt_snprintf(buf, sizeof(buf), "%02u:%02u", hour, minute);
rt_hw_slcd_clear();
rt_hw_slcd_display_string(buf);
}

void rt_hw_slcd_display_point(uint8_t point)
{
uint8_t i;

for (i = 0U; i < 6U; i++)
{
if (point & (1U << i))
{
SLCD_SetFrontPlaneOnePhase(BOARD_SLCD, point_pin[i], kSLCD_PhaseAIndex, true);
}
}
}

#endif /* BSP_USING_SLCD */
Loading
Loading