summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author褚仕成 <[email protected]>2023-01-18 14:55:00 +0800
committerMan, Jianting (Meco) <[email protected]>2023-01-19 21:41:53 -0500
commit61631c393ea6bb1dd9a025fc6d4cfca6037f9425 (patch)
tree9c5442f8b23786c3dacf7ff09b2a7dbd797eabb0
parent65adce2989e73cb47d8f751ae8792004f50c4ace (diff)
[bsp/bl808] add: drv_i2c
-rw-r--r--bsp/bl808/README.md1
-rw-r--r--bsp/bl808/m0/drivers/Kconfig17
-rw-r--r--bsp/bl808/m0/drivers/SConscript6
-rw-r--r--bsp/bl808/m0/drivers/board.c6
-rw-r--r--bsp/bl808/m0/drivers/drv_i2c.c186
-rw-r--r--bsp/bl808/m0/drivers/drv_i2c.h43
6 files changed, 256 insertions, 3 deletions
diff --git a/bsp/bl808/README.md b/bsp/bl808/README.md
index 0007f508f3..9a609207ec 100644
--- a/bsp/bl808/README.md
+++ b/bsp/bl808/README.md
@@ -100,6 +100,7 @@ Windows下推荐使用[env工具][1],在console下进入bsp/bl808目录中,�
| ------ | ---- | :------: |
| UART | 支持 | UART0,用于shell,默认波特率2000000 |
| GPIO | 支持 | |
+| I2C | 支持 | 软件 I2C1,默认 SCL——20,SDA——21 |
## 5. 联系人信息
diff --git a/bsp/bl808/m0/drivers/Kconfig b/bsp/bl808/m0/drivers/Kconfig
index eca0033e7b..ac17b47215 100644
--- a/bsp/bl808/m0/drivers/Kconfig
+++ b/bsp/bl808/m0/drivers/Kconfig
@@ -18,6 +18,23 @@ menu "On-chip Peripheral Drivers"
select RT_USING_PIN
default y
+ menuconfig BSP_USING_I2C1
+ bool "Enable I2C1 BUS (software simulation)"
+ 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 33
+ default 20
+ config BSP_I2C1_SDA_PIN
+ int "I2C1 sda pin number"
+ range 0 33
+ default 21
+ endif
+
menuconfig BSP_USING_UART
bool "Enable UART"
default y
diff --git a/bsp/bl808/m0/drivers/SConscript b/bsp/bl808/m0/drivers/SConscript
index 503dd50f4c..3cd7a608dd 100644
--- a/bsp/bl808/m0/drivers/SConscript
+++ b/bsp/bl808/m0/drivers/SConscript
@@ -18,6 +18,9 @@ if GetDepend(['RT_USING_SERIAL']):
if GetDepend('RT_USING_PIN'):
src += ['drv_gpio.c']
+if GetDepend('RT_USING_I2C'):
+ src += ['drv_i2c.c']
+
# if GetDepend('BSP_USING_LCD'):
# src += ['drv_lcd.c']
# src += ['drv_mpylcd.c']
@@ -28,9 +31,6 @@ if GetDepend('RT_USING_PIN'):
# if GetDepend('RT_USING_CPUTIME'):
# src += ['drv_cputime.c']
-# if GetDepend('RT_USING_I2C'):
-# src += ['drv_i2c.c']
-
# if GetDepend('RT_USING_SPI'):
# src += ['drv_spi.c']
diff --git a/bsp/bl808/m0/drivers/board.c b/bsp/bl808/m0/drivers/board.c
index 525488eaec..a5c823ac8d 100644
--- a/bsp/bl808/m0/drivers/board.c
+++ b/bsp/bl808/m0/drivers/board.c
@@ -6,6 +6,7 @@
* Change Logs:
* Date Author Notes
* 2022/12/25 flyingcys first version
+ * 2023/01/17 chushicheng add pin and i2c
*/
#include <rthw.h>
#include <rtthread.h>
@@ -81,6 +82,11 @@ void rt_hw_board_init(void)
rt_hw_pin_init();
#endif
+ /* I2C driver initialization is open by default */
+#ifdef RT_USING_I2C
+ rt_hw_i2c_init();
+#endif
+
/* UART driver initialization is open by default */
#ifdef RT_USING_SERIAL
rt_hw_uart_init();
diff --git a/bsp/bl808/m0/drivers/drv_i2c.c b/bsp/bl808/m0/drivers/drv_i2c.c
new file mode 100644
index 0000000000..b69c6e623f
--- /dev/null
+++ b/bsp/bl808/m0/drivers/drv_i2c.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023/01/17 chushicheng first version
+ */
+
+#include <board.h>
+#include "drv_i2c.h"
+#include "bl808_common.h"
+
+#ifdef RT_USING_I2C
+
+#define DBG_TAG "drv.i2c"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#if !defined(BSP_USING_I2C1)
+#error "Please define at least one BSP_USING_I2Cx"
+/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
+#endif
+
+static const struct bl808_soft_i2c_config soft_i2c_config[] =
+{
+#ifdef BSP_USING_I2C1
+ I2C1_BUS_CONFIG,
+#endif
+};
+
+static struct bl808_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])];
+
+/**
+ * This function initializes the i2c pin.
+ *
+ * @param bl808 i2c dirver class.
+ */
+static void bl808_i2c_gpio_init(struct bl808_i2c *i2c)
+{
+ struct bl808_soft_i2c_config* cfg = (struct bl808_soft_i2c_config*)i2c->ops.data;
+
+ rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD);
+ rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD);
+
+ rt_pin_write(cfg->scl, PIN_HIGH);
+ rt_pin_write(cfg->sda, PIN_HIGH);
+}
+
+/**
+ * This function sets the sda pin.
+ *
+ * @param bl808 config class.
+ * @param The sda pin state.
+ */
+static void bl808_set_sda(void *data, rt_int32_t state)
+{
+ struct bl808_soft_i2c_config* cfg = (struct bl808_soft_i2c_config*)data;
+ if (state)
+ {
+ rt_pin_write(cfg->sda, PIN_HIGH);
+ }
+ else
+ {
+ rt_pin_write(cfg->sda, PIN_LOW);
+ }
+}
+
+/**
+ * This function sets the scl pin.
+ *
+ * @param bl808 config class.
+ * @param The scl pin state.
+ */
+static void bl808_set_scl(void *data, rt_int32_t state)
+{
+ struct bl808_soft_i2c_config* cfg = (struct bl808_soft_i2c_config*)data;
+ if (state)
+ {
+ rt_pin_write(cfg->scl, PIN_HIGH);
+ }
+ else
+ {
+ rt_pin_write(cfg->scl, PIN_LOW);
+ }
+}
+
+/**
+ * This function gets the sda pin state.
+ *
+ * @param The sda pin state.
+ */
+static rt_int32_t bl808_get_sda(void *data)
+{
+ struct bl808_soft_i2c_config* cfg = (struct bl808_soft_i2c_config*)data;
+ return rt_pin_read(cfg->sda);
+}
+
+/**
+ * This function gets the scl pin state.
+ *
+ * @param The scl pin state.
+ */
+static rt_int32_t bl808_get_scl(void *data)
+{
+ struct bl808_soft_i2c_config* cfg = (struct bl808_soft_i2c_config*)data;
+ return rt_pin_read(cfg->scl);
+}
+/**
+ * The time delay function.
+ *
+ * @param microseconds.
+ */
+static void bl808_udelay(rt_uint32_t us)
+{
+ arch_delay_us(us);
+}
+
+static const struct rt_i2c_bit_ops bl808_bit_ops_default =
+{
+ .data = RT_NULL,
+ .set_sda = bl808_set_sda,
+ .set_scl = bl808_set_scl,
+ .get_sda = bl808_get_sda,
+ .get_scl = bl808_get_scl,
+ .udelay = bl808_udelay,
+ .delay_us = 1,
+ .timeout = 100
+};
+
+/**
+ * if i2c is locked, this function will unlock it
+ *
+ * @param bl808 config class
+ *
+ * @return RT_EOK indicates successful unlock.
+ */
+static rt_err_t bl808_i2c_bus_unlock(const struct bl808_soft_i2c_config *cfg)
+{
+ rt_int32_t i = 0;
+
+ if (PIN_LOW == rt_pin_read(cfg->sda))
+ {
+ while (i++ < 9)
+ {
+ rt_pin_write(cfg->scl, PIN_HIGH);
+ bl808_udelay(100);
+ rt_pin_write(cfg->scl, PIN_LOW);
+ bl808_udelay(100);
+ }
+ }
+ if (PIN_LOW == rt_pin_read(cfg->sda))
+ {
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+/* I2C initialization function */
+int rt_hw_i2c_init(void)
+{
+ rt_err_t result;
+
+ for (rt_size_t i = 0; i < sizeof(i2c_obj) / sizeof(struct bl808_i2c); i++)
+ {
+ i2c_obj[i].ops = bl808_bit_ops_default;
+ i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
+ i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
+ bl808_i2c_gpio_init(&i2c_obj[i]);
+ result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name);
+ RT_ASSERT(result == RT_EOK);
+ bl808_i2c_bus_unlock(&soft_i2c_config[i]);
+
+ LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
+ soft_i2c_config[i].bus_name,
+ soft_i2c_config[i].scl,
+ soft_i2c_config[i].sda);
+ }
+
+ return RT_EOK;
+}
+INIT_BOARD_EXPORT(rt_hw_i2c_init);
+
+#endif /* RT_USING_I2C */
diff --git a/bsp/bl808/m0/drivers/drv_i2c.h b/bsp/bl808/m0/drivers/drv_i2c.h
new file mode 100644
index 0000000000..4add722a00
--- /dev/null
+++ b/bsp/bl808/m0/drivers/drv_i2c.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2023/01/17 chushicheng first version
+ */
+
+#ifndef __DRV_I2C__
+#define __DRV_I2C__
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+
+/* bl808 config class */
+struct bl808_soft_i2c_config
+{
+ rt_uint8_t scl;
+ rt_uint8_t sda;
+ const char *bus_name;
+};
+/* bl808 i2c dirver class */
+struct bl808_i2c
+{
+ struct rt_i2c_bit_ops ops;
+ struct rt_i2c_bus_device i2c2_bus;
+};
+
+#ifdef BSP_USING_I2C1
+#define I2C1_BUS_CONFIG \
+ { \
+ .scl = BSP_I2C1_SCL_PIN, \
+ .sda = BSP_I2C1_SDA_PIN, \
+ .bus_name = "i2c1", \
+ }
+#endif
+
+int rt_hw_i2c_init(void);
+
+#endif