/*
*
* RP2040_interrupt_simple-2.ino
*
* code from:
*
* https://wokwi.com/projects/381398511352819713
* author: Alan Reed, 2021
*
* https://raspberrypi.stackexchange.com/questions/137456/rpi-pico-irq-with-callback-freezes-pico
* author: tmajz @ May 12, 2022
*
*
* code developed on: WOKWI
* https://wokwi.com/projects/391893524910605313
*
*
* // :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
* //
* // only ONE CALLBACK can be implemented for -ALL- the interrupts
* //
* // :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
*
*
* -----------------------------------------------------------------------------------------------------------------------
*
*
* https://arduino-pico.readthedocs.io/en/latest/analog.html
*
* Analog Outputs
* The RP2040 does not have any onboard DACs, so analog outputs are simulated
* using the standard method of using pulse width modulation (PWM) using
* the RP2040’s hardware PWM units.
* While up to 16 PWM channels can be generated, they are not independent
* and there are significant restrictions as to allowed pins in parallel.
* See the RP2040 datasheet for full details.
*
* Analog Output Restrictions
* The PWM generator source clock restricts the legal combinations
* of frequency and ranges. At a CPU frequency of 133MHz, the 16 bit
* maximum range decreases by 1 bit for every doubling of the default
* PWM frequency of 1 kHz. For example, at 1MHz only about 6 bits
* of range are possible. When you define an analogWriteFreq and
* analogWriteRange that can’t be fulfilled by the hardware, the frequency
* will be preserved but the accuracy (range) will be reduced automatically.
* Your code will still send in the range you specify, but the core itself
* will transparently map it into the allowable PWN range.
*
* void analogWriteFreq(uint32_t freq)
* Sets the master PWM frequency used (i.e. how often the PWM output cycles).
* From 100Hz to 1MHz are supported.
*
* void analogWriteRange(uint32_t range) and analogWriteResolution(int res)
* These calls set the maximum PWM value (i.e. writing this value will result
* in a PWM duty cycle of 100%)/ either explicitly (range) or as a power-of-two
* (res). A range of 16 to 65535 is supported.
*
* void analogWrite(pin_size_t pin, int val)
* Writes a PWM value to a specific pin. The PWM machine is enabled and set
* to the requested frequency and scale, and the output is generated.
* This will continue until a digitalWrite or other digital output is performed.
*
*
* -----------------------------------------------------------------------------------------------------------------------
*
*
* Only on WOKWI, PAY ATTENTION to the following CONDITION:
* using the LEFT/RIGHT mouse button, select the -PUSH BUTTON-
* in the diagram: then proceed to UNSELECT the [Bounce] box.
* This enables the DEBOUNCE for the selected -PUSH BUTTON-.
* Only on WOKWI, if you don't, ALL this code becomes GARBAGE!!
*
* WARNING: to run the << decrement >> interrupt alone,
* the value of the GLOBAL -- Gvlt_Event8 --
* >>>> MUST BE set to 255 <<<<, NOT ZERO!
*
*
*/
// ** GLOBALS declarations **************************************************
volatile uint8_t Gvlt_Event8 = 0;
//volatile uint8_t Gvlt_Event8 = 255; // USE for test DECREMENT button alone
const int G_pinINCRbttn8 = 8;
const int G_pinDECRbttn8 = 9;
// **************************************************************************
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
// only ONE CALLBACK can be implemented for -ALL- the interrupts
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
// **************************************************************************
void Bttn_clbk(uint gpio, uint32_t events) {
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
// only ONE CALLBACK can be implemented for -ALL- the interrupts
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
uint8_t OnOff8 = 0, OutPin8 = 255;
//
switch(gpio) {
case G_pinINCRbttn8:
// event management code
if (Gvlt_Event8 < 255) {
Gvlt_Event8 += 1;
OnOff8 = 1, OutPin8 = 18;
// the following line of code, -DISABLE- the INTERRUPT
// ATTENTION: furthermore, to become RELIABLE, IT MUST NOT BE inserted
// in a generic position at the end of this function: instead it
// MUST RESIDE INSIDE of THIS event handling code
gpio_set_irq_enabled_with_callback(gpio, 0x04, false, &Bttn_clbk);
// NOTE: in the function -gpio_set_irq_enabled_with_callback()-
// the SECOND parameter is the > event_mask < [0x04 --> FALLING]
// the THIRD parameter is the - Disable(false) [Enable(true)] - flag
} // if
break;
case G_pinDECRbttn8:
// event management code
if (Gvlt_Event8 > 0) {
Gvlt_Event8 -= 1;
OnOff8 = 1, OutPin8 = 19;
// the following line of code, -DISABLE- the INTERRUPT
// ATTENTION: furthermore, to become RELIABLE, IT MUST NOT BE inserted
// in a generic position at the end of this function: instead it
// MUST RESIDE INSIDE of THIS event handling code
gpio_set_irq_enabled_with_callback(gpio, 0x04, false, &Bttn_clbk);
// NOTE: in the function -gpio_set_irq_enabled_with_callback()-
// the SECOND parameter is the > event_mask < [0x04 --> FALLING]
// the THIRD parameter is the - Disable(false) [Enable(true)] - flag
} // if
break;
default:
OnOff8 = 0;
break;
}
//
if (OnOff8 > 0) digitalWrite(OutPin8, OnOff8);
//
} // Bttn_clbk()
// **************************************************************************
void setup() {
//
Serial1.begin(115200);
while (!Serial1);
//
Serial1.println("\nsetup started...\n");
//
pinMode(G_pinINCRbttn8, INPUT); // RED bttn. INCR.
pinMode(G_pinDECRbttn8, INPUT); // BLUE bttn. DECR.
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
// only ONE CALLBACK can be implemented for -ALL- the interrupts
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
// NOTE, in the function -gpio_set_irq_enabled_with_callback()-:
// A) the SECOND parameter is the > event_mask <
// (which event will trigger the interrupt):
// 0 - GPIO_IRQ_LEVEL_LOW => 0x1u Continuously while level is low
// 1 - GPIO_IRQ_LEVEL_HIGH => 0x2u Continuously while level is high
// 2 - GPIO_IRQ_EDGE_FALL => 0x4u On each transition from high to low
// 3 - GPIO_IRQ_EDGE_RISE => 0x8u On each transition from low to high
// B) the THIRD parameter is the - Enable(1) or Disable(0) - flag
gpio_set_irq_enabled_with_callback(G_pinINCRbttn8, 0x04, true, &Bttn_clbk);
gpio_set_irq_enabled_with_callback(G_pinDECRbttn8, 0x04, true, &Bttn_clbk);
// interrupt triggered by FALLING edge [2 - GPIO_IRQ_EDGE_FALL => 0x04)]
// NOTE: in the function -gpio_set_irq_enabled_with_callback()-
// the SECOND parameter is the > event_mask < [0x04 --> FALLING]
// the THIRD parameter is the - Enable(true) [Disable(false)] - flag
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
// only ONE CALLBACK can be implemented for -ALL- the interrupts
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
pinMode(18, OUTPUT);
pinMode(19, OUTPUT);
// brute force lit ALL led...just to see if all works :)
digitalWrite(18, 1);
digitalWrite(19, 1);
delay(1000);
// brute force zeroing ALL led
digitalWrite(18, 0);
digitalWrite(19, 0);
//
Serial1.println("... setup ended.\n");
//
} // setup()
void loop() {
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
// only ONE CALLBACK can be implemented for -ALL- the interrupts
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
static uint8_t oldEvnt8 = 0;
//
if (Gvlt_Event8 != oldEvnt8) {
// re-enables the interrupt that generated the event
if (Gvlt_Event8 < oldEvnt8) {
gpio_set_irq_enabled_with_callback(G_pinDECRbttn8, 0x04, true, &Bttn_clbk);
} else if (Gvlt_Event8 > oldEvnt8) {
gpio_set_irq_enabled_with_callback(G_pinINCRbttn8, 0x04, true, &Bttn_clbk);
} // if-else
//
oldEvnt8 = Gvlt_Event8;
Serial1.print("Gvlt_Event8 ="); Serial1.println(Gvlt_Event8);
//
// NOTE: in the function -gpio_set_irq_enabled_with_callback()-
// the THIRD parameter is the - Enable(true) [Disable(false)] - flag
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
// only ONE CALLBACK can be implemented for -ALL- the interrupts
//
// :::: WARNING :::: :::: WARNING :::: :::: WARNING ::::
//
// brute force zeroing ALL led
delay(300);
digitalWrite(18, 0);
digitalWrite(19, 0);
//
} // if
//
delay(100);
//
} // loop()