summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iaudio/lcd-remote-iaudio.c')
-rw-r--r--firmware/target/coldfire/iaudio/lcd-remote-iaudio.c125
1 files changed, 74 insertions, 51 deletions
diff --git a/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c b/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c
index 5a03dc6180..6565d3088d 100644
--- a/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c
+++ b/firmware/target/coldfire/iaudio/lcd-remote-iaudio.c
@@ -64,83 +64,106 @@ bool remote_initialized = false;
64static inline void _write_byte(unsigned data) 64static inline void _write_byte(unsigned data)
65{ 65{
66 asm volatile ( 66 asm volatile (
67 "move.l (%[gpo0]), %%d0 \n" /* Get current state of data line */ 67 "move.w %%sr,%%d2 \n" /* Get current interrupt level */
68 "and.l %[dbit], %%d0 \n" 68 "move.w #0x2700,%%sr \n" /* Disable interrupts */
69
70 "move.l (%[gpo0]), %%d0 \n" /* Get current state of data port */
71 "move.l %%d0, %%d1 \n"
72 "and.l %[dbit], %%d1 \n" /* Check current state of data line */
69 "beq.s 1f \n" /* and set it as previous-state bit */ 73 "beq.s 1f \n" /* and set it as previous-state bit */
70 "bset #8, %[data] \n" 74 "bset #8, %[data] \n"
71 "1: \n" 75 "1: \n"
72 "move.l %[data], %%d0 \n" /* Compute the 'bit derivative', i.e. a value */ 76 "move.l %[data], %%d1 \n" /* Compute the 'bit derivative', i.e. a value */
73 "lsr.l #1, %%d0 \n" /* with 1's where the data changes from the */ 77 "lsr.l #1, %%d1 \n" /* with 1's where the data changes from the */
74 "eor.l %%d0, %[data] \n" /* previous state, and 0's where it doesn't */ 78 "eor.l %%d1, %[data] \n" /* previous state, and 0's where it doesn't */
75 "swap %[data] \n" /* Shift data to upper byte */ 79 "swap %[data] \n" /* Shift data to upper byte */
76 "lsl.l #8, %[data] \n" 80 "lsl.l #8, %[data] \n"
77 81
78 "move.l %[cbit], %%d1 \n" /* Prepare mask for flipping CLK */ 82 "eor.l %[cbit], %%d0 \n" /* precalculate opposite state of clock line */
79 "or.l %[dbit], %%d1 \n" /* and DATA at once */ 83
80
81 "lsl.l #1,%[data] \n" /* Shift out MSB */ 84 "lsl.l #1,%[data] \n" /* Shift out MSB */
82 "bcc.s 1f \n" 85 "bcc.s 1f \n"
83 "eor.l %%d1, (%[gpo0]) \n" /* 1: Flip both CLK and DATA */ 86 "eor.l %[dbit], %%d0 \n" /* 1: Flip data bit */
84 ".word 0x51fa \n" /* (trapf.w - shadow next insn) */
85 "1: \n" 87 "1: \n"
86 "eor.l %[cbit], (%[gpo0]) \n" /* else flip CLK only */ 88 "move.l %%d0, %%d1 \n"
87 "eor.l %[cbit], (%[gpo0]) \n" /* Flip CLK again */ 89 "move.l %%d0, (%[gpo0]) \n" /* Output new state and set CLK = 0*/
90 "eor.l %[cbit], %%d1 \n"
91 "nop \n"
88 92
89 "lsl.l #1,%[data] \n" /* ..unrolled.. */ 93 "lsl.l #1,%[data] \n" /* ..unrolled.. */
90 "bcc.s 1f \n" 94 "bcc.s 1f \n"
91 "eor.l %%d1, (%[gpo0]) \n" 95 "eor.l %[dbit], %%d0 \n"
92 ".word 0x51fa \n"
93 "1: \n" 96 "1: \n"
94 "eor.l %[cbit], (%[gpo0]) \n" 97 "move.l %%d1, (%[gpo0]) \n" /* set CLK = 1 (delayed) */
95 "eor.l %[cbit], (%[gpo0]) \n" 98 "move.l %%d0, %%d1 \n"
99 "move.l %%d0, (%[gpo0]) \n"
100 "eor.l %[cbit], %%d1 \n"
101 "nop \n"
96 102
97 "lsl.l #1,%[data] \n" 103 "lsl.l #1,%[data] \n" /* ..unrolled.. */
98 "bcc.s 1f \n" 104 "bcc.s 1f \n"
99 "eor.l %%d1, (%[gpo0]) \n" 105 "eor.l %[dbit], %%d0 \n"
100 ".word 0x51fa \n"
101 "1: \n" 106 "1: \n"
102 "eor.l %[cbit], (%[gpo0]) \n" 107 "move.l %%d1, (%[gpo0]) \n"
103 "eor.l %[cbit], (%[gpo0]) \n" 108 "move.l %%d0, %%d1 \n"
109 "move.l %%d0, (%[gpo0]) \n"
110 "eor.l %[cbit], %%d1 \n"
111 "nop \n"
104 112
105 "lsl.l #1,%[data] \n" 113 "lsl.l #1,%[data] \n" /* ..unrolled.. */
106 "bcc.s 1f \n" 114 "bcc.s 1f \n"
107 "eor.l %%d1, (%[gpo0]) \n" 115 "eor.l %[dbit], %%d0 \n"
108 ".word 0x51fa \n"
109 "1: \n" 116 "1: \n"
110 "eor.l %[cbit], (%[gpo0]) \n" 117 "move.l %%d1, (%[gpo0]) \n"
111 "eor.l %[cbit], (%[gpo0]) \n" 118 "move.l %%d0, %%d1 \n"
119 "move.l %%d0, (%[gpo0]) \n"
120 "eor.l %[cbit], %%d1 \n"
121 "nop \n"
112 122
113 "lsl.l #1,%[data] \n" 123 "lsl.l #1,%[data] \n" /* ..unrolled.. */
114 "bcc.s 1f \n" 124 "bcc.s 1f \n"
115 "eor.l %%d1, (%[gpo0]) \n" 125 "eor.l %[dbit], %%d0 \n"
116 ".word 0x51fa \n"
117 "1: \n" 126 "1: \n"
118 "eor.l %[cbit], (%[gpo0]) \n" 127 "move.l %%d1, (%[gpo0]) \n"
119 "eor.l %[cbit], (%[gpo0]) \n" 128 "move.l %%d0, %%d1 \n"
129 "move.l %%d0, (%[gpo0]) \n"
130 "eor.l %[cbit], %%d1 \n"
131 "nop \n"
120 132
121 "lsl.l #1,%[data] \n" 133 "lsl.l #1,%[data] \n" /* ..unrolled.. */
122 "bcc.s 1f \n" 134 "bcc.s 1f \n"
123 "eor.l %%d1, (%[gpo0]) \n" 135 "eor.l %[dbit], %%d0 \n"
124 ".word 0x51fa \n"
125 "1: \n" 136 "1: \n"
126 "eor.l %[cbit], (%[gpo0]) \n" 137 "move.l %%d1, (%[gpo0]) \n"
127 "eor.l %[cbit], (%[gpo0]) \n" 138 "move.l %%d0, %%d1 \n"
139 "move.l %%d0, (%[gpo0]) \n"
140 "eor.l %[cbit], %%d1 \n"
141 "nop \n"
128 142
129 "lsl.l #1,%[data] \n" 143 "lsl.l #1,%[data] \n" /* ..unrolled.. */
130 "bcc.s 1f \n" 144 "bcc.s 1f \n"
131 "eor.l %%d1, (%[gpo0]) \n" 145 "eor.l %[dbit], %%d0 \n"
132 ".word 0x51fa \n"
133 "1: \n" 146 "1: \n"
134 "eor.l %[cbit], (%[gpo0]) \n" 147 "move.l %%d1, (%[gpo0]) \n"
135 "eor.l %[cbit], (%[gpo0]) \n" 148 "move.l %%d0, %%d1 \n"
149 "move.l %%d0, (%[gpo0]) \n"
150 "eor.l %[cbit], %%d1 \n"
151 "nop \n"
136 152
137 "lsl.l #1,%[data] \n" 153 "lsl.l #1,%[data] \n" /* ..unrolled.. */
138 "bcc.s 1f \n" 154 "bcc.s 1f \n"
139 "eor.l %%d1, (%[gpo0]) \n" 155 "eor.l %[dbit], %%d0 \n"
140 ".word 0x51fa \n"
141 "1: \n" 156 "1: \n"
142 "eor.l %[cbit], (%[gpo0]) \n" 157 "move.l %%d1, (%[gpo0]) \n"
143 "eor.l %[cbit], (%[gpo0]) \n" 158 "move.l %%d0, %%d1 \n"
159 "move.l %%d0, (%[gpo0]) \n"
160 "eor.l %[cbit], %%d1 \n"
161 "nop \n"
162
163 "nop \n"
164 "move.l %%d1, (%[gpo0]) \n" /* set CLK = 1 (delayed) */
165
166 "move.w %%d2, %%sr \n" /* Restore interrupt level */
144 : /* outputs */ 167 : /* outputs */
145 [data]"+d"(data) 168 [data]"+d"(data)
146 : /* inputs */ 169 : /* inputs */
@@ -148,7 +171,7 @@ static inline void _write_byte(unsigned data)
148 [cbit]"d"(0x00004000), 171 [cbit]"d"(0x00004000),
149 [dbit]"d"(0x00002000) 172 [dbit]"d"(0x00002000)
150 : /* clobbers */ 173 : /* clobbers */
151 "d0", "d1" 174 "d0", "d1", "d2"
152 ); 175 );
153} 176}
154 177
@@ -157,7 +180,7 @@ static inline void _write_byte(unsigned data)
157static inline void _write_fast(unsigned data) 180static inline void _write_fast(unsigned data)
158{ 181{
159 asm volatile ( 182 asm volatile (
160 "move.w %%sr,%%d3 \n" /* Get current interrupt level */ 183 "move.w %%sr,%%d2 \n" /* Get current interrupt level */
161 "move.w #0x2700,%%sr \n" /* Disable interrupts */ 184 "move.w #0x2700,%%sr \n" /* Disable interrupts */
162 185
163 "move.l (%[gpo0]), %%d0 \n" /* Get current state of data port */ 186 "move.l (%[gpo0]), %%d0 \n" /* Get current state of data port */
@@ -239,7 +262,7 @@ static inline void _write_fast(unsigned data)
239 "move.l %%d1, (%[gpo0]) \n" 262 "move.l %%d1, (%[gpo0]) \n"
240 "move.l %%d0, (%[gpo0]) \n" 263 "move.l %%d0, (%[gpo0]) \n"
241 264
242 "move.w %%d3, %%sr \n" /* Restore interrupt level */ 265 "move.w %%d2, %%sr \n" /* Restore interrupt level */
243 : /* outputs */ 266 : /* outputs */
244 [data]"+d"(data) 267 [data]"+d"(data)
245 : /* inputs */ 268 : /* inputs */
@@ -247,7 +270,7 @@ static inline void _write_fast(unsigned data)
247 [cbit]"d"(0x00004000), 270 [cbit]"d"(0x00004000),
248 [dbit]"d"(0x00002000) 271 [dbit]"d"(0x00002000)
249 : /* clobbers */ 272 : /* clobbers */
250 "d0", "d1", "d2", "d3" 273 "d0", "d1", "d2"
251 ); 274 );
252} 275}
253 276