1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
diff --git a/firmware/target/arm/as3525/button-clip.c b/firmware/target/arm/as3525/button-clip.c
index 18bac8a..f6cbcf0 100644
--- a/firmware/target/arm/as3525/button-clip.c
+++ b/firmware/target/arm/as3525/button-clip.c
@@ -55,19 +55,47 @@ void button_init_device(void)
     IN_DIR &= ~((1<<2) | (1<<1) | (1<<0));
 
     for (int i = 0; i < 3; i++) {
-        OUT_PIN(rows[i]) = INITIAL << rows[i];
         OUT_DIR |= 1 << rows[i];
+        OUT_PIN(rows[i]) = INITIAL << rows[i];
     }
 
+    for (int volatile i = 500; i; i--) ;
+
     /* get initial readings */
     button_read_device();
     button_read_device();
     button_read_device();
 }
 
-int button_read_device(void)
+static int a(void)
 {
     static int row, buttons;
+    static const int matrix [3][3] = {
+        { 0 /*unused*/, BUTTON_VOL_UP,   BUTTON_UP },
+        { BUTTON_LEFT,  BUTTON_SELECT,   BUTTON_RIGHT },
+        { BUTTON_DOWN,  BUTTON_VOL_DOWN, BUTTON_HOME },
+    };
+
+    /* prepare next row */
+    OUT_PIN(rows[row]) = (!INITIAL) << rows[row];
+
+    for (int volatile i = 500; i; i--) ;
+
+    for (int i = 0; i<3; i++)
+        if (IN_PIN(i) ^ (INITIAL << i))
+            buttons |=  matrix[row][i];
+        else
+            buttons &= ~matrix[row][i];
+
+    row++;
+    row %= 3;
+
+    OUT_PIN(rows[row]) = INITIAL << rows[row];
+    return buttons;
+}
+
+int button_read_device(void)
+{
     static unsigned power_counter;
 
     if(button_hold())
@@ -83,30 +111,18 @@ int button_read_device(void)
     if (power_counter)
         power_counter--;
 
+    int b = 0;
     if (GPIOA_PIN(7) && !power_counter)
-        buttons |= BUTTON_POWER;
+        b |= BUTTON_POWER;
     else
-        buttons &= ~BUTTON_POWER;
-
-    static const int matrix [3][3] = {
-        { 0 /*unused*/, BUTTON_VOL_UP,   BUTTON_UP },
-        { BUTTON_LEFT,  BUTTON_SELECT,   BUTTON_RIGHT },
-        { BUTTON_DOWN,  BUTTON_VOL_DOWN, BUTTON_HOME },
-    };
-
-    for (int i = 0; i<3; i++)
-        if (IN_PIN(i) ^ (INITIAL << i))
-            buttons |=  matrix[row][i];
-        else
-            buttons &= ~matrix[row][i];
-
-    /* prepare next row */
-    OUT_PIN(rows[row]) = INITIAL << rows[row];
-    row++;
-    row %= 3;
-    OUT_PIN(rows[row]) = (!INITIAL) << rows[row];
-
-    return buttons;
+        b &= ~BUTTON_POWER;
+
+    OUT_DIR |= (1<<3)|(1<<4)|(1<<5);
+    a();
+    a();
+    b |= a();
+    OUT_DIR &= ~((1<<3)|(1<<4)|(1<<5));
+    return b;
 }
 
 bool button_hold(void)