|
| 1 | +/* |
| 2 | + * Copyright (c) 2006-2024 RT-Thread Development Team |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + * |
| 6 | + * Change Logs: |
| 7 | + * Date Author Notes |
| 8 | + * 2023-08-21 hywing The first version |
| 9 | + */ |
| 10 | + |
| 11 | +#include <rtdevice.h> |
| 12 | +#include "fsl_lpi2c.h" |
| 13 | +#include "fsl_lpi2c_edma.h" |
| 14 | +#include "fsl_edma.h" |
| 15 | + |
| 16 | + |
| 17 | +#ifdef RT_USING_I2C |
| 18 | + |
| 19 | +enum |
| 20 | +{ |
| 21 | +#ifdef BSP_USING_I2C0 |
| 22 | + I2C0_INDEX, |
| 23 | +#endif |
| 24 | +}; |
| 25 | + |
| 26 | + |
| 27 | +#define i2c_dbg rt_kprintf |
| 28 | + |
| 29 | +struct lpc_i2c_bus |
| 30 | +{ |
| 31 | + struct rt_i2c_bus_device parent; |
| 32 | + LPI2C_Type *I2C; |
| 33 | + clock_attach_id_t clock_attach_id; |
| 34 | + clock_div_name_t clock_div_name; |
| 35 | + clock_name_t clock_src; |
| 36 | + uint32_t baud; |
| 37 | + char *name; |
| 38 | +}; |
| 39 | + |
| 40 | + |
| 41 | +struct lpc_i2c_bus lpc_obj[] = |
| 42 | +{ |
| 43 | +#ifdef BSP_USING_I2C0 |
| 44 | + { |
| 45 | + .I2C = LPI2C0, |
| 46 | + .baud = 100000U, |
| 47 | + .clock_attach_id = kFRO12M_to_LPI2C0, |
| 48 | + .clock_div_name = kCLOCK_DivLPI2C0, |
| 49 | + .clock_src = kCLOCK_Fro12M, |
| 50 | + .name = "i2c0", |
| 51 | + }, |
| 52 | +#endif |
| 53 | +}; |
| 54 | + |
| 55 | +static rt_ssize_t lpc_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) |
| 56 | +{ |
| 57 | + struct rt_i2c_msg *msg; |
| 58 | + lpi2c_master_transfer_t xfer = {0}; |
| 59 | + rt_uint32_t i; |
| 60 | + rt_ssize_t ret = 0; |
| 61 | + |
| 62 | + struct lpc_i2c_bus *lpc_i2c = (struct lpc_i2c_bus *)bus; |
| 63 | + |
| 64 | + for (i = 0; i < num; i++) |
| 65 | + { |
| 66 | + msg = &msgs[i]; |
| 67 | + |
| 68 | + if (msg->flags & RT_I2C_RD) |
| 69 | + { |
| 70 | + xfer.slaveAddress = msg->addr; |
| 71 | + xfer.direction = kLPI2C_Read; |
| 72 | + xfer.subaddress = 0; |
| 73 | + xfer.subaddressSize = 0; |
| 74 | + xfer.data = msg->buf; |
| 75 | + xfer.dataSize = msg->len; |
| 76 | + if(i != 0) |
| 77 | + xfer.flags = kLPI2C_TransferRepeatedStartFlag; |
| 78 | + else |
| 79 | + xfer.flags = kLPI2C_TransferDefaultFlag; |
| 80 | + |
| 81 | + if (LPI2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success) |
| 82 | + { |
| 83 | + i2c_dbg("i2c bus read failed!\n"); |
| 84 | + return i; |
| 85 | + } |
| 86 | + } |
| 87 | + else |
| 88 | + { |
| 89 | + xfer.slaveAddress = msg->addr; |
| 90 | + xfer.direction = kLPI2C_Write; |
| 91 | + xfer.subaddress = 0; |
| 92 | + xfer.subaddressSize = 0; |
| 93 | + xfer.data = msg->buf; |
| 94 | + xfer.dataSize = msg->len; |
| 95 | + if(i == 0) |
| 96 | + xfer.flags = kLPI2C_TransferNoStopFlag; |
| 97 | + else |
| 98 | + xfer.flags = kLPI2C_TransferDefaultFlag; |
| 99 | + |
| 100 | + if (LPI2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success) |
| 101 | + { |
| 102 | + i2c_dbg("i2c bus write failed!\n"); |
| 103 | + return i; |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | + ret = i; |
| 108 | + |
| 109 | + return ret; |
| 110 | +} |
| 111 | + |
| 112 | +static const struct rt_i2c_bus_device_ops i2c_ops = |
| 113 | +{ |
| 114 | + lpc_i2c_xfer, |
| 115 | + RT_NULL, |
| 116 | + RT_NULL |
| 117 | +}; |
| 118 | + |
| 119 | +int rt_hw_i2c_init(void) |
| 120 | +{ |
| 121 | + int i; |
| 122 | + lpi2c_master_config_t masterConfig; |
| 123 | + |
| 124 | + for(i=0; i<ARRAY_SIZE(lpc_obj); i++) |
| 125 | + { |
| 126 | + CLOCK_SetClockDiv(lpc_obj[i].clock_div_name, 1u); |
| 127 | + CLOCK_AttachClk(lpc_obj[i].clock_attach_id); |
| 128 | + |
| 129 | + LPI2C_MasterGetDefaultConfig(&masterConfig); |
| 130 | + masterConfig.baudRate_Hz = lpc_obj[i].baud; |
| 131 | + |
| 132 | + LPI2C_MasterInit(lpc_obj[i].I2C, &masterConfig, CLOCK_GetFreq(lpc_obj[i].clock_src)); |
| 133 | + |
| 134 | + lpc_obj[i].parent.ops = &i2c_ops; |
| 135 | + |
| 136 | + rt_i2c_bus_device_register(&lpc_obj[i].parent, lpc_obj[i].name); |
| 137 | + } |
| 138 | + |
| 139 | + return RT_EOK; |
| 140 | +} |
| 141 | +INIT_DEVICE_EXPORT(rt_hw_i2c_init); |
| 142 | + |
| 143 | +#endif /* RT_USING_I2C */ |
| 144 | + |
| 145 | + |
| 146 | + |
0 commit comments