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

Joystick Interrupt

Are there any sample applications that use a joystick press as an interrupt instead of a button press? The dev board I'm using uses the nRF6350 display and I was wondering if there's any code around that I could refer to

  • Hi,

    The joystick on the nRF6350 is accessed via an GPIO extender IC over I2C. What it does is read the GPIO status and sends it back to the I2C master in a muxed data format (you can see this in the nRF6350.c file, in ..\Nordic\nrf51822\Source\ext_sensors\nRF6350)

    Interfacing a "normal" joystick would be fairly similar. Here's an example:

    Joystick has Up/down/right/left. Up connected to P0.00 Down connected to P0.01 Right connected to P0.02 Left connected to P0.03

    You must also set the active level (ie: when you push the button, is it logic '1' or '0') by connecting the button-press-behavior to a defined level (GND or VDD).

    Example with logic '0' as active (buttons active low, being pulled to GND). You initialize with this:

    
    nrf_gpio_cfg_sense_input(GPIO_JOYSTICK_UP, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    nrf_gpio_cfg_input(GPIO_JOYSTICK_DWN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    nrf_gpio_cfg_input(GPIO_JOYSTICK_LEFT, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    nrf_gpio_cfg_input(GPIO_JOYSTICK_RIGHT, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
    
    

    You enable the GPIOTE port event like this:

    
    NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
    NVIC_EnableIRQ(GPIOTE_IRQn);
    

    Then you can read with this routine:

    
    void GPIOTE_Handler(void)
    {
    if(NRF_GPIOTE->EVENTS_PORT){
        uint32_t gpio_state = NRF_GPIO->IN;
        NRF_GPIOTE->EVENTS_PORT = 0;
        if (!((gpio_state >> GPIO_JOYSTICK_UP) & 0x01 ))
            // Up is detected
        if (!((gpio_state >> GPIO_JOYSTICK_DWN) & 0x01 ))
            // Down is detected
        if (!((gpio_state >> GPIO_JOYSTICK_LEFT) & 0x01 ))
            // Left is detected
        if (!((gpio_state >> GPIO_JOYSTICK_RIGHT) & 0x01 ))
            // Right is detected
        }
    }
    
    

    You can use the app_button library to make these GPIOs give you an interrupt, which includes debouncing and other features. See example ble_hids_app_mouse for how to setup the app_button library.

    edit Read your question too quick. You want interrupt instead of polling.

    Best regards Håkon

  • Hi Håkon Alseth:

        I use the PORT EVENT to produce multiple interrupts.But I have a question by these: 
    

    NRF_GPIO->PIN_CNF[BUTTON1] = (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos) | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | (NRF_GPIO_PIN_NOPULL << GPIO_PIN_CNF_PULL_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);

    NRF_GPIO->PIN_CNF[BUTTON2] = (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos) | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) | (NRF_GPIO_PIN_NOPULL << GPIO_PIN_CNF_PULL_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);

    void GPIOTE_IRQHandler(void) {
    if ((NRF_GPIOTE->EVENTS_PORT != 0)) { NRF_GPIOTE->EVENTS_PORT = 0; } . if (nrf_gpio_pin_read(BUTTON1) == 0) { //do something
    }

    if (nrf_gpio_pin_read(BUTTON2) == 0) { //do something
    }

    }

    I found that when the BOTTON1 is pressed, now I press BOTTON2, it couldn't product a interrupt.At the same time can't have two keys in pressed state.How I could solve it??
    
Related