diff --git a/bsp/nxp/mcx/mcxa/Libraries/drivers/drv_i2c.c b/bsp/nxp/mcx/mcxa/Libraries/drivers/drv_i2c.c new file mode 100644 index 00000000000..f92f55f9228 --- /dev/null +++ b/bsp/nxp/mcx/mcxa/Libraries/drivers/drv_i2c.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-06 YangXi The first version + * 2024-6-15 liujianhua + */ + +#include +#include "fsl_lpi2c.h" +#include "fsl_lpi2c_edma.h" +#include "fsl_edma.h" + + +#ifdef RT_USING_I2C + +enum +{ +#ifdef BSP_USING_I2C0 + I2C0_INDEX, +#endif +#ifdef BSP_USING_I2C1 + I2C1_INDEX, +#endif +#ifdef BSP_USING_I2C2 + I2C2_INDEX, +#endif +}; + + +#define i2c_dbg rt_kprintf + +struct lpc_i2c_bus +{ + struct rt_i2c_bus_device parent; + LPI2C_Type *I2C; + clock_attach_id_t clock_attach_id; + clock_div_name_t clock_div_name; + clock_name_t clock_src; + uint32_t baud; + char *name; +}; + + +struct lpc_i2c_bus lpc_obj[] = +{ +#ifdef BSP_USING_I2C0 + { + .I2C = LPI2C0, + .baud = 100000U, + .clock_attach_id = kFRO12M_to_LPI2C0, /*!< Attach FRO12M to LPI2C0. */ + .clock_div_name = kCLOCK_DivLPI2C0, /*!< LPI2C0 clock divider */ + .clock_src = kCLOCK_Fro12M, + .name = "i2c0", + }, +#endif + +}; + +static rt_ssize_t lpc_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) +{ + struct rt_i2c_msg *msg; + lpi2c_master_transfer_t xfer = {0}; + rt_uint32_t i; + rt_ssize_t ret = 0; + + struct lpc_i2c_bus *lpc_i2c = (struct lpc_i2c_bus *)bus; + + for (i = 0; i < num; i++) + { + msg = &msgs[i]; + + if (msg->flags & RT_I2C_RD) + { + xfer.slaveAddress = msg->addr; + xfer.direction = kLPI2C_Read; + xfer.subaddress = 0; + xfer.subaddressSize = 0; + xfer.data = msg->buf; + xfer.dataSize = msg->len; + if(i != 0) + xfer.flags = kLPI2C_TransferRepeatedStartFlag; + else + xfer.flags = kLPI2C_TransferDefaultFlag; + + if (LPI2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success) + { + i2c_dbg("i2c bus read failed!\n"); + return i; + } + } + else + { + xfer.slaveAddress = msg->addr; + xfer.direction = kLPI2C_Write; + xfer.subaddress = 0; + xfer.subaddressSize = 0; + xfer.data = msg->buf; + xfer.dataSize = msg->len; + if(i == 0) + xfer.flags = kLPI2C_TransferNoStopFlag; + else + xfer.flags = kLPI2C_TransferDefaultFlag; + + if (LPI2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success) + { + i2c_dbg("i2c bus write failed!\n"); + return i; + } + } + } + ret = i; + + return ret; +} + +static const struct rt_i2c_bus_device_ops i2c_ops = +{ + lpc_i2c_xfer, + RT_NULL, + RT_NULL +}; + +int rt_hw_i2c_init(void) +{ + int i; + lpi2c_master_config_t masterConfig; + + for(i=0; i 500K * sample = 75% at baud > 800K */ -#if defined(CH32V30x_D8C) /* APB1 (PCLK1 72MHz) */ +#if (defined CH32V30x_D8C) || (defined CH32V20x_D8W) /* APB1 (PCLK1 72MHz) */ static const struct ch32v307x_can_baud_info can_baud_rate_tab[] = { CH32V307X_CAN_BAUD_DEF( CAN1MBaud, CAN_SJW_1tq, CAN_BS1_15tq, CAN_BS2_2tq, 4), @@ -91,7 +91,7 @@ static struct ch32v307x_can_obj drv_can1 = }; #endif -#ifdef BSP_USING_CAN2 +#ifdef CAN2 static struct ch32v307x_can_obj drv_can2 = { .name = "can2", @@ -99,6 +99,7 @@ static struct ch32v307x_can_obj drv_can2 = }; #endif + #ifdef BSP_USING_CAN rt_weak void ch32v307x_can_gpio_init(CAN_TypeDef *can_base) { @@ -132,7 +133,7 @@ rt_weak void ch32v307x_can_gpio_init(CAN_TypeDef *can_base) */ } #endif -#ifdef BSP_USING_CAN2 +#ifdef CAN2 if (CAN2 == can_base) { RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE ); @@ -203,10 +204,12 @@ static rt_err_t _can_filter_config(struct ch32v307x_can_obj *drv_can_obj) { CAN_FilterInit( &(drv_can_obj->can_filter_init) ); } +#ifdef CAN2 else if (drv_can_obj->can_base == CAN2) { CAN_FilterInit( &(drv_can_obj->can_filter_init) ); } +#endif else { LOG_E("can filter config error"); @@ -234,10 +237,12 @@ static rt_err_t _can_config(struct rt_can_device *can, struct can_configure *cfg { ch32v307x_can_gpio_init(CAN1); } +#ifdef CAN2 else if (drv_can_obj->can_base == CAN2) { ch32v307x_can_gpio_init(CAN2); } +#endif else { LOG_E("can gpio init error"); @@ -300,11 +305,13 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); NVIC_DisableIRQ(CAN1_RX1_IRQn); } +#ifdef CAN2 if (CAN2 == drv_can_obj->can_base) { NVIC_DisableIRQ(CAN2_RX0_IRQn); NVIC_DisableIRQ(CAN2_RX1_IRQn); } + #endif // CAN_ClearITPendingBit( drv_can_obj->can_base, CAN_IT_FMP0 ); // CAN_ClearITPendingBit( drv_can_obj->can_base, CAN_IT_FF0 ); // CAN_ClearITPendingBit( drv_can_obj->can_base, CAN_IT_FOV0 ); @@ -325,10 +332,12 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) { NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); } +#ifdef CAN2 if (CAN2 == drv_can_obj->can_base) { NVIC_DisableIRQ(CAN2_TX_IRQn); } +#endif CAN_ITConfig(drv_can_obj->can_base, CAN_IT_TME, DISABLE); /*!< Transmit mailbox empty Interrupt*/ } else if (argval == RT_DEVICE_CAN_INT_ERR) @@ -337,10 +346,12 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) { NVIC_DisableIRQ(CAN1_SCE_IRQn); } +#ifdef CAN2 if (CAN2 == drv_can_obj->can_base) { NVIC_DisableIRQ(CAN2_SCE_IRQn); } + #endif CAN_ClearITPendingBit( drv_can_obj->can_base, CAN_IT_EWG ); CAN_ClearITPendingBit( drv_can_obj->can_base, CAN_IT_EPV ); CAN_ClearITPendingBit( drv_can_obj->can_base, CAN_IT_BOF ); @@ -379,6 +390,7 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) NVIC_SetPriority(CAN1_RX1_IRQn, 1); NVIC_EnableIRQ(CAN1_RX1_IRQn); } +#ifdef CAN2 if (CAN2 == drv_can_obj->can_base) { NVIC_SetPriority(CAN2_RX0_IRQn, 1); @@ -386,6 +398,7 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) NVIC_SetPriority(CAN2_RX1_IRQn, 1); NVIC_EnableIRQ(CAN2_RX1_IRQn); } +#endif } else if (argval == RT_DEVICE_FLAG_INT_TX) { @@ -397,11 +410,13 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) NVIC_SetPriority(USB_HP_CAN1_TX_IRQn, 1); NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn); } +#ifdef CAN2 if (CAN2 == drv_can_obj->can_base) { NVIC_SetPriority(CAN2_TX_IRQn, 1); NVIC_EnableIRQ(CAN2_TX_IRQn); } +#endif } else if (argval == RT_DEVICE_CAN_INT_ERR) { @@ -416,11 +431,13 @@ static rt_err_t _can_control(struct rt_can_device *can, int cmd, void *arg) NVIC_SetPriority(CAN1_SCE_IRQn, 1); NVIC_EnableIRQ(CAN1_SCE_IRQn); } +#ifdef CAN2 if (CAN2 == drv_can_obj->can_base) { NVIC_SetPriority(CAN2_SCE_IRQn, 1); NVIC_EnableIRQ(CAN2_SCE_IRQn); } +#endif } break; case RT_CAN_CMD_SET_FILTER: @@ -730,10 +747,12 @@ static int _can_recv_rtmsg(CAN_TypeDef *can_base, struct rt_can_msg *pmsg, rt_ui { pmsg->hdr_index = (RxMessage->FMI + 1) >> 1; } +#ifdef CAN2 else if (can_base == CAN2) { pmsg->hdr_index = (RxMessage->FMI >> 1) + 14; } +#endif /* Release FIFO */ CAN_FIFORelease(can_base,FIFONum); return RT_EOK; @@ -955,7 +974,7 @@ void CAN1_SCE_IRQHandler(void) } #endif /* BSP_USING_CAN1 */ -#ifdef BSP_USING_CAN2 +#ifdef CAN2 /** * @brief This function handles CAN2 TX interrupts. */ @@ -1132,7 +1151,7 @@ int rt_hw_can_init(void) rt_hw_can_register(&drv_can1.device, drv_can1.name, &_can_ops, &drv_can1); #endif /* BSP_USING_CAN1 */ -#ifdef BSP_USING_CAN2 +#ifdef CAN2 CAN_SlaveStartBank(14); diff --git a/bsp/wch/risc-v/ch32v208w-r0/board/Kconfig b/bsp/wch/risc-v/ch32v208w-r0/board/Kconfig index 567e4ce6b52..aa9c24c89ad 100644 --- a/bsp/wch/risc-v/ch32v208w-r0/board/Kconfig +++ b/bsp/wch/risc-v/ch32v208w-r0/board/Kconfig @@ -255,9 +255,7 @@ menu "On-chip Peripheral Drivers" config BSP_USING_CAN1 bool "Using CAN1" default n - config BSP_USING_CAN2 - bool "Using CAN2" - default n + endif config BSP_USING_TIM diff --git a/components/drivers/include/drivers/serial.h b/components/drivers/include/drivers/serial.h index 9438ed43f95..addb158cfbb 100644 --- a/components/drivers/include/drivers/serial.h +++ b/components/drivers/include/drivers/serial.h @@ -139,7 +139,7 @@ struct rt_serial_rx_fifo struct rt_serial_tx_fifo { - struct rt_completion completion; + struct rt_completion *completion; }; /*