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

Proggram GPIOTE using registers

Hi everyone,

I'm learning about proggram the nRF52840 dongle and I tried to code an interruption. Press the SW2 to turn on a LED

#include "boards.h"
#include "nrf_delay.h"
#include <stdbool.h>
#include <stdint.h>

#define MODE 0
#define PSEL 8
#define PORT 13
#define POLARITY 16
#define OUTINIT 20

int main(void) {

  //PIN SETTINGS
  //Boton
  NRF_P1->PIN_CNF[6] = (0x00 << 0x00) | (0x01 << 0x02) | (0x00 << 0x08) | (0x02 << 0x16);
  
  //LED
  NRF_P0->PIN_CNF[8] = (0x01 << 0x00);

  //BOTON config
  NRF_GPIOTE->CONFIG[0] = (0x01 << MODE) | (0x02 << PSEL) | (0x00 << PORT) | (0x01 << POLARITY);
  
  //LED config
  NRF_GPIOTE->CONFIG[1] = (0x03 << MODE) | (0x08 << PSEL) | (0x00 << PORT) | (0x00 << POLARITY) | (0x01 << OUTINIT);
 
  //Enable Tasks & Events
  NRF_GPIOTE->INTENSET = (0x01 << 0x00) | (0x01 << 0x01);
  
  //RESET EVENTS
  NRF_GPIOTE->EVENTS_IN[0] = 0;  

  NRF_P0->OUT = (0x01 << 0x08);

  //CODE

  while (true) {
    if (NRF_GPIOTE->EVENTS_IN[0] != 0) {
      NRF_GPIOTE->TASKS_SET[1];
    } else {
      NRF_GPIOTE->TASKS_CLR[1];
    }
  }
}

So, looking at this code, where did I fail?

Thanks for helping and best regards.

Parents
  • I have looked at your code and managed to get it work with the following changes

    • Skipped the code for setting the LED as output, it will be taken care of during the GPIOTE configuration
    • Did not set the SENSE field (However, you used a value 0x16, which is 22 in decimal, and will not set the SENSE field)
    • When configuring button 1 I used port 0 instead of port 1
    • No point of running NRF_P0->OUT = (0x01 << 0x08), since the value assigned to OUTINIT will overwite it
    • Better to use BUTTON_1 and LED_1, if using pca10059 examples it will be defined to appropriate pins to work with the nRF52840 dongle
    • When configuring button 1 through PIN_CNF I used pulldown instead of pullup
    • Added NRF_GPIOTE->EVENTS_IN[0] = 0; in if condition
    • Changed TASK_SET[1] to TASKS_OUT[1] = 1
    • Changed polarity from 0 to 3 when configuring the LED as a GPIOTE event

    If these bulletpoints are too messy, take a look at the code:

    GPIOTE_DONGLE.zip

    For the nRF52840 use the example in pca10059/mbr, and the hex file is located in pca10059/mbr/Output/Release/Exe

    However I would advice you to use PPI, which will connect tasks to events and you can make peripherals interact with each other without using the CPU. Using a higher abstraction layer, like GPIOTE HAL will make it easier.

    Best regards Simon

Reply
  • I have looked at your code and managed to get it work with the following changes

    • Skipped the code for setting the LED as output, it will be taken care of during the GPIOTE configuration
    • Did not set the SENSE field (However, you used a value 0x16, which is 22 in decimal, and will not set the SENSE field)
    • When configuring button 1 I used port 0 instead of port 1
    • No point of running NRF_P0->OUT = (0x01 << 0x08), since the value assigned to OUTINIT will overwite it
    • Better to use BUTTON_1 and LED_1, if using pca10059 examples it will be defined to appropriate pins to work with the nRF52840 dongle
    • When configuring button 1 through PIN_CNF I used pulldown instead of pullup
    • Added NRF_GPIOTE->EVENTS_IN[0] = 0; in if condition
    • Changed TASK_SET[1] to TASKS_OUT[1] = 1
    • Changed polarity from 0 to 3 when configuring the LED as a GPIOTE event

    If these bulletpoints are too messy, take a look at the code:

    GPIOTE_DONGLE.zip

    For the nRF52840 use the example in pca10059/mbr, and the hex file is located in pca10059/mbr/Output/Release/Exe

    However I would advice you to use PPI, which will connect tasks to events and you can make peripherals interact with each other without using the CPU. Using a higher abstraction layer, like GPIOTE HAL will make it easier.

    Best regards Simon

Children
  • Thanks a lot Simon. God bless you. I will try PPI.

    Best regards, Pablo.

  • This code is what I made to turn up the LED. With the changes you suggested me it worked and using the PPI is so much easier. Thank you very much Sir

    #include "boards.h"
    #include "nrf_delay.h"
    #include <stdbool.h>
    #include <stdint.h>
    
    
    #define MODE 0
    #define PSEL 8
    #define PORT 13
    #define POLARITY 16
    #define OUTINIT 20
    #define PULL 2
    #define DIR 0
    #define INPUT 1
    #define PULL 2
    #define DRIVE 8
    #define SENSE 16
    
    int main(void) {
    
      //PIN SETTINGS
      //Boton
      NRF_P1->PIN_CNF[6] = (0x00 << DIR) | (0x03 << PULL) | (0x00 << DRIVE) | (0x00 << SENSE);
    //  
    //  //LED
    //  //NRF_P0->PIN_CNF[8] = (0x01 << 0x00);
    //
    //  //BOTON config
      NRF_GPIOTE->CONFIG[0] = (0x01 << MODE) | (0x06 << PSEL) | (0x01 << PORT) | (0x03 << POLARITY);
    //  
    //  //LED config
      NRF_GPIOTE->CONFIG[1] = (0x03 << MODE) | (0x08 << PSEL) | (0x00 << PORT) | (0x03 << POLARITY) | (0x01 << OUTINIT);
    // 
    //  //Enable Tasks & Events
      NRF_GPIOTE->INTENSET = (0x01 << 0x00) | (0x01 << 0x01);
    //  
    //  //RESET EVENTS
      NRF_GPIOTE->EVENTS_IN[0] = 0;  
    //
    //  //PPI
      NRF_PPI->CH[0].EEP = (uint32_t) &NRF_GPIOTE->EVENTS_IN[0];
      NRF_PPI->CH[0].TEP = (uint32_t) &NRF_GPIOTE->TASKS_OUT[1];
      NRF_PPI->CHEN = (0x01 << 0x00);
    }

Related