summaryrefslogtreecommitdiff
path: root/bsp
diff options
context:
space:
mode:
authorwirano <[email protected]>2024-04-11 16:59:10 +0800
committerMeco Man <[email protected]>2024-04-12 19:02:49 -0400
commit5e9257fcd1a447533435b92bccafd0989ccf5f0d (patch)
treefca7ae18ad1609e1dd5b51a65b9e33e99e2f93a1 /bsp
parent86f1a0d2b233247b78e54b5fe7eafd92e21acd8f (diff)
bsp/tm4c123: add hardware i2c support
Diffstat (limited to 'bsp')
-rw-r--r--bsp/tm4c123bsp/board/Kconfig80
-rw-r--r--bsp/tm4c123bsp/board/board.c3
-rw-r--r--bsp/tm4c123bsp/board/board.h4
-rw-r--r--bsp/tm4c123bsp/libraries/Drivers/SConscript6
-rw-r--r--bsp/tm4c123bsp/libraries/Drivers/config/i2c_config.h93
-rw-r--r--bsp/tm4c123bsp/libraries/Drivers/drv_i2c.c226
-rw-r--r--bsp/tm4c123bsp/libraries/Drivers/drv_i2c.h31
-rw-r--r--bsp/tm4c123bsp/libraries/TivaWare_C_series/SConscript3
8 files changed, 429 insertions, 17 deletions
diff --git a/bsp/tm4c123bsp/board/Kconfig b/bsp/tm4c123bsp/board/Kconfig
index 9c93c1a0cc..b7356b7fad 100644
--- a/bsp/tm4c123bsp/board/Kconfig
+++ b/bsp/tm4c123bsp/board/Kconfig
@@ -188,21 +188,75 @@ menu "On-chip Peripheral Drivers"
default n
endif
- menuconfig BSP_USING_I2C1
- bool "Enable I2C1 BUS (software simulation)"
+ menuconfig BSP_USING_I2C
+ bool "Enable I2C BUS"
default n
select RT_USING_I2C
- select RT_USING_I2C_BITOPS
- select RT_USING_PIN
- if BSP_USING_I2C1
- config BSP_I2C1_SCL_PIN
- int "i2c1 scl pin number"
- range 0 175
- default 22
- config BSP_I2C1_SDA_PIN
- int "I2C1 sda pin number"
- range 0 175
- default 23
+ if BSP_USING_I2C
+ config BSP_USING_I2C0
+ bool "Enable I2C0 BUS"
+ default n
+ if BSP_USING_I2C0
+ choice
+ prompt "I2C0 CLK frequency"
+ default BSP_I2C0_CLK_100
+
+ config BSP_I2C0_CLK_100
+ bool "100kHz"
+
+ config BSP_I2C0_CLK_400
+ bool "400kHz"
+ endchoice
+ endif
+
+ config BSP_USING_I2C1
+ bool "Enable I2C1 BUS"
+ default n
+ if BSP_USING_I2C1
+ choice
+ prompt "I2C1 CLK frequency"
+ default BSP_I2C1_CLK_100
+
+ config BSP_I2C1_CLK_100
+ bool "100kHz"
+
+ config BSP_I2C1_CLK_400
+ bool "400kHz"
+ endchoice
+ endif
+
+ config BSP_USING_I2C2
+ bool "Enable I2C2 BUS"
+ default n
+ if BSP_USING_I2C2
+ choice
+ prompt "I2C2 CLK frequency"
+ default BSP_I2C3_CLK_100
+
+ config BSP_I2C2_CLK_100
+ bool "100kHz"
+
+ config BSP_I2C2_CLK_400
+ bool "400kHz"
+ endchoice
+ endif
+
+ config BSP_USING_I2C3
+ bool "Enable I2C3 BUS"
+ default n
+ if BSP_USING_I2C3
+ choice
+ prompt "I2C3 CLK frequency"
+ default BSP_I2C4_CLK_100
+
+ config BSP_I2C3_CLK_100
+ bool "100kHz"
+
+ config BSP_I2C3_CLK_400
+ bool "400kHz"
+ endchoice
+ endif
+
endif
menuconfig BSP_USING_TIM
diff --git a/bsp/tm4c123bsp/board/board.c b/bsp/tm4c123bsp/board/board.c
index 4f75212b08..0748f2436b 100644
--- a/bsp/tm4c123bsp/board/board.c
+++ b/bsp/tm4c123bsp/board/board.c
@@ -59,6 +59,9 @@ void rt_hw_board_init()
#ifdef RT_USING_PWM
rt_hw_pwm_init();
#endif
+#ifdef RT_USING_I2C
+ rt_hw_i2c_init();
+#endif
/* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
diff --git a/bsp/tm4c123bsp/board/board.h b/bsp/tm4c123bsp/board/board.h
index 0f8c5aff40..990da9b42a 100644
--- a/bsp/tm4c123bsp/board/board.h
+++ b/bsp/tm4c123bsp/board/board.h
@@ -47,6 +47,10 @@
#include "drv_spi.h"
#endif /* RT_USING_SPI*/
+#ifdef RT_USING_I2C
+#include "drv_i2c.h"
+#endif /* RT_USING_I2C*/
+
#endif /*__BOARD_H__*/
/************************** end of file ******************/
diff --git a/bsp/tm4c123bsp/libraries/Drivers/SConscript b/bsp/tm4c123bsp/libraries/Drivers/SConscript
index d50fd5cadc..94e0d77ba1 100644
--- a/bsp/tm4c123bsp/libraries/Drivers/SConscript
+++ b/bsp/tm4c123bsp/libraries/Drivers/SConscript
@@ -26,9 +26,9 @@ if GetDepend(['RT_USING_SPI']):
if GetDepend(['RT_USING_QSPI']):
src += ['drv_qspi.c']
-if GetDepend(['RT_USING_I2C', 'RT_USING_I2C_BITOPS']):
- if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3') or GetDepend('BSP_USING_I2C4'):
- src += ['drv_soft_i2c.c']
+if GetDepend(['RT_USING_I2C']):
+ if GetDepend('BSP_USING_I2C0') or GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3'):
+ src += ['drv_i2c.c']
if GetDepend(['BSP_USING_ETH', 'RT_USING_LWIP']):
src += ['drv_eth.c']
diff --git a/bsp/tm4c123bsp/libraries/Drivers/config/i2c_config.h b/bsp/tm4c123bsp/libraries/Drivers/config/i2c_config.h
new file mode 100644
index 0000000000..f89a3c3d8b
--- /dev/null
+++ b/bsp/tm4c123bsp/libraries/Drivers/config/i2c_config.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2006-2024, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2024-01-20 wirano first version
+ */
+
+#ifndef __I2C_CONFIG_H__
+#define __I2C_CONFIG_H__
+
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(BSP_I2C0_CLK_100)
+#define I2C0_CLK 100000
+#elif defined(BSP_I2C0_CLK_400)
+#define I2C0_CLK 400000
+#endif
+
+#if defined(BSP_I2C1_CLK_100)
+#define I2C1_CLK 100000
+#elif defined(BSP_I2C1_CLK_400)
+#define I2C1_CLK 400000
+#endif
+
+#if defined(BSP_I2C2_CLK_100)
+#define I2C2_CLK 100000
+#elif defined(BSP_I2C2_CLK_400)
+#define I2C2_CLK 400000
+#endif
+
+#if defined(BSP_I2C3_CLK_100)
+#define I2C3_CLK 100000
+#elif defined(BSP_I2C3_CLK_400)
+#define I2C3_CLK 400000
+#endif
+
+#ifdef BSP_USING_I2C0
+#ifndef I2C0_BUS_CONFIG
+#define I2C0_BUS_CONFIG \
+ { \
+ .base = I2C0_BASE, \
+ .bus_name = "i2c0", \
+ .clk_freq = I2C0_CLK, \
+ }
+#endif /* I2C0_BUS_CONFIG */
+#endif /* BSP_USING_I2C0 */
+
+#ifdef BSP_USING_I2C1
+#ifndef I2C1_BUS_CONFIG
+#define I2C1_BUS_CONFIG \
+ { \
+ .base = I2C1_BASE, \
+ .bus_name = "i2c1", \
+ .clk_freq = I2C1_CLK, \
+ }
+#endif /* I2C1_BUS_CONFIG */
+#endif /* BSP_USING_I2C1 */
+
+#ifdef BSP_USING_I2C2
+#ifndef I2C2_BUS_CONFIG
+#define I2C2_BUS_CONFIG \
+ { \
+ .base = I2C2_BASE, \
+ .bus_name = "i2c2", \
+ .clk_freq = I2C2_CLK, \
+ }
+#endif /* I2C2_BUS_CONFIG */
+#endif /* BSP_USING_I2C2 */
+
+#ifdef BSP_USING_I2C3
+#ifndef I2C3_BUS_CONFIG
+#define I2C3_BUS_CONFIG \
+ { \
+ .base = I2C3_BASE, \
+ .bus_name = "i2c3", \
+ .clk_freq = I2C3_CLK, \
+ }
+#endif /* I2C3_BUS_CONFIG */
+#endif /* BSP_USING_I2C3 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__I2C_CONFIG_H__
diff --git a/bsp/tm4c123bsp/libraries/Drivers/drv_i2c.c b/bsp/tm4c123bsp/libraries/Drivers/drv_i2c.c
new file mode 100644
index 0000000000..066e16fa22
--- /dev/null
+++ b/bsp/tm4c123bsp/libraries/Drivers/drv_i2c.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2006-2024, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2024-01-20 wirano first version
+ */
+
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rtdbg.h>
+
+#ifdef BSP_USING_I2C
+
+#if defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3)
+
+#include "drv_i2c.h"
+#include "inc/hw_memmap.h"
+#include <stdbool.h>
+#include "i2c_config.h"
+#include "driverlib/rom.h"
+#include "driverlib/sysctl.h"
+#include "driverlib/pin_map.h"
+#include "driverlib/gpio.h"
+#include "driverlib/i2c.h"
+
+enum {
+#ifdef BSP_USING_I2C0
+ I2C0_INDEX,
+#endif
+#ifdef BSP_USING_I2C1
+ I2C1_INDEX,
+#endif
+#ifdef BSP_USING_I2C2
+ I2C2_INDEX,
+#endif
+#ifdef BSP_USING_I2C3
+ I2C3_INDEX,
+#endif
+};
+
+static struct tm4c123_i2c tm4c123_i2cs[] =
+ {
+#ifdef BSP_USING_I2C0
+ I2C0_BUS_CONFIG,
+#endif
+
+#ifdef BSP_USING_I2C1
+ I2C1_BUS_CONFIG,
+#endif
+
+#ifdef BSP_USING_I2C2
+ I2C2_BUS_CONFIG,
+#endif
+
+#ifdef BSP_USING_I2C3
+ I2C3_BUS_CONFIG,
+#endif
+ };
+
+
+static rt_ssize_t tm4c123_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num);
+
+
+struct rt_i2c_bus_device_ops tm4c123_i2c_ops =
+ {
+ tm4c123_i2c_xfer,
+ RT_NULL,
+ RT_NULL
+ };
+
+
+static rt_ssize_t tm4c123_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) {
+ RT_ASSERT(bus != RT_NULL);
+ RT_ASSERT(msgs != RT_NULL);
+
+ struct rt_i2c_msg *msg;
+ struct tm4c123_i2c *i2c_info = (struct tm4c123_i2c *) bus;
+
+ rt_err_t ret = -RT_ERROR;
+ rt_uint32_t i;
+
+ for (i = 0; i < num; i++) {
+ msg = &msgs[i];
+
+ if (msg->flags & RT_I2C_ADDR_10BIT) {
+ LOG_E("does not support 10bits address!\n");
+ }
+
+ if (msg->flags & RT_I2C_RD) {
+ rt_uint8_t *data = msg->buf;
+
+ ROM_I2CMasterSlaveAddrSet(i2c_info->base, msg->addr, true);
+
+ if (msg->flags & RT_I2C_NO_START) {
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ *data = ROM_I2CMasterDataGet(i2c_info->base);
+ } else {
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_START);
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ *data = ROM_I2CMasterDataGet(i2c_info->base);
+ }
+
+ if (msg->len > 1) {
+ data++;
+
+ for (int j = 1; j < msg->len - 1; ++j) {
+
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ *data = ROM_I2CMasterDataGet(i2c_info->base);
+ data++;
+ }
+
+ if (msg->flags & RT_I2C_NO_STOP) {
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ *data = ROM_I2CMasterDataGet(i2c_info->base);
+ } else {
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ *data = ROM_I2CMasterDataGet(i2c_info->base);
+ }
+ }
+ } else {
+ rt_uint8_t *data = msg->buf;
+
+ ROM_I2CMasterSlaveAddrSet(i2c_info->base, msg->addr, false);
+
+ // use single send when data len = 1
+ if (msg->len == 1) {
+ if (msg->flags & RT_I2C_NO_START) {
+ ROM_I2CMasterDataPut(i2c_info->base, *data);
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
+ } else if (msg->flags & RT_I2C_NO_STOP) {
+ ROM_I2CMasterDataPut(i2c_info->base, *data);
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
+ } else {
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_SINGLE_SEND);
+ ROM_I2CMasterDataPut(i2c_info->base, *data);
+ }
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ // otherwise use burst send
+ } else {
+ if (msg->flags & RT_I2C_NO_START) {
+ ROM_I2CMasterDataPut(i2c_info->base, *data);
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ } else {
+ ROM_I2CMasterDataPut(i2c_info->base, *data);
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_START);
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ }
+
+ data++;
+
+ for (int j = 1; j < msg->len - 1; ++j) {
+ ROM_I2CMasterDataPut(i2c_info->base, *data);
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ data++;
+ }
+
+ if (msg->flags & RT_I2C_NO_STOP) {
+ ROM_I2CMasterDataPut(i2c_info->base, *data);
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_CONT);
+ } else {
+ ROM_I2CMasterDataPut(i2c_info->base, *data);
+ ROM_I2CMasterControl(i2c_info->base, I2C_MASTER_CMD_BURST_SEND_FINISH);
+ }
+ while (ROM_I2CMasterBusy(i2c_info->base));
+ }
+
+ }
+ }
+ ret = i;
+ return ret;
+}
+
+int rt_hw_i2c_init(void) {
+ rt_err_t ret = RT_EOK;
+
+ for (uint32_t i = 0; i < sizeof(tm4c123_i2cs) / sizeof(tm4c123_i2cs[0]); i++) {
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
+
+ ROM_GPIOPinConfigure(GPIO_PB2_I2C0SCL);
+ ROM_GPIOPinConfigure(GPIO_PB3_I2C0SDA);
+
+ ROM_GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
+ ROM_GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
+
+ ROM_SysCtlPeripheralDisable(SYSCTL_PERIPH_I2C0);
+ ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
+ while (!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C0));
+
+ // timeout:5ms
+ ROM_I2CMasterTimeoutSet(I2C0_BASE, 0x7d);
+
+ if (tm4c123_i2cs[i].clk_freq == 400000) {
+ ROM_I2CMasterInitExpClk(tm4c123_i2cs[i].base, ROM_SysCtlClockGet(), RT_TRUE);
+ } else {
+ ROM_I2CMasterInitExpClk(tm4c123_i2cs[i].base, ROM_SysCtlClockGet(), RT_FALSE);
+ }
+ ROM_I2CMasterEnable(tm4c123_i2cs[i].base);
+
+ tm4c123_i2cs[i].bus.ops = &tm4c123_i2c_ops;
+ ret = rt_i2c_bus_device_register(&tm4c123_i2cs[i].bus, tm4c123_i2cs[i].bus_name);
+ if (ret != RT_EOK) {
+ LOG_E("rt i2c device %s register failed, status=%d\n", tm4c123_i2cs[i].bus_name, ret);
+ }
+ }
+
+ return ret;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_i2c_init);
+
+#endif /* BSP_USING_I2C1 || BSP_USING_I2C2 || BSP_USING_I2C3 || BSP_USING_I2C4 */
+
+#endif /* BSP_USING_I2C */
+
diff --git a/bsp/tm4c123bsp/libraries/Drivers/drv_i2c.h b/bsp/tm4c123bsp/libraries/Drivers/drv_i2c.h
new file mode 100644
index 0000000000..3f1883e73c
--- /dev/null
+++ b/bsp/tm4c123bsp/libraries/Drivers/drv_i2c.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2006-2024, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2024-01-20 wirano first version
+ */
+
+#ifndef __DRV_I2C_H__
+#define __DRV_I2C_H__
+
+
+#include <stdint.h>
+#include <rtdevice.h>
+#include <rthw.h>
+
+
+struct tm4c123_i2c
+{
+ struct rt_i2c_bus_device bus;
+ uint32_t base;
+ char *bus_name;
+ uint32_t clk_freq;
+};
+
+int rt_hw_i2c_init(void);
+
+#endif /* __DRV_I2C_H__ */
+
diff --git a/bsp/tm4c123bsp/libraries/TivaWare_C_series/SConscript b/bsp/tm4c123bsp/libraries/TivaWare_C_series/SConscript
index bd6ba1b1cf..6bd89e4889 100644
--- a/bsp/tm4c123bsp/libraries/TivaWare_C_series/SConscript
+++ b/bsp/tm4c123bsp/libraries/TivaWare_C_series/SConscript
@@ -20,7 +20,8 @@ tm4c123_driverlib/src/gpio.c
if GetDepend(['RT_USING_SERIAL']):
src += ['tm4c123_driverlib/src/uart.c']
-#if GetDepend(['RT_USING_I2C']):
+if GetDepend(['RT_USING_I2C']):
+ src += ['tm4c123_driverlib/src/i2c.c']
if GetDepend(['RT_USING_SPI']):