[bsp][mcxc] add rtc/wdog/uart driver

This commit is contained in:
yandld 2024-09-03 17:25:23 +08:00 committed by Meco Man
parent a4882e1d40
commit cf56227000
7 changed files with 319 additions and 43 deletions

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2024, Your Company Name
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-09-04 Alex First version for MCXC444
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <sys/time.h>
#include "drv_rtc.h"
#include "fsl_rtc.h"
#include "fsl_clock.h"
#define DBG_TAG "drv.rtc"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
static rt_err_t mcxc444_rtc_init(rt_device_t dev)
{
rtc_config_t rtcConfig;
CLOCK_EnableClock(kCLOCK_Rtc0);
RTC_GetDefaultConfig(&rtcConfig);
RTC_Init(RTC, &rtcConfig);
RTC_SetClockSource(RTC);
rt_thread_mdelay(10);
RTC_StartTimer(RTC);
return RT_EOK;
}
static rt_err_t mcxc444_rtc_get_time(time_t *ts)
{
if (ts == RT_NULL)
{
return -RT_EINVAL;
}
*ts = RTC->TSR;
return RT_EOK;
}
static rt_err_t mcxc444_rtc_set_time(time_t *ts)
{
if (ts == RT_NULL)
{
return -RT_EINVAL;
}
RTC_StopTimer(RTC);
RTC->TSR = *ts;
RTC_StartTimer(RTC);
return RT_EOK;
}
static rt_err_t mcxc444_rtc_control(rt_device_t dev, int cmd, void *args)
{
rt_err_t result = RT_EOK;
switch (cmd)
{
case RT_DEVICE_CTRL_RTC_GET_TIME:
result = mcxc444_rtc_get_time((time_t *)args);
break;
case RT_DEVICE_CTRL_RTC_SET_TIME:
result = mcxc444_rtc_set_time((time_t *)args);
break;
default:
return -RT_EINVAL;
}
return result;
}
static struct rt_device rtc_device;
int rt_hw_rtc_init(void)
{
rt_err_t ret;
rtc_device.type = RT_Device_Class_RTC;
rtc_device.init = mcxc444_rtc_init;
rtc_device.open = RT_NULL;
rtc_device.close = RT_NULL;
rtc_device.read = RT_NULL;
rtc_device.write = RT_NULL;
rtc_device.control = mcxc444_rtc_control;
ret = rt_device_register(&rtc_device, "rtc", RT_DEVICE_FLAG_RDWR);
if (ret != RT_EOK)
{
LOG_E("rtc register err code: %d\n", ret);
return ret;
}
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_rtc_init);

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-09-04 Alex First version for MCXC444
*/
#ifndef __DRV_RTC_H__
#define __DRV_RTC_H__
#include <rtthread.h>
#include <rtdevice.h>
int rt_hw_rtc_init(void);
#endif

View File

@ -6,6 +6,7 @@
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2024-08-25 RT-Thread First version for MCXC444 * 2024-08-25 RT-Thread First version for MCXC444
* 2024-09-03 yandld Updated to support multiple UARTs
*/ */
#include <rtthread.h> #include <rtthread.h>
@ -18,7 +19,6 @@
#ifdef RT_USING_SERIAL #ifdef RT_USING_SERIAL
/* MCXC444 UART driver */
struct mcxc444_uart struct mcxc444_uart
{ {
LPUART_Type *uart_base; LPUART_Type *uart_base;
@ -29,22 +29,27 @@ struct mcxc444_uart
static void uart_isr(struct rt_serial_device *serial); static void uart_isr(struct rt_serial_device *serial);
#if defined(BSP_USING_UART0) #define UART_DEVICE(uart_base, irq_name, device_name) \
struct rt_serial_device serial0; { \
uart_base, \
irq_name, \
RT_NULL, \
device_name, \
}
void LPUART0_IRQHandler(void) static const struct mcxc444_uart uarts[] = {
{ #ifdef BSP_USING_UART0
uart_isr(&serial0); UART_DEVICE(LPUART0, LPUART0_IRQn, "uart0"),
}
static const struct mcxc444_uart uart0 =
{
LPUART0,
LPUART0_IRQn,
&serial0,
"uart0",
};
#endif #endif
#ifdef BSP_USING_UART1
UART_DEVICE(LPUART1, LPUART1_IRQn, "uart1"),
#endif
};
#define UART_COUNT (sizeof(uarts) / sizeof(uarts[0]))
static struct rt_serial_device serial_devices[UART_COUNT];
static rt_err_t mcxc444_configure(struct rt_serial_device *serial, struct serial_configure *cfg) static rt_err_t mcxc444_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{ {
@ -92,7 +97,15 @@ static rt_err_t mcxc444_configure(struct rt_serial_device *serial, struct serial
return RT_ERROR; return RT_ERROR;
} }
if (uart->uart_base == LPUART0)
{
CLOCK_SetLpuart0Clock(0x1U); CLOCK_SetLpuart0Clock(0x1U);
}
else if (uart->uart_base == LPUART1)
{
CLOCK_SetLpuart1Clock(0x1U);
}
LPUART_Init(uart->uart_base, &config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk)); LPUART_Init(uart->uart_base, &config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk));
return RT_EOK; return RT_EOK;
@ -145,16 +158,21 @@ static int mcxc444_getc(struct rt_serial_device *serial)
static void uart_isr(struct rt_serial_device *serial) static void uart_isr(struct rt_serial_device *serial)
{ {
uint32_t status;
struct mcxc444_uart *uart = (struct mcxc444_uart *)serial->parent.user_data; struct mcxc444_uart *uart = (struct mcxc444_uart *)serial->parent.user_data;
rt_interrupt_enter(); status = LPUART_GetStatusFlags(uart->uart_base);
if (LPUART_GetStatusFlags(uart->uart_base) & kLPUART_RxDataRegFullFlag) if (status & kLPUART_RxDataRegFullFlag)
{ {
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
} }
rt_interrupt_leave(); if (status & kLPUART_RxOverrunFlag)
{
LPUART_ClearStatusFlags(uart->uart_base, kLPUART_RxOverrunFlag);
}
} }
static const struct rt_uart_ops mcxc444_uart_ops = static const struct rt_uart_ops mcxc444_uart_ops =
@ -165,18 +183,33 @@ static const struct rt_uart_ops mcxc444_uart_ops =
mcxc444_getc, mcxc444_getc,
}; };
#ifdef BSP_USING_UART0
void LPUART0_IRQHandler(void)
{
uart_isr(&serial_devices[0]);
}
#endif
#ifdef BSP_USING_UART1
void LPUART1_IRQHandler(void)
{
uart_isr(&serial_devices[1]);
}
#endif
int rt_hw_uart_init(void) int rt_hw_uart_init(void)
{ {
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
#ifdef BSP_USING_UART0 for (rt_size_t i = 0; i < UART_COUNT; i++)
serial0.ops = &mcxc444_uart_ops; {
serial0.config = config; serial_devices[i].ops = &mcxc444_uart_ops;
serial_devices[i].config = config;
rt_hw_serial_register(&serial0, uart0.device_name, rt_hw_serial_register(&serial_devices[i], uarts[i].device_name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
(void *)&uart0); (void *)&uarts[i]);
#endif }
return 0; return 0;
} }

View File

@ -0,0 +1,92 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-09-04 Alex First version for MCXC444
*/
#include <rtthread.h>
#include "drv_wdt.h"
#include "fsl_cop.h"
#include "fsl_clock.h"
struct mcx_cop
{
rt_watchdog_t watchdog;
SIM_Type *cop_base;
};
static struct mcx_cop cop_dev;
static rt_err_t cop_init(rt_watchdog_t *wdt)
{
cop_config_t config;
COP_GetDefaultConfig(&config);
config.timeoutMode = kCOP_ShortTimeoutMode;
config.clockSource = kCOP_LpoClock;
config.timeoutCycles = kCOP_2Power10CyclesOr2Power18Cycles;
config.enableStop = true;
config.enableDebug = true;
COP_Init(cop_dev.cop_base, &config);
return RT_EOK;
}
static rt_err_t cop_control(rt_watchdog_t *wdt, int cmd, void *arg)
{
switch (cmd)
{
case RT_DEVICE_CTRL_WDT_START:
{
return RT_EOK;
}
case RT_DEVICE_CTRL_WDT_STOP:
{
COP_Disable(cop_dev.cop_base);
return RT_EOK;
}
case RT_DEVICE_CTRL_WDT_KEEPALIVE:
{
COP_Refresh(cop_dev.cop_base);
return RT_EOK;
}
case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
return -RT_ERROR;
default:
return -RT_ERROR;
}
}
static struct rt_watchdog_ops cop_ops =
{
cop_init,
cop_control,
};
int rt_hw_cop_init(void)
{
cop_dev.cop_base = SIM;
cop_dev.watchdog.ops = &cop_ops;
if (rt_hw_watchdog_register(&cop_dev.watchdog, "cop", RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)
{
rt_kprintf("cop register failed\n");
return -RT_ERROR;
}
return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_cop_init);

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-09-04 Alex First version for MCXC444
*/
#ifndef __DRV_WDT_H__
#define __DRV_WDT_H__
#include <rtthread.h>
#include <rtdevice.h>
int rt_hw_wdt_init(void);
#endif /* __DRV_WDT_H__ */

View File

@ -26,7 +26,9 @@ menu "On-chip Peripheral Drivers"
config BSP_USING_UART0 config BSP_USING_UART0
bool "Enable UART0" bool "Enable UART0"
default y default y
config BSP_USING_UART1
bool "Enable UART1"
default y
endif endif
menuconfig BSP_USING_I2C menuconfig BSP_USING_I2C

View File

@ -22,22 +22,17 @@ void BOARD_InitBootPins(void)
void BOARD_InitPins(void) void BOARD_InitPins(void)
{ {
/* Port A Clock Gate Control: Clock enabled */
CLOCK_EnableClock(kCLOCK_PortA); CLOCK_EnableClock(kCLOCK_PortA);
CLOCK_EnableClock(kCLOCK_PortB);
CLOCK_EnableClock(kCLOCK_PortC);
CLOCK_EnableClock(kCLOCK_PortD);
CLOCK_EnableClock(kCLOCK_PortE);
/* PORTA1 (pin 23) is configured as LPUART0_RX */ PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); /* LPUART0_RX */
PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); /* LPUART0_TX */
/* PORTA2 (pin 24) is configured as LPUART0_TX */ PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); /* LPUART1_TX */
PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); PORT_SetPinMux(PORTE, 1U, kPORT_MuxAlt3); /* LPUART1_RX */
SIM->SOPT5 = ((SIM->SOPT5 & SIM->SOPT5 = 0;
/* Mask bits to zero which are setting */
(~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK)))
/* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */
| SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX)
/* LPUART0 Receive Data Source Select: LPUART_RX pin. */
| SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX));
} }