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