Skip to content
Snippets Groups Projects
Commit d7caf511 authored by Paulus Kruger's avatar Paulus Kruger
Browse files

add I2C smbus driver

parent 3edacee0
No related branches found
No related tags found
No related merge requests found
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"type": "cppdbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"linux": {
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"program": "${workspaceFolder}/output/main"
},
"osx": {
"MIMode": "lldb",
"miDebuggerPath": "lldb-mi",
"program": "${workspaceFolder}/output/main"
},
"windows": {
"MIMode": "gdb",
"miDebuggerPath": "gdb.exe",
"program": "${workspaceFolder}/output/main.exe"
},
"preLaunchTask": "build"
}
]
}
\ No newline at end of file
{
"files.associations": {
"string": "cpp",
"iostream": "cpp"
}
}
\ No newline at end of file
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"group": {
"kind": "build",
"isDefault": true
},
"windows": {
"command": "powershell",
"args": [
"-c",
"mingw32-make"
]
},
"linux": {
"command": "bash",
"args": [
"-c",
"make"
]
},
"osx": {
"command": "bash",
"args": [
"-c",
"make"
]
}
},
{
"label": "build & run",
"type": "shell",
"windows": {
"command": "powershell",
"args": [
"-c",
"'mingw32-make run'"
]
},
"linux": {
"command": "bash",
"args": [
"-c",
"'make run'"
]
},
"osx": {
"command": "bash",
"args": [
"-c",
"'make run'"
]
}
},
{
"label": "clean",
"type": "shell",
"windows": {
"command": "powershell",
"args": [
"-c",
"'mingw32-make clean'"
]
},
"linux": {
"command": "bash",
"args": [
"-c",
"'make clean'"
]
},
"osx": {
"command": "bash",
"args": [
"-c",
"'make clean'"
]
}
}
]
}
\ No newline at end of file
......@@ -2,17 +2,11 @@
#include <iostream>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include "smbus.h"
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
//https://www.pololu.com/docs/0J73/15.8
bool i2c_smbus_write_block_data(int file,uint8_t adress,uint8_t len,uint8_t* buff){
struct i2c_msg message = {adress,0,len,buff};
struct i2c_rdwr_ioctl_data ioctl_data = {&message,1};
ioctl(file,I2C_RDWR,&ioctl_data);
}
c_i2c::c_i2c(const t_driver config1) : drvbase (config1){
std::cout << config.name <<": i2c server, connecting to device " << config.parameters[0] << "\n";
......@@ -35,8 +29,8 @@ bool c_i2c::I2Csend_reg(int addr,int reg,int len,t_buffer* data){
bool c_i2c::I2Cget_reg(int addr,int reg,int len,t_buffer* data){
std::cout << config.name <<": i2c get from addr="<<addr<<" reg="<<reg<<" len="<<len<<" value="<<int(data[0]) <<"\n";
if (ioctl(file, I2C_SLAVE, addr)<0) return false;
return true;
// return i2c_smbus_read_i2c_block_data(file,reg,len,data);
// return true;
return (i2c_smbus_read_i2c_block_data(file,reg,len,data)==len);
}
bool c_i2c::I2Csend(int addr,int len,t_buffer* data){
......
/*
smbus.c - SMBus level access helper functions
Copyright (C) 1995-97 Simon G. Vogl
Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
Copyright (C) 2012 Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#include <errno.h>
#include "smbus.h" // NB: Path changed!
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
//NB: Added by John Burns
#ifndef NULL
#define NULL 0
#endif
/* Compatibility defines */
#ifndef I2C_SMBUS_I2C_BLOCK_BROKEN
#define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA
#endif
#ifndef I2C_FUNC_SMBUS_PEC
#define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC
#endif
__s32 i2c_smbus_access(int file, char read_write, __u8 command,
int size, union i2c_smbus_data *data)
{
struct i2c_smbus_ioctl_data args;
__s32 err;
args.read_write = read_write;
args.command = command;
args.size = size;
args.data = data;
err = ioctl(file, I2C_SMBUS, &args);
if (err == -1)
err = -errno;
return err;
}
__s32 i2c_smbus_write_quick(int file, __u8 value)
{
return i2c_smbus_access(file, value, 0, I2C_SMBUS_QUICK, NULL);
}
__s32 i2c_smbus_read_byte(int file)
{
union i2c_smbus_data data;
int err;
err = i2c_smbus_access(file, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data);
if (err < 0)
return err;
return 0x0FF & data.byte;
}
__s32 i2c_smbus_write_byte(int file, __u8 value)
{
return i2c_smbus_access(file, I2C_SMBUS_WRITE, value,
I2C_SMBUS_BYTE, NULL);
}
__s32 i2c_smbus_read_byte_data(int file, __u8 command)
{
union i2c_smbus_data data;
int err;
err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
I2C_SMBUS_BYTE_DATA, &data);
if (err < 0)
return err;
return 0x0FF & data.byte;
}
__s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value)
{
union i2c_smbus_data data;
data.byte = value;
return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
I2C_SMBUS_BYTE_DATA, &data);
}
__s32 i2c_smbus_read_word_data(int file, __u8 command)
{
union i2c_smbus_data data;
int err;
err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
I2C_SMBUS_WORD_DATA, &data);
if (err < 0)
return err;
return 0x0FFFF & data.word;
}
__s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value)
{
union i2c_smbus_data data;
data.word = value;
return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
I2C_SMBUS_WORD_DATA, &data);
}
__s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
{
union i2c_smbus_data data;
data.word = value;
if (i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
I2C_SMBUS_PROC_CALL, &data))
return -1;
else
return 0x0FFFF & data.word;
}
/* Returns the number of read bytes */
__s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values)
{
union i2c_smbus_data data;
int i, err;
err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
I2C_SMBUS_BLOCK_DATA, &data);
if (err < 0)
return err;
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
__s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
const __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > I2C_SMBUS_BLOCK_MAX)
length = I2C_SMBUS_BLOCK_MAX;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
I2C_SMBUS_BLOCK_DATA, &data);
}
/* Returns the number of read bytes */
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
ask for less than 32 bytes, your code will only work with kernels
2.6.23 and later. */
__s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
__u8 *values)
{
union i2c_smbus_data data;
int i, err;
if (length > I2C_SMBUS_BLOCK_MAX)
length = I2C_SMBUS_BLOCK_MAX;
data.block[0] = length;
err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
I2C_SMBUS_I2C_BLOCK_DATA, &data);
if (err < 0)
return err;
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
__s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,
const __u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > I2C_SMBUS_BLOCK_MAX)
length = I2C_SMBUS_BLOCK_MAX;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
}
/* Returns the number of read bytes */
__s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
__u8 *values)
{
union i2c_smbus_data data;
int i, err;
if (length > I2C_SMBUS_BLOCK_MAX)
length = I2C_SMBUS_BLOCK_MAX;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
err = i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
I2C_SMBUS_BLOCK_PROC_CALL, &data);
if (err < 0)
return err;
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
/*
smbus.h - SMBus level access helper functions
Copyright (C) 1995-97 Simon G. Vogl
Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA.
*/
#ifndef LIB_I2C_SMBUS_H
#define LIB_I2C_SMBUS_H
#include <linux/types.h>
#include <linux/i2c.h>
__s32 i2c_smbus_access(int file, char read_write, __u8 command,
int size, union i2c_smbus_data *data);
__s32 i2c_smbus_write_quick(int file, __u8 value);
__s32 i2c_smbus_read_byte(int file);
__s32 i2c_smbus_write_byte(int file, __u8 value);
__s32 i2c_smbus_read_byte_data(int file, __u8 command);
__s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);
__s32 i2c_smbus_read_word_data(int file, __u8 command);
__s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
__s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);
/* Returns the number of read bytes */
__s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
__s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
const __u8 *values);
/* Returns the number of read bytes */
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
ask for less than 32 bytes, your code will only work with kernels
2.6.23 and later. */
__s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
__u8 *values);
__s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,
const __u8 *values);
/* Returns the number of read bytes */
__s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
__u8 *values);
#endif /* LIB_I2C_SMBUS_H */
// Generated by Cap'n Proto compiler, DO NOT EDIT
// source: pypcc.capnp
#include "pypcc.capnp.h"
namespace capnp {
namespace schemas {
static const ::capnp::_::AlignedData<29> b_b1dfe08305a4b99c = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
156, 185, 164, 5, 131, 224, 223, 177,
12, 0, 0, 0, 2, 0, 0, 0,
127, 221, 126, 140, 222, 153, 44, 159,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 170, 0, 0, 0,
29, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
25, 0, 0, 0, 79, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
112, 121, 112, 99, 99, 46, 99, 97,
112, 110, 112, 58, 73, 110, 115, 116,
84, 121, 112, 101, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0,
12, 0, 0, 0, 1, 0, 2, 0,
0, 0, 0, 0, 0, 0, 0, 0,
29, 0, 0, 0, 58, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 66, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
2, 0, 0, 0, 0, 0, 0, 0,
13, 0, 0, 0, 58, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
118, 97, 114, 83, 101, 116, 0, 0,
118, 97, 114, 82, 101, 97, 100, 0,
109, 101, 116, 104, 111, 100, 0, 0, }
};
::capnp::word const* const bp_b1dfe08305a4b99c = b_b1dfe08305a4b99c.words;
#if !CAPNP_LITE
static const uint16_t m_b1dfe08305a4b99c[] = {2, 1, 0};
const ::capnp::_::RawSchema s_b1dfe08305a4b99c = {
0xb1dfe08305a4b99c, b_b1dfe08305a4b99c.words, 29, nullptr, m_b1dfe08305a4b99c,
0, 3, nullptr, nullptr, nullptr, { &s_b1dfe08305a4b99c, nullptr, nullptr, 0, 0, nullptr }
};
#endif // !CAPNP_LITE
CAPNP_DEFINE_ENUM(InstType_b1dfe08305a4b99c, b1dfe08305a4b99c);
static const ::capnp::_::AlignedData<85> b_aaca83afea5f387e = {
{ 0, 0, 0, 0, 5, 0, 6, 0,
126, 56, 95, 234, 175, 131, 202, 170,
12, 0, 0, 0, 1, 0, 1, 0,
127, 221, 126, 140, 222, 153, 44, 159,
2, 0, 7, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
21, 0, 0, 0, 170, 0, 0, 0,
29, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
25, 0, 0, 0, 231, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
112, 121, 112, 99, 99, 46, 99, 97,
112, 110, 112, 58, 79, 80, 67, 85,
65, 115, 101, 116, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 1, 0,
16, 0, 0, 0, 3, 0, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
97, 0, 0, 0, 26, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
92, 0, 0, 0, 3, 0, 1, 0,
104, 0, 0, 0, 2, 0, 1, 0,
1, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
101, 0, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
96, 0, 0, 0, 3, 0, 1, 0,
108, 0, 0, 0, 2, 0, 1, 0,
2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 2, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
105, 0, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
100, 0, 0, 0, 3, 0, 1, 0,
128, 0, 0, 0, 2, 0, 1, 0,
3, 0, 0, 0, 1, 0, 0, 0,
0, 0, 1, 0, 3, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
125, 0, 0, 0, 42, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
120, 0, 0, 0, 3, 0, 1, 0,
148, 0, 0, 0, 2, 0, 1, 0,
105, 100, 0, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
116, 121, 112, 101, 0, 0, 0, 0,
15, 0, 0, 0, 0, 0, 0, 0,
156, 185, 164, 5, 131, 224, 223, 177,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
15, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
100, 97, 116, 97, 0, 0, 0, 0,
14, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3, 0, 1, 0,
6, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
14, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
109, 97, 115, 107, 0, 0, 0, 0,
14, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 3, 0, 1, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
14, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, }
};
::capnp::word const* const bp_aaca83afea5f387e = b_aaca83afea5f387e.words;
#if !CAPNP_LITE
static const ::capnp::_::RawSchema* const d_aaca83afea5f387e[] = {
&s_b1dfe08305a4b99c,
};
static const uint16_t m_aaca83afea5f387e[] = {2, 0, 3, 1};
static const uint16_t i_aaca83afea5f387e[] = {0, 1, 2, 3};
const ::capnp::_::RawSchema s_aaca83afea5f387e = {
0xaaca83afea5f387e, b_aaca83afea5f387e.words, 85, d_aaca83afea5f387e, m_aaca83afea5f387e,
1, 4, i_aaca83afea5f387e, nullptr, nullptr, { &s_aaca83afea5f387e, nullptr, nullptr, 0, 0, nullptr }
};
#endif // !CAPNP_LITE
} // namespace schemas
} // namespace capnp
// =======================================================================================
// OPCUAset
constexpr uint16_t OPCUAset::_capnpPrivate::dataWordSize;
constexpr uint16_t OPCUAset::_capnpPrivate::pointerCount;
#if !CAPNP_LITE
constexpr ::capnp::Kind OPCUAset::_capnpPrivate::kind;
constexpr ::capnp::_::RawSchema const* OPCUAset::_capnpPrivate::schema;
#endif // !CAPNP_LITE
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment