beagley-ai i2c4 device tree

Need to use i2c4 and found that it is commented out. Does this imply something will break if it is enabled or was it just commented out for rpi compatibility?

//&main_i2c4 {
//	symlink = "hat/i2c4";
//	status = "okay";
//	clock-frequency = <100000>;
//};

Checking this page (I2C at BeagleY-AI GPIO Pinout) it says at bottom “(*) BeagleY-AI can make an additional I2C interface available (I2C4) via Header Pins 15 and 22 respectively.” - so I think you are ok enabling.

It appears that the only conflict would be with those are also 2 of the PWM pins (but there are plenty of those).

It references a node that is not present in the base tree, that snippet might just be a WIP marker.

@RobertCNelson Need to know the exact node to attach i2c4 onto. When I attach to root with the i2c4 register address the USB breaks, attach to what I assume as the controller, main_i2c0 the kernel breaks. Can you point me in the direction that has the correct node.

1 Like

How can one use i2c(N) if any are available?

Seth

P.S. I will be going through the .dts files slowly (new here). If someone knows how to enable the i2c(N) for a device, please let me know.

I see in the .dts, there are some ideas relative to i2c4:

        hat_15_i2c: hat-15-i2c-pins {
                pinctrl-single,pins = <
                        J722S_IOPAD(0x0A8, PIN_INPUT_PULLUP, 1) /* (R27) GPMC0_CSn0.I2C4_SCL */
                >;
        };

        hat_22_i2c: hat-22-i2c-pins {
                pinctrl-single,pins = <
                        J722S_IOPAD(0x0AC, PIN_INPUT_PULLUP, 1) /* (P21) GPMC0_CSn1.I2C4_SDA */
                >;
        };

When I use i2cdetect, I get no data back for a known reason. Now, do I understand the known reason? No.

Any guidance is welcomed. I am starting to think i2c-4 is not literally supposed to be used.

Was there a group of people that decided that the only i2c bus is not supposed to be used with specific modules? I have an Infineon CO2 module (still) and I finally am thinking that using it with a logic level translator would be beneficial to rule out CO2 in the confines.

Anyway, send data back when you have time!

bus = smbus.SMBus(1)

So, something like the below source and not the above source may work or am I off base here with gesturing this solution?

bus = smbus.SMBus('/dev/hat/main_i2c1')

Actually, I tried. Is there a key element I am missing here?

Seth

P.S. I will keep at it to figure out my woes. If not CO2 and if I am getting some odd VOCs at a residence, I need to get current. I know this seems odd. Sorry.

A-Okay…please do not laugh at this short script. The source was derived from a TIC/i2c program online:

// Uses the Linux I2C API to send and receive data.
// NOTE: The control mode must be "Serial / I2C / USB".
// NOTE: For reliable operation on a BeagleY-AI, enable the i2c-gpio
//   overlay and use the I2C device it provides (usually /dev/i2c-3).
// NOTE: You might need to change the 'const char * device' line below
//   to specify the correct I2C device.
// NOTE: You might need to change the `const uint8_t address' line below
// to match the device number of your board.

#include <fcntl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>

// Opens the specified I2C device.  Returns a non-negative file descriptor
// on success, or -1 on failure.
int open_i2c_device(const char * device)
{
  int fd = open(device, O_RDWR);
  if (fd == -1)
  {
    perror(device);
    return -1;
  }
  return fd;
}

// Sends the "Exit safe start" command.
// Returns 0 on success and -1 on failure.
int exit_safe_start(int fd, uint8_t address)
{
  uint8_t command[] = { 0x83 };
  struct i2c_msg message = { address, 0, sizeof(command), command };
  struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 };
  int result = ioctl(fd, I2C_RDWR, &ioctl_data);
  if (result != 1)
  {
    perror("failed to exit safe start");
    return -1;
  }
  return 0;
}

// Sets the target position, returning 0 on success and -1 on failure.
//
int set_target_position(int fd, uint8_t address, int32_t target)
{
  uint8_t command[] = {
    0xE0,
    (uint8_t)(target >> 0  & 0xFF), // Not set in stone yet
    (uint8_t)(target >> 8  & 0xFF), // Not set in stone yet and etc...
    (uint8_t)(target >> 16 & 0xFF),
    (uint8_t)(target >> 24 & 0xFF),
  };
  struct i2c_msg message = { address, 0, sizeof(command), command };
  struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 };
  int result = ioctl(fd, I2C_RDWR, &ioctl_data);
  if (result != 1)
  {
    perror("failed to set target position");
    return -1;
  }
  return 0;
}

// Gets one or more variables from the BeagleY-AI (without clearing them).
// Returns 0 for success, -1 for failure.
int get_variable(int fd, uint8_t address, uint8_t offset,
  uint8_t * buffer, uint8_t length)
{
  uint8_t command[] = { 0xA1, offset };
  struct i2c_msg messages[] = {
    { address, 0, sizeof(command), command },
    { address, I2C_M_RD, length, buffer },
  };
  struct i2c_rdwr_ioctl_data ioctl_data = { messages, 2 };
  int result = ioctl(fd, I2C_RDWR, &ioctl_data);
  if (result != 2)
  {
    perror("failed to get variables");
    return -1;
  }
  return 0;
}

// Gets the "Current position" variable from the BeagleY-AI.
// Returns 0 for success, -1 for failure.
int get_current_position(int fd, uint8_t address, int32_t * output)
{
  *output = 0;
  uint8_t buffer[4];
  int result = get_variable(fd, address, 0x22, buffer, sizeof(buffer));
  if (result) { return -1; }
  *output = buffer[0] + ((uint32_t)buffer[1] << 8) +
    ((uint32_t)buffer[2] << 16) + ((uint32_t)buffer[3] << 24);
  return 0;
}

int main()
{
  // Choose the I2C device.
  const char * device = "/dev/hat/main_i2c1";

  // Set the I2C address of the BeagleY-AI (the device number).
  const uint8_t address = 14;

  int fd = open_i2c_device(device);
  if (fd < 0) { return 1; }

  int result;

  int32_t position;
  result = get_current_position(fd, address, &position);
  if (result) { return 1; }
  printf("Current position is %d.\n", position);

  int32_t new_target = position > 0 ? -200 : 200;
  printf("Setting target position to %d.\n", new_target);
  result = exit_safe_start(fd, address);
  if (result) { return 1; }
  result = set_target_position(fd, address, new_target);
  if (result) { return 1; }

  close(fd);
  return 0;
}

The TIC is a controller I am guessing from Pololu.com but I do not find their ideas of the controller online for now. It must be an older model. Anyway, without correctly entering in my data, I am guessing in the dark again. Oh and the i2c device is not registered… What do I have to do to register the i2c device on the BeagleY-AI?

If memory is correct, it has at least one i2c enabled on the factory image. Pretty sure we did some testing with at least 2 i2c sensors connected. Take a known working sensor and just connect it to i2c designated pins and scan the bus and look for its id. If you can see it on the bus it will work.

Start out with the simplest code, read the sensor and squirt that data out to the console in raw form. Once you get that working the rest will fall into place. Not sure how old you are so you might not have experienced a puzzle, those required all the pieces to be assembled correctly to create a really cool picture. Same thing with this stuff, ONE PIECE at A TIME, too big of a bite and you will choke.

Break down your code, one part at a time, cli and printf are your friend. Did you get a FD??, output it or error message if it failed. When that works, move forward.

1 Like

i2cdetect returns nothing…

I have tested with 0, 1, 2, 3, 4, 5.

No go on any of them… And, hopefully I did not fry the bus because of testing for 0.

Seth

P.S. The code is way off. I know this is a fact, i.e. this is why I stopped. I could not even register a i2c bus that I could find.

update

@foxsquirrel , do you think that using a logic level translator may get in the way of reporting the output of i2cdetect?

If the sensor does not have pull-up resistors install something like 4.7k to 5.6k range. Gnd must be common ground on the header and pullups on both lines. I just carefully tack them on the board.

I bought some of the those logic level translators on amazon a few years ago, they were all junk and do absolutely nothing. I suspect they were floor sweepings or rejects.

What sensor are you trying this with, the temp/humidity sensor is pretty straight forward. If memory is correct its like aht or dht 10 or something like that and it does not have pull-ups.

1 Like

Okay and do not laugh too hard:

  1. Sensor
    a. Xensiv PASCO2 board with adapter 5v…
  2. Level Translation Part for Pi (I Think)?
    a. oono

Seth

Specs callout UART, use a usb to ttl adapter. That would be a quick and easy start. Something like that sensor would be at home on usb. Its not a high speed device, and usb is simple to talk to. When you get it and get your data parsed work on i2c if that is a better fit.

1 Like

I have the board now…

Thus i2c. But usb…okay. I will try. It shows up as a device.

Seth

I have it plugged in to i2c4 (GPIO15 and GPIO22) and about this connection, should I just plainly plug in the USB to the BeagleY-AI and use UART/Serial?

Good, the data sheet did not have much on uart protocol, I did find this link and it give a little more insight into communicating with it.

1 Like

With i2c connecting that would be a good way to go, just depends and what the end game is.

@foxsquirrel …I have not used UART/Serial with a C file in a bit or at all. I am not even sure now.

Anyway, okay. I will attempt it.

Seth

P.S. Is there some fashion to using Serial that I may be unaware of now? Oh and the end game is testing for CO2 concentrations in the this house. Seriously, I have been having spits of sleep and no sleep. The alarm was fooled with from some worker(s) and I am not 100% positive that things got fixed correctly or broken where I would not notice… (Or whatever).

Many years ago we had some squirrel(s) that packed the fiberglass insulation into the gas water heater vent. Occasionally our co monitor would go off and it was dismissed as a batteries…Well, finally the hvac guys found it with a special detector. We could not believe how much insulation they had packed into that vent pipe. It was 100% obstructed. Point is, the sensors don’t lie, if it is going off you have an issue some place.

1 Like

Right on pecan!

I am not any closer than before…I got swamped down by fluff barriers of installable source packages for Win 11. Boo.

Anyway, I still could not get WSL2 to accept that I was trying to log in to a serial port with /dev/ttyACM0.

Seth

P.S. Still trying. I feel like a fresh new born again! Off to Linux soon! Hey man, did you see where the GOV wants to hush C/C++ from programmers? Look at this funny idea: The US government wants devs to stop using C and C++ • The Register

Odd days?

Also…back to the issue at hand!

I found a, through website jumping and some small research, an installable PASCO2 lib. and am currently testing it…

https://infineon.github.io/sensor-xensiv-pasco2/html/index.html

Seth

They have no clue, maybe one of the big tech companies has a new CF of programming language and want to force every developer to use it on a subscription… What about python, that is built on top of C++… EVERY THING is attached to a dollar bill…

1 Like

Probably,

On the same note as beforehand, how would I connect to the USB device within the fs (Linux) on the BeagleY-AI or BBAI-64?

For instance, would I just say something like:

$ stty -F /dev/ttyACM0 115200

or would using source be an easier route. Right now, I am thinking that the i2c device on the boards from beagleboard.org would be easier for me but…

  1. I am lacking developmental capabilities for UART communication.
    a. I am not quite sure how to go about putting UART in to a C file…

I have some source but it is hearsay now. I will be reviewing the source and testing as needed…

The “hearsay” source is lengthy and actually has functions for programming the onboard chip on the CO2 for the heater.

Look at this data: The photoacoustic principle can be traced back to over 100 years ago, first discovered by Alexander Graham Bell in 1880. That is how the heater on this device works…

Photoacoustic Spectroscopy…

Seth

P.S. This is what I have been using: Programming guide for XENSIVTM PAS CO2