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.
This commit is contained in:
32
main.c
32
main.c
@@ -15,8 +15,16 @@ static void mfrc522_integration_irq_handler(uint gpio, uint32_t event_mask)
|
||||
(void) mfrc522_irq_handler(&ctx);
|
||||
}
|
||||
|
||||
static void mfrc522_integration_irq_init(void)
|
||||
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);
|
||||
}
|
||||
@@ -47,19 +55,31 @@ void mfrc522_integration_init(void)
|
||||
mfrc522_set_interface(&ctx, MFRC522_INTERFACE_SPI);
|
||||
uint8_t init_retval = mfrc522_init(&ctx);
|
||||
|
||||
if (init_retval == 0) {
|
||||
mfrc522_integration_irq_init();
|
||||
} else {
|
||||
printf("ERR: %s failed: %d\n", __FUNCTION__, init_retval);
|
||||
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();
|
||||
sleep_ms(2500);
|
||||
|
||||
printf("Hello World!\n");
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/spi.h"
|
||||
#include "hardware/sync.h"
|
||||
|
||||
#ifndef NO_DEBUG
|
||||
#include <stdarg.h>
|
||||
@@ -52,12 +53,22 @@
|
||||
#define MFRC522_CFG_SPI_SS_GPIO 13
|
||||
#define MFRC522_CFG_SPI_SPEED_MHZ (1000 * 1000)
|
||||
|
||||
static inline void print_hex(uint8_t *bytes, size_t len)
|
||||
{
|
||||
for (size_t idx = 0; idx < len; ++idx) {
|
||||
mfrc522_interface_debug_print("%x", bytes[idx]);
|
||||
}
|
||||
mfrc522_interface_debug_print("\n");
|
||||
}
|
||||
|
||||
static uint32_t irq_status = 0;
|
||||
/**
|
||||
* @brief Helper function to pull the CS line low
|
||||
*
|
||||
* Taken from pico-examples, bme280_spi.c
|
||||
*/
|
||||
static inline void cs_select() {
|
||||
// irq_status = save_and_disable_interrupts();
|
||||
asm volatile("nop \n nop \n nop");
|
||||
gpio_put(MFRC522_CFG_SPI_SS_GPIO, 0); // Active low
|
||||
asm volatile("nop \n nop \n nop");
|
||||
@@ -72,6 +83,7 @@ static inline void cs_deselect() {
|
||||
asm volatile("nop \n nop \n nop");
|
||||
gpio_put(MFRC522_CFG_SPI_SS_GPIO, 1);
|
||||
asm volatile("nop \n nop \n nop");
|
||||
// restore_interrupts(irq_status);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,6 +254,10 @@ uint8_t mfrc522_interface_spi_read(uint8_t reg, uint8_t *buf, uint16_t len)
|
||||
// ...and ignore the first byte we received.
|
||||
memcpy(buf, local_buf + 1, len);
|
||||
|
||||
// XXX Debug - remove me
|
||||
mfrc522_interface_debug_print("[SPI-RX]: ");
|
||||
print_hex(buf, len);
|
||||
|
||||
return (uint8_t) (n_bytes_read == local_buf_len) ? 0 : 1;
|
||||
}
|
||||
|
||||
@@ -266,6 +282,10 @@ uint8_t mfrc522_interface_spi_write(uint8_t reg, uint8_t *buf, uint16_t len)
|
||||
local_buf[0] = reg;
|
||||
memcpy(&local_buf[1], buf, len);
|
||||
|
||||
// XXX Debug - remove me
|
||||
mfrc522_interface_debug_print("[SPI-TX]: ");
|
||||
print_hex(buf, len);
|
||||
|
||||
cs_select();
|
||||
uint16_t n_bytes_written = spi_write_blocking(MFRC522_CFG_SPI_INSTANCE, local_buf, local_buf_len);
|
||||
cs_deselect();
|
||||
|
||||
Reference in New Issue
Block a user