@@ -31,44 +31,52 @@ static void handle_interrupt_in(void) {
31
31
uint32_t fall0 = LPC_GPIOINT -> IO0IntStatF ;
32
32
uint32_t rise2 = LPC_GPIOINT -> IO2IntStatR ;
33
33
uint32_t fall2 = LPC_GPIOINT -> IO2IntStatF ;
34
- uint32_t mask0 = 0 ;
35
- uint32_t mask2 = 0 ;
36
- int i ;
37
-
38
- // P0.0-0.31
39
- for (i = 0 ; i < 32 ; i ++ ) {
40
- uint32_t pmask = (1 << i );
41
- if (rise0 & pmask ) {
42
- mask0 |= pmask ;
43
- if (channel_ids [i ] != 0 )
44
- irq_handler (channel_ids [i ], IRQ_RISE );
45
- }
46
- if (fall0 & pmask ) {
47
- mask0 |= pmask ;
48
- if (channel_ids [i ] != 0 )
49
- irq_handler (channel_ids [i ], IRQ_FALL );
50
- }
34
+ uint8_t bitloc ;
35
+
36
+ while (rise0 > 0 ) { //Continue as long as there are interrupts pending
37
+ bitloc = 31 - __CLZ (rise0 ); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
38
+ if (channel_ids [bitloc ] != 0 )
39
+ irq_handler (channel_ids [bitloc ], IRQ_RISE ); //Run that interrupt
40
+
41
+ //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
42
+ LPC_GPIOINT -> IO0IntClr = 1 << bitloc ;
43
+ rise0 -= 1 <<bitloc ;
51
44
}
52
45
53
- // P2.0-2.15
54
- for (i = 0 ; i < 16 ; i ++ ) {
55
- uint32_t pmask = (1 << i );
56
- int channel_index = i + 32 ;
57
- if (rise2 & pmask ) {
58
- mask2 |= pmask ;
59
- if (channel_ids [channel_index ] != 0 )
60
- irq_handler (channel_ids [channel_index ], IRQ_RISE );
61
- }
62
- if (fall2 & pmask ) {
63
- mask2 |= pmask ;
64
- if (channel_ids [channel_index ] != 0 )
65
- irq_handler (channel_ids [channel_index ], IRQ_FALL );
66
- }
46
+ while (fall0 > 0 ) { //Continue as long as there are interrupts pending
47
+ bitloc = 31 - __CLZ (fall0 ); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
48
+ if (channel_ids [bitloc ] != 0 )
49
+ irq_handler (channel_ids [bitloc ], IRQ_FALL ); //Run that interrupt
50
+
51
+ //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
52
+ LPC_GPIOINT -> IO0IntClr = 1 << bitloc ;
53
+ fall0 -= 1 <<bitloc ;
54
+ }
55
+
56
+ //Same for port 2, only we need to watch the channel_index
57
+ while (rise2 > 0 ) { //Continue as long as there are interrupts pending
58
+ bitloc = 31 - __CLZ (rise2 ); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
59
+
60
+ if (bitloc < 16 ) //Not sure if this is actually needed
61
+ if (channel_ids [bitloc + 32 ] != 0 )
62
+ irq_handler (channel_ids [bitloc + 32 ], IRQ_RISE ); //Run that interrupt
63
+
64
+ //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
65
+ LPC_GPIOINT -> IO2IntClr = 1 << bitloc ;
66
+ rise2 -= 1 <<bitloc ;
67
+ }
68
+
69
+ while (fall2 > 0 ) { //Continue as long as there are interrupts pending
70
+ bitloc = 31 - __CLZ (fall2 ); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
71
+
72
+ if (bitloc < 16 ) //Not sure if this is actually needed
73
+ if (channel_ids [bitloc + 32 ] != 0 )
74
+ irq_handler (channel_ids [bitloc + 32 ], IRQ_FALL ); //Run that interrupt
75
+
76
+ //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
77
+ LPC_GPIOINT -> IO2IntClr = 1 << bitloc ;
78
+ fall2 -= 1 <<bitloc ;
67
79
}
68
-
69
- // Clear the interrupts we just handled
70
- LPC_GPIOINT -> IO0IntClr = mask0 ;
71
- LPC_GPIOINT -> IO2IntClr = mask2 ;
72
80
}
73
81
74
82
int gpio_irq_init (gpio_irq_t * obj , PinName pin , gpio_irq_handler handler , uint32_t id ) {
0 commit comments