RT-Thread使用——I2C硬件驱动

前言

使用了RT-Thread一段时间了,总体感觉还不错,配置起来挺方便的,资料也挺齐全。但是有个很不爽的地方,I2C还是用软件模拟,太浪费cpu的资源了。捣鼓了几天,通过研究spi驱动框架,仿照着写了一个I2C硬件驱动文件。

  • 硬件:STM32F405RGT6芯片
  • RT-Thread版本:4.1.0(发行版)

RT-Thread SPI设备组成

在这里插入图片描述
RT-Thread配置使用SPI后,工程文件中会在DeviceDrivers分组中添加spi_core.c和spi_dev.c文件,在Drivers分组下会添加drv_spi.c文件。
spi_dev.c文件实现了对SPI的设备抽象操作,如设备初始化,打开,关闭,读,写等操作,spi_core.c文件实现的是对SPI的总线抽象操作,如总线注册,设备挂在,收发等操作。在这两个文件中,其实并不涉及到对SPI硬件本身的操作。对于SPI的硬件操作,是在drv_spi.c文件中实现的,包括硬件初始化,中断处理等,调用了HAL实现。

RT-Thread I2C总线设备组成

在这里插入图片描述
RT-Thread在配置使用I2C后,工程文件中会在DeviceDrivers分组中添加i2c_core.c、i2c_dev.c和i2c-bit-ops.c文件,在Drivers分组下会添加drv_soft_i2c.c文件。
与SPI类似的,i2c_dev.c文件实现了对SPI的设备抽象操作,如设备初始化,打开,关闭,读,写等操作,i2c_core.c文件实现的是对SPI的总线抽象操作,如总线注册,收发等操作。比起SPI设备,I2C总线设备的组件文件多了一个i2c-bit-ops.c,用来模拟i2c的时序。drv_soft_i2c.c文件实现的是硬件操作,即初始化gpio,配置i2c参数,初始化互斥锁等。
通过对比发现,I2C的总线设备框架和SPI设备框架基本一样,只是I2C多了一个实现模拟时序的i2c-bit-ops.c文件而已。因此,我们可以依样画葫芦,保留i2c_core.c和i2c_dev.c,重新写一个drv_i2c.c文件,用来调用HAL的I2C相关操作函数,以此来实现在RT-Thread上使用硬件I2C。

RT-Thread 硬件I2C实现

为了更方便地使用I2C,我把ENV跟I2C配置相关的文件修改了,并且添加了几个文件:

  • 在bsp\stm32\libraries\HAL_Drivers文件夹下添加两个文件
    在这里插入图片描述
    drv_i2c.h
#ifndef __DRV_I2C_H
#define __DRV_I2C_H

#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#include <drv_common.h>
#include "drv_dma.h"
#include <drivers/i2c.h>

struct stm32_i2c_config
{
   
    I2C_TypeDef *Instance;
    char *bus_name;
    struct dma_config *dma_rx, *dma_tx;
};

struct rt_i2c_configuration
{
   
  uint32_t ClockSpeed;       /*!< Specifies the clock frequency.
                                  This parameter must be set to a value lower than 400kHz */

  uint32_t DutyCycle;        /*!< Specifies the I2C fast mode duty cycle.
                                  This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */

  uint32_t OwnAddress1;      /*!< Specifies the first device own address.
                                  This parameter can be a 7-bit or 10-bit address. */

  uint32_t AddressingMode;   /*!< Specifies if 7-bit or 10-bit addressing mode is selected.
                                  This parameter can be a value of @ref I2C_addressing_mode */

  uint32_t DualAddressMode;  /*!< Specifies if dual addressing mode is selected.
                                  This parameter can be a value of @ref I2C_dual_addressing_mode */

  uint32_t OwnAddress2;      /*!< Specifies the second device own address if dual addressing mode is selected
                                  This parameter can be a 7-bit address. */

  uint32_t GeneralCallMode;  /*!< Specifies if general call mode is selected.
                                  This parameter can be a value of @ref I2C_general_call_addressing_mode */

  uint32_t NoStretchMode;    /*!< Specifies if nostretch mode is selected.
                                  This parameter can be a value of @ref I2C_nostretch_mode */
};

/* stm32 i2c dirver class */
struct stm32_i2c
{
   
    I2C_HandleTypeDef handle;
    struct stm32_i2c_config *config;
    struct rt_i2c_configuration *cfg;

    struct
    {
   
        DMA_HandleTypeDef handle_rx;
        DMA_HandleTypeDef handle_tx;
    } dma;
    
    rt_uint8_t i2c_dma_flag;
    struct rt_i2c_bus_device i2c_bus;
};

int rt_hw_i2c_init(void);
rt_err_t rt_i2c_master_read(struct rt_i2c_bus_device *bus, uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值