[bsp][mcxc] add rtc/wdog/uart driver
This commit is contained in:
parent
a4882e1d40
commit
cf56227000
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLOCK_SetLpuart0Clock(0x1U);
|
if (uart->uart_base == LPUART0)
|
||||||
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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__ */
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); /* LPUART0_RX */
|
||||||
|
PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); /* LPUART0_TX */
|
||||||
|
|
||||||
|
PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); /* LPUART1_TX */
|
||||||
|
PORT_SetPinMux(PORTE, 1U, kPORT_MuxAlt3); /* LPUART1_RX */
|
||||||
|
|
||||||
/* PORTA1 (pin 23) is configured as LPUART0_RX */
|
SIM->SOPT5 = 0;
|
||||||
PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2);
|
|
||||||
|
|
||||||
/* PORTA2 (pin 24) is configured as LPUART0_TX */
|
|
||||||
PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2);
|
|
||||||
|
|
||||||
SIM->SOPT5 = ((SIM->SOPT5 &
|
|
||||||
/* 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));
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue