Class pn532::esp32::spi_channel
Defined in File spi.hpp
Inheritance Relationships
Base Type
public pn532::channel
(Class pn532::channel)
Class Documentation
-
class spi_channel : public pn532::channel
Implementation of SPI channel protocol for PN532 over ESP32’s SPI driver (UM0701-02 §6.2.5).
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.
Note
This class supports a “stream-like” usage, i.e. it can progressively read pieces of an incoming info frame in order to determine its length. To achieve that, it is stateful (during a receive operation), as any receive operation other than the first has to omit specifying the data read prefix.
Warning
Experiments have shown that the SPI channel is often unstable, especially at high clocks (> 1MHz). It is not clear why this occurs, but it looks like at high speeds it fails when transmitting extended info frames. Even at low speeds, it seldom fails after long exchanges. The PN532 enters an invalid state in which it never returns an answer. Therefore it’s recommended to stay within 1MHz of speed.
Public Functions
-
virtual bool wake() override
Sends the byte sequence
55 55 55
.
-
spi_channel(spi_host_device_t host, spi_bus_config_t const &bus_config, spi_device_interface_config_t device_cfg, spi_dma_chan_t dma_chan)
Construct an SPI channel for a PN532.
Note
In case of invalid host, device or bus 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:
host – SPI Host to use. Note that on ESP32-S2
SPI1_HOST
is not supported (as per ESP32’s documentation).bus_config – SPI bus configuration.
device_cfg – SPI device configuration. Note that despite PN532 supporting up to 5MHz speed, the channel may be unstable and a lower speed (1MHz) is recommended.
dma_chan – The DMA channel to use for transmitting data. Note that DMA channel 0 is not supported (as per ESP32’s documentation), therefore it must be either DMA channel 1 or DMA channel 2.
-
spi_channel(spi_host_device_t host, spi_bus_config_t const &bus_config, spi_device_interface_config_t device_cfg, int dma_chan, gpio_num_t response_irq_line, bool manage_isr_service)
Construct an SPI channel for a PN532, using the given GPIO pin to signal when the answer is ready (IRQ line).
Using the IRQ line reduces the amount of noise on the line because it will only read the answer once it’s available.
See also
Note
In case of invalid host, device or bus 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:
host – SPI Host to use. Note that on ESP32-S2
SPI1_HOST
is not supported (as per ESP32’s documentation).bus_config – SPI bus configuration.
device_cfg – SPI device configuration. Note that despite PN532 supporting up to 5MHz speed, the channel may be unstable and a lower speed (1MHz) is recommended.
dma_chan – The DMA channel to use for transmitting data. Note that DMA channel 0 is not supported (as per ESP32’s documentation), therefore it must be either DMA channel 1 or DMA channel 2.
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, this parm should be set to true.
-
~spi_channel() override
Frees the SPI device and uninstalls the ISR service, if specified.
Protected Functions
-
virtual result raw_send(mlab::range<bin_data::const_iterator> buffer, ms timeout) override
Wraps around
spi_device_transmit
, where onlyspi_transaction_ext_t.base.tx_buffer
is populated.
-
virtual result raw_receive(mlab::range<bin_data::iterator> buffer, ms timeout) override
Wraps around
spi_device_transmit
, where onlyspi_transaction_ext_t.base.rx_buffer
is populated.
-
result raw_poll_status(ms timeout)
Waits until data is ready to be received when an IRQ line is not available.
In IRQ mode, this method always immediately returns (because no polling has to occur). Without IRQ line, we can send a spi_command::status_read command to poll whether incoming data is ready to be received. This is sent every 10ms until
timeout
runs out or data is available.- Parameters:
timeout – Maximum timeout before returning channel_error::timeout
- Returns:
mlab::result_success
or one of
-
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 through raw_poll_status.
See also
-
virtual void on_receive_complete(result<> const&) override
Close the communications by unasserting the CS line.
But there is no good way to end the transaction, so this method just reads an empty byte and releases the bus.
-
virtual comm_rx_mode raw_receive_mode() const override
- Returns:
For spi_channel, this is always comm_rx_mode::stream.
-
virtual bool wake() override