This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52832 SPI Slave Interrupt handler

Hello,

I'm trying to setup interrupt routines in SPIS1 peripheral.

I have a void IRQ function

void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void)
{
    if  (NRF_SPIS1->EVENTS_ACQUIRED)
    {
        NRF_SPIS1->EVENTS_ACQUIRED = 0x0UL;

        spis_set_tx_buffer(tx_buffer, strlen(tx_buffer));
        spis_set_rx_buffer(rx_buffer, sizeof(rx_buffer));
        NRF_SPIS1->TASKS_RELEASE = true;
    }

    if  (NRF_SPIS1->EVENTS_END)
    {
        NRF_SPIS1->EVENTS_END = 0x0UL;
        NRF_SPIS1->TASKS_ACQUIRE = true;
    }

    if  (NRF_SPIS1->EVENTS_ENDRX)
    {
        NRF_SPIS1->EVENTS_ENDRX = 0x0UL;
        NRF_SPIS1->TASKS_ACQUIRE = true;
    }
}

But it seems like it never gets called

my init function

void spis_init(void)
{
    spis_pins_init();

    spis_set_tx_buffer(NULL, 0);
    spis_set_rx_buffer(NULL, 0);

    spis_configure();

    spis_def_set(0xFF);
    spis_orc_set(0xFF);
    
    NRF_SPIS1->EVENTS_END = 0x0UL;
    NRF_SPIS1->EVENTS_ACQUIRED = 0x0UL;

    spis_shorts_enable(SPIS_SHORTS_END_ACQUIRE_Msk);
    
    spis_interrupt_enable(SPIS_INTENSET_ACQUIRED_Msk);
    spis_interrupt_enable(SPIS_INTENSET_END_Msk);
    
    NVIC_SetPriority(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn, 6);
    NVIC_ClearPendingIRQ(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn);
    NVIC_EnableIRQ(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn);

    NRF_SPIS1->TASKS_ACQUIRE = true;

    NRF_SPIS1->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos);    
}

some static functions

static volatile uint8_t tx_buffer[32] = "Hello.";
static volatile uint8_t rx_buffer[32];


static void spis_pins_init(void)
{
    gpio_config_input(MOSI_PIN, GPIO_PIN_CNF_PULL_Disabled);
    gpio_config_input(MISO_PIN, GPIO_PIN_CNF_PULL_Disabled);
    gpio_config_input(CLK_PIN, GPIO_PIN_CNF_PULL_Disabled);
    gpio_config_input(CS_PIN, GPIO_PIN_CNF_PULL_Disabled);
    
    NRF_SPIS1->PSEL.MOSI = MOSI_PIN;
    NRF_SPIS1->PSEL.MISO = MISO_PIN;
    NRF_SPIS1->PSEL.SCK  = CLK_PIN;
    NRF_SPIS1->PSEL.CSN  = CS_PIN;
}

static void spis_set_rx_buffer(uint8_t * buff, size_t length)
{
    NRF_SPIS1->RXD.PTR    = (uint32_t)buff;
    NRF_SPIS1->RXD.MAXCNT = length;
}

static void spis_set_tx_buffer(uint8_t * buff, size_t length)
{
    NRF_SPIS1->TXD.PTR    = (uint32_t)buff;
    NRF_SPIS1->TXD.MAXCNT = length;
}

static void spis_configure(void)
{
    uint32_t config = SPIS_CONFIG_ORDER_MsbFirst;
    config |= (SPIS_CONFIG_CPOL_ActiveHigh << SPIS_CONFIG_CPOL_Pos) |
             (SPIS_CONFIG_CPHA_Leading << SPIS_CONFIG_CPHA_Pos);
    NRF_SPIS1->CONFIG = config;
}

// default 0xFF
static void spis_def_set(uint8_t ch)
{
    NRF_SPIS1->DEF = ch;
}

// default 0xFF
static void spis_orc_set(uint8_t orc)
{
    NRF_SPIS1->ORC = orc;
}

static void spis_shorts_enable(uint32_t mask)
{
    NRF_SPIS1->SHORTS |= mask;
}

static void spis_enable(void)
{
    NRF_SPIS1->ENABLE = (SPIS_ENABLE_ENABLE_Disabled << SPIS_ENABLE_ENABLE_Pos);
}

static void spis_interrupt_enable(uint32_t mask)
{
    NRF_SPIS1->INTENSET = mask;
}

This piece of code works fine without interrupt. But now I'm trying to enable interrupts to setup pointers for TX and RX buffers.

  • I think I found the solution. It seems to be working fine now.

    I had to trigger the TASKS_ACQUIRE after the peripheral is enabled.

    void spis_init(void)
    {
        spis_pins_init();
    
        spis_set_tx_buffer(NULL, 0);
        spis_set_rx_buffer(NULL, 0);
    
        spis_configure();
    
        spis_def_set(0xFF);
        spis_orc_set(0xFF);
        
        NRF_SPIS1->EVENTS_END = 0x0UL;
        NRF_SPIS1->EVENTS_ACQUIRED = 0x0UL;
    
        spis_shorts_enable(SPIS_SHORTS_END_ACQUIRE_Msk);
        
        spis_interrupt_enable(SPIS_INTENSET_ACQUIRED_Msk);
        spis_interrupt_enable(SPIS_INTENSET_END_Msk);
        
        NVIC_SetPriority(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn, 6);
        NVIC_ClearPendingIRQ(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn);
        NVIC_EnableIRQ(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn);
    
        NRF_SPIS1->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos);
        
        NRF_SPIS1->TASKS_ACQUIRE = true;
    }

Related