Skip to content

cpu/kinetis/periph_gpio_irq: fix re-enabling an existing interrupt#14376

Open
benemorius wants to merge 4 commits into
RIOT-OS:masterfrom
benemorius:pr/kinetis-gpio-fixes
Open

cpu/kinetis/periph_gpio_irq: fix re-enabling an existing interrupt#14376
benemorius wants to merge 4 commits into
RIOT-OS:masterfrom
benemorius:pr/kinetis-gpio-fixes

Conversation

@benemorius

Copy link
Copy Markdown
Member

Contribution description

This PR has 3 related bugfixes that I've split out of #11789. In that PR, the UART implementation is modified to use GPIO interrupts to wake from low power. It fails to work after the first received character without these fixes. IIRC disabling and re-enabling a GPIO interrupt always triggers these bugs.

Testing procedure

  • configure a pin interrupt and test that it works
  • disable the interrupt and re-enable it
  • test that the pin interrupt still works
  • without this PR, the pin interrupt has stopped working until reset

Issues/PRs references

This PR is needed for #14377 to work properly.

@benpicco benpicco added Area: cpu Area: CPU/MCU ports CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) labels Jun 27, 2020
Comment thread cpu/kinetis/periph/gpio.c Outdated
static inline int get_ctx(int port, int pin)
{
return (isr_map[(port * 4) + (pin >> 3)] >> ((pin & 0x7) * 4)) & 0xf;
return ((isr_map[(port * 4) + (pin >> 3)] >> ((pin & 0x7) * 4)) & 0xf) - 1;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also be done in write_map?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The equivalent is done in the only consumer of write_map() that needs it, in gpio_init_int()

Comment thread cpu/kinetis/periph/gpio.c Outdated
isr_ctx[ctx_num].arg = arg;
isr_ctx[ctx_num].state = flank;
write_map(port_num(pin), pin_num(pin), ctx_num);
/* context map requires ctx_num + 1, as 0 is the no-context value */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have thought ctx_num < 0 would indicate no context - or how is this meant?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the efficient way that someone did the isr_map, we need the isr_map to store 0 when a pin has no context to map to. This means that when we want to map a pin to isr_ctx 0, we actually need to write 1 to isr_map.

It would read cleaner to rewrite everything to use -1 for no-context but that isn't compatible with how the bitmapped isr_map is done. But I could be mistaken. I didn't try that hard.

Comment thread cpu/kinetis/periph/gpio.c
* @brief Calculate the needed memory (in bytes) to store 4 bits per MCU pin
*/
#define ISR_MAP_SIZE (GPIO_PORTS_NUMOF * PINS_PER_PORT * 4 / 8)
#define ISR_MAP_SIZE (GPIO_PORTS_NUMOF * PINS_PER_PORT * 4 / 8 / sizeof(uint32_t))

@benpicco benpicco Jun 27, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So just for my understanding: we can have 16 interrupts in total, mapped to any pin?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, more or less. We can have up to all pins mapped, with up to CTX_NUMOF unique callbacks to map them to.

isr_map is what maps a pin to (if applicable) a callback context in isr_ctx

In isr_map each pin gets 4 bits to specify an isr_ctx which is 16 minus 1 possible callbacks that a pin can point to. It's minus 1 because we need a value to indicate that there is no isr_ctx for that pin in isr_map and that value is 0. There used to be no concept of a no-context value in isr_map and that's what the fix irq contexts not being freed commit is for.

An additional limitation is CTX_NUMOF which currently limits us to only 8 callback contexts in isr_ctx. We could increase this to 15 before having to change the workings of isr_map.

@benemorius

Copy link
Copy Markdown
Member Author

It's been a long while since I wrote these commits and apparently the fact that I can't easily answer you @benpicco without studying the code means that the code or comments need further improvement. I'll try to get to this soon.

@benemorius

Copy link
Copy Markdown
Member Author

@benpicco I had hoped to address your comments by changing code or comments but I didn't seen much opportunity for that. Let me know if you didn't understand my responses or if you'd still like to suggest changes.

@benpicco

benpicco commented Aug 6, 2020

Copy link
Copy Markdown
Contributor

Sorry for dropping the ball on this.
Comments on the PR don't help - if someone is going to read this code in the future, they will not have access to PR comments.

@benemorius

Copy link
Copy Markdown
Member Author

@benpicco if you found the PR comments adequate I will use them to supplement the code comments. Otherwise we can continue to discuss the confusion until we get it right and then I will update the code comments accordingly.

@benemorius

Copy link
Copy Markdown
Member Author

Nevermind, I did actually find some code changes to improve readability. With that plus the comments I moved from PR comments to code comments, hopefully this is in better shape. Let me know what you think @benpicco

These changes didn't fit well as fixup commits so I left it as a proper commit.

@fjmolinas

Copy link
Copy Markdown
Contributor

ping @benpicco!

@benpicco benpicco self-assigned this Aug 18, 2020
@MrKevinWeiss MrKevinWeiss added this to the Release 2021.07 milestone Jun 21, 2021
@MrKevinWeiss

Copy link
Copy Markdown
Contributor

Can we move this one forward?

@MrKevinWeiss MrKevinWeiss removed this from the Release 2021.07 milestone Jul 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: cpu Area: CPU/MCU ports CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants