Class pn532::esp32::i2c_channel

Inheritance Relationships

Base Type

Class Documentation

class i2c_channel : public pn532::channel

Implementation of I2C channel protocol for PN532 over ESP32’s I2C driver (UM0701-02 §6.2.4).

This class supports, when specified, the possibility of using a GPIO pin for the PN532’s IRQ line; in that case, the class does not have to poll the controller until the answers are ready, but it will instead idle and wait for the IRQ line to become active, and read the answer only then once it’s ready. That is done through a semaphore and an interrupt installed on the GPIO.

Warning

Due to ESP32’s “buffered” type of I2C commands, it is not possible to easily read variable length data. This channel is relatively slow because in order to read a full PN532 packet, it has to issue several I2C commands. The reason is that we need to build the I2C command in beforehand, so we need to know already the read length. To work around this limitation, we request the packet several times using an PN532-level NACK message until we have enough information to read the full extent of the message. Attempts at “tricking” the ESP32’s driver by not issuing the necessary stop failed, as they put the PN532 in an invalid state.

Public Functions

virtual bool wake() override

Sends an empty I2C command to wake the PN532.

i2c_channel(i2c_port_t port, i2c_config_t config, std::uint8_t slave_address = default_slave_address)

Construct an I2C channel for a PN532 with the given settings.

Note

In case of invalid port or configuration, an error message is printed, but the class is correctly constructed. It will simply always fail to send and receive anything (and may clog your output with error messages).

Parameters:
  • port – Communication port for the I2C channel. This is passed as-is to the I2C driver.

  • config – Configuration for the I2C channel. This is passed as-is to the I2C driver.

  • slave_address – Override for the slave address, defaults to default_slave_address.

i2c_channel(i2c_port_t port, i2c_config_t config, gpio_num_t response_irq_line, bool manage_isr_service, std::uint8_t slave_address = default_slave_address)

Construct an I2C channel for a PN532 with the given settings, using GPIO pin to signal when the answer is ready.

This reduces the amount of I2C noise on the line because it will only read the answer once it’s available.

See also

irq_assert

Note

In case of invalid port or configuration, an error message is printed, but the class is correctly constructed. It will simply always fail to send and receive anything (and may clog your output with error messages).

Parameters:
  • port – Communication port for the I2C channel. This is passed as-is to the I2C driver.

  • config – Configuration for the I2C channel. This is passed as-is to the I2C driver.

  • response_irq_line – The GPIO pin connected to the IRQ line on the PN532. The PN532 signals when the responses are available by setting this line to low; an interrupt triggers then a semaphore that allows this class to read the answer only once it’s ready.

  • manage_isr_service – If set to true, the class will call gpio_install_isr_service and the corresponding uninstall command at destruction. Unless the caller manages the ISR service by themselves, this parm should be set to true.

  • slave_address – Override for the slave address, defaults to default_slave_address.

~i2c_channel() override

Releases the I2C driver.

inline std::uint8_t slave_address_to_write() const
Returns:

Slave address for sending commands to the PN532.

inline std::uint8_t slave_address_to_read() const
Returns:

Slave address for reading data from the PN532.

Public Static Functions

static inline channel_error error_from_i2c_error(i2c::error e)

Converts a i2c::error into a channel_error status code.

Parameters:

e – I2C protocol-level error.

Returns:

Channel-level error.

Public Static Attributes

static constexpr std::uint8_t default_slave_address = 0x48

Default PN532 slave address.

Protected Functions

i2c::command raw_prepare_command(comm_dir mode) const

Prepares a command with the correct mode (write, read) depending on mode;

Returns:

A new command containing only the slave address.

virtual result raw_send(mlab::range<bin_data::const_iterator> buffer, ms timeout) override

Wraps around i2c_master_write, i2c_master_cmd_begin and so on.

virtual result raw_receive(mlab::range<bin_data::iterator> buffer, ms timeout) override

Wraps around i2c_master_read, i2c_master_cmd_begin and so on.

inline virtual comm_rx_mode raw_receive_mode() const override
Returns:

For i2c_channel, this is always comm_rx_mode::buffered.

virtual bool on_receive_prepare(ms timeout) override

Asserts that that data is available to receive.

When using an IRQ line, it waits until the the IRQ line is triggered. When not using an IRQ line, it will poll the PN532 every 10ms to know whether a response is ready or not. This is done directly in raw_receive.