-
Notifications
You must be signed in to change notification settings - Fork 0
/
gpiocontroller.cpp
180 lines (141 loc) · 4.29 KB
/
gpiocontroller.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <QDebug>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "i2c-dev.h"
#include <iostream>
#include "gpiocontroller.h"
int GpioController::pin(int pin)
{
uint32_t reg = 0x0;
if (pin < GPIO_MIN_PIN || pin > GPIO_MAX_PIN) {
qDebug() << "Pin " << pin << " is invalid!";
return -1;
}
qDebug() << "Getting pin " << pin;
reg = i2c_smbus_read_byte_data(m_fd, GPIO_CTRL_REG);
if ((reg >> pin) & 0x1) {
qDebug() << "Getting output reg ";
reg = i2c_smbus_read_byte_data(m_fd, GPIO_OUT_REG);
} else {
qDebug() << "Getting input reg ";
reg = i2c_smbus_read_byte_data(m_fd, GPIO_INPUT_REG);
}
qDebug() << "reg val: " << QByteArray::number(reg).toHex();
return (reg >> pin) & 0x1;
}
bool GpioController::setPin(int pin, int val)
{
uint32_t reg = 0x0;
if (pin < GPIO_MIN_PIN || pin > GPIO_MAX_PIN) {
qDebug() << "Pin " << pin << " is invalid!";
return false;
}
qDebug() << "Setting pin " << pin << " value to " << val;
reg = i2c_smbus_read_byte_data(m_fd, GPIO_CTRL_REG);
if (((reg >> pin) & 0x1)) {
qDebug() << "Pin " << pin << " is an input and cannot be set!";
return false;
}
reg = i2c_smbus_read_byte_data(m_fd, GPIO_OUT_REG);
qDebug() << "out reg 0x" << QByteArray::number(reg, 16);
if (val == 0) {
reg &= ~(0x01 << pin);
} else {
reg |= (0x1 << pin);
}
qDebug() << "new out reg: " << QByteArray::number(reg, 16);
auto rv = i2c_smbus_write_byte_data(m_fd, GPIO_OUT_REG, reg);
if (rv != 0) {
qDebug() << "i2c dev failed to set direction";
return false;
}
return true;
}
QString GpioController::direction(int pin)
{
uint32_t reg = 0x0;
if ((pin < GPIO_MIN_PIN) || (pin > GPIO_MAX_PIN)) {
return "";
}
reg = i2c_smbus_read_byte_data(m_fd, GPIO_CTRL_REG);
qDebug() << "Getting pin " << pin << " direction " << QByteArray::number(reg).toHex();
if ((reg >> pin) & 0x1) {
return "in";
} else {
return "out";
}
}
bool GpioController::setDirection(int pin, QString dir)
{
uint32_t reg = 0x0;
if (pin < GPIO_MIN_PIN || pin > GPIO_MAX_PIN) {
qDebug() << "Pin " << pin << " is invalid!";
return false;
}
reg = i2c_smbus_read_byte_data(m_fd, GPIO_CTRL_REG);
qDebug() << "ctrl reg 0x" << QByteArray::number(reg, 16);
if (dir.compare("out") == 0) {
/* set as output - 0 */
reg &= ~(0x1 << pin);
} else if (dir.compare("in") == 0){
/* set as intput - 1 */
reg |= (0x1 << pin);
} else {
/* invalid direction */
qDebug() << "Direction '" << dir << "' is invalid";
return false;
}
qDebug() << "writing reg 0x" << QByteArray::number(reg, 16);
auto rv = i2c_smbus_write_byte_data(m_fd, GPIO_CTRL_REG, reg);
if (rv != 0) {
qDebug() << "i2c dev failed to set direction";
return false;
}
return true;
}
GpioController::GpioController(QObject *parent): QObject(parent) ,
m_fd(0)
{
qDebug() << "GpioController constructor";
m_fd = open(GPIO_DEV, O_RDWR);
if (m_fd > 0) {
qDebug() << "i2c dev open";
} else {
qDebug() << "i2c dev failed to open";
return;
}
auto rv = ioctl(m_fd, I2C_SLAVE, GPIO_I2C_ADDR);
if (rv != 0) {
qDebug() << "i2c dev failed to set address";
return;
}
/* set all pins as input, the default */
rv = i2c_smbus_write_byte_data(m_fd, GPIO_CTRL_REG, 0xff);
if (rv != 0) {
qDebug() << "i2c dev failed to set output";
return;
}
/* clear the out reg */
rv = i2c_smbus_write_byte_data(m_fd, GPIO_OUT_REG, 0x0);
if (rv != 0) {
qDebug() << "i2c dev failed to set output";
}
}
GpioController::~GpioController()
{
if (m_fd > 0) {
/* reset GPIO pins to input, clear out reg */
auto rv = i2c_smbus_write_byte_data(m_fd, GPIO_OUT_REG, 0x0);
if (rv != 0) {
qDebug() << "i2c dev failed to set output";
}
rv = i2c_smbus_write_byte_data(m_fd, GPIO_CTRL_REG, 0xff);
if (rv != 0) {
qDebug() << "i2c dev failed to set control";
}
qDebug() << "closing i2c dev";
close(m_fd);
}
}