Hotwheels-Cluster 1.2
Creation of Cluster APP for SEA:ME project.
 
Loading...
Searching...
No Matches
PeripheralController.cpp
Go to the documentation of this file.
1
15
17
26 uint8_t byte;
27 uint16_t word;
28 uint8_t block[34]; // Block size for SMBus
29};
30
31/* ------------------------------------ */
32
33#define I2C_SMBUS_WRITE 0
34#define I2C_SMBUS_READ 1
35#define I2C_SMBUS_BYTE_DATA 2
36
45template <typename T> T clamp(T value, T min_val, T max_val) {
46 return (value < min_val) ? min_val : ((value > max_val) ? max_val : value);
47}
48
59PeripheralController::PeripheralController(int servo_addr, int motor_addr)
60 : servo_addr_(servo_addr), motor_addr_(motor_addr) {
61 // Initialize I2C buses
62 servo_bus_fd_ = open("/dev/i2c-1", O_RDWR);
63 motor_bus_fd_ = open("/dev/i2c-1", O_RDWR);
64
65 if (servo_bus_fd_ < 0 || motor_bus_fd_ < 0) {
66 throw std::runtime_error("Failed to open I2C device");
67 return;
68 }
69
70 // Set device addresses
71 if (ioctl(servo_bus_fd_, I2C_SLAVE, servo_addr_) < 0 ||
72 ioctl(motor_bus_fd_, I2C_SLAVE, motor_addr_) < 0) {
73 throw std::runtime_error("Failed to set I2C address");
74 return;
75 }
76}
77
89
100 uint8_t value) {
101 union i2c_smbus_data data;
102 data.byte = value;
103
104 struct i2c_smbus_ioctl_data args;
105 args.read_write = I2C_SMBUS_WRITE;
106 args.command = command;
107 args.size = I2C_SMBUS_BYTE_DATA;
108 args.data = &data;
109
110 return ioctl(file, I2C_SMBUS, &args);
111}
112
121 union i2c_smbus_data data;
122
123 struct i2c_smbus_ioctl_data args;
124 args.read_write = I2C_SMBUS_READ;
125 args.command = command;
126 args.size = I2C_SMBUS_BYTE_DATA;
127 args.data = &data;
128
129 if (ioctl(file, I2C_SMBUS, &args) < 0) {
130 return -1;
131 }
132 return data.byte;
133}
134
143void PeripheralController::write_byte_data(int fd, int reg, int value) {
144 if (i2c_smbus_write_byte_data(fd, reg, value) < 0) {
145 throw std::runtime_error("I2C write failed");
146 }
147}
148
157
159 int result = i2c_smbus_read_byte_data(fd, reg);
160 if (result < 0) {
161 throw std::runtime_error("I2C read failed");
162 }
163 return result;
164}
165
177void PeripheralController::set_servo_pwm(int channel, int on_value,
178 int off_value) {
179 int base_reg = 0x06 + (channel * 4);
180 write_byte_data(servo_bus_fd_, base_reg, on_value & 0xFF);
181 write_byte_data(servo_bus_fd_, base_reg + 1, on_value >> 8);
182 write_byte_data(servo_bus_fd_, base_reg + 2, off_value & 0xFF);
183 write_byte_data(servo_bus_fd_, base_reg + 3, off_value >> 8);
184}
185
195void PeripheralController::set_motor_pwm(int channel, int value) {
196 value = clamp(value, 0, 4095);
197 write_byte_data(motor_bus_fd_, 0x06 + (4 * channel), 0);
198 write_byte_data(motor_bus_fd_, 0x07 + (4 * channel), 0);
199 write_byte_data(motor_bus_fd_, 0x08 + (4 * channel), value & 0xFF);
200 write_byte_data(motor_bus_fd_, 0x09 + (4 * channel), value >> 8);
201}
202
212
214 write_byte_data(servo_bus_fd_, 0x00, 0x06);
215 usleep(100000);
216
217 write_byte_data(servo_bus_fd_, 0x00, 0x10);
218 usleep(100000);
219
220 write_byte_data(servo_bus_fd_, 0xFE, 0x79);
221 usleep(100000);
222
223 write_byte_data(servo_bus_fd_, 0x01, 0x04);
224 usleep(100000);
225
226 write_byte_data(servo_bus_fd_, 0x00, 0x20);
227 usleep(100000);
228}
229
237 write_byte_data(motor_bus_fd_, 0x00, 0x20);
238
239 int prescale = static_cast<int>(std::floor(25000000.0 / 4096.0 / 100 - 1));
240 int oldmode = read_byte_data(motor_bus_fd_, 0x00);
241 int newmode = (oldmode & 0x7F) | 0x10;
242
243 write_byte_data(motor_bus_fd_, 0x00, newmode);
244 write_byte_data(motor_bus_fd_, 0xFE, prescale);
245 write_byte_data(motor_bus_fd_, 0x00, oldmode);
246 usleep(5000);
247 write_byte_data(motor_bus_fd_, 0x00, oldmode | 0xa1);
248}
T clamp(T value, T min_val, T max_val)
Clamps a value to a given range.
#define I2C_SMBUS_BYTE_DATA
T clamp(T value, T min_val, T max_val)
Clamps a value to a given range.
#define I2C_SMBUS_READ
#define I2C_SMBUS_WRITE
File containing the PeripheralController class.
void init_motors() override
Initializes the motor controllers.
void init_servo() override
Initializes the servo controller.
~PeripheralController() override
Destructor for the PeripheralController class.
void set_servo_pwm(int channel, int on_value, int off_value) override
Sets the PWM of a servo motor.
int i2c_smbus_read_byte_data(int file, uint8_t command) override
Reads a byte of data from a specific register.
void set_motor_pwm(int channel, int value) override
Sets the PWM value for a motor.
virtual void write_byte_data(int fd, int reg, int value) override
Writes a byte of data to a specific register.
virtual int read_byte_data(int fd, int reg) override
Reads a byte of data from a specific register.
PeripheralController(int servo_addr, int motor_addr)
Constructor for the PeripheralController class.
int i2c_smbus_write_byte_data(int file, uint8_t command, uint8_t value) override
Writes a byte of data to a specific register.
Represents data formats for I2C SMBus communication.