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

Raw GPIO output without using API Functions?

Probably frowned upon but like being able to work from raw datasheet, so I know that I can. So given that the datasheet would suggest that changing a GPIO pin to be an output is as simple as setting a bit, as a specific address, to 1. So I would expect the code:

int main(int argc, char **argv)
{
    uint32_t *p0_outset = (uint32_t *)0x50000508;
    uint32_t *p0_dirset = (uint32_t *)0x50000518;

    *p0_dirset |= 0x01 << 17;
    *p0_dirset |= 0x01 << 18;

    *p0_outset |= 0x01 << 17;
    while (1) {
    }
}

to illuminate the LED on pin P0.18, as the uC is on the low side of the LED. Either that or the LED on pin P0.17 to light. As it is neither LED lights and I'm confused as to why. The GPIO section of the datasheet doesn't mention having to specifically enable that Peripheral?

Parents
  • Waaay too many magic numbers.

    Directly manipluating reisters should lookr like this:

    int PIN_NR= 3; // or use a define
    
    NRF_GPIO->PIN_CNF[PIN_NR] = 
        (NRF_GPIO_PIN_DIR_OUTPUT << GPIO_PIN_CNF_DIR_Pos) 
      | (NRF_GPIO_PIN_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) ;
      
     NRF_GPIO->DIRSET = (1<< PIN_NR);
     NRF_GPIO->OUTSET = (1<< PIN_NR);

    Note that on the bigger NRF52840 you'll need to use NRF_P0 and NRF_P1 for the GPIO Ports.

Reply
  • Waaay too many magic numbers.

    Directly manipluating reisters should lookr like this:

    int PIN_NR= 3; // or use a define
    
    NRF_GPIO->PIN_CNF[PIN_NR] = 
        (NRF_GPIO_PIN_DIR_OUTPUT << GPIO_PIN_CNF_DIR_Pos) 
      | (NRF_GPIO_PIN_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) ;
      
     NRF_GPIO->DIRSET = (1<< PIN_NR);
     NRF_GPIO->OUTSET = (1<< PIN_NR);

    Note that on the bigger NRF52840 you'll need to use NRF_P0 and NRF_P1 for the GPIO Ports.

Children
  • Is it not working because of the Magic numbers? That's impressive silicone!

    I'll try replacing the numbers with const declarations and see how it works out.. I'll let you know.

  • you might want to say which of the many chips and development boards you're using, I'm guessing the nRF52836 dev board but it could be anything. 

    The declarations come in very handy when you switch from one chip to another. As long as the peripheral has the same behavior you don't have to go edit all your code. I have stuff I wrote for the old nRF51 series and still use now. Those struct/entry type definitions for peripherals are followed by just about every manufacturer of anything using ARM, and it's certainly not frowned upon to use them. 

Related