Pārlūkot izejas kodu

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

yandld 11 mēneši atpakaļ
vecāks
revīzija
cf56227000

+ 116 - 0
bsp/nxp/mcx/mcxc/Libraries/drivers/drv_rtc.c

@@ -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);
+
+

+ 19 - 0
bsp/nxp/mcx/mcxc/Libraries/drivers/drv_rtc.h

@@ -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

+ 58 - 25
bsp/nxp/mcx/mcxc/Libraries/drivers/drv_uart.c

@@ -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 uarts[] = {
+#ifdef BSP_USING_UART0
+    UART_DEVICE(LPUART0, LPUART0_IRQn, "uart0"),
+#endif
+#ifdef BSP_USING_UART1
+    UART_DEVICE(LPUART1, LPUART1_IRQn, "uart1"),
+#endif
 
-static const struct mcxc444_uart uart0 =
-{
-    LPUART0,
-    LPUART0_IRQn,
-    &serial0,
-    "uart0",
 };
-#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;
     }
 
-    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));
 
     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_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
-                          (void *)&uart0);
-#endif
+        rt_hw_serial_register(&serial_devices[i], uarts[i].device_name,
+                              RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                              (void *)&uarts[i]);
+    }
 
     return 0;
 }

+ 92 - 0
bsp/nxp/mcx/mcxc/Libraries/drivers/drv_wdt.c

@@ -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);
+

+ 19 - 0
bsp/nxp/mcx/mcxc/Libraries/drivers/drv_wdt.h

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

+ 3 - 1
bsp/nxp/mcx/mcxc/frdm-mcxc444/board/Kconfig

@@ -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

+ 12 - 17
bsp/nxp/mcx/mcxc/frdm-mcxc444/board/MCUX_Config/board/pin_mux.c

@@ -22,22 +22,17 @@ void BOARD_InitBootPins(void)
 
 void BOARD_InitPins(void)
 {
-    /* Port A Clock Gate Control: Clock enabled */
     CLOCK_EnableClock(kCLOCK_PortA);
-
-    /* PORTA1 (pin 23) is configured as LPUART0_RX */
-    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));
+    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 */
+
+    SIM->SOPT5 = 0;
 }