grove_lcd/grove_lcd.c

115 lines
3.1 KiB
C
Raw Normal View History

2023-11-07 14:05:51 +00:00
#include <errno.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
#include <getopt.h>
//Device specific information. (Perhaps better as command options or config file)
#define MPC9808_BUS "/dev/i2c-2"
#define DISPLAY_RGB_ADDR 0x62
#define DISPLAY_TEXT_ADDR 0x3e
void init_display(int file) {
// Function set 0010 1000 // 2 line mode and 5x8
i2c_smbus_write_byte_data(file, 0x00, 0x28);
// Display on/off control 0000 1110 // Diplay on; cursor off; blink off
i2c_smbus_write_byte_data(file, 0x00, 0x0C);
// Clear display
i2c_smbus_write_byte_data(file, 0x00, 0x01);
i2c_smbus_write_byte_data(file, 0x00, 0x06);
i2c_smbus_write_byte_data(file, 0x00, 0x02);
i2c_smbus_write_byte_data(file, 0x00, 0x84);
}
void clear_display(int file) {
i2c_smbus_write_byte_data(file, 0x00, 0x01);
}
void write_to_display_xy(int file, int x, int y, char* message) {
int line;
if(x > 16) {
fprintf(stderr, "Invalid line position");
return;
}
if(y == 1)
line = 0x80; // first line (1000 0000 to 1000 1111 possible on 16 characters line) = 0x80 to 0x8f
else if(y == 2)
line = 0xC0; // second line (1100 0000 to 1100 1111 possible on 16 characters line) = 0xC0 to 0xCf
else {
fprintf(stderr, "Invalid line position");
return;
}
line += x-1;
i2c_smbus_write_byte_data(file, 0x00, line);
while (*message != 0) {
i2c_smbus_write_byte_data(file, 0x40, *message);
message++;
}
}
int i2c_init(char *bus, unsigned int address) {
int file;
file = open(bus, O_RDWR);
if (file < 0) { // If error
fprintf(stderr, "ERROR: opening %s - %s\n", bus, strerror(errno));
exit(1);
}
if (ioctl(file, I2C_SLAVE, address) == -1 ) { // If error
fprintf(stderr, "ERROR: setting address %d on i2c bus %s with ioctl() - %s", address, bus, strerror(errno) );
exit(1);
}
return(file);
}
void set_backlight(int r, int g, int b) {
int file;
file = i2c_init(MPC9808_BUS, DISPLAY_RGB_ADDR);
i2c_smbus_write_byte_data(file, 0, 0);
i2c_smbus_write_byte_data(file, 1, 0);
i2c_smbus_write_byte_data(file, 0x08,0xaa);
i2c_smbus_write_byte_data(file, 4, r);
i2c_smbus_write_byte_data(file, 3, g);
i2c_smbus_write_byte_data(file, 2, b);
}
int main(int argc, char *argv[]) {
int l1p = 1;
int l2p = 1;
int option;
while ((option = getopt (argc, argv, "l1:l2:")) != -1) {
switch (option) {
case '1':
l1p = atoi(optarg);
break;
case '2':
l2p = atoi(optarg);
break;
default:
fprintf(stderr, "Usage: %s -l1 <value> -l2 <value>\n", argv[0]);
exit(EXIT_FAILURE);
}
}
printf("l1p = %d, l2p = %d\n", l1p, l2p);
int file;
set_backlight(1, 0, 0);
file = i2c_init(MPC9808_BUS, DISPLAY_TEXT_ADDR);
init_display(file);
write_to_display_xy(file, l1p, 1, "Mercantec");
write_to_display_xy(file, l2p, 2, "Mercantec");
return 0;
}