This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Can't get SPI1 interrupt (nrf51)

Hi! I'm experimenting with a bare-metal implementation of SPI connectivity among two nrf51 modules. One of them is master, another is slave.

The problem is, the below code doesn't trigger an interrupt after starting task in send_spi_data. Is it fine? Shall I do something else to enable SPIM1 peripherial?

static uint32_t rx_dword = 0;
static uint32_t tx_dword = 0;
static bool rx_done = false;
static bool tx_done = false;

void send_spi_data(uint32_t data)
{

    NRF_SPIM1->RXD.PTR = (uint32_t)&rx_dword;
    NRF_SPIM1->TXD.PTR = (uint32_t)&tx_dword;
    tx_dword = data;
    NRF_GPIO->OUTCLR = 1UL << SPIM_CSN_PIN;

    NRF_SPIM1->EVENTS_ENDRX = 0;
    NRF_SPIM1->EVENTS_ENDTX = 0;
    NRF_SPIM1->EVENTS_STOPPED = 0;

    NRF_SPIM1->TASKS_START = 1;

}


void init_spim()
{
    NRF_GPIO->OUTCLR = 1UL << SPIM_SCK_PIN;
    NRF_GPIO->PIN_CNF[SPIM_SCK_PIN] =
            (uint32_t) NRF_GPIO_PIN_DIR_OUTPUT << GPIO_PIN_CNF_DIR_Pos
            | (uint32_t) NRF_GPIO_PIN_INPUT_CONNECT << GPIO_PIN_CNF_INPUT_Pos
            | (uint32_t) NRF_GPIO_PIN_NOPULL << GPIO_PIN_CNF_PULL_Pos
            | (uint32_t) NRF_GPIO_PIN_S0S1 << GPIO_PIN_CNF_DRIVE_Pos
            | (uint32_t) NRF_GPIO_PIN_NOSENSE << GPIO_PIN_CNF_SENSE_Pos;
    NRF_SPIM1->PSEL.SCK = SPIM_SCK_PIN;

    NRF_GPIO->OUTCLR = 1UL << SPIM_MOSI_PIN;
    NRF_GPIO->PIN_CNF[SPIM_MOSI_PIN] =
            (uint32_t) NRF_GPIO_PIN_DIR_OUTPUT << GPIO_PIN_CNF_DIR_Pos
            | (uint32_t) NRF_GPIO_PIN_INPUT_DISCONNECT << GPIO_PIN_CNF_INPUT_Pos
            | (uint32_t) NRF_GPIO_PIN_NOPULL << GPIO_PIN_CNF_PULL_Pos
            | (uint32_t) NRF_GPIO_PIN_S0S1 << GPIO_PIN_CNF_DRIVE_Pos
            | (uint32_t) NRF_GPIO_PIN_NOSENSE << GPIO_PIN_CNF_SENSE_Pos;
    NRF_SPIM1->PSEL.MOSI = SPIM_MOSI_PIN;

    NRF_GPIO->PIN_CNF[SPIM_MISO_PIN] =
            (uint32_t) NRF_GPIO_PIN_DIR_INPUT << GPIO_PIN_CNF_DIR_Pos
            | (uint32_t) NRF_GPIO_PIN_INPUT_CONNECT << GPIO_PIN_CNF_INPUT_Pos
            | (uint32_t) NRF_GPIO_PIN_NOPULL << GPIO_PIN_CNF_PULL_Pos
            | (uint32_t) NRF_GPIO_PIN_S0S1 << GPIO_PIN_CNF_DRIVE_Pos
            | (uint32_t) NRF_GPIO_PIN_NOSENSE << GPIO_PIN_CNF_SENSE_Pos;
    NRF_SPIM1->PSEL.MISO = SPIM_MISO_PIN;

    NRF_GPIO->OUTSET = 1UL << SPIM_CSN_PIN;
    NRF_GPIO->PIN_CNF[SPIM_CSN_PIN] =
            (uint32_t) NRF_GPIO_PIN_DIR_OUTPUT << GPIO_PIN_CNF_DIR_Pos
            | (uint32_t) NRF_GPIO_PIN_INPUT_DISCONNECT << GPIO_PIN_CNF_INPUT_Pos
            | (uint32_t) NRF_GPIO_PIN_NOPULL << GPIO_PIN_CNF_PULL_Pos
            | (uint32_t) NRF_GPIO_PIN_S0S1 << GPIO_PIN_CNF_DRIVE_Pos
            | (uint32_t) NRF_GPIO_PIN_NOSENSE << GPIO_PIN_CNF_SENSE_Pos;

    NRF_SPIM1->CONFIG = 0; // CPOL = 0 - ActiveHigh, CPHA = 0 - Leading edge, ByteOrder = 0 - MSB
    NRF_SPIM1->ORC = 0x55;

    NRF_SPIM1->FREQUENCY = SPIM_FREQUENCY_FREQUENCY_M4;
    NRF_SPIM1->RXD.MAXCNT = sizeof(rx_dword);
    NRF_SPIM1->TXD.MAXCNT = sizeof(tx_dword);
    NRF_SPIM1->RXD.PTR = (uint32_t)&rx_dword;
    NRF_SPIM1->TXD.PTR = (uint32_t)&tx_dword;


    NRF_SPIM1->INTENSET =
            (SPIM_INTENSET_ENDRX_Set << SPIM_INTENSET_ENDRX_Pos)
            | (SPIM_INTENSET_ENDTX_Set << SPIM_INTENSET_ENDTX_Pos)
            | (SPIM_INTENSET_STOPPED_Set << SPIM_INTENSET_STOPPED_Pos);

    NRF_SPIM1->ENABLE = SPIM_ENABLE_ENABLE_Enabled;

    NVIC_SetPriority(SPI1_TWI1_IRQn, 3);
    NVIC_ClearPendingIRQ(SPI1_TWI1_IRQn);
    NVIC_EnableIRQ(SPI1_TWI1_IRQn);

}

__attribute__((__interrupt__))
void SPI1_TWI1_IRQHandler (void)
{
    UART_PRINT(__func__);
    if(NRF_SPIM1->EVENTS_STOPPED)
    {
        NRF_SPIM1->EVENTS_STOPPED = 0;
        NRF_GPIO->OUTSET = 1UL << SPIM_CSN_PIN;
        rx_done = false;
        tx_done = false;
    }
    else
    {
        if(NRF_SPIM1->EVENTS_ENDRX)
        {
            NRF_SPIM1->EVENTS_ENDRX = 0;
            rx_done = true;
        }
        else if (NRF_SPIM1->EVENTS_ENDTX)
        {
            NRF_SPIM1->EVENTS_ENDTX = 0;
            tx_done = true;
        }

        if(rx_done && tx_done)
        {
            NRF_SPIM1->TASKS_STOP = 1;
        }
    }
}
Parents Reply Children
Related