[bsp][ch32v307v]添加了硬件iic驱动
This commit is contained in:
parent
1bf8a460e7
commit
1ea7ddfa9a
|
@ -18,6 +18,9 @@ if GetDepend('SOC_RISCV_FAMILY_CH32'):
|
|||
if GetDepend('BSP_USING_DAC'):
|
||||
src += ['drv_dac.c']
|
||||
|
||||
if GetDepend('BSP_USING_I2C'):
|
||||
src += ['drv_i2c.c']
|
||||
|
||||
if GetDepend('BSP_USING_SOFT_I2C'):
|
||||
src += ['drv_soft_i2c.c']
|
||||
|
||||
|
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-4-1 IceBear003 the first version
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_i2c.h"
|
||||
|
||||
#ifdef BSP_USING_HWI2C
|
||||
|
||||
#define LOG_TAG "drv.hwi2c"
|
||||
#include "drv_log.h"
|
||||
|
||||
#if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2)
|
||||
#error "Please define at least one BSP_USING_I2Cx"
|
||||
/* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
|
||||
#endif
|
||||
|
||||
#define TIMEOUT 0xFF
|
||||
|
||||
#ifdef BSP_USING_I2C1
|
||||
struct i2c_bus_device i2c_bus1;
|
||||
#endif
|
||||
#ifdef BSP_USING_I2C2
|
||||
struct i2c_bus_device i2c_bus2;
|
||||
#endif
|
||||
|
||||
static int i2c_read(I2C_TypeDef *i2c_periph,
|
||||
rt_uint16_t addr,
|
||||
rt_uint8_t flags,
|
||||
rt_uint16_t len,
|
||||
rt_uint8_t *buf)
|
||||
{
|
||||
rt_uint16_t try = 0;
|
||||
while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY))
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
I2C_GenerateSTART(i2c_periph, ENABLE);
|
||||
|
||||
try = 0;
|
||||
while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT)) //EVT5
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
if(flags & RT_I2C_ADDR_10BIT) //10-bit address mode
|
||||
{
|
||||
rt_uint8_t frame_head = 0xF0 + (addr >> 8) << 1; //11110XX0
|
||||
I2C_SendData(i2c_periph, frame_head); //FrameHead
|
||||
|
||||
try = 0;
|
||||
while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_ADDRESS10)) //EVT9
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
I2C_SendData(i2c_periph,0xff & addr);
|
||||
|
||||
try = 0;
|
||||
while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //EVT6
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
I2C_GenerateSTART(i2c_periph, ENABLE); //Sr
|
||||
|
||||
try = 0;
|
||||
while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT)) //EVT5
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
I2C_SendData(i2c_periph,frame_head); //Resend FrameHead
|
||||
}
|
||||
else
|
||||
{
|
||||
I2C_Send7bitAddress(i2c_periph, addr << 1, I2C_Direction_Receiver);
|
||||
}
|
||||
|
||||
try = 0;
|
||||
while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) //EVT6
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
while(len-- > 0)
|
||||
{
|
||||
|
||||
try = 0;
|
||||
while (!I2C_GetFlagStatus(i2c_periph, I2C_FLAG_RXNE)) //Got ACK For the Last Byte
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
*(buf++)=I2C_ReceiveData(i2c_periph);
|
||||
}
|
||||
|
||||
I2C_GenerateSTOP(i2c_periph, ENABLE);
|
||||
}
|
||||
|
||||
static int i2c_write(I2C_TypeDef *i2c_periph,
|
||||
rt_uint16_t addr,
|
||||
rt_uint8_t flags,
|
||||
rt_uint8_t *buf,
|
||||
rt_uint16_t len)
|
||||
{
|
||||
rt_uint16_t try = 0;
|
||||
while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY))
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
I2C_GenerateSTART(i2c_periph, ENABLE);
|
||||
|
||||
try = 0;
|
||||
while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT)) //EVT5
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
if(flags & RT_I2C_ADDR_10BIT) //10-bit address mode
|
||||
{
|
||||
I2C_SendData(i2c_periph,0xF0 + (addr >> 8) << 1); //FrameHead 11110XX0
|
||||
|
||||
try = 0;
|
||||
while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_ADDRESS10)) //EVT9
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
I2C_SendData(i2c_periph,0xff & addr);
|
||||
}
|
||||
else //7-bit address mode
|
||||
{
|
||||
I2C_Send7bitAddress(i2c_periph, addr << 1, I2C_Direction_Transmitter);
|
||||
}
|
||||
|
||||
try = 0;
|
||||
while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //EVT6
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
//Missing Evt8_1 (No definition)
|
||||
|
||||
while(len-- > 0)
|
||||
{
|
||||
try = 0;
|
||||
while (!I2C_GetFlagStatus(i2c_periph, I2C_FLAG_TXE)) //Got ACK For the Last Byte
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
I2C_SendData(i2c_periph,*(buf++));
|
||||
}
|
||||
|
||||
try = 0;
|
||||
while(!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) //Last byte sent successfully
|
||||
if (try++ >= TIMEOUT) return -1;
|
||||
|
||||
I2C_GenerateSTOP(i2c_periph, ENABLE);
|
||||
}
|
||||
|
||||
rt_size_t i2c_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)
|
||||
{
|
||||
i2c_read(i2c_bus_dev->periph,
|
||||
msg->addr,
|
||||
msg->flags,
|
||||
msg->len,
|
||||
msg->buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
i2c_write(i2c_bus_dev->periph,
|
||||
msg->addr,
|
||||
msg->flags,
|
||||
msg->buf,
|
||||
msg->len);
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static const struct rt_i2c_bus_device_ops ch32_i2c_ops =
|
||||
{
|
||||
.master_xfer = i2c_master_xfer,
|
||||
.slave_xfer = RT_NULL, //Not Used in i2c_core?
|
||||
.i2c_bus_control = RT_NULL
|
||||
};
|
||||
|
||||
int rt_hw_i2c_init(struct i2c_config *config = &{5000, I2C_DutyCycle_2, 0, I2C_Ack_Disable, I2C_AcknowledgedAddress_7bit})
|
||||
{
|
||||
int result = RT_EOK;
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
|
||||
|
||||
I2C_InitTypeDef I2C_InitTSturcture = {0};
|
||||
I2C_StructInit(&I2C_InitTSturcture);
|
||||
I2C_InitTSturcture.I2C_ClockSpeed = config->clock_speed;
|
||||
I2C_InitTSturcture.I2C_DutyCycle = config->duty_cycle;
|
||||
I2C_InitTSturcture.I2C_OwnAddress1 = config->own_address;
|
||||
I2C_InitTSturcture.I2C_Ack = config->enable_ack ? I2C_Ack_Enable : I2C_Ack_Disable;
|
||||
I2C_InitTSturcture.I2C_AcknowledgedAddress = config->is_7_bit_address ? I2C_AcknowledgedAddress_7bit : I2C_AcknowledgedAddress_10bit;
|
||||
|
||||
|
||||
#ifdef BSP_USING_I2C1
|
||||
|
||||
i2c_bus1.periph = I2C1;
|
||||
|
||||
//Clock & IO Initialization
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
|
||||
|
||||
//I2C Initialization Config
|
||||
I2C_Init(I2C1, &I2C_InitTSturcture);
|
||||
I2C_Cmd(I2C1, ENABLE);
|
||||
|
||||
//Hook to RT-Thread
|
||||
i2c_bus1.parent.ops = &ch32_i2c_ops;
|
||||
result += rt_i2c_bus_device_register(&i2c_bus1.parent, "i2c1");
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_I2C2
|
||||
|
||||
i2c_bus2.periph = I2C2;
|
||||
|
||||
//Clock & IO Initialization
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
|
||||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
//I2C Initialization Config
|
||||
I2C_Init(I2C2, &I2C_InitTSturcture);
|
||||
I2C_Cmd(I2C2, ENABLE);
|
||||
|
||||
//Hook to RT-Thread
|
||||
i2c_bus2.parent.ops = &ch32_i2c_ops;
|
||||
result += rt_i2c_bus_device_register(&i2c_bus2.parent, "i2c2");
|
||||
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif //BSP_USING_HWI2C
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2024-4-1 IceBear003 the first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_I2C_H_
|
||||
#define __DRV_I2C_H_
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
struct i2c_bus_device
|
||||
{
|
||||
struct rt_i2c_bus_device parent;
|
||||
I2C_TypeDef *periph;
|
||||
};
|
||||
|
||||
struct i2c_config
|
||||
{
|
||||
rt_uint32_t clock_speed;
|
||||
uint16_t duty_cycle;
|
||||
uint16_t own_address;
|
||||
uint8_t enable_ack;
|
||||
uint8_t is_7_bit_address;
|
||||
};
|
||||
|
||||
struct i2c_config i2c_default_conf={5000, I2C_Mode_I2C, I2C_DutyCycle_2, 0, I2C_Ack_Disable, I2C_AcknowledgedAddress_7bit};
|
||||
|
||||
int rt_hw_i2c_init(struct i2c_config *config);
|
||||
|
||||
#endif
|
|
@ -121,6 +121,21 @@ menu "On-chip Peripheral Drivers"
|
|||
default n
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_I2C
|
||||
bool "Enable I2C"
|
||||
select RT_USING_I2C
|
||||
|
||||
if BSP_USING_I2C
|
||||
config BSP_USING_I2C1
|
||||
bool "Enable I2C1"
|
||||
default n
|
||||
|
||||
config BSP_USING_I2C2
|
||||
bool "Enable I2C2"
|
||||
default n
|
||||
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_SOFT_I2C
|
||||
bool "Enable I2C Bus"
|
||||
select RT_USING_I2C
|
||||
|
|
Loading…
Reference in New Issue