Hi, Alan and David!

I'm using nrf52_sx1509.c (at boards/arm/nrf62/thingy52/src) as model for my 
driver. I've attached what I have wrote so far and I'd like to know if you 
could tell me if I'm at the right direction:
[cid:efd68788-44d6-4e3f-a528-ab0fb1e35f03] (print from nrf52_sx1509.c, 
nrf52_sx1509_pinscfg() method)

My guess for what I should implement is to set the direction and option for 
every pin in PCF8575 and after that write bytes to those I set as outputs, is 
it correct?
what exactly does IOEXP_SETOPTION() do?

Thank you for the support!
________________________________
De: Alan C. Assis <acas...@gmail.com>
Enviado: sexta-feira, 6 de outubro de 2023 10:36
Para: dev@nuttx.apache.org <dev@nuttx.apache.org>
Assunto: Re: PCF8575 driver for NuttX

Hi David,

In a quick search I noticed that i2c_vbus_initialize() never was part
of NuttX, maybe it is something you created to abstract from different
MCUs initialization.

I think we can use some similar (a generic function) to create a
boards/common/ directory to keep all I2C, SPI, devices initialization
that could be common for all boards, even for boards from different
chip families or architecture.

So, i2cbus_initialize() could be just an "alias" to
stm32_i2cbus_initialize, esp32s2_i2cbus_uninitialize,
cxd56_i2cbus_initialize(), etc, depending of what is the MCU arch of
the board.

It could simplify the sensor or other devices support as in this PCF8575 case.

BR,

Alan

On 10/5/23, David S. Alessio <david.s.ales...@gmail.com> wrote:
> Hi, Alan,
>
> I don’t see my I2C virtual bus driver code in the current repo.  I’m not
> sure what happened, but I’d like to [re-] submit it.  Can you point me to
> how that’s done today?  (I’m sure email won’t work).
>
> The problem I see with the existing IOEXPANDER code is that I don’t believe
> it’s thread safe (multiple threads each hammering its own sensor on
> different sub buses).
>
> Cheers,
> -david
>
>
>> On Oct 5, 2023, at 6:18 AM, Alan C. Assis <acas...@gmail.com> wrote:
>>
>> Hi David,
>>
>> I think you figure out Gustavo's mistake.
>>
>> Gustavo, all you need to do is use the existing driver. In your code
>> you was trying to implement a low level driver to communicate with
>> your PCF8575. You don't need to do it.
>>
>> Unfortunately there is not much boards examples using IOEXPANDER (shame on
>> us).
>>
>> But I think Mateusz (raiden00) created one here:
>> boards/arm/nrf52/thingy52/src/nrf52_sx1509.c
>>
>> Just look this example and you will figure out everything.
>>
>> Basically:
>>
>> struct pcf8575_config_s g_pcf8575_cfg
>> {
>>  .address   = 0x71;      /* the I2C address returned by i2ctool */
>>  .frequency = 100000;
>> };
>>
>> ...
>>
>> int stm32_pcf8575_initialize(void)
>> {
>>  struct i2c_master_s     *i2c = NULL;
>>  struct ioexpander_dev_s *ioe = NULL;
>>  int                      ret = OK;
>>
>>  i2c = stm32_i2c_register(I2C_BUS); /* I2C_BUS is your I2Cx bus
>> number (0, 1, etc) */
>>
>>  ioe = pcf8575_initialize(i2c, &g_pcf8575_cfg);
>>  ...
>>
>> }
>>
>> BR,
>>
>> Alan
>>
>> On 10/5/23, David S. Alessio <david.s.ales...@gmail.com> wrote:
>>> Hi, Gustavo,
>>>
>>> You might consider using the I2C IO expander driver I wrote some time ago
>>> to
>>> manage a multi-tiered tree of I2C bus expanders.
>>>
>>> The advantages are:
>>>  * I2C sub buses are transparently available to application space
>>> through
>>> /dev/i2c*
>>>  * transparently manages hierarch of I2C bus expanders
>>>  * downstream I2C device drivers go through the I2C character driver
>>> (pro
>>> and con)
>>>
>>> The disadvantages are:
>>>  * I2C drivers need to use the I2C character driver
>>>  * many I2C HW drivers don’t properly handle multiple command packets in
>>> I2C_TRANSFER()
>>>
>>> Example:  let’s say we have an 4-port I2C switch PCA9545A attached to
>>> /dev/i2c1 using an STM32F407 MCU.  The board initialization would be:
>>>
>>>
>>>  i2c = stm32_i2c_register(1);
>>>
>>>  /*
>>>   *    support for I2C bus epander
>>>   *    /dev/i2c1.0 -- /dev/i2c1.3
>>>   */
>>>  ret = i2c_vbus_initialize("/dev/i2c1", 0x70, I2C_VBUS_PCA9545, 0x0f, 0,
>>> NULL);
>>>  if (ret != OK)
>>>    {
>>>      syslog(LOG_ERR, "ERROR: Failed to initialize i2c_vbus %#x: %d\n",
>>> 0x70, ret);
>>>    }
>>>
>>> Now the sub bus I2C segments are transparently available as /dev/i2c1.0
>>> through /dev/i2c1.3.
>>>
>>> You can add a second PCA9545A, let’s say connected to port 2
>>> (/dev/i2c1.2)
>>> of the first PCA9545A.  It would be registered as:
>>>
>>>      ret = i2c_vbus_initialize("/dev/i2c1.2", 0x71, I2C_VBUS_PCA9545, 0x0f,
>>> 0,
>>> NULL);
>>>
>>> and its ports would be addressable as /dev/i2c1.2.0 through
>>> /dev/i2c1.2.3.
>>>
>>> Let me know if this is something of interest to you, I’ll help you get
>>> it
>>> working...
>>>
>>> Cheers,
>>> -david
>>>
>>>
>>>
>>>> On Oct 4, 2023, at 7:36 PM, Gregory Nutt <spudan...@gmail.com> wrote:
>>>>
>>>>
>>>> On 10/4/2023 8:02 PM, Gustavo Soares wrote:
>>>>> Hi Greg!
>>>>>
>>>>> Yes, if I use #include <nuttx/ioexpander/pcf8575.h> this problem is
>>>>> solved, but then the code loses the reference to that specific struct
>>>>> causing another error.
>>>>>
>>>>> And how exactly "the file does not exist"? I can open it and it is at
>>>>> the
>>>>> nuttx repo, I shared it's link.
>>>> Because the compiler keeps a list of paths that it will include files
>>>> from.  It will NOT include files from drivers/ioexpander because that
>>>> is
>>>> not in that include path list.  So "the file does not exists" in any
>>>> directory in the list of include paths. You could hack up  the build
>>>> system  (but no PRs for that please)or you could just copy the header
>>>> file
>>>> (a lot easier). But you cannot include it from drivers/ioexpander.
>>>> Since
>>>> this is necessarily throw-away code, the easier solution is
>>>> recommended.
>>>
>>>
>
>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/ioexpander/pcf8575.h>
#include <nuttx/ioexpander/ioexpander.h>

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#define PCF8575_I2C_BUS 1
#define PCF8575_I2C_ADDR 0x20 
#define PCF8575_I2C_MAXFREQUENCY 400000
#define OK 0

struct pcf8575_config_s config =
    {
      .address = PCF8575_I2C_ADDR,
      .frequency = PCF8575_I2C_MAXFREQUENCY
    };

static void pcf8575_pinscfg(struct ioexpander_dev_s *dev)
{
    
}

int main(void) //stm32_pcf8575_initialize(void) 
{
    struct i2c_master_s *i2c = NULL;
    struct ioexpander_dev_s *ioe = NULL;
    int ret = OK;

    ret = i2c_register(i2c, PCF8575_I2C_BUS); // stm32_i2c_register()?

    if(ret != OK)
    {
        perror("Could not register i2c");
        return -1;
    }

    ioe = pcf8575_initialize(i2c, &config);

    if (!ioe) 
    {
        perror("Could not init PCF8575");
        return -1;
    }

    pcf8575_pinscfg(ioe);

    //return I2C_TRANSFER(ioe, , 1);
    return 1;
}

Reply via email to