NRF52840 error while reading SPI during interrupt

Hello.
I am using NRF SDK 1.9 version + VS Code to process accelerometer data.
NRF52840 + ADXL375

The accelerometer is configured to issue an interrupt under a certain condition. The interrupt is issued successfully.

Here is the interrupt initialization code on the indicated pin:

dts board file:

buttons {
compatible = "gpio-keys";
INT1_AX: INT1_AXPin{
gpios = <&gpio1 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "INT1_AXPin";
};

aliases {
intpin = &INT1_AX;
};



#define INTAX_NODE DT_ALIAS(intpin)
#define INTAX_PIN DT_GPIO_PIN(INTAX_NODE, gpios)
#define INTAX_FLAGS DT_GPIO_FLAGS(INTAX_NODE, gpios)

static void adxl_interrupt_handler(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins)
{
res = k_mutex_lock(&spi_mutex, K_MSEC(100));
if (res == 0)
{
uint8_t count = ADXL_ReadRegister(SPIPORT, &spi_cfg, ADXL375_REG_FIFO_STATUS) & 0x3f;
led_update();

while (count--)
{
AccellValue impact = ADXL_GetXYZ(SPIPORT, &spi_cfg);

X = (float)impact.X * GRAVITY_SCALE;
Y = (float)impact.Y * GRAVITY_SCALE;
Z = (float)impact.Z * GRAVITY_SCALE;

#ifdef AXIS_XYZ
magnitude = Q_rsqrt((X * X) + (Y * Y) + (Z * Z)); // 60us
#else
#ifdef AXIS_XY
magnitude = Q_rsqrt((X * X) + (Y * Y));
#else
#error select axis mode
#endif
#endif
}
k_mutex_unlock(&spi_mutex);
}
ClearInterruptFlag(SPIPORT, &spi_cfg);
}

// Configure interrupt for ADXL
    gpio_pin_configure(PORT1, INTAX_PIN, GPIO_INPUT | GPIO_ACTIVE_HIGH);
    gpio_init_callback(&button_callback, adxl_interrupt_handler, BIT(INTAX_PIN));
    gpio_add_callback(PORT1, &button_callback);
    gpio_pin_interrupt_configure(PORT1, INTAX_PIN, GPIO_INT_EDGE_FALLING);




But for some reason, when the adxl_interrupt_handler interrupt is triggered, some kind of error occurs when accessing the SPI port.
I put a breakpoint in adxl_interrupt_handler. The first time an interrupt is triggered, I get into this code. But I can't go on and analyze it.

GDB server writes the following message in the terminal:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.


if you run the code without a debugger, the light will blink a couple of times and that's it .. everything hangs.

Maybe I'm not correctly accessing the port from the interrupt ?? Maybe some kind of synchronization methods are needed? A mutex does not provide any advantage here.

  • If after the LED fades, the debugger is stopped, then it gets into this code:

    FUNC_NORETURN __weak void arch_system_halt(unsigned int reason)
    {
    	ARG_UNUSED(reason);
    
    	/* TODO: What's the best way to totally halt the system if SMP
    	 * is enabled?
    	 */
    
    	(void)arch_irq_lock();
    	for (;;) {
    		/* Spin endlessly */
    	}
    }

    The value of the reason in this case is equal to zero.

    If you believe this conversion function, then the error means cpu exception

    static const char *reason_to_str(unsigned int reason)
    {
    	switch (reason) {
    	case K_ERR_CPU_EXCEPTION:
    		return "CPU exception";
    	case K_ERR_SPURIOUS_IRQ:
    		return "Unhandled interrupt";
    	case K_ERR_STACK_CHK_FAIL:
    		return "Stack overflow";
    	case K_ERR_KERNEL_OOPS:
    		return "Kernel oops";
    	case K_ERR_KERNEL_PANIC:
    		return "Kernel panic";
    	default:
    		return "Unknown error";
    	}
    }

Related