Files
rpi_pico_mfrc522/main.c
Stefan Kratochwil 561b6d7ff7 Probably (!) fixed problem with spurious interrupts.
After turning on the analog section of the mfrc522, a lot of spurious
interrupts could be observed. Debugging revealed that the mfrc522 did not
give consistent information about an interrupt source.

A closer look into the chip documentation (chapter 9.3.1.4) revealed that
the interrupt pin is open drain by default, but can be set to CMOS.

Switched to CMOS, deactivated internal and external pull down resistors.
No more spurious interrupts.
2024-05-31 15:20:11 +02:00

98 lines
3.6 KiB
C

#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "driver_mfrc522_interface.h"
#define MFRC522_CFG_IRQ_GPIO 14
static mfrc522_handle_t ctx = {0};
static void mfrc522_integration_irq_handler(uint gpio, uint32_t event_mask)
{
(void) gpio;
(void) event_mask;
// Dump return value for now, we cannot do anything at the moment.
(void) mfrc522_irq_handler(&ctx);
}
static void mfrc522_integration_irq_init(mfrc522_handle_t* const ctx)
{
bool pu = gpio_is_pulled_up(MFRC522_CFG_IRQ_GPIO);
bool pd = gpio_is_pulled_down(MFRC522_CFG_IRQ_GPIO);
ctx->debug_print("GPIO PU: %d PD: %d\n", (int) pu, (int) pd);
gpio_set_pulls(MFRC522_CFG_IRQ_GPIO, false, false);
pu = gpio_is_pulled_up(MFRC522_CFG_IRQ_GPIO);
pd = gpio_is_pulled_down(MFRC522_CFG_IRQ_GPIO);
ctx->debug_print("GPIO PU: %d PD: %d\n", (int) pu, (int) pd);
gpio_set_irq_enabled_with_callback(MFRC522_CFG_IRQ_GPIO, GPIO_IRQ_EDGE_RISE, true,
mfrc522_integration_irq_handler);
}
void mfrc522_integration_init(void)
{
DRIVER_MFRC522_LINK_INIT(&ctx, mfrc522_handle_t);
DRIVER_MFRC522_LINK_RESET_GPIO_INIT(&ctx, mfrc522_interface_reset_gpio_init);
DRIVER_MFRC522_LINK_RESET_GPIO_DEINIT(&ctx, mfrc522_interface_reset_gpio_deinit);
DRIVER_MFRC522_LINK_RESET_GPIO_WRITE(&ctx, mfrc522_interface_reset_gpio_write);
DRIVER_MFRC522_LINK_IIC_INIT(&ctx, mfrc522_interface_iic_init);
DRIVER_MFRC522_LINK_IIC_DEINIT(&ctx, mfrc522_interface_iic_deinit);
DRIVER_MFRC522_LINK_IIC_WRITE(&ctx, mfrc522_interface_iic_write);
DRIVER_MFRC522_LINK_IIC_READ(&ctx, mfrc522_interface_iic_read);
DRIVER_MFRC522_LINK_UART_INIT(&ctx, mfrc522_interface_uart_init);
DRIVER_MFRC522_LINK_UART_DEINIT(&ctx, mfrc522_interface_uart_deinit);
DRIVER_MFRC522_LINK_UART_READ(&ctx, mfrc522_interface_uart_read);
DRIVER_MFRC522_LINK_UART_WRITE(&ctx, mfrc522_interface_uart_write);
DRIVER_MFRC522_LINK_UART_FLUSH(&ctx, mfrc522_interface_uart_flush);
DRIVER_MFRC522_LINK_SPI_INIT(&ctx, mfrc522_interface_spi_init);
DRIVER_MFRC522_LINK_SPI_DEINIT(&ctx, mfrc522_interface_spi_deinit);
DRIVER_MFRC522_LINK_SPI_READ(&ctx, mfrc522_interface_spi_read);
DRIVER_MFRC522_LINK_SPI_WRITE(&ctx, mfrc522_interface_spi_write);
DRIVER_MFRC522_LINK_DELAY_MS(&ctx, mfrc522_interface_delay_ms);
DRIVER_MFRC522_LINK_DEBUG_PRINT(&ctx, mfrc522_interface_debug_print);
DRIVER_MFRC522_LINK_RECEIVE_CALLBACK(&ctx, mfrc522_interface_receive_callback);
mfrc522_set_interface(&ctx, MFRC522_INTERFACE_SPI);
uint8_t init_retval = mfrc522_init(&ctx);
if (init_retval != 0) {
mfrc522_interface_debug_print("ERR: %s failed: %d\n", __FUNCTION__, init_retval);
}
uint8_t irq_pin_type_ret = mfrc522_set_interrupt_pin_type(&ctx, MFRC522_INTERRUPT_PIN_TYPE_STANDARD_CMOS);
if (irq_pin_type_ret != 0) {
mfrc522_interface_debug_print("ERR: Could not set interrupt pin type.");
}
else
{
mfrc522_integration_irq_init(&ctx);
}
// TODO Clear all interrupt bits here?
uint8_t analog_enable_retval = mfrc522_set_receiver_analog(&ctx, MFRC522_BOOL_TRUE);
if (analog_enable_retval != 0) {
mfrc522_interface_debug_print("ERR: Enabling analog receiver failed: %d\n", analog_enable_retval);
}
}
int main(void)
{
timer_hw->dbgpause = 0;
stdio_init_all();
printf("Hello World!\n");
mfrc522_integration_init();
const uint LED_PIN = PICO_DEFAULT_LED_PIN;
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
gpio_put(LED_PIN, 1);
sleep_ms(250);
gpio_put(LED_PIN, 0);
sleep_ms(250);
}
}