Giter Site home page Giter Site logo

I2C device driver about rtems_rpi_testing HOT 6 CLOSED

asuol avatar asuol commented on July 30, 2024
I2C device driver

from rtems_rpi_testing.

Comments (6)

asuol avatar asuol commented on July 30, 2024

Hello Giorgio,

Stuff has changed places a bit in the RTEMS source tree in the last 5 years. The drivers in this repository were originally used with RTEMS 4.11, so the README is a bit out-of-date.

RTEMS stayed in version 4.11 for a few years and only somewhat recently moved to version 5, and with this version bump the tree structure has been updated.

The device drivers in this repository were developed so I could test the rpi BSP I2C and SPI drivers while connected with real hardware through the buses. The SPI and I2C drivers were integrated on the RTEMS repository, but the device drivers were kept out-of-tree (in this repository) as only I had these specific hardware (mcp23008 and 23k256) and it was not relevant for the community to have and maintain these drivers in the RTEMS tree.

Therefore to use these device drivers with RTEMS, you need to copy the sources into the RTEMS source tree so RTEMS can be compiled with them and you can use them from your RTEMS application.

Looking at the current RTEMS source tree, the current procedure should be:

  • The include for <dev/i2c/i2c.h> in the driver header should now be <rtems/libi2c.h>
  • The file mcp23008.c should be placed in the directory bsps/shared/dev/i2c instead of libchip/I2C
  • The file mcp23008.h should be placed in the directory bsps/include/libchip
  • For this to be compiled with RTEMS, you need to add the driver .c to the bsps/shared/shared-sources.am file:
    • librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/i2c/mcp23008.c
  • And the driver .h to the bsps/headers.am file under the libchip headers:
    • include_libchip_HEADERS += ../../bsps/include/libchip/mcp23008.h
  • And then compile RTEMS.

To use the driver from your application just include it with

#include <libchip/mcp23008.h>

along with the <bsp/i2c.h> to include the raspberry I2C driver as shown in the test case (I2C_MCP23008_TEST) provided.

The test may not work directly as the test framework and libraries have likely changed since then, but the driver operation is still the same so it should be enough for you to see how to operate the driver.

I have not tested the proposed changes above on RTEMS 5, but this should work, or at least nudge you in the right direction I hope :)

Let me know how it goes

from rtems_rpi_testing.

giorgiobasile avatar giorgiobasile commented on July 30, 2024

I see, so it has to be included in the source code and then built with RSB. It is probably a silly question, but I just wonder whether it is feasible to just include the driver in my RTEMS test application to make it work, or if doing that will result in a failure (especially when the device driver references to the i2c driver i.e. I currently have an error when calling i2c_dev_alloc_and_init)

I'm just interested in understanding whether compiling the driver with RTEMS is the only feasible approach or just including it in my app is also a viable solution and I should expect it to be working.

Again, thanks a lot for your help!

from rtems_rpi_testing.

asuol avatar asuol commented on July 30, 2024

Having the driver in the RTEMS source tree is not mandatory, it was just cleaner that way when using the device driver as part of a RTEMS testsuite test.

Since all applications are linked with RTEMS you have access to the RTEMS libraries, so you can compile the driver alongside your application.

Regarding the i2c_dev_alloc_and_init() function problem, I realized I pointed you to the wrong I2C library: it should still be <dev/i2c/i2c.h> (located at cpukit/include/dev/i2c/i2c.h in the RTEMS tree for reference) as stated on mcp23008.h.

The <libchip/i2c.h> header is for the legacy I2C library. Sorry for the confusion.

You should be able to just take the device driver as is from this repo and compile it together with your application. The <bsp/i2c.h> driver will also be available to your application since you are compiling RTEMS for the RPI BSP (all headers under "bsp" come from the compiled BSP include/bsp directory).

from rtems_rpi_testing.

giorgiobasile avatar giorgiobasile commented on July 30, 2024

Great, compiling the device driver with the application seems to be working now, the problem with i2c_dev_alloc_and_init() was related to a wrong bus_path.
Sorry for bothering you again, but I have one more question: we have made some adaptations to your driver to create a simple application that reads two bytes from a register of an MCP3425.
Here is a simplified version of the code we are implementing:

rpi_setup_i2c_bus();
i2c_dev_register_mcp3425("/dev/i2c-1", "/dev/i2c-1.mcp3425", MCP3425_ADDR);
int fd = open("/dev/i2c-1.mcp3425", O_RDWR);

ioctl(fd, MCP3425_READ);

where MCP3425_READ is used by our i2c_mcp3425_linux_ioctl to trigger a i2c_mcp3425_read function very similar to your i2c_mcp23008_read_register:

static int i2c_mcp3425_linux_ioctl(i2c_dev *dev, ioctl_command_t command, void *arg) {

    uint8_t reg_content [2] = {0};  // *edit*
    int rv = 0;
    switch ( command ) {
        case MCP3425_READ:
             rv = i2c_mcp3425_read(dev, 0x00, reg_content);   // *edit*
             break;
        default:
             rv = -1;
    }
    return rv;
}
static int i2c_mcp3425_read(i2c_dev *dev,  uint8_t reg,  uint8_t* reg_content) {
  i2c_msg msg = {
    {
    .addr = dev->address,
    .flags = 0,
    .len = 1,
    .buf = &reg
    },
    {
    .addr = dev->address,
    .flags = I2C_M_RD,
    .len = 2,    // *edit*
    .buf = reg_content
    }
  };

  return i2c_bus_transfer(dev->bus, &msg, 2);
}

Unfortunately, the application seems to get stuck on i2c_bus_transfer, so we are not getting any error code back, nor any fatal error reported by RTEMS, so it is quite difficult to understand what's happening.
Do you have any idea or suggestion on which situations this may happen, other than in case of hardware issues?

Thanks again for your time and useful info!

from rtems_rpi_testing.

asuol avatar asuol commented on July 30, 2024

In polling mode (the default) the driver can be stuck in an endless loop (I2C polling function) if the expected data never arrives. An alternative to this is to use the driver in interrupt mode (set I2C_IO_MODE to 1, using the RSB option --with-rtems-bspopts="I2C_IO_MODE=1"), where i2c_bus_transfer should terminate with a timeout after a while.

Reasons for the data not arriving from the device may include:

  • incorrect order of operations (maybe you need to write to the device first)
  • an incorrect slave address (double check your constant MCP3425_ADDR)
  • the device does not support the bus speed (in this case the driver's default clock is 100Khz, which is the standard)
  • length of your I2C cables (max ~20cm depending on bus speed). Data from the device may be lost to impedance due to a long cable and the RPI never receives the data

from rtems_rpi_testing.

giorgiobasile avatar giorgiobasile commented on July 30, 2024

The length of the cable was indeed to blame, the RPi receives the data now. Thanks again for your support!

from rtems_rpi_testing.

Related Issues (3)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.