#include <zephyr/logging/log.h>
#include <haly/nrfy_gpio.h>
#include <zephyr/net/socket.h>
#include <zephyr/sys/fdtable.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/kernel.h>
#include <hal/nrf_dppi.h>
#include <nrfx_dppi.h>
#include <nrfx_timer.h>
#include <nrfx_spim.h>
#include <nrfx_gpiote.h>
#include "Wifi_Stationing.h"
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "UDP_Server_Ack.h"
#include "deviceInformation.h"
// ✅ FIX: unique log module name
LOG_MODULE_REGISTER(intan_spi, CONFIG_LOG_DEFAULT_LEVEL);
// Thread settings
#define SPI_RHD_STACK_SIZE 2048
#define STM_PRIORITY 4
static struct k_thread intanspi_rhd;
K_THREAD_STACK_DEFINE(intanspi_rhd_stack, SPI_RHD_STACK_SIZE);
// Frame settings
#define TIMER_PERIOD_MS 4 // period between frames 2 10
#define TIMER_FREQ NRF_TIMER_FREQ_16MHz
#define TIMER_PERIOD_TICKS ((TIMER_PERIOD_MS * 2UL) /* ticks at 8MHz */)
#define CS_ACTIVE_US 1
#define CS_ACTIVE_TICKS (CS_ACTIVE_US * 8UL)
// DPPI/SPIM instances
#define TIMER_INSTANCE 1
#define DPPI_INSTANCE 0
#define SPI_INSTANCE 4
#define SPI_SCK_PIN NRF_GPIO_PIN_MAP(1, 13)
#define SPI_MOSI_PIN NRF_GPIO_PIN_MAP(1, 14)
#define SPI_MISO_PIN NRF_GPIO_PIN_MAP(1, 15)
#define SPI_CS_PIN NRF_GPIO_PIN_MAP(1, 12)
#define GPIO_REF_PIN NRF_GPIO_PIN_MAP(0,3)
#define SPI_FREQUENCY NRFX_MHZ_TO_HZ(8)
// Peripherals
static const nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(TIMER_INSTANCE);
static const nrfx_spim_t m_spim = NRFX_SPIM_INSTANCE(SPI_INSTANCE);
static const nrfx_gpiote_t m_gpiote = NRFX_GPIOTE_INSTANCE(0);
// DPPI channels
static uint8_t m_dppi_ch_timer_to_spi;
static uint8_t m_dppi_ch_spi_to_cs_high;
// Buffers
static uint8_t m_spi_tx_buf[1028] = {
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,
0x00,0x00,0x00,0x00,
};
/*static uint8_t m_spi_tx_buf[1028] = {
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x01,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x0c,0x01,0x0d,0x01,0x0e,0x01,0x0f,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01,0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1a,0x01,0x1b,0x01,0x1c,0x01,0x1d,0x01,0x1e,0x01,0x1f,
0x00,0x00,0x00,0x00,
};*/
static uint8_t m_rx_buf[1028];
/*static uint8_t m_spi_command_tx_buf[64] ={
0xff,0x00, 0xff,0x00, 0x80,0xde, 0x81,0x42, 0x82,0x04, 0x83,0x00, 0x84,0x80, 0x85,0x40, 0x86,0x80, 0x87,0x00,
0x88,0x0b, 0x89,0x80, 0x8a,0x08, 0x8b,0x80, 0x8c,0x2c, 0x8d,0x06, 0x8e,0xff, 0x8f,0xff, 0x90,0xff, 0x91,0xff,
0x55,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00,
0x00,0x01, 0x01,0x01,
};*/
static uint8_t m_spi_command_tx_buf[64] ={
0xff,0x00, 0xff,0x00, 0x80,0xde, 0x81,0x42, 0x82,0x04, 0x83,0x00, 0x84,0x80, 0x85,0x40, 0x86,0x80, 0x87,0x00,
0x88,0x03, 0x89,0x01, 0x8a,0x0d, 0x8b,0x01, 0x8c,0x0f, 0x8d,0x00, 0x8e,0xff, 0x8f,0xff, 0x90,0xff, 0x91,0xff,
0x55,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00, 0xff,0x00,
0x00,0x01, 0x01,0x01,
};
static uint8_t m_spi_command_rx_buf[64];
static uint16_t spi_counter=0;
static bool command_mode=true;
int32_t flags = NRFX_SPIM_FLAG_HOLD_XFER
| NRFX_SPIM_FLAG_REPEATED_XFER
| NRFX_SPIM_FLAG_TX_POSTINC
| NRFX_SPIM_FLAG_RX_POSTINC;
int32_t single_flags = NRFX_SPIM_FLAG_HOLD_XFER
| NRFX_SPIM_FLAG_REPEATED_XFER
| NRFX_SPIM_FLAG_TX_POSTINC
| NRFX_SPIM_FLAG_RX_POSTINC;
// Prepare one-frame descriptor
static nrfx_spim_xfer_desc_t m_xfer_desc = NRFX_SPIM_XFER_TRX(m_spi_tx_buf, 2, m_rx_buf, 2);
static nrfx_spim_xfer_desc_t m_xfer_rw = NRFX_SPIM_XFER_TRX(m_spi_command_tx_buf, 2, m_spi_command_rx_buf, 2);
// --- Event Handler ---
void spim_event_handler(nrfx_spim_evt_t const *p_event, void *p_context)
{
if (p_event->type == NRFX_SPIM_EVENT_DONE) {
spi_counter++;
if (spi_counter==514){
nrfx_spim_abort(&m_spim);
UDP_Ack_Server_Send(m_rx_buf,sizeof(m_rx_buf));
spi_counter=0;
nrfx_spim_xfer(&m_spim, &m_xfer_desc, flags);
}
if(command_mode==true){
if (spi_counter==32){
nrfx_spim_abort(&m_spim);
UDP_Ack_Server_Send(m_spi_command_rx_buf,sizeof(m_spi_command_rx_buf));
spi_counter=0;
command_mode=false;
nrfx_spim_xfer(&m_spim, &m_xfer_desc, flags);
}
}
}
}
void single_command(uint8_t command[64]){
nrfx_spim_abort(&m_spim);
UDP_Ack_Server_Send(m_rx_buf,sizeof(m_rx_buf));
command_mode=true;
spi_counter=0;
if (command!=0){
memcpy(m_spi_command_tx_buf,command,64);
};
nrfx_spim_xfer(&m_spim, &m_xfer_rw, single_flags);
}
// --- GPIOTE init for CS control ---
static void gpiote_init(void)
{
nrfx_err_t err;
// Initialize GPIOTE
if (!nrfx_gpiote_init_check(&m_gpiote)) {
err = nrfx_gpiote_init(&m_gpiote, NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY);
NRFX_ASSERT(err == NRFX_SUCCESS);
}
// Configure CS pin as task-driven output
nrfx_gpiote_output_config_t output_config = {
.drive = NRF_GPIO_PIN_H0H1,
.input_connect= NRF_GPIO_PIN_INPUT_DISCONNECT,
.pull = NRF_GPIO_PIN_NOPULL,
};
nrfx_gpiote_task_config_t task_config = {
.task_ch = 0, // A specific channel can be used if needed, 0 is fine for basic tasks
.polarity = GPIOTE_CONFIG_POLARITY_Toggle, // Not critical for OUT tasks, but good to define
.init_val = NRF_GPIOTE_INITIAL_VALUE_HIGH
};
nrfx_gpiote_output_configure(&m_gpiote, SPI_CS_PIN, &output_config, &task_config);
nrfx_gpiote_out_task_enable(&m_gpiote,SPI_CS_PIN);
nrf_gpio_pin_set(GPIO_REF_PIN);
nrf_gpio_cfg(GPIO_REF_PIN,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_PULLUP,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE);
}
int change_ref(void){
bool amp_ref_status;
nrf_gpio_pin_toggle(GPIO_REF_PIN);
amp_ref_status=nrf_gpio_pin_out_read(GPIO_REF_PIN);
single_command(m_spi_command_tx_buf);
return amp_ref_status;
}
// --- Timer init for periodic DPPI triggers ---
static void timer_init(void)
{
nrfx_timer_config_t tcfg = NRFX_TIMER_DEFAULT_CONFIG(TIMER_FREQ);
tcfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
NRFX_ASSERT(nrfx_timer_init(&m_timer, &tcfg, NULL) == NRFX_SUCCESS);
// Clear on COMPARE0
nrfx_timer_extended_compare(&m_timer,
NRF_TIMER_CC_CHANNEL0,
TIMER_PERIOD_TICKS,
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
false);
// We won't use COMPARE1 (CS release handled by SPIM end event)
LOG_INF("Timer initialized: period=%d ms, CS active=%d us",
TIMER_PERIOD_MS, CS_ACTIVE_US);
}
// --- SPIM init with one-frame, repeated, post-increment ---
static void spim_init(void)
{
nrfx_spim_config_t spim_config = NRFX_SPIM_DEFAULT_CONFIG(
SPI_SCK_PIN,
SPI_MOSI_PIN,
SPI_MISO_PIN,
NRF_SPIM_PIN_NOT_CONNECTED );
spim_config.frequency = SPI_FREQUENCY;
nrfx_spim_init(&m_spim, &spim_config, spim_event_handler, NULL);
nrf_gpio_cfg(
SPI_SCK_PIN,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE
);
nrf_gpio_cfg(
SPI_MOSI_PIN,
NRF_GPIO_PIN_DIR_OUTPUT,
NRF_GPIO_PIN_INPUT_DISCONNECT,
GPIO_PIN_CNF_PULL_Pullup,
NRF_GPIO_PIN_H0H1,
NRF_GPIO_PIN_NOSENSE
);
nrfx_spim_xfer(&m_spim, &m_xfer_rw, single_flags);
}
// --- DPPI setup to link TIMER → SPIM start + CS low, SPIM end → CS high ---
static void dppi_init_and_connect(void)
{
nrfx_err_t err;
const nrfx_dppi_t dppi = NRFX_DPPI_INSTANCE(DPPI_INSTANCE);
// Allocate channels
err = nrfx_dppi_channel_alloc(&dppi, &m_dppi_ch_timer_to_spi);
NRFX_ASSERT(err == NRFX_SUCCESS);
err = nrfx_dppi_channel_alloc(&dppi, &m_dppi_ch_spi_to_cs_high);
NRFX_ASSERT(err == NRFX_SUCCESS);
// Get addresses
uint32_t evt_timer_cmp0 = nrfx_timer_event_address_get(&m_timer, NRF_TIMER_EVENT_COMPARE0);
uint32_t task_spim_start = nrfx_spim_start_task_address_get(&m_spim);
uint32_t task_cs_low = nrfx_gpiote_set_task_address_get(&m_gpiote, SPI_CS_PIN) - /* CLR idx */ 0x4; // GPIOTE CLR offset
uint32_t evt_spim_end = nrfx_spim_end_event_address_get(&m_spim);
uint32_t task_cs_high = nrfx_gpiote_set_task_address_get(&m_gpiote, SPI_CS_PIN);
uint32_t task_cs_out = nrfx_gpiote_out_task_address_get(&m_gpiote, SPI_CS_PIN);
// Channel: TIMER compare0 → CS_LOW + SPIM_START
NRF_DPPI_ENDPOINT_SETUP(evt_timer_cmp0, m_dppi_ch_timer_to_spi);
NRF_DPPI_ENDPOINT_SETUP(task_cs_out, m_dppi_ch_timer_to_spi);
NRF_DPPI_ENDPOINT_SETUP(task_spim_start, m_dppi_ch_timer_to_spi);
nrfx_dppi_channel_enable(&dppi, m_dppi_ch_timer_to_spi);
// Channel: SPIM end → CS_HIGH
NRF_DPPI_ENDPOINT_SETUP(evt_spim_end, m_dppi_ch_spi_to_cs_high);
NRF_DPPI_ENDPOINT_SETUP(task_cs_high, m_dppi_ch_spi_to_cs_high);
nrfx_dppi_channel_enable(&dppi, m_dppi_ch_spi_to_cs_high);
LOG_INF("DPPI channels configured");
}
// --- Main SPI thread entry ---
static int spi_rhd(void)
{ k_sem_take(&sem_spi0, K_FOREVER);
LOG_INF("Starting autonomous periodic SPI...");
gpiote_init();
spim_init();
timer_init();
dppi_init_and_connect();
// Enable timer to drive DPPI
nrfx_timer_enable(&m_timer);
// Nothing else to do: hardware handles transfers
while (0.1) {
k_sleep(K_FOREVER);
}
return 0;
}
// --- Public init function ---
void Intan_SPI_Init(void)
{
k_thread_create(
&intanspi_rhd,
intanspi_rhd_stack,
SPI_RHD_STACK_SIZE,
(k_thread_entry_t)spi_rhd,
NULL, NULL, NULL,
STM_PRIORITY,
0,
K_NO_WAIT
);
k_thread_name_set(&intanspi_rhd, "rhd_spi");
k_thread_start(&intanspi_rhd);
}
//////////////////////////////////////////
prj.conf
# Copyright (c) 2022 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
CONFIG_WIFI=y
CONFIG_WIFI_NRF70=y
CONFIG_BT=n
# WPA supplicant
CONFIG_WIFI_NM_WPA_SUPPLICANT=y
# CONFIG_SHELL=y
#CONFIG_NET_L2_WIFI_SHELL=y
#CONFIG_SHELL_STACK_SIZE=8192
# Below configs need to be modified based on security
# CONFIG_STA_KEY_MGMT_NONE=y
CONFIG_STA_KEY_MGMT_WPA2=y
# CONFIG_STA_KEY_MGMT_WPA2_256=y
# CONFIG_STA_KEY_MGMT_WPA3=y
CONFIG_STA_SAMPLE_SSID="Toure"
CONFIG_STA_SAMPLE_PASSWORD="sblee302"
#CONFIG_STA_SAMPLE_SSID="toure"
#CONFIG_STA_SAMPLE_PASSWORD="27022303"
CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.168.0.6"
# System settings
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_NANO=n
CONFIG_THREAD_NAME=y
# Networking
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_IPV4=y
CONFIG_NET_UDP=y
CONFIG_NET_TCP=n
CONFIG_NET_DHCPV4=y
CONFIG_NET_PKT_RX_COUNT=2
CONFIG_NET_PKT_TX_COUNT=16
CONFIG_NET_MAX_CONN=3
# Below section is the primary contributor to SRAM and is currently
# tuned for performance, but this will be revisited in the future.
CONFIG_NET_BUF_RX_COUNT=2
CONFIG_NET_BUF_TX_COUNT=32
CONFIG_NET_CONTEXT_NET_PKT_POOL=y
CONFIG_NET_BUF_DATA_SIZE=1500
CONFIG_NET_BUF_FIXED_DATA_SIZE=y
CONFIG_HEAP_MEM_POOL_SIZE=220000
CONFIG_NET_TC_TX_COUNT=0
CONFIG_NET_TC_RX_COUNT=1
CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=1
CONFIG_NET_MAX_CONTEXTS=2
CONFIG_NET_CONTEXT_SYNC_RECV=y
CONFIG_INIT_STACKS=y
CONFIG_NET_L2_ETHERNET=y
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_SOCKETS_POLL_MAX=16
CONFIG_POSIX_MAX_FDS=20
# Memories
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_NET_TX_STACK_SIZE=4096
CONFIG_NET_RX_STACK_SIZE=2048
CONFIG_NRF70_MAX_TX_PENDING_QLEN=12
# Debugging
CONFIG_STACK_SENTINEL=y
CONFIG_DEBUG_COREDUMP=y
CONFIG_DEBUG_COREDUMP_BACKEND_LOGGING=y
CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN=y
CONFIG_SHELL_CMDS_RESIZE=n
# Kernel options
CONFIG_ENTROPY_GENERATOR=y
CONFIG_TEST_RANDOM_GENERATOR=y
# Logging
#CONFIG_LOG=y
#CONFIG_LOG_BUFFER_SIZE=2048
#CONFIG_POSIX_CLOCK=y
CONFIG_PM=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.0.11"
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
CONFIG_NET_CONFIG_MY_IPV4_GW="192.168.0.1"
# printing of scan results puts pressure on queues in new locking
# design in net_mgmt. So, use a higher timeout for a crowded
# environment.
CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT=5000
CONFIG_GPIO=y
CONFIG_NRF70_QSPI_LOW_POWER=n
CONFIG_NRF_WIFI_LOW_POWER=n
CONFIG_WIFI_MGMT_EXT=y
CONFIG_WIFI_CREDENTIALS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_MPU_ALLOW_FLASH_WRITE=y
CONFIG_SETTINGS=y
CONFIG_SETTINGS_NVS=y
CONFIG_NET_L2_WIFI_SHELL=n
CONFIG_NET_L2_WIFI_MGMT=y
CONFIG_NET_SHELL=n
CONFIG_SHELL=y
CONFIG_LOG=n
CONFIG_PRINTK=n
CONFIG_GPIO=y
CONFIG_NFCT_PINS_AS_GPIOS=y
CONFIG_SPI=y
CONFIG_NRFX_SPIM4=y
CONFIG_NRFX_SPIM3=n
# Enable RTT to replace UART
#CONFIG_STDOUT_CONSOLE=y
#CONFIG_UART_CONSOLE=n
#CONFIG_USE_SEGGER_RTT=y
#CONFIG_SHELL_BACKEND_RTT=y
#CONFIG_NET_LOG=y
CONFIG_NRFX_TIMER0=y
CONFIG_NRFX_TIMER1=y
CONFIG_NRFX_PPI=y
CONFIG_NRFX_DPPI0=y
CONFIG_CLOCK_CONTROL_NRF=y
CONFIG_NRFX_TIMER2=n
CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=y
CONFIG_WIFI_RANDOM_MAC_ADDRESS=y
# reboot
#CONFIG_REBOOT=y
[00:08:59.372,680] <inf> intan_spi: Starting autonomous periodic SPI...
[00:08:59.372,711] <inf> intan_spi: Timer initialized: period=4 ms, CS active=1 us
[00:08:59.372,711] <inf> intan_spi: DPPI channels configured
[00:08:59.372,741] <err> os: Unhandled IRQn: 10
[00:08:59.372,741] <err> os: >>> ZEPHYR FATAL ERROR 1: Unhandled interrupt on CPU 0
[00:08:59.372,772] <err> os: Current thread: 0x20002208 (logging)
[00:08:59.423,370] <err> coredump: #CD:BEGIN#
[00:08:59.431,213] <err> coredump: #CD:5a4502000300050001000000
[00:08:59.440,582] <err> coredump: #CD:4d010008220020d0220020
[00:08:59.449,798] <err> coredump: #CD:10270020386401200000000000800e0000000000000000000000000000000000
[00:08:59.462,646] <err> coredump: #CD:00000000000000000000000000000000ffffffff000000000000000098ed0600
[00:08:59.475,494] <err> coredump: #CD:ffffffffffffffff0c1e00200000000030e60120000000006022002060220020
[00:08:59.488,342] <err> coredump: #CD:000000007d960000000000000000000000000000c03900206c6f6767696e6700
[00:08:59.501,190] <err> coredump: #CD:0000000000000000000000000000000000000000000000000000000088e30120
[00:00:40.661,041] <inf> sta: UDP Server waiting for packets on port 4243...
[00:08:59.514,038] <err> coredump: #CD:0003000000000000b41b00200000000000000000000000000000000000000000
[00:08:59.524,261] <err> coredump: #CD:0000000000000000
[00:08:59.537,109] <err> coredump: #CD:4d010088e3012088e60120
[00:08:59.545,806] <err> coredump: #CD:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
[00:08:59.555,023] <err> coredump: #CD:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
[00:08:59.567,871] <err> coredump: #CD:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
[00:08:59.580,718] <err> coredump: #CD:ffffffffDffffffffffffffffffffffffff[00:08:59.593,536] <err> coredump: #CD:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
[00:08:59.600,830] <err> os: ***** USAGE FAULT *****
[00:08:59.616,271] <err> os: Unaligned memory access
[00:08:59.624,694] <err> os: r0/a1: 0x00000000 r1/a2: 0x00000020 r2/a3: 0x00000001
[00:08:59.633,300] <err> os: r3/a4: 0x50008000 r12/ip: 0x01010101 r14/lr: 0x0003144d
[00:08:59.644,744] <err> os: xpsr: 0xffffffff
[00:08:59.656,219] <err> os: Faulting instruction address (r15/pc): 0xffffff00
[00:08:59.664,215] <err> os: >>> ZEPHYR FATAL ERROR 31: Unknown error on CPU 0
[00:08:59.674,896] <err> os: Fault during interrupt handling
[00:08:59.685,577] <err> os: Current thread: 0x20002208 (logging)
When i use spi4 there is Unhandled IRQn error, which is not occurs at spi3, spi2, spi1.
How can i fixed these errors?
Thx for reading this.