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

GPIO pin errors

Hello, I am toggling two separate pins at different rates but it looks like for whatever reason the when I go to clear one gpio register it clears everything. I understand that writing a 0 to the outclr and dirset registers have no impact. so I am "OR" ing my OUT register with the specific bit I want to clear or set.

I am experiencing unusual behavior when I set the OUTCLR register. If the OUTCLR and out OUTSET are set to 0x1080 and I assert:

NRF_GPIO -> OUTCLR |= 0x80 I would expect this pin to go low and my other pin stays high but what happens is the registers go to 0.

This code works for one LED but when I introduced a timer interrupt to toggle a pin I encountered this unusual behavior. any ideas?

below is a snippet of my code

// simple function to toggle and led pin void toggle_led(uint8_t pin_number) {

if (ledpin == true) //if high turn off 
{
	NRF_GPIO -> OUTCLR |= (1 << pin_number);
	ledpin = false;
}

else
{
	NRF_GPIO -> OUTSET |= (1 << pin_number);
	ledpin = true;
}

}

void TIMER0_IRQHandler(void) {

if (NRF_TIMER0->EVENTS_COMPARE[0] == 1)
{
    if (((NRF_GPIO -> OUT & (1 << bitbang)) == 0)  //low 
    NRF_GPIO-> OUTSET |= (1 << bitbang);
else //high capture event
{
    val = (1<<HX711) & NRF_GPIO-> IN; // is it a 1 or 0?
    val <<= 1; //left shift to get into place 
    NRF_GPIO-> OUTCLR |= (1 << bitbang);
}
NRF_TIMER0->EVENTS_COMPARE[0] = 0;
}

}

here is how my pins are configured {

#define bitbang				 				12  										
//bitbang clock. should create a clock of 80hz
define bitbang_DIR						GPIO_PIN_CNF_DIR_Output
define bitbang_BUF						GPIO_PIN_CNF_INPUT_Disconnect
define bitbang_PUL						GPIO_PIN_CNF_PULL_Disabled 
define bitbang_DRIVE					GPIO_PIN_CNF_DRIVE_S0S1
define bitbang_SENSE					GPIO_PIN_CNF_SENSE_Disabled
define HX711				 			11											
define HX711_DIR						GPIO_PIN_CNF_DIR_Input
define HX711_BUF						GPIO_PIN_CNF_INPUT_Connect
define HX711_PUL						GPIO_PIN_CNF_PULL_Disabled
define HX711_DRIVE					GPIO_PIN_CNF_DRIVE_S0S1
define HX711_SENSE					GPIO_PIN_CNF_SENSE_Disabled

#define bitbang_cfg							(STPb_DIR << GPIO_PIN_CNF_DIR_Pos ) | ( STPb_BUF << GPIO_PIN_CNF_INPUT_Pos) | ( STPb_PUL << GPIO_PIN_CNF_PULL_Pos )| ( STPb_DRIVE << GPIO_PIN_CNF_DRIVE_Pos) | ( STPb_SENSE << GPIO_PIN_CNF_SENSE_Pos )
//bitbang clock pin 
NRF_P0->PIN_CNF[bitbang] = bitbang_cfg;

//hx711 sensor 
NRF_P0->PIN_CNF[HX711] = HX711_cfg;

} the names inside the PIN_CNF represent all of the above defines OR'd to create a word.

Thank you,

Eric Micallef

Parents
  • You don't do an OR when you use outset and outclr. The outset and outclr registers are designed to keep you from OR'ing or AND'ing with the gpio state register whenever you want to use it.

    Per the spec if you read the outset or outclear registers they contain the current state of the pin. So, using your code you are reading the register then OR'ing with your intended state for one pin. This could cause a state change on all pins depending on whether they are high or low at the time.

    So, correct way is:

    NRF_GPIO -> OUTCLR = (1 << pin_number);
    
    NRF_GPIO -> OUTSET = (1 << pin_number);
    
Reply
  • You don't do an OR when you use outset and outclr. The outset and outclr registers are designed to keep you from OR'ing or AND'ing with the gpio state register whenever you want to use it.

    Per the spec if you read the outset or outclear registers they contain the current state of the pin. So, using your code you are reading the register then OR'ing with your intended state for one pin. This could cause a state change on all pins depending on whether they are high or low at the time.

    So, correct way is:

    NRF_GPIO -> OUTCLR = (1 << pin_number);
    
    NRF_GPIO -> OUTSET = (1 << pin_number);
    
Children
Related