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

Using the NFC pins as GPIO breaks SPI instance

On a custom board with an nRF52832, I have some LEDs I'm driving from the pins 9 and 10. One or both of these pins are used for the NFC antenna unless you configure them as GPIO. Many posts here show how to do that. One of them explains that, for gcc, you should set up a SECTION in the linker script and declare a const like this:

const uint32_t UICR_ADDR_0x20C __attribute__ ((section(".uicrNfcPinsAddress"))) __attribute__((used));

That line alone will cause my GPIO outputs to start working. However, it will also cause my SPI instance to stop working. I have no idea why.

I'm using the SPI for a driver for a GPS receiver, and with this const in place, the driver never sees any data there on the SPI interface. This is with SDK 14.0.0.

The only significant difference in the .map files for the broken and working code is exactly what you'd expect. No static software behaviour has changed:

$diff app_spi_broken.map app_spi_working.map 
19731d19730
<                 0x000000001000120c        0x4
19733,19735d19731
<  .uicrNfcPinsAddress
<                 0x000000001000120c        0x4 _build/app/power.c.o
<                 0x000000001000120c                UICR_ADDR_0x20C

[Edit]

Elsewhere on devzone, it's implied that you merely need to declare that const, not assign it. But I think it should really be set to 0xFFFFFFFE;

Here are the relevant bits of my linker script.

MEMORY
{
  ...
  /** Location in UICR where NFC pins register is stored. */
  UICR_NFCPINS(r) : ORIGIN = 0x1000120C, LENGTH = 0x04
}

SECTIONS {
  .uicrNfcPinsAddress :
  {
    KEEP(*(.uicrNfcPinsAddress))
  } > UICR_NFCPINS
}
Parents
  • I would suggest you to try writing to UICR (to the address 0x1000120c) using nrfjprog, just for testing first. Check if both GPIO and SPI work or not.

    If that work then you need to check your attribute declaration, I don't see you set it to a value (should be 0x01). This is how we set the address of the bootloader in UICR:

       volatile uint32_t m_uicr_bootloader_start_address  __attribute__ ((section(".uicr_bootloader_start_address")))
                                                = BOOTLOADER_START_ADDR;
    
Reply
  • I would suggest you to try writing to UICR (to the address 0x1000120c) using nrfjprog, just for testing first. Check if both GPIO and SPI work or not.

    If that work then you need to check your attribute declaration, I don't see you set it to a value (should be 0x01). This is how we set the address of the bootloader in UICR:

       volatile uint32_t m_uicr_bootloader_start_address  __attribute__ ((section(".uicr_bootloader_start_address")))
                                                = BOOTLOADER_START_ADDR;
    
Children
No Data
Related