adafruit / Adafruit_CircuitPython_PN532

CircuitPython driver for the PN532 NFC/RFID Breakout and PN532 NFC/RFID Shield
MIT License
91 stars 48 forks source link

Could the driver be changed to support passing I2C address as a parameter? #49

Closed ErlendFj closed 1 year ago

ErlendFj commented 2 years ago

Often more than one PN532 needs to be connected to one I2C bus. The chip can be set to different address than the default x24, but at present this driver does not support it, rather it is set as a constant in the code. I can make my own version, but I believe this change would benefit others too. E.g. NFC = PN532_I2C(SCL, SDA, ADDR) ADDR could be an optional parameter, and if left out the default x24 will be set.

FoamyGuy commented 2 years ago

Yes. There are drivers for other hardware device that work that way with the address being passed as an argument to the constructor.

Want to make a PR with that change?

ErlendFj commented 2 years ago

Looking inside the driver the I2C address seems to be a class varaible. I think that is not so good practice. But, NFC is becoming increasingly relevant, and the particular project I am involved in now need 6 of them together. Can do that with SPI, but I2C would be much more elegant and economic. What would a PR involve? (I am not a seasoned git'er). If such a move is supported it would also make sense to provide a change-chip-address command.

dhalbert commented 2 years ago

We have a guide about how to use git and GitHub, including submitting PR's: https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github

FoamyGuy commented 2 years ago

If such a move is supported it would also make sense to provide a change-chip-address command.

I think it's more typical to accept the address as argument for the constructor, but not provide a way to change it after it's been initialized. If user wants to change after initialization they would need to initialize a new instance. I'm not super familiar with this device though, if it's able to change it's address over time during normal usage then maybe it would make sense to provide a property that can be set. But I think most devices typically keep the same address during usage, they just allow jumpers or some other switch that gets checked at power up to determine which of the available addresses to use.

ErlendFj commented 2 years ago

Agree. I did not describe well what I wanted: A method that sends a command and some parameters to the chip itself, with the effect of changing the address of the chip. The chips ususally come with a default address, some of them can be changed by strapping on the board, and some of them can be changed by means of an I2C command. The PN532 is of the latter type. When many of the same type of chip are on the same bus they need to have/ get different addresses.

ErlendFj commented 2 years ago

We have a guide about how to use git and GitHub, including submitting PR's: https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github

Some years ago I did an attempt to learn the git process, but I gave up because my brain just is not made for the command line interface (CLI-dyslexia?), and there where no real GUI solution that I could find. Reading through the above linked material I ended up giving up again, unfortunately. I would like to contribute to Open Source, but I think the only way that works for me is by sharing my code, as-is. In this particular case (PN532 driver) the change is only a few lines of code, but I would spend days to push it through the git process. Sorry, that just does not add up for me.

tannewt commented 2 years ago

@ErlendFj You can edit files from the github site and create a new pull request: https://docs.github.com/en/repositories/working-with-files/managing-files/editing-files That is easy for small changes.

ErlendFj commented 2 years ago

@ErlendFj You can edit files from the github site and create a new pull request: https://docs.github.com/en/repositories/working-with-files/managing-files/editing-files That is easy for small changes.

Thanks, that looks easy.

tcfranks commented 1 year ago

looking at the data sheet, there are master / slave configurations for multiple chips. but i've yet to find an example of running multiple chips separately addressed as masters (but, only 60 pgs in of 222 pgs of specs, so it's a lot of reading!) https://www.nxp.com/docs/en/nxp/data-sheets/PN532_C1.pdf

caternuson commented 1 year ago

Can you provide a page number in the datasheet that is showing multiple PN532's sharing the same I2C bus?

It might only have the one fixed address of 0x48. So would want to use something like a muxer for multiple PN532's: https://learn.adafruit.com/working-with-multiple-i2c-devices

tcfranks commented 1 year ago

The I2C interface description starts in section 8.3.2 on page 50 of the pdf I referenced. It isn't clear about how x48 becomes the starting address. It DOES discuss the 4 modes of I2C operation, which I didn't follow.

There is also this (unhelpful?) thread on the nxp forums touching on it: https://community.nxp.com/t5/NFC/Host-interface-PN532-and-I2C-address/m-p/1046057

There is this thread too on adafruit: https://forums.adafruit.com/viewtopic.php?f=31&t=39773 This thread emphasizes the fixed address and mentions using something like a pico where you can have multiple i2c channels defined for accessing multiple devices. A mux chip should work as well, I imagine.

caternuson commented 1 year ago

I'd suggest just using a mux.

Looks like there's a register that can set the address. But it's confusing. Datasheet shows reset value is 0x00 but just powering a PN532 in I2C mode a scanning returns address of 0x24 (that's the 7 bit address, 0x48/0x49 are just the 7bit address+1bit read/write values).

NXP didn't really answer the question in that thread. They just say look at 8.3.2 of datasheet - which shows 0x00 address.

Even if that register could be used to set an alt address. It's unclear it'd be retained on reset. Or require a convoluted sequential power up, set I2C address, dance for every PN532.

tcfranks commented 1 year ago

That was my conclusion as well

On Fri, Feb 10, 2023 at 4:52 PM Carter Nelson @.***> wrote:

I'd suggest just using a mux.

Looks like there's a register that can set the address. But it's confusing. Datasheet shows reset value is 0x00 but just powering a PN532 in I2C mode a scanning returns address of 0x24 (that's the 7 bit address, 0x48/0x49 are just the 7bit address+1bit read/write values).

NXP didn't really answer the question in that thread. They just say look at 8.3.2 of datasheet - which shows 0x00 address.

Even if that register could be used to set an alt address. It's unclear it'd be retained on reset. Or require a convoluted sequential power up, set I2C address, dance for every PN532.

— Reply to this email directly, view it on GitHub https://github.com/adafruit/Adafruit_CircuitPython_PN532/issues/49#issuecomment-1426387871, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQVC4PRNUEHXH3TV24JGUNLWW22C7ANCNFSM5GQB7SDA . You are receiving this because you commented.Message ID: @.***>

caternuson commented 1 year ago

The code change needed for this is minimal. Made a PR to add it. See #62.

caternuson commented 1 year ago

Closing. Added with #62.