| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 | 
							- /*
 
-  * Copyright (c) 2006-2018, RT-Thread Development Team
 
-  *
 
-  * SPDX-License-Identifier: Apache-2.0
 
-  *
 
-  * Change Logs:
 
-  * Date           Author       Notes
 
-  * 2018-11-08     balanceTWK   first version
 
-  */
 
- #include <board.h>
 
- #include "drv_soft_i2c.h"
 
- #include "drv_config.h"
 
- #ifdef RT_USING_I2C
 
- //#define DRV_DEBUG
 
- #define LOG_TAG              "drv.i2c"
 
- #include <drv_log.h>
 
- #if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4)
 
- #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 stm32_soft_i2c_config soft_i2c_config[] =
 
- {
 
- #ifdef BSP_USING_I2C1
 
-     I2C1_BUS_CONFIG,
 
- #endif
 
- #ifdef BSP_USING_I2C2
 
-     I2C2_BUS_CONFIG,
 
- #endif
 
- #ifdef BSP_USING_I2C3
 
-     I2C3_BUS_CONFIG,
 
- #endif
 
- #ifdef BSP_USING_I2C4
 
-     I2C4_BUS_CONFIG,
 
- #endif
 
- };
 
- static struct stm32_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])];
 
- /**
 
-  * This function initializes the i2c pin.
 
-  *
 
-  * @param Stm32 i2c dirver class.
 
-  */
 
- static void stm32_i2c_gpio_init(struct stm32_i2c *i2c)
 
- {
 
-     struct stm32_soft_i2c_config* cfg = (struct stm32_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 Stm32 config class.
 
-  * @param The sda pin state.
 
-  */
 
- static void stm32_set_sda(void *data, rt_int32_t state)
 
- {
 
-     struct stm32_soft_i2c_config* cfg = (struct stm32_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 Stm32 config class.
 
-  * @param The scl pin state.
 
-  */
 
- static void stm32_set_scl(void *data, rt_int32_t state)
 
- {
 
-     struct stm32_soft_i2c_config* cfg = (struct stm32_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 stm32_get_sda(void *data)
 
- {
 
-     struct stm32_soft_i2c_config* cfg = (struct stm32_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 stm32_get_scl(void *data)
 
- {
 
-     struct stm32_soft_i2c_config* cfg = (struct stm32_soft_i2c_config*)data;
 
-     return rt_pin_read(cfg->scl);
 
- }
 
- /**
 
-  * The time delay function.
 
-  *
 
-  * @param microseconds.
 
-  */
 
- static void stm32_udelay(rt_uint32_t us)
 
- {
 
-     rt_uint32_t ticks;
 
-     rt_uint32_t told, tnow, tcnt = 0;
 
-     rt_uint32_t reload = SysTick->LOAD;
 
-     ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
 
-     told = SysTick->VAL;
 
-     while (1)
 
-     {
 
-         tnow = SysTick->VAL;
 
-         if (tnow != told)
 
-         {
 
-             if (tnow < told)
 
-             {
 
-                 tcnt += told - tnow;
 
-             }
 
-             else
 
-             {
 
-                 tcnt += reload - tnow + told;
 
-             }
 
-             told = tnow;
 
-             if (tcnt >= ticks)
 
-             {
 
-                 break;
 
-             }
 
-         }
 
-     }
 
- }
 
- static const struct rt_i2c_bit_ops stm32_bit_ops_default =
 
- {
 
-     .data     = RT_NULL,
 
-     .set_sda  = stm32_set_sda,
 
-     .set_scl  = stm32_set_scl,
 
-     .get_sda  = stm32_get_sda,
 
-     .get_scl  = stm32_get_scl,
 
-     .udelay   = stm32_udelay,
 
-     .delay_us = 1,
 
-     .timeout  = 100
 
- };
 
- /**
 
-  * if i2c is locked, this function will unlock it
 
-  *
 
-  * @param stm32 config class
 
-  *
 
-  * @return RT_EOK indicates successful unlock.
 
-  */
 
- static rt_err_t stm32_i2c_bus_unlock(const struct stm32_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);
 
-             stm32_udelay(100);
 
-             rt_pin_write(cfg->scl, PIN_LOW);
 
-             stm32_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_size_t obj_num = sizeof(i2c_obj) / sizeof(struct stm32_i2c);
 
-     rt_err_t result;
 
-     for (int i = 0; i < obj_num; i++)
 
-     {
 
-         i2c_obj[i].ops = stm32_bit_ops_default;
 
-         i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
 
-         i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
 
-         stm32_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);
 
-         stm32_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 */
 
 
  |