ICC 和 SPI 的读写实例

项目背景

1. 上层需求是操作芯片(读写寄存器)
2. 操作方式使用IIC和SPI,直接读写文件节点(linux以及类linux环境下)

已知信息

1. BSP 提供了SPI和IIC的驱动节点(等同文件,打开,读写即可)
2. BSP 给定Slave address: 0x1c(7字节)

读写代码

ICC 操作实例

#include<linux/i2c.h>
#include<linux/i2c-dev.h>
#include<sys/ioctl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

static const char g_szIICNode[] = "/dev/i2c-5"; // the device file provided by BSP  
int g_devI2C5Fd = -1;	// the file node for writing and reading data

// init ICC device
void IIC_Initialize()
{

    g_devI2C5Fd = open(g_szIICNode,O_RDWR);
    if(g_devI2C5Fd == -1) {
        Tr_Warn("Error: open /dev/i2c5 error");
		return ;
    }
	
	// set valid bit of chip is 7 bit
	// and there is a option that is 10 bit
    int nSize = ioctl(g_devI2C5Fd, I2C_TENBIT, ICC_ADDRESS_Bit_7);
    if(nSize != 0){
        Tr_Warn("Error: write I2C_TENBIT failed");
		return ;
    }
	
	// set ICC address
    nSize = ioctl(g_devI2C5Fd, I2C_SLAVE, ICC_ADDRESS);
    if(nSize != 0){
        Tr_Warn("Error: write I2C_SLAVE error");
		return ;
    }
    return ;
}

// write data by ICC
bool ICC_Write_Register(uint8_t device, uint8_t* wdata, size_t num_bytes)
{
    uint8_t write_data[100] = {0};
    write_data[0] = device;
    memcpy(write_data+1, wdata, num_bytes);
    uint8_t write_len = num_bytes+1;

    int write_size = write(g_devI2C5Fd, write_data, write_len);
    if (write_size != write_len) {
        Tr_Warn("Error: ICC_Read_Register write error");
		return false;
    } 
    return true;
}

bool ICC_Read_Register(uint8_t device, uint8_t* rdata, size_t num_bytes)
{
    uint8_t wdata[1] = {0};
    wdata[0] = device;
    // wdata[1] = device;

    int write_size = write(g_devI2C5Fd, wdata, 1u);
    if (write_size != 1u) {
        Tr_Warn("Error: ICC_Read_Register write error");
		return false;
    }

    sleep(1);

    int read_size = read(g_devI2C5Fd, rdata, num_bytes);
    if(read_size != num_bytes) {
        Tr_Warn("Error: read error");
		return false;
    }

    return (bool_t)(true);
}

SPI 读写实例

#include<sys/ioctl.h>
#include<linux/spi/spidev.h>
#include<fcntl.h>

static const char g_szSPIFile[] = "/dev/spidev0.0";
static uint32_t SPIMODE = SPI_MODE_1;	// 上升沿,极性
static uint8_t SPIBITS = 8;
static uint32_t MAXSPEED = 20000000;  //500000

bool_t Initialize_SPI_Node()
{
    int ret = 0;

    g_devSpide0Fd = open(g_szSPIFile, O_RDWR);
    if(-1 == g_devSpide0Fd){
        Tr_Warn("open g_szSPIFile error");
        return false;
    }

    ret = ioctl(g_devSpide0Fd, SPI_IOC_WR_MODE,&SPIMODE);
    if(ret < 0){
        Tr_Warn("set SPI_IOC_WR_MODE error");
        return false;
    }

    ret = ioctl(g_devSpide0Fd, SPI_IOC_RD_MODE, &SPIMODE);
    if(ret < 0){
        Tr_Warn("set SPI_IOC_RD_MODE error");
        return false;
    } 

    ret = ioctl(g_devSpide0Fd, SPI_IOC_RD_BITS_PER_WORD, &SPIBITS);
    if(ret < 0){
        Tr_Warn("set SPI_IOC_RD_BITS_PER_WORD error");
        return false;
    }
   ret = ioctl(g_devSpide0Fd,SPI_IOC_WR_MAX_SPEED_HZ,&MAXSPEED);
   if( ret == -1)
   {
        Tr_Warn("SPI_IOC_WR_MAX_SPEED_HZ error");
   }
   ret = ioctl(g_devSpide0Fd,SPI_IOC_RD_MAX_SPEED_HZ,&MAXSPEED);
   if( ret == -1)
   {
        Tr_Warn("SPI_IOC_RD_MAX_SPEED_HZ error");
   }
    return true;
}

bool_t SPI_Write(const uint8_t *wdata, size_t num_bytes)
{
    if(-1 == g_devSpide0Fd){
        Tr_Warn("Error: g_devSpide0Fd is not inited");
        return SPI_OPEN_ERROR;
    }

    if(num_bytes > SPI_WRITE_MAX_LENGTH){
        size_t write_len = 0;
        uint8_t* readBuffer = (uint8_t *)malloc(sizeof(uint8_t)*SPI_WRITE_MAX_LENGTH);
        uint8_t* writeBuffer = (uint8_t *)malloc(sizeof(uint8_t)*SPI_WRITE_MAX_LENGTH);
        while(write_len <  num_bytes){
            int copy_len = (num_bytes-write_len) > SPI_WRITE_MAX_LENGTH ? SPI_WRITE_MAX_LENGTH : (num_bytes-write_len);
            memcpy(writeBuffer, wdata+write_len,copy_len);
            struct spi_ioc_transfer writeTr = {
                .tx_buf = (unsigned long )writeBuffer,
                .rx_buf = (unsigned long )readBuffer,
                .len = copy_len,
            };
            int ret = ioctl(g_devSpide0Fd, SPI_IOC_MESSAGE(1), &writeTr);
            if(ret < 0) {
                Tr_Warn("Error: ioctl error, ret: %d", ret);
                Tr_Warn("ErroNo: %d, Error String %s",errno, strerror(errno));
                free(writeBuffer);
                free(readBuffer);
                writeBuffer = NULL;
                readBuffer = NULL;
                return false;
            }
            write_len += copy_len;
        }
        free(writeBuffer);
        free(readBuffer);
        writeBuffer = NULL;
        readBuffer = NULL;
    }
    else{
        uint8_t *readBuffer = (uint8_t *)malloc(sizeof(uint8_t)*num_bytes);
        struct spi_ioc_transfer writeTr = {
            .tx_buf = (unsigned long )wdata,
            .rx_buf = (unsigned long )readBuffer,
            .len = num_bytes,
        };

        int ret = ioctl(g_devSpide0Fd, SPI_IOC_MESSAGE(1), &writeTr);

        free(readBuffer);
        readBuffer = NULL;

        if(ret < 0) {
            Tr_Warn("Error: ioctl error, ret: %d", ret);
            Tr_Warn("ErroNo: %d, Error String %s",errno, strerror(errno));
            return false;
        }
    }

    return true;
}
posted @   王清河  阅读(269)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
历史上的今天:
2019-10-28 一起学Makefile(三)
点击右上角即可分享
微信分享提示