diff options
| author | Ulf Lilleengen <[email protected]> | 2025-03-26 07:50:13 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-03-26 07:50:13 +0000 |
| commit | 9edf5b7f049f95742b60b041e4443967d8a6b708 (patch) | |
| tree | f5ed3461351b206e8f6c4c4d2bb57777a71d7d6c | |
| parent | 4f250f399513319220853bfa0e13b9a588de8000 (diff) | |
| parent | db7759ea7db24b00e6f585f560c73bad9fdc1def (diff) | |
Merge pull request #4009 from i509VCB/mspm0-gpio-disable-event
mspm0: disable events before clearing gpio RIS
| -rw-r--r-- | embassy-mspm0/src/gpio.rs | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/embassy-mspm0/src/gpio.rs b/embassy-mspm0/src/gpio.rs index e1eb7eecf..1048d980e 100644 --- a/embassy-mspm0/src/gpio.rs +++ b/embassy-mspm0/src/gpio.rs | |||
| @@ -935,15 +935,32 @@ impl<'d> InputFuture<'d> { | |||
| 935 | fn new(pin: PeripheralRef<'d, AnyPin>, polarity: Polarity) -> Self { | 935 | fn new(pin: PeripheralRef<'d, AnyPin>, polarity: Polarity) -> Self { |
| 936 | let block = pin.block(); | 936 | let block = pin.block(); |
| 937 | 937 | ||
| 938 | // Before clearing any previous edge events, we must disable events. | ||
| 939 | // | ||
| 940 | // If we don't do this, it is possible that after we clear the interrupt, the current event | ||
| 941 | // the hardware is listening for may not be the same event we will configure. This may result | ||
| 942 | // in RIS being set. Then when interrupts are unmasked and RIS is set, we may get the wrong event | ||
| 943 | // causing an interrupt. | ||
| 944 | // | ||
| 945 | // Selecting which polarity events happen is a RMW operation. | ||
| 946 | critical_section::with(|_cs| { | ||
| 947 | if pin.bit_index() >= 16 { | ||
| 948 | block.polarity31_16().modify(|w| { | ||
| 949 | w.set_dio(pin.bit_index() - 16, Polarity::DISABLE); | ||
| 950 | }); | ||
| 951 | } else { | ||
| 952 | block.polarity15_0().modify(|w| { | ||
| 953 | w.set_dio(pin.bit_index(), Polarity::DISABLE); | ||
| 954 | }); | ||
| 955 | }; | ||
| 956 | }); | ||
| 957 | |||
| 938 | // First clear the bit for this event. Otherwise previous edge events may be recorded. | 958 | // First clear the bit for this event. Otherwise previous edge events may be recorded. |
| 939 | block.cpu_int().iclr().write(|w| { | 959 | block.cpu_int().iclr().write(|w| { |
| 940 | w.set_dio(pin.bit_index(), true); | 960 | w.set_dio(pin.bit_index(), true); |
| 941 | }); | 961 | }); |
| 942 | 962 | ||
| 943 | // Selecting which polarity events happens is a RMW operation. | 963 | // Selecting which polarity events happen is a RMW operation. |
| 944 | // | ||
| 945 | // Guard with a critical section in case two different threads try to select events at the | ||
| 946 | // same time. | ||
| 947 | critical_section::with(|_cs| { | 964 | critical_section::with(|_cs| { |
| 948 | // Tell the hardware which pin event we want to receive. | 965 | // Tell the hardware which pin event we want to receive. |
| 949 | if pin.bit_index() >= 16 { | 966 | if pin.bit_index() >= 16 { |
