123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /*
- * Copyright (c) 2006-2022, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2021-08-10 charlown first version
- */
- #include <rtthread.h>
- #include <rtdevice.h>
- #include <rthw.h>
- #include "board.h"
- #include "drv_hwi2c.h"
- #ifdef BSP_USING_HWI2C
- #define LOG_TAG "drv.hwi2c"
- #include "drv_log.h"
- #define TIMEOUT 0x0FF
- struct i2c_bus_device
- {
- struct rt_i2c_bus_device parent;
- I2C_TypeDef *periph;
- };
- #ifdef BSP_USING_HWI2C1
- struct i2c_bus_device i2c_bus1;
- #endif
- #ifdef BSP_USING_HWI2C2
- struct i2c_bus_device i2c_bus2;
- #endif
- static int ch32f1_i2c_read(I2C_TypeDef *i2c_periph,
- rt_uint8_t flags,
- rt_uint16_t slave_address,
- rt_uint8_t *p_buffer,
- rt_uint16_t data_byte)
- {
- rt_uint32_t try;
- if (flags & RT_I2C_ADDR_10BIT)
- {
- //fixme
- }
- else
- {
- //7 bit address
- try = 0;
- while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY) != RESET)
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus read getflag timeout! \n");
- return -1;
- }
- try++;
- };
- I2C_GenerateSTART(i2c_periph, ENABLE);
- try = 0;
- while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT))
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus read checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- I2C_Send7bitAddress(i2c_periph, (slave_address << 1), I2C_Direction_Transmitter);
- try = 0;
- while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus read checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- I2C_GenerateSTART(i2c_periph, ENABLE);
- try = 0;
- while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT))
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus read checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- I2C_Send7bitAddress(i2c_periph, (slave_address << 1), I2C_Direction_Receiver);
- try = 0;
- while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus read checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- if (data_byte == 1)
- {
- try = 0;
- while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_RXNE) == RESET)
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus read checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- I2C_AcknowledgeConfig(i2c_periph, DISABLE);
- *p_buffer = I2C_ReceiveData(i2c_periph);
- I2C_GenerateSTOP(i2c_periph, ENABLE);
- }
- else
- {
- try = 0;
- while (data_byte)
- {
- if (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_RXNE) == RESET)
- {
- *p_buffer = I2C_ReceiveData(i2c_periph);
- p_buffer++;
- data_byte--;
- try = 0;
- if (data_byte == 1)
- {
- I2C_AcknowledgeConfig(i2c_periph, DISABLE);
- I2C_GenerateSTOP(i2c_periph, ENABLE);
- }
- }
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus read checkevent timeout! \n");
- return -1;
- }
- try++;
- }
- }
- }
- return 0;
- }
- static int ch32f1_i2c_write(I2C_TypeDef *i2c_periph,
- rt_uint8_t flags,
- rt_uint16_t slave_address,
- rt_uint8_t *p_buffer,
- rt_uint16_t data_byte)
- {
- rt_uint32_t try;
- if (flags & RT_I2C_ADDR_10BIT)
- {
- //fixme
- }
- else
- {
- //7 bit address
- try = 0;
- while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY) != RESET)
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus write getflag timeout! \n");
- return -1;
- }
- try++;
- };
- I2C_GenerateSTART(i2c_periph, ENABLE);
- try = 0;
- while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT))
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus write checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- I2C_Send7bitAddress(i2c_periph, (slave_address << 1), I2C_Direction_Transmitter);
- try = 0;
- while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus write checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- I2C_GenerateSTART(i2c_periph, ENABLE);
- try = 0;
- while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT))
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus write checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- I2C_Send7bitAddress(i2c_periph, (slave_address << 1), I2C_Direction_Transmitter);
- try = 0;
- while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus write checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- try = 0;
- while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_TXE) == RESET)
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus write checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- while (data_byte)
- {
- I2C_SendData(i2c_periph, *p_buffer);
- p_buffer++;
- data_byte--;
- try = 0;
- while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
- {
- if (try == TIMEOUT)
- {
- LOG_E("i2c bus write checkevent timeout! \n");
- return -1;
- }
- try++;
- };
- }
- I2C_GenerateSTOP(i2c_periph, ENABLE);
- }
- return 0;
- }
- static rt_size_t ch32f1_master_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
- {
- struct rt_i2c_msg *msg;
- struct i2c_bus_device *i2c_bus_dev;
- rt_uint32_t index;
- i2c_bus_dev = (struct i2c_bus_device *)bus;
- for (index = 0; index < num; index++)
- {
- msg = &msgs[index];
- if (msg->flags & RT_I2C_RD)
- {
- if (ch32f1_i2c_read(i2c_bus_dev->periph, msg->flags, msg->addr, msg->buf, msg->len) != 0)
- {
- LOG_E("i2c bus write failed,i2c bus stop!");
- return 0;
- }
- }
- else
- {
- if (ch32f1_i2c_write(i2c_bus_dev->periph, msg->flags, msg->addr, msg->buf, msg->len) != 0)
- {
- LOG_E("i2c bus write failed,i2c bus stop!");
- return 0;
- }
- }
- }
- return index;
- }
- const struct rt_i2c_bus_device_ops ch32f1_i2c_ops = {
- .master_xfer = ch32f1_master_xfer,
- .slave_xfer = RT_NULL,
- .i2c_bus_control = RT_NULL,
- };
- int rt_hw_i2c_init(void)
- {
- int result = RT_EOK;
- #ifdef BSP_USING_HWI2C1
- i2c_bus1.periph = I2C1;
- ch32f1_i2c_clock_and_io_init(i2c_bus1.periph);
- ch32f1_i2c_config(i2c_bus1.periph);
- i2c_bus1.parent.ops = &ch32f1_i2c_ops;
- result = rt_i2c_bus_device_register(&i2c_bus1.parent, "hwi2c1");
- if (result != RT_EOK)
- {
- return result;
- }
- #endif
- #ifdef BSP_USING_HWI2C2
- i2c_bus2.periph = I2C2;
- ch32f1_i2c_clock_and_io_init(i2c_bus2.periph);
- ch32f1_i2c_config(i2c_bus2.periph);
- i2c_bus2.parent.ops = &ch32f1_i2c_ops;
- rt_i2c_bus_device_register(&i2c_bus2.parent, "hwi2c2");
- if (result != RT_EOK)
- {
- return result;
- }
- #endif
- return RT_EOK;
- }
- INIT_DEVICE_EXPORT(rt_hw_i2c_init);
- #endif /* BSP_USING_HWI2C */
|