项目背景
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;
}