DarkElvenAngel
Posts: 2952
Joined: Tue Mar 20, 2018 9:53 pm

i2c slave mode question [ANSWERED]

Thu Feb 29, 2024 1:13 am

Hello Everyone,

I'm looking at the example code https://github.com/raspberrypi/pico-exa ... _mem_i2c.c and the docs https://www.raspberrypi.com/documentati ... rdware_i2c I don't see the function i2c_slave_init. So I have questions.

Where can I find documentation for this function?

Where can I find documentation for the callback function?

Is there a way to NACK to the master?

Can I listen on more than one address? Looks like No when looking in the data sheet.

I can only assume by the example we can listen on multiple addresses so long as we define them a callback but this is a bold assumption I see the call back has no return so how do we NACK?
Last edited by DarkElvenAngel on Thu Feb 29, 2024 1:52 am, edited 1 time in total.

trejan
Posts: 7204
Joined: Tue Jul 02, 2019 2:28 pm

Re: i2c slave mode question

Thu Feb 29, 2024 1:41 am

DarkElvenAngel wrote:
Thu Feb 29, 2024 1:13 am
Where can I find documentation for this function?
It isn't a hardware API. https://www.raspberrypi.com/documentati ... _i2c_slave
DarkElvenAngel wrote:
Thu Feb 29, 2024 1:13 am
Where can I find documentation for the callback function?
https://www.raspberrypi.com/documentati ... 1712bcbf40
DarkElvenAngel wrote:
Thu Feb 29, 2024 1:13 am
Is there a way to NACK to the master?
IC_SLV_DATA_NACK_ONLY sounds like it'd do it but the SDK doesn't use it.
DarkElvenAngel wrote:
Thu Feb 29, 2024 1:13 am
Can I listen on more than one address?
The controller only supports a single address.

DarkElvenAngel
Posts: 2952
Joined: Tue Mar 20, 2018 9:53 pm

Re: i2c slave mode question

Thu Feb 29, 2024 1:46 am

Thank you,

This is most helpful.

I found this project https://github.com/dgatf/I2C-slave-multi-address-RP2040 that has the multi-address support with a pio was just reading through it. No NACK support though.

In case anyone else comes across this looking for similar.

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: i2c slave mode question [ANSWERED]

Thu Feb 29, 2024 2:54 am

I haven't used I2C yet on RP2040 so have no idea if this works but maybe there's a way to fake NACK. When the I2C interrupt handler runs, the I2C controller is bus stretching by bringing SCL low. It will keep doing that until it has a byte to send or receive. I wonder what would happen if, instead, in the interrupt handler, change the function of the SCL GPIO to SIO. Now the I2C master sees SCL pulled high and and proceeds to clock out the ACK bit, which if SDA is pulled high at that point, would be interpreted as NACK. Could change the function of the SDA GPIO to SIO as well to ensure it is high. This might leave the I2C controller state machine totally confused. I wonder if the multi-master stuff will think there's a bus conflict and give up.

DarkElvenAngel
Posts: 2952
Joined: Tue Mar 20, 2018 9:53 pm

Re: i2c slave mode question [ANSWERED]

Thu Feb 29, 2024 3:10 am

I'm mostly looking to test software on a Pi and use a Pico as a mock device. Having multi addresses would let me populate the bus with fake devices to see if my software could detect the hardware configuration. I know there is a kernel device to do this but I could never get it built and working.

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: i2c slave mode question [ANSWERED]

Thu Feb 29, 2024 5:02 am

Maybe some of these: https://www.renesas.com/us/en/document/ ... ?r=1563671

They are many times programmable. I expect you could use a Pico to do it. I haven't tried but hope to find time soon.

They contain an I2C macrocell with programmable address, though I don't believe the I2C macrocell can be made to NACK.

However, I expect the "circuits" that you can configure are sophisticated enough to make a mock I2C decoder that identifies that it has been addressed and NACKs. https://www.renesas.com/us/en/document/ ... spi-bridge

DarkElvenAngel
Posts: 2952
Joined: Tue Mar 20, 2018 9:53 pm

Re: i2c slave mode question [ANSWERED]

Thu Feb 29, 2024 6:58 pm

alastairpatrick wrote:
Thu Feb 29, 2024 5:02 am
Maybe some of these: https://www.renesas.com/us/en/document/ ... ?r=1563671

They are many times programmable. I expect you could use a Pico to do it. I haven't tried but hope to find time soon.

They contain an I2C macrocell with programmable address, though I don't believe the I2C macrocell can be made to NACK.

However, I expect the "circuits" that you can configure are sophisticated enough to make a mock I2C decoder that identifies that it has been addressed and NACKs. https://www.renesas.com/us/en/document/ ... spi-bridge
Sending the NACK isn't strictly required in my use case. For me it's more about mock hardware and learning how the communications work between the Pi and the Pico/RP2040 and then taking that knowledge to make something with it. So if I can see how NACK would work with only one device address that's good enough the idea of multiple addresses more for what I have planed to maintain backwards compatibility but use a different address for my own implementation. Another reason for the multiple addresses is I do a bus scan to detect what addresses are in use and depending on what addresses are detected I can know what configuration to use.

I also want to see what probing the bus does to the device. I read that it can mess up some chips so I want write my device to avoid that.

In an effort to maintain backwards compatibility and use a different address I could infer from everything (examples, datasheet, SDK documents) I read that it would be possible to switch addresses (on the fly) while using the SDK? So if my device I want to mimic were to use address 0x55 I could simply mock all it's registers and since it has unused ones I could use one of them to basically switch the alternate mode those changing the device address to 0x56 for example? This way under normal operations it would act just the same as it would without my changes and then switch the value in the register and it becomes a different device. I would only need to redirect the callback?

From the example this would set up the default device

Code: Select all

    // configure I2C0 for slave mode
    i2c_slave_init(i2c0, I2C_SLAVE_ADDRESS, &i2c_slave_handler);
Then in i2c_slave_handler when a magic value is written to the right address I could set a flag that would run this code

Code: Select all

    // configure I2C0 for slave mode using second device
    i2c_slave_init(i2c0, I2C_SLAVE_ADDRESS2, &i2c_slave_handler2);
Or should you reset the bus with the i2c_slave_deinit first. The software on the Pi would need to allow time for this to complete.

alastairpatrick
Posts: 753
Joined: Fri Apr 22, 2022 1:39 am
Location: USA

Re: i2c slave mode question [ANSWERED]

Thu Feb 29, 2024 7:55 pm

DarkElvenAngel wrote:
Thu Feb 29, 2024 6:58 pm
So if my device I want to mimic were to use address 0x55 I could simply mock all it's registers and since it has unused ones I could use one of them to basically switch the alternate mode those changing the device address to 0x56 for example?
You could use a second serial channel to communicate which address the mock I2C device should currently use. It could be the second I2C or just regular serial. Serial over USB even if that's easier.

A different idea: if you only needed two mock devices on the same I2C bus, you could wire both RP2040 I2C peripherals in parallel and give each a different address.

Return to “SDK”