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

NRF52810 SPI PSEL pins wont set & infinite loop

Currently blocked by this issue.

// CFG_PIN_GLUE_DAT = 5

// CFG_PIN_GLUE_CLK = 6

NRF_GPIO->PIN_CNF[CFG_PIN_GLUE_DAT] = pinDisconnectInputBuffer | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
NRF_GPIO->PIN_CNF[CFG_PIN_GLUE_CLK] = (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);

NRF_SPI0->PSEL.SCK = CFG_PIN_GLUE_CLK;
NRF_SPI0->PSEL.MOSI = CFG_PIN_GLUE_DAT;
NRF_SPI0->PSEL.MISO = SPI_PSEL_MOSI_CONNECT_Disconnected << SPI_PSEL_MOSI_CONNECT_Pos; // unused

// WARN - pins appear not be set, see screenshot! Huh?!?

NRF_SPIM0->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;

NRF_SPI0->TXD = 15;

while (!NRF_SPI0->EVENTS_READY) {}  // STUCK HERE. Does writing to TXD auto trigger a send?
NRF_SPI0->EVENTS_READY = 0;

Parents Reply Children
  • Segger, and yes to the rest. Actually you can see in the same screenshot the "frequency" is read correctly.

    I've followed the manual/spec to the letter. For the PSEL pins maybe that is still the debugger reading from the wrong memory location. If not, it could be the reason why TX doesn't work (according to the lack of EVENTS_READY flag).

    All other peripherals are disabled and SoftDevice not initialized (although I don't think anything touches SPI anyway but worth considering the main crystal hasn't been halted).

  • i can see in the SES that the registers are just updated (red) when writing these registers. I haven't seen the behavior you see before, 

    Can you please attach your project so that i can try to replicate this behavior.

  • If you're an employee and can take it private I can send the project.

    I've also (yesterday) followed through to spim_pins_set and it's doing the same thing under the hood.

  • I found the debugging issue, I had the nrf52.svd register file selected, a left over. So now the values show up correctly.

    Which leaves the EVENTS_READY not setting. According to the manual this event is flag when TX has shifted out and RX has shifted in. In my case TX is set and RX should be null by the disconnect. Therefore something must be stopping TX from sending.

  • Further investigation. The EVENT_READY is most likely set by interrupt, which I wasn't using. I've therefore set this with an inner loop.

    inline void GLUE_Start (void) {
    
      NVIC_SetPriority(SPIM0_SPIS0_SPI0_IRQn, 4);
      NVIC_EnableIRQ(SPIM0_SPIS0_SPI0_IRQn);
      __enable_irq(); // TODO: maybe not required
      NRF_SPIM0->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
    }
    
    void SPIM0_SPIS0_SPI0_IRQHandler (void) {
    
      waiton = 0;
      NRF_SPI0->EVENTS_READY = 0;
    }
    
    static void sendWait (uint8_t payload) {
    
      waiton = 1;
      NRF_SPI0->TXD = payload;
      while (waiton) {
        __WFE();
      }
    }
    


    Unfortunately the behaviour is the same, the interrupt isn't called. All this is pre-softdevice.




Related