Linux C++ implementation of ioctl SOLVED
-
Broken 5V supply to LCD! I should have know better since the LCD did not react to power-up - reset and show 5/7 characters - but the power LED was on on the i2c module itself ! Learned few Linux tools on how to troubleshoot i2c, so no big loss. Now I can proceed with implementing ioctl. I would like to discuss implementation of Linux ioctl function. There are few reasons I am posting my question here and not on Linux forum. However, if you feel it is inappropriate you have two options - ignore my request ( preferred to sermon ) or flag it to be removed. I am basically aware WHAT ioctl does, and have been thru few documents ( Linux Device drivers, CodeProject driver tutorials etc.) I am trying to implement ioctl "driver" to output (Raspberry Pi) to I2C LCD. The problems I cannot get straight is how to configure I2C speed (using C++, not Linux commands ) and implement ACK read from slave I2C device. I understand I2C protocol, but all of the sample codes I have read so far are "limited" to open ioctl file and "write " to I2C slave address. I like to see or make my own code to implement I2C "start /stop " and read ACK/ NACK from slave. Any to the point help will as always be appreciated. Thanks
-
Broken 5V supply to LCD! I should have know better since the LCD did not react to power-up - reset and show 5/7 characters - but the power LED was on on the i2c module itself ! Learned few Linux tools on how to troubleshoot i2c, so no big loss. Now I can proceed with implementing ioctl. I would like to discuss implementation of Linux ioctl function. There are few reasons I am posting my question here and not on Linux forum. However, if you feel it is inappropriate you have two options - ignore my request ( preferred to sermon ) or flag it to be removed. I am basically aware WHAT ioctl does, and have been thru few documents ( Linux Device drivers, CodeProject driver tutorials etc.) I am trying to implement ioctl "driver" to output (Raspberry Pi) to I2C LCD. The problems I cannot get straight is how to configure I2C speed (using C++, not Linux commands ) and implement ACK read from slave I2C device. I understand I2C protocol, but all of the sample codes I have read so far are "limited" to open ioctl file and "write " to I2C slave address. I like to see or make my own code to implement I2C "start /stop " and read ACK/ NACK from slave. Any to the point help will as always be appreciated. Thanks
You have two options:
- Use the existing I2C support on the Raspberry Pi with the I2C GPIO pins
- Implement your own I2C support on general use GPIO pins
The I2C speed is defined by the master by generating the clock. A device might use "clock stretching" to slow down (Clock, Stretching, Arbitration - I2C Bus[^]). So implementations are not time critical. They can use a predefined (max.) clock and have not to care about being slowed down by other tasks on the system. I have implemented I2C in assembler on micro controllers. Implementing it in C is not a problem but be aware that it might be a frustrating tasks because it can't be simply debugged. I highly recommend to use a logic analyser or at least a storage oscilloscope to check the signals on the bus.
Quote:
all of the sample codes I have read so far are "limited" to open ioctl file and "write " to I2C slave address.
With device drivers use
i2c_transfer()
. Have a look at the source of any Linux driver for a I2C device like rtc-pcf8563.c [^]. When usingioctl()
on the I2C device just useread()
:int fd = open("/dev/i2c-1", O_RDWR);
// Use I2C_SLAVE_FORCE if the device is in use (e.g. when a driver is installed)
ioctl(fd, I2C_SLAVE, addr);
read(fd, buffer, length);Or use
ioctl(I2C_RDWR)
orioctl(I2C_SMBUS)
for reading which both does not require theI2C_SLAVE[_FORCE]
. In any case check first if the usedioctl()
call is supported. -
Broken 5V supply to LCD! I should have know better since the LCD did not react to power-up - reset and show 5/7 characters - but the power LED was on on the i2c module itself ! Learned few Linux tools on how to troubleshoot i2c, so no big loss. Now I can proceed with implementing ioctl. I would like to discuss implementation of Linux ioctl function. There are few reasons I am posting my question here and not on Linux forum. However, if you feel it is inappropriate you have two options - ignore my request ( preferred to sermon ) or flag it to be removed. I am basically aware WHAT ioctl does, and have been thru few documents ( Linux Device drivers, CodeProject driver tutorials etc.) I am trying to implement ioctl "driver" to output (Raspberry Pi) to I2C LCD. The problems I cannot get straight is how to configure I2C speed (using C++, not Linux commands ) and implement ACK read from slave I2C device. I understand I2C protocol, but all of the sample codes I have read so far are "limited" to open ioctl file and "write " to I2C slave address. I like to see or make my own code to implement I2C "start /stop " and read ACK/ NACK from slave. Any to the point help will as always be appreciated. Thanks
The speed is configured outside the program or on the library you are using on the Pi Edit /boot/config.txt if it doesn't exist create it add the line or edit the line with your baudrate
dtoverlay=i2c-speed,i2c1_baudrate=400000
i2c1 may also be disabled by default I can't remember if so you need
dtparam=i2c_vc=on
In the userland repository there is also a direct header and library bcm2835: C library for Broadcom BCM 2835 as used in Raspberry Pi[^] and a forum bcm2835 : Google Groups[^] Standard use
#include int main(int argc, char **argv)
{
char buf[1];if (!bcm2835\_init())return 1; bcm2835\_i2c\_begin(); //Start I2C operations. bcm2835\_i2c\_setSlaveAddress(0x20); //I2C address bcm2835\_i2c\_set\_baudrate(10000); //1M baudrate while(1) { buf\[0\] = 0xEF; //LED ON bcm2835\_i2c\_write(buf,1); bcm2835\_delay(500); buf\[0\] = 0xFF; //LED OFF bcm2835\_i2c\_write(buf,1); bcm2835\_delay(500); } bcm2835\_i2c\_end(); bcm2835\_close(); return 0;
}
In vino veritas
-
The speed is configured outside the program or on the library you are using on the Pi Edit /boot/config.txt if it doesn't exist create it add the line or edit the line with your baudrate
dtoverlay=i2c-speed,i2c1_baudrate=400000
i2c1 may also be disabled by default I can't remember if so you need
dtparam=i2c_vc=on
In the userland repository there is also a direct header and library bcm2835: C library for Broadcom BCM 2835 as used in Raspberry Pi[^] and a forum bcm2835 : Google Groups[^] Standard use
#include int main(int argc, char **argv)
{
char buf[1];if (!bcm2835\_init())return 1; bcm2835\_i2c\_begin(); //Start I2C operations. bcm2835\_i2c\_setSlaveAddress(0x20); //I2C address bcm2835\_i2c\_set\_baudrate(10000); //1M baudrate while(1) { buf\[0\] = 0xEF; //LED ON bcm2835\_i2c\_write(buf,1); bcm2835\_delay(500); buf\[0\] = 0xFF; //LED OFF bcm2835\_i2c\_write(buf,1); bcm2835\_delay(500); } bcm2835\_i2c\_end(); bcm2835\_close(); return 0;
}
In vino veritas
Thanks for replies. I am currently "on the road" and will reply when I get home. In short I did try "just GPIO" , it worked to the point, but it got too convoluted. Hence I am after using ioctl. I'll take a look at the bcm2835.h, hopefully I can use it for bcm2837 chip used in RPi 3B. I think my main concern is still to be able to "see" the code following / running the I2C spec - mainly changing hardware pins directions and reading START /STOP and ACK/NACK back. Of course I am verifying the actual LCD and sometime even using scope. Thanks for all your comments, appreciate that.