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

GPIOTE PWM config question

Hi, in the (not great) mBed PWM driver, when setting up GPIOTE to toggle the output pin they do this:

/** @brief Function for initializing the GPIO Tasks/Events peripheral.
 */
void gpiote_init(PinName pin, uint8_t channel_number)
{
    // Connect GPIO input buffers and configure PWM_OUTPUT_PIN_NUMBER as an output.
    NRF_GPIO->PIN_CNF[pin] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
                            | (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
                            | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
                            | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
                            | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
    NRF_GPIO->OUTCLR = (1UL << pin);
    // Configure GPIOTE channel 0 to toggle the PWM pin state
    // @note Only one GPIOTE task can be connected to an output pin.
    /* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
    NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
                                         (31UL << GPIOTE_CONFIG_PSEL_Pos) |
                                         (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
    /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
    __NOP();
    __NOP();
    __NOP();
    /* Launch the task to take the GPIOTE channel output to the desired level */
    NRF_GPIOTE->TASKS_OUT[channel_number] = 1;

    /* Finally configure the channel as the caller expects. If OUTINIT works, the channel is configured properly.
       If it does not, the channel output inheritance sets the proper level. */
    NRF_GPIOTE->CONFIG[channel_number] = (GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos) |
                                         ((uint32_t)pin << GPIOTE_CONFIG_PSEL_Pos) |
                                         ((uint32_t)GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos) |
                                         ((uint32_t)GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos); // ((uint32_t)GPIOTE_CONFIG_OUTINIT_High <<
                                                                                                             // GPIOTE_CONFIG_OUTINIT_Pos);//

    /* Three NOPs are required to make sure configuration is written before setting tasks or getting events */
    __NOP();
    __NOP();
    __NOP();
}

Can someone explain why they set pin 31 (which doesn't exist) to low using GPIOTE? What won't work if you only do the final CONFIG? Also what do the mean by If OUTINIT works? Does it not always work?

Parents
  • All I can say is that I've never done anything like that and never had an issue, the nordic driver code doesn't do anything like that, including the three NOPs, I've never heard of anything using one pin before using the one you want, P0.31 does exist (just not on the QFN48) and I've never head of an issue with OUTINIT, well apart from it is possible to get a one clock cycle blip when you configure the GPIOTE, but you can avoid that by setting the pin to the right level before you set it up.

    I really don't know what issue they thought they were solving with that piece of code.

Reply
  • All I can say is that I've never done anything like that and never had an issue, the nordic driver code doesn't do anything like that, including the three NOPs, I've never heard of anything using one pin before using the one you want, P0.31 does exist (just not on the QFN48) and I've never head of an issue with OUTINIT, well apart from it is possible to get a one clock cycle blip when you configure the GPIOTE, but you can avoid that by setting the pin to the right level before you set it up.

    I really don't know what issue they thought they were solving with that piece of code.

Children
No Data
Related