Trying to add LCD display to a CM3, I can see the device but I cannot write to the screen…
// Steps to recreate…
sudo apt-get install -y build-essential wireless-tools spi-tools i2c-tools
# add i2c to rock so no need for sudo
sudo usermod -aG i2c rock
sudo reboot
# look for i2c devices
ls -ltr /dev/i*
i2cdetect -l
i2c-6 i2c DesignWare HDMI I2C adapter
i2c-0 i2c rk3x-i2c I2C adapter
vi /boot/config.txt
append at end
dtoverlay=rk3568-i2c2-m0
sudo update_extlinux.sh
sudo reboot
i2cdetect -l
i2c-6 i2c DesignWare HDMI I2C adapter
i2c-2 i2c rk3x-i2c I2C adapter
i2c-0 i2c rk3x-i2c I2C adapter
before add display
i2cdetect -y 2
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – -- – -- – -- – -- – -- – -- –
10: – -- – -- – -- – -- – -- – -- – -- – --
20: – -- – -- – -- – -- – -- – -- – -- – --
30: – -- – -- – -- – -- – -- – -- – -- – --
40: – -- – -- – -- – -- – -- – -- – -- – --
50: – 51 – -- – -- – -- – -- – -- – -- – --
60: – -- – -- – -- – -- – -- – -- – -- – --
70: – -- – -- – -- – --
add display
i2cdetect -y 2
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – -- – -- – -- – -- – -- – -- –
10: – -- – -- – -- – -- – -- – -- – -- – --
20: – -- – -- – -- – 27 – -- – -- – -- – --
30: – -- – -- – -- – -- – -- – -- – -- – --
40: – -- – -- – -- – -- – -- – -- – -- – --
50: – 51 – -- – -- – -- – -- – -- – -- – --
60: – -- – -- – -- – -- – -- – -- – -- – --
70: – -- – -- – -- – --
//. c test programme
#include
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <string.h>
// HD44780U Commands
#define LCD_CLEAR 0x01
#define LCD_HOME 0x02
#define LCD_ENTRY 0x04
#define LCD_CTRL 0x08
#define LCD_CDSHIFT 0x10
#define LCD_FUNC 0x20
#define LCD_CGRAM 0x40
#define LCD_DGRAM 0x80
// Bits in the entry register
#define LCD_ENTRY_SH 0x01
#define LCD_ENTRY_ID 0x02
// Bits in the control register
#define LCD_BLINK_CTRL 0x01
#define LCD_CURSOR_CTRL 0x02
#define LCD_DISPLAY_CTRL 0x04
// Bits in the function register
#define LCD_FUNC_F 0x04
#define LCD_FUNC_N 0x08
#define LCD_FUNC_DL 0x10
#define LCD_CDSHIFT_RL 0x04
#define I2C_BUS “/dev/i2c-2”
// I2C address of the LCD module
// i2cdetect -y 2
// #define LCD_ADDR 0x3F
#define LCD_ADDR 0x27
// Function to send a command to the LCD
void sendCommand(int fd, unsigned char command)
{
unsigned char buffer[2];
buffer[0] = 0x80; // Co = 1, Rs = 0 (control byte)
buffer[1] = command;
printf(“Sending command 0x%02X \n”, command);
if (write(fd, buffer, 2) != 2)
{
printf(“Error sending command to the I2C LCD : 0x%02X \n”, command);
close(fd);
exit(1);
}
}
void sendData(int fd, unsigned char data)
{
unsigned char buffer[2];
buffer[0] = 0x40;
buffer[1] = data;
printf(“Sending data 0x%02X \n”, data);
if (write(fd, buffer, 2) != 2)
{
printf(“Error sending data to the I2C LCD : 0x%02X \n”, data);
close(fd);
exit(1);
}
}
void setCursorPosition(int fd, int row, int col)
{
int row_offsets[] = {0x00, 0x40, 0x14, 0x54}; // Row offsets for a 20x4 LCD;
if (row > 0 && row <= 4)
{
sendCommand(fd, 0x80 | ((col - 1) + row_offsets[row - 1]));
}
}
void delay(int milliseconds)
{
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
nanosleep(&ts, NULL);
}
int main()
{
// Open the I2C bus
printf(“start”);
int fd = open(I2C_BUS, O_RDWR);
if (fd == -1)
{
printf( “Error opening the I2C bus \n” );
return 1;
}
// Set the I2C address of the LCD
if (ioctl(fd, I2C_SLAVE, LCD_ADDR) == -1)
{
printf( “Error setting I2C address \n” );
close(fd);
return 1;
}
printf(“Start Initialize\n”);
sendCommand(fd, 0x33); // Initialize
sendCommand(fd, 0x32); // Initialize
sendCommand(fd, LCD_CLEAR);
sendData(fd, ‘H’);
// Close the I2C bus
close(fd);
return 0;
}