[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:
|
||||
* Date Author Notes
|
||||
* 2024-08-25 RT-Thread First version for MCXC444
|
||||
* 2024-09-03 yandld Updated to support multiple UARTs
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
@ -18,7 +19,6 @@
|
|||
|
||||
#ifdef RT_USING_SERIAL
|
||||
|
||||
/* MCXC444 UART driver */
|
||||
struct mcxc444_uart
|
||||
{
|
||||
LPUART_Type *uart_base;
|
||||
|
@ -29,22 +29,27 @@ struct mcxc444_uart
|
|||
|
||||
static void uart_isr(struct rt_serial_device *serial);
|
||||
|
||||
#if defined(BSP_USING_UART0)
|
||||
struct rt_serial_device serial0;
|
||||
#define UART_DEVICE(uart_base, irq_name, device_name) \
|
||||
{ \
|
||||
uart_base, \
|
||||
irq_name, \
|
||||
RT_NULL, \
|
||||
device_name, \
|
||||
}
|
||||
|
||||
void LPUART0_IRQHandler(void)
|
||||
{
|
||||
uart_isr(&serial0);
|
||||
}
|
||||
|
||||
static const struct mcxc444_uart uart0 =
|
||||
{
|
||||
LPUART0,
|
||||
LPUART0_IRQn,
|
||||
&serial0,
|
||||
"uart0",
|
||||
};
|
||||
static const struct mcxc444_uart uarts[] = {
|
||||
#ifdef BSP_USING_UART0
|
||||
UART_DEVICE(LPUART0, LPUART0_IRQn, "uart0"),
|
||||
#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)
|
||||
{
|
||||
|
@ -92,7 +97,15 @@ static rt_err_t mcxc444_configure(struct rt_serial_device *serial, struct serial
|
|||
return RT_ERROR;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
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_interrupt_leave();
|
||||
if (status & kLPUART_RxOverrunFlag)
|
||||
{
|
||||
LPUART_ClearStatusFlags(uart->uart_base, kLPUART_RxOverrunFlag);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct rt_uart_ops mcxc444_uart_ops =
|
||||
|
@ -165,18 +183,33 @@ static const struct rt_uart_ops mcxc444_uart_ops =
|
|||
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)
|
||||
{
|
||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||
|
||||
#ifdef BSP_USING_UART0
|
||||
serial0.ops = &mcxc444_uart_ops;
|
||||
serial0.config = config;
|
||||
for (rt_size_t i = 0; i < UART_COUNT; i++)
|
||||
{
|
||||
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,
|
||||
(void *)&uart0);
|
||||
#endif
|
||||
(void *)&uarts[i]);
|
||||
}
|
||||
|
||||
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
|
||||
bool "Enable UART0"
|
||||
default y
|
||||
|
||||
config BSP_USING_UART1
|
||||
bool "Enable UART1"
|
||||
default y
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_I2C
|
||||
|
|
|
@ -22,22 +22,17 @@ void BOARD_InitBootPins(void)
|
|||
|
||||
void BOARD_InitPins(void)
|
||||
{
|
||||
/* Port A Clock Gate Control: Clock enabled */
|
||||
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);
|
||||
PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); /* LPUART0_RX */
|
||||
PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); /* LPUART0_TX */
|
||||
|
||||
/* PORTA2 (pin 24) is configured as LPUART0_TX */
|
||||
PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2);
|
||||
PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); /* LPUART1_TX */
|
||||
PORT_SetPinMux(PORTE, 1U, kPORT_MuxAlt3); /* LPUART1_RX */
|
||||
|
||||
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));
|
||||
SIM->SOPT5 = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue