123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- /*
- * File : drv_i2c.c
- * This file is part of gkipc BSP for RT-Thread distribution.
- *
- * Copyright (c) 2016 Shanghai goke Microelectronics Co., Ltd.
- * All rights reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Visit http://www.goke.com to get contact with Fullhan.
- *
- * Change Logs:
- * Date Author Notes
- */
- #include <rtdevice.h>
- #include <rthw.h>
- #include "drv_i2c.h"
- #include "gtypes.h"
- #include "platform.h"
- #include "gd_i2c.h"
- /*---------------------------------------------------------------------------*/
- /* local defines */
- /*---------------------------------------------------------------------------*/
- //#define GK_I2C_DEBUG
- #ifndef GK_I2C_DEBUG
- #define I2C_PRINT_DBG(fmt, args...)
- #define I2C_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
- #else
- #define I2C_PRINT_DBG(fmt, args...) rt_kprintf(fmt, ##args);
- #define I2C_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
- #endif
- //*****************************************************************************
- //*****************************************************************************
- //** Local structures
- //*****************************************************************************
- //*****************************************************************************
- //*****************************************************************************
- //*****************************************************************************
- //** Global Data
- //*****************************************************************************
- //*****************************************************************************
- //*****************************************************************************
- //*****************************************************************************
- //** Local Data
- //*****************************************************************************
- //*****************************************************************************
- //*****************************************************************************
- //*****************************************************************************
- //** Local Functions Declaration
- //*****************************************************************************
- //*****************************************************************************
- //*****************************************************************************
- //*****************************************************************************
- //** Local Functions
- //*****************************************************************************
- //*****************************************************************************
- static int gk_i2c_init(struct gk_i2c_obj *i2c_obj)
- {
- int ret = RT_EOK;
- ret = GD_I2C_Init((GD_I2C_INIT_PARAMS_S*)&i2c_obj->config.i2cInitParams);
- return ret;
- }
- static rt_size_t gk_i2c_xfer(struct rt_i2c_bus_device *dev,
- struct rt_i2c_msg msgs[], rt_uint32_t num)
- {
- int ret;
- U8 address = 0;
- U8* buffer = NULL;
- U8* regbuffer = NULL;
- U32 regbytes = 0;
- U32 bytes = 0;
- struct gk_i2c_obj *i2c_obj = (struct gk_i2c_obj *)dev->priv;
- if (num < 2)
- {
- if (msgs[0].flags == RT_I2C_WR)
- {
- address = msgs[0].addr;
- buffer = msgs[0].buf;
- bytes = msgs[0].len;
- ret = GD_I2C_Write( (GD_HANDLE *)&i2c_obj->handle,address,buffer,bytes );
- if (ret != RT_EOK)
- {
- I2C_PRINT_ERR("[%s:%d]I2C Write error!\n",__func__,__LINE__);
- return RT_ERROR;
- }
- }
- }
- else
- {
- if ((msgs[0].flags == RT_I2C_WR) && (msgs[1].flags == RT_I2C_RD))
- {
- address = msgs[0].addr;
- regbuffer = msgs[0].buf;
- regbytes = msgs[0].len;
- buffer = msgs[1].buf;
- bytes = msgs[1].len;
- }
- else if ((msgs[0].flags == RT_I2C_RD ) && (msgs[1].flags == RT_I2C_WR))
- {
- address = msgs[1].addr;
- regbuffer = msgs[1].buf;
- regbytes = msgs[1].len;
- buffer = msgs[0].buf;
- bytes = msgs[0].len;
- }
- ret = GD_I2C_Read( (GD_HANDLE *)&i2c_obj->handle,(U8)address, (U8*)regbuffer,(U32)regbytes,(U8*) buffer, (U32)bytes );
- if (ret != RT_EOK)
- {
- I2C_PRINT_ERR("[%s:%d]I2C_Read error!\n",__func__,__LINE__);
- return RT_ERROR;
- }
- }
- return ret;
- }
- static const struct rt_i2c_bus_device_ops gk_i2c_ops = {
- .master_xfer = gk_i2c_xfer,
- };
- int gk_i2c_probe(void *priv_data)
- {
- int ret;
- struct rt_i2c_bus_device *i2c_bus_dev;
- struct gk_i2c_obj *i2c_obj = (struct gk_i2c_obj *)priv_data;
- char i2c_dev_name[5] = {0};
- i2c_bus_dev = (struct rt_i2c_bus_device *)rt_malloc(sizeof(struct rt_i2c_bus_device));
- rt_memset(i2c_bus_dev, 0, sizeof(struct rt_i2c_bus_device));
- i2c_bus_dev->ops = &gk_i2c_ops;
- rt_sprintf(i2c_dev_name, "%s%d", "i2c", i2c_obj->id);
- ret = rt_i2c_bus_device_register(i2c_bus_dev, i2c_dev_name);
- if (ret != RT_EOK)
- {
- I2C_PRINT_ERR("ERROR:rt_spi_bus_register failed, ret=%d\n", ret);
- return -RT_ENOMEM;
- }
- // priv struct init
- i2c_obj->lock = rt_mutex_create("i2c_mux", RT_IPC_FLAG_FIFO);
- gk_i2c_init(i2c_obj);
- return ret;
- }
- int gk_i2c_exit(void *priv_data)
- {
- struct gk_i2c_obj *i2c_obj = (struct gk_i2c_obj *)priv_data;
- GD_I2C_Close((GD_HANDLE *)&i2c_obj->handle);
- GD_I2C_Exit();
- return 0;
- }
- struct gk_platform_driver i2c_driver_ops = {
- .name = "i2c", .probe = gk_i2c_probe, .remove = gk_i2c_exit,
- };
- void rt_hw_i2c_init(void)
- {
- I2C_PRINT_DBG("%s start\n", __func__);
- gk_platform_driver_init(&i2c_driver_ops);
- I2C_PRINT_DBG("%s end\n", __func__);
- // fixme: never release?
- }
- //#define GK_TEST_I2C
- #ifdef GK_TEST_I2C
- static rt_err_t gk_i2c_test_read_reg(struct rt_i2c_bus_device *gk_i2c,
- rt_uint16_t reg, rt_uint8_t *data)
- {
- struct rt_i2c_msg msg[2];
- rt_uint8_t send_buf[2];
- rt_uint8_t recv_buf[1] = {0};
- I2C_PRINT_DBG("%s start\n", __func__);
- send_buf[0] = (reg & 0xFF);
- msg[0].addr = 0x51;
- msg[0].flags = RT_I2C_WR;
- msg[0].len = 1;
- msg[0].buf = send_buf;
- msg[1].addr = 0x51;
- msg[1].flags = RT_I2C_RD;
- msg[1].len = 1;
- msg[1].buf = recv_buf;
- rt_i2c_transfer(gk_i2c, msg, 2);
- *data = recv_buf[0];
- return RT_EOK;
- }
- static rt_err_t gk_i2c_test_write_reg(struct rt_i2c_bus_device *gk_i2c,
- rt_uint16_t reg, rt_uint8_t data)
- {
- struct rt_i2c_msg msg;
- rt_uint8_t send_buf[3];
- I2C_PRINT_DBG("%s start\n", __func__);
- // send_buf[0] = ((reg >> 8) & 0xff);
- send_buf[1] = (reg & 0xFF);
- send_buf[2] = data;
- msg.addr = 0x51;
- msg.flags = RT_I2C_WR;
- msg.len = 2;
- msg.buf = send_buf;
- rt_i2c_transfer(gk_i2c, &msg, 1);
- I2C_PRINT_DBG("%s end\n", __func__);
- return RT_EOK;
- }
- void i2c_test_sensor()
- {
- struct rt_i2c_bus_device *gk_i2c;
- gk_i2c_obj_s i2c_obj;
- rt_uint8_t data[1] = {0x00};
- int ret = 0;
- gk_i2c = rt_i2c_bus_device_find("i2c1");
- GD_I2C_OPEN_PARAMS_S i2c_param;
- i2c_param.channel = GADI_I2C_CHANNEL_ONE;
- i2c_param.speed = GADI_I2C_100KBPS;
- i2c_param.mode = GADI_I2C_INTERRUPT;//GADI_I2C_NORMAL;
- i2c_obj.handle = 0;
- ret = GD_I2C_Open((GD_I2C_OPEN_PARAMS_S*)&i2c_param, &i2c_obj.handle);
- if (ret != 0)
- {
- I2C_PRINT_DBG("GD_I2C_Open error!\n");
- return -1;
- }
- gk_i2c.priv = &i2c_obj;
- gk_i2c_test_write_reg(gk_i2c, 0x04, 0x02);
- gk_i2c_test_read_reg(gk_i2c, 0x02, data);
- I2C_PRINT_DBG("data read from 0x3038 is 0x%x\r\n", data[0]);
- I2C_PRINT_DBG("%s end\n", __func__);
- }
- #ifdef RT_USING_FINSH
- #include <finsh.h>
- FINSH_FUNCTION_EXPORT(i2c_test_sensor, sensor i2c test);
- #endif
- #endif /*GK_TEST_I2C end*/
|