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.
98 lines
3.6 KiB
C
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);
|
|
}
|
|
}
|