Skip to content

Commit 2b64902

Browse files
committed
Created entities per features (gpio io, pwm, etc)
1 parent a29fcd8 commit 2b64902

File tree

2 files changed

+156
-134
lines changed

2 files changed

+156
-134
lines changed

Gpio.cpp

Lines changed: 109 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "Gpio.h"
22

33
Gpio::Gpio(bool enable_spi) {
4+
this->enable_spi = enable_spi;
5+
46
if (this->init_gpio() == NO_ERROR && enable_spi) {
57
this->init_spi();
68
}
@@ -11,150 +13,150 @@ Gpio::~Gpio() {
1113
}
1214

1315
int Gpio::init_gpio() {
14-
int errnum = NO_ERROR;
15-
// Start the BCM2835 Library to access GPIO
16-
if (!bcm2835_init()) {
17-
cerr << "bcm2835_init failed (Are you running as root?)" << endl;
18-
errnum = BCM2835_INIT_ERROR;
19-
exit(errnum);
20-
}
21-
return errnum;
16+
int errnum = NO_ERROR;
17+
// Start the BCM2835 Library to access GPIO
18+
if (!bcm2835_init()) {
19+
std::cerr << "bcm2835_init failed (Are you running as root?)" << std::endl;
20+
errnum = BCM2835_INIT_ERROR;
21+
exit(errnum);
22+
}
23+
return errnum;
2224
}
2325

2426
int Gpio::init_spi() {
25-
int errnum = NO_ERROR;
26-
// Enable SPI bus
27+
int errnum = NO_ERROR;
28+
// Enable SPI bus
2729
if (!bcm2835_spi_begin()) {
28-
cerr << "bcm2835_spi_begin failed (Are you running as root?)" << endl;
29-
errnum = BCM2835_INIT_SPI_ERROR;
30-
exit(errnum);
30+
std::cerr << "bcm2835_spi_begin failed (Are you running as root?)" << std::endl;
31+
errnum = BCM2835_INIT_SPI_ERROR;
32+
exit(errnum);
3133
}
32-
return errnum;
34+
return errnum;
3335
}
3436

3537
int Gpio::close_gpio() {
36-
int errnum = NO_ERROR;
37-
if (!bcm2835_close()) {
38-
cerr << "bcm2835_close failed (Are you running as root?)" << endl;
39-
errnum = BCM2835_CLOSE_ERROR;
40-
exit(errnum);
41-
}
38+
int errnum = NO_ERROR;
39+
40+
if (enable_spi) {
41+
bcm2835_spi_end();
42+
}
43+
44+
if (!bcm2835_close()) {
45+
std::cerr << "bcm2835_close failed (Are you running as root?)" << std::endl;
46+
errnum = BCM2835_CLOSE_ERROR;
47+
exit(errnum);
48+
}
49+
4250
return errnum;
4351
}
4452

4553
void Gpio::setup_pwm(GpioPwmClock clock) {
4654
std::uint32_t clock_static = static_cast<std::uint32_t>(clock);
47-
4855
bcm2835_pwm_set_clock(clock_static);
56+
LOG("set pwm clock:%d", clock_static);
4957
}
5058

51-
void Gpio::setup_pin(GpioPin pin) {
52-
std::uint8_t funStatic = static_cast<std::uint8_t>(pin.function);
53-
std::uint8_t pullUpStatic = static_cast<std::uint8_t>(pin.pullUp);
54-
std::uint8_t pinStatic = static_cast<std::uint8_t>(pin.name);
55-
Feature feature = getFeature(pin);
56-
LOG("set_direction(function=%d, pullUp=%d) on pin:%d", unsigned(funStatic), unsigned(pullUpStatic), unsigned(pinStatic));
57-
58-
if (pin.name != GpioPinName::unknown) {
59-
// Set function
60-
if (feature == Feature::io) {
61-
bcm2835_gpio_fsel(pinStatic, funStatic);
62-
} else if (feature == Feature::pwm) {
63-
std::uint8_t channel = get_pwm_channel(pin);
64-
std::uint8_t mode_static = static_cast<std::uint8_t>(pin.pwmMode);
65-
std::uint8_t range = pin.pwmRange;
66-
67-
if (channel >= 0 && pin.pwmMode != GpioPwmMode::unknown) {
68-
bcm2835_pwm_set_mode(channel, mode_static, 1 /* 1=enable */);
69-
}
59+
void Gpio::setup_pin(GpioPinIO pin) {
60+
std::uint8_t pin_static = static_cast<std::uint8_t>(pin.name);
61+
std::uint8_t fun_static = static_cast<std::uint8_t>(pin.function);
7062

71-
if (channel >= 0 && range > 0) {
72-
bcm2835_pwm_set_range(channel, range);
73-
}
74-
}
63+
bcm2835_gpio_fsel(pin_static, fun_static);
64+
LOG("setup pin:%d function:%d", pin_static, fun_static);
7565

76-
// if specified set PullUp resistor
77-
if (pin.pullUp != GpioPullUp::none) {
78-
LOG("override pull up setting");
79-
bcm2835_gpio_set_pud(pinStatic, pullUpStatic);
80-
} else {
81-
LOG("leave pull up setting as is");
82-
}
66+
// if specified set PullUp resistor
67+
if (pin.pullUp != GpioPullUp::none) {
68+
LOG("override pull up setting");
69+
bcm2835_gpio_set_pud(pin_static, static_cast<std::uint8_t>(pin.pullUp));
8370
} else {
84-
cerr << "setup_pin() pin name not initialised" << endl;
71+
LOG("leave pull up setting as is");
8572
}
8673
}
8774

88-
void Gpio::read(std::list<GpioPin*> pin_list) {
89-
for (GpioPin *pin : pin_list) {
90-
uint8_t pin_static = static_cast<std::uint8_t>(pin->name);
91-
pin->value = bcm2835_gpio_lev(pin_static);
92-
LOG("read pin:%d value:%d", pin_static, pin->value);
75+
void Gpio::setup_pin(GpioPwm pin) {
76+
std::uint8_t channel = get_pwm_channel(pin);
77+
78+
if (channel >= 0 && pin.mode != GpioPwmMode::unknown) {
79+
bcm2835_pwm_set_mode(channel, static_cast<std::uint8_t>(pin.mode), 1 /* 1=enable */);
80+
}
81+
82+
if (channel >= 0 && pin.range > 0) {
83+
bcm2835_pwm_set_range(channel, pin.range);
9384
}
9485
}
9586

96-
std::list<GpioPin*> Gpio::get_pins_up(std::list<GpioPin*> pins_to_check) {
97-
std::list<GpioPin*> switches_pushed = {};
87+
std::uint8_t Gpio::get_pwm_channel(GpioPwm pin) {
88+
std::uint8_t channel = -1;
9889

99-
if (!pins_to_check.empty()) {
100-
read(pins_to_check);
101-
for (GpioPin *pin : pins_to_check) {
102-
// Keep pins up only
103-
if ((pin->value == 0 && pin->pullUp == GpioPullUp::up) || (pin->value != 0 && pin->pullUp != GpioPullUp::up)) {
104-
switches_pushed.push_back(pin);
105-
}
106-
}
107-
}
90+
switch(pin.name) {
91+
case GpioPwmName::pwm1_gpio19:
92+
case GpioPwmName::pwm1_gpio13:
93+
channel = 1;
94+
break;
10895

109-
return switches_pushed;
96+
case GpioPwmName::pwm0_gpio18:
97+
case GpioPwmName::pwm0_gpio12:
98+
channel = 0;
99+
break;
100+
101+
default:
102+
channel = -1;
103+
break;
104+
}
105+
106+
return channel;
110107
}
111108

112-
void Gpio::write(GpioPin* pin, uint8_t val) {
113-
std::uint8_t val_static = static_cast<std::uint8_t>(val);
114-
std::uint8_t pin_static = static_cast<std::uint8_t>(pin->name);
115-
std::uint8_t channel = get_pwm_channel(*pin);
109+
void Gpio::read(std::list<GpioPinIO*> pin_list) {
110+
for (GpioPinIO *pin : pin_list) {
111+
std::uint8_t pin_static = static_cast<std::uint8_t>(pin->name);
116112

117-
if (channel < 0) {
118-
bcm2835_gpio_write(pin_static, val_static);
119-
LOG("write pin:%d value:%d", pin_static, val_static);
120-
} else {
121-
bcm2835_pwm_set_data(channel, val_static);
122-
LOG("write PWM pin:%d value:%d", pin_static, val_static);
113+
pin->value = bcm2835_gpio_lev(pin_static) != 0;
114+
LOG("read IO pin:%d value:%d", pin_static, pin->value);
123115
}
116+
}
117+
118+
void Gpio::read(std::list<GpioPwm*> pin_list) {
119+
for (GpioPwm *pin : pin_list) {
120+
std::uint8_t pin_static = static_cast<std::uint8_t>(pin->name);
124121

125-
pin->value = val_static;
122+
pin->value = bcm2835_gpio_lev(pin_static);
123+
LOG("read PWM pin:%d value:%d", pin_static, pin->value);
124+
}
126125
}
127126

128-
std::uint8_t Gpio::get_pwm_channel(GpioPin pin) {
129-
std::uint8_t channel = -1;
130-
GpioPinName name = pin.name;
131-
GpioFunction func = pin.function;
132-
133-
if (getFeature(pin) != Feature::pwm) {
134-
channel = -1;
135-
} else if ((name == GpioPinName::gpio13 && func == GpioFunction::alt0) ||
136-
(name == GpioPinName::gpio19 && func == GpioFunction::alt5)) {
137-
channel = 1;
138-
} else if (name == GpioPinName::gpio18 && func == GpioFunction::alt5) {
139-
channel = 0;
127+
std::list<GpioPinIO*> Gpio::get_pins_up(std::list<GpioPinIO*> pins_to_check) {
128+
std::list<GpioPinIO*> switches_pushed = {};
129+
130+
if (!pins_to_check.empty()) {
131+
read(pins_to_check);
132+
133+
for (GpioPinIO *pin : pins_to_check) {
134+
// Keep pins up only
135+
if ((!pin->value && pin->pullUp == GpioPullUp::up) ||
136+
(pin->value && pin->pullUp != GpioPullUp::up)) {
137+
switches_pushed.push_back(pin);
138+
}
139+
}
140140
}
141141

142-
return channel;
142+
return switches_pushed;
143143
}
144144

145-
Feature Gpio::getFeature(GpioPin pin) {
146-
Feature feature = Feature::unknown;
147-
GpioPinName name = pin.name;
148-
GpioFunction func = pin.function;
149-
150-
if ((name != GpioPinName::unknown && func == GpioFunction::input) ||
151-
(name != GpioPinName::unknown && func == GpioFunction::output)) {
152-
feature = Feature::io;
153-
} else if ((name == GpioPinName::gpio13 && func == GpioFunction::alt0) ||
154-
(name == GpioPinName::gpio19 && func == GpioFunction::alt5) ||
155-
(name == GpioPinName::gpio18 && func == GpioFunction::alt5)) {
156-
feature = Feature::pwm;
157-
}
145+
void Gpio::write(GpioPinIO* pin, bool val) {
146+
std::uint8_t pin_static = static_cast<std::uint8_t>(pin->name);
147+
std::uint8_t val_static = static_cast<std::uint8_t>(val);
158148

159-
return feature;
149+
bcm2835_gpio_write(pin_static, val_static);
150+
LOG("write pin:%d value:%d", pin_static, val_static);
151+
}
152+
153+
void Gpio::write(GpioPwm* pin, std::uint32_t val) {
154+
std::uint8_t channel = get_pwm_channel(*pin);
155+
156+
if (channel >= 0) {
157+
bcm2835_pwm_set_data(channel, val);
158+
LOG("write PWM channel:%d value:%d", channel, val);
159+
} else {
160+
std::cerr << "write PWM channel not found" << std::endl;
161+
}
160162
}

Gpio.h

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,22 @@ enum class GpioPinName: std::uint8_t {
3838
gpio27 = RPI_V2_GPIO_P1_13,
3939
gpio22 = RPI_V2_GPIO_P1_15,
4040
gpio10 = RPI_V2_GPIO_P1_19,
41-
gpio19 = RPI_V2_GPIO_P1_35, /*!< Can be PWM channel 1 in ALT FUN 5 */
42-
gpio18 = RPI_V2_GPIO_P1_12, /*!< Can be PWM channel 0 in ALT FUN 5 */
43-
gpio13 = RPI_V2_GPIO_P1_33, /*!< Can be PWM channel 1 in ALT FUN 0 */
44-
gpio12 = RPI_V2_GPIO_P1_32, /*!< Can be PWM channel 0 in ALT FUN 0 */
41+
gpio19 = RPI_V2_GPIO_P1_35,
42+
gpio18 = RPI_V2_GPIO_P1_12,
43+
gpio13 = RPI_V2_GPIO_P1_33,
44+
gpio12 = RPI_V2_GPIO_P1_32,
4545
gpio4 = RPI_V2_GPIO_P1_07
4646
};
4747

48+
// Pin names
49+
enum class GpioPwmName: std::uint8_t {
50+
unknown = 0xff,
51+
pwm1_gpio19 = RPI_V2_GPIO_P1_35, /*!< Can be PWM channel 1 in ALT FUN 5 */
52+
pwm0_gpio18 = RPI_V2_GPIO_P1_12, /*!< Can be PWM channel 0 in ALT FUN 5 */
53+
pwm1_gpio13 = RPI_V2_GPIO_P1_33, /*!< Can be PWM channel 1 in ALT FUN 0 */
54+
pwm0_gpio12 = RPI_V2_GPIO_P1_32, /*!< Can be PWM channel 0 in ALT FUN 0 */
55+
};
56+
4857
// Functions
4958
enum class GpioFunction: std::uint8_t {
5059
unknown = 0xff,
@@ -89,43 +98,54 @@ enum class GpioPwmMode: std::uint8_t {
8998
markspace = 1
9099
};
91100

92-
// GPIO pin
93-
struct GpioPin {
94-
GpioPinName name = GpioPinName::unknown;
95-
GpioFunction function = GpioFunction::unknown;
96-
GpioPullUp pullUp = GpioPullUp::none;
97-
98-
// PWM
99-
GpioPwmMode pwmMode = GpioPwmMode::unknown;
100-
std::uint32_t pwmRange = 255;
101+
class GpioPinConfigCommon
102+
{
103+
public:
104+
virtual ~GpioPinConfigCommon() {}
105+
};
101106

102-
std::uint32_t value = 0;
107+
// GPIO
108+
class GpioPinIO : GpioPinConfigCommon
109+
{
110+
public:
111+
GpioPinName name = GpioPinName::unknown;
112+
bool value = false;
113+
GpioFunction function = GpioFunction::unknown;
114+
GpioPullUp pullUp = GpioPullUp::none;
103115
};
104116

105-
enum class Feature {
106-
unknown,
107-
io,
108-
pwm,
109-
spi
117+
// PWM
118+
class GpioPwm : GpioPinConfigCommon
119+
{
120+
public:
121+
GpioPwmName name = GpioPwmName::unknown;
122+
std::uint32_t value = 0;
123+
GpioPwmMode mode = GpioPwmMode::unknown;
124+
std::uint32_t range = 0xff;
110125
};
111126

112127
class Gpio {
113128
public:
114129
Gpio(bool enable_spi = false);
115130
~Gpio();
116131

117-
void setup_pin(GpioPin pin);
132+
void setup_pin(GpioPinIO pin);
133+
void setup_pin(GpioPwm pin);
118134
void setup_pwm(GpioPwmClock clock);
119-
void read(std::list<GpioPin*> pin_list);
120-
std::list<GpioPin*> get_pins_up(std::list<GpioPin*> pins_to_check);
121-
void write(GpioPin* pin, std::uint8_t val);
135+
136+
void write(GpioPinIO* pin, bool val);
137+
void write(GpioPwm* pin, std::uint32_t val);
138+
139+
std::list<GpioPinIO*> get_pins_up(std::list<GpioPinIO*> pins_to_check);
140+
void read(std::list<GpioPinIO*> pin_list);
141+
void read(std::list<GpioPwm*> pin_list);
122142

123143
private:
144+
bool enable_spi = false;
124145
int init_gpio();
125-
int init_spi();
126-
int close_gpio();
127-
std::uint8_t get_pwm_channel(GpioPin pin);
128-
Feature getFeature(GpioPin pin);
146+
int init_spi();
147+
int close_gpio();
148+
std::uint8_t get_pwm_channel(GpioPwm pin);
129149
};
130150

131151
#endif

0 commit comments

Comments
 (0)