FastLED  3.1
bitswap.h
Go to the documentation of this file.
1 #ifndef __INC_BITSWAP_H
2 #define __INC_BITSWAP_H
3 
4 #include "FastLED.h"
5 
6 FASTLED_NAMESPACE_BEGIN
7 
10 
14 #if defined(FASTLED_ARM) || defined(FASTLED_ESP8266)
15 typedef union {
17  uint8_t raw;
18  struct {
19  uint32_t a0:1;
20  uint32_t a1:1;
21  uint32_t a2:1;
22  uint32_t a3:1;
23  uint32_t a4:1;
24  uint32_t a5:1;
25  uint32_t a6:1;
26  uint32_t a7:1;
27  };
28 } just8bits;
29 
31 typedef struct {
32  uint32_t a0:1;
33  uint32_t a1:1;
34  uint32_t a2:1;
35  uint32_t a3:1;
36  uint32_t a4:1;
37  uint32_t a5:1;
38  uint32_t a6:1;
39  uint32_t a7:1;
40  uint32_t b0:1;
41  uint32_t b1:1;
42  uint32_t b2:1;
43  uint32_t b3:1;
44  uint32_t b4:1;
45  uint32_t b5:1;
46  uint32_t b6:1;
47  uint32_t b7:1;
48  uint32_t c0:1;
49  uint32_t c1:1;
50  uint32_t c2:1;
51  uint32_t c3:1;
52  uint32_t c4:1;
53  uint32_t c5:1;
54  uint32_t c6:1;
55  uint32_t c7:1;
56  uint32_t d0:1;
57  uint32_t d1:1;
58  uint32_t d2:1;
59  uint32_t d3:1;
60  uint32_t d4:1;
61  uint32_t d5:1;
62  uint32_t d6:1;
63  uint32_t d7:1;
64 } sub4;
65 
67 typedef union {
68  uint32_t word[2];
69  uint8_t bytes[8];
70  struct {
71  sub4 a;
72  sub4 b;
73  };
74 } bitswap_type;
75 
76 
77 #define SWAPSA(X,N) out. X ## 0 = in.a.a ## N; \
78  out. X ## 1 = in.a.b ## N; \
79  out. X ## 2 = in.a.c ## N; \
80  out. X ## 3 = in.a.d ## N;
81 
82 #define SWAPSB(X,N) out. X ## 0 = in.b.a ## N; \
83  out. X ## 1 = in.b.b ## N; \
84  out. X ## 2 = in.b.c ## N; \
85  out. X ## 3 = in.b.d ## N;
86 
87 #define SWAPS(X,N) out. X ## 0 = in.a.a ## N; \
88  out. X ## 1 = in.a.b ## N; \
89  out. X ## 2 = in.a.c ## N; \
90  out. X ## 3 = in.a.d ## N; \
91  out. X ## 4 = in.b.a ## N; \
92  out. X ## 5 = in.b.b ## N; \
93  out. X ## 6 = in.b.c ## N; \
94  out. X ## 7 = in.b.d ## N;
95 
96 
98 __attribute__((always_inline)) inline void swapbits8(bitswap_type in, bitswap_type & out) {
99 
100  // SWAPS(a.a,7);
101  // SWAPS(a.b,6);
102  // SWAPS(a.c,5);
103  // SWAPS(a.d,4);
104  // SWAPS(b.a,3);
105  // SWAPS(b.b,2);
106  // SWAPS(b.c,1);
107  // SWAPS(b.d,0);
108 
109  // SWAPSA(a.a,7);
110  // SWAPSA(a.b,6);
111  // SWAPSA(a.c,5);
112  // SWAPSA(a.d,4);
113  //
114  // SWAPSB(a.a,7);
115  // SWAPSB(a.b,6);
116  // SWAPSB(a.c,5);
117  // SWAPSB(a.d,4);
118  //
119  // SWAPSA(b.a,3);
120  // SWAPSA(b.b,2);
121  // SWAPSA(b.c,1);
122  // SWAPSA(b.d,0);
123  // //
124  // SWAPSB(b.a,3);
125  // SWAPSB(b.b,2);
126  // SWAPSB(b.c,1);
127  // SWAPSB(b.d,0);
128 
129  for(int i = 0; i < 8; i++) {
130  just8bits work;
131  work.a3 = in.word[0] >> 31;
132  work.a2 = in.word[0] >> 23;
133  work.a1 = in.word[0] >> 15;
134  work.a0 = in.word[0] >> 7;
135  in.word[0] <<= 1;
136  work.a7 = in.word[1] >> 31;
137  work.a6 = in.word[1] >> 23;
138  work.a5 = in.word[1] >> 15;
139  work.a4 = in.word[1] >> 7;
140  in.word[1] <<= 1;
141  out.bytes[i] = work.raw;
142  }
143 }
144 
146 __attribute__((always_inline)) inline void slowswap(unsigned char *A, unsigned char *B) {
147 
148  for(int row = 0; row < 7; row++) {
149  uint8_t x = A[row];
150 
151  uint8_t bit = (1<<row);
152  unsigned char *p = B;
153  for(uint32_t mask = 1<<7 ; mask ; mask >>= 1) {
154  if(x & mask) {
155  *p++ |= bit;
156  } else {
157  *p++ &= ~bit;
158  }
159  }
160  // B[7] |= (x & 0x01) << row; x >>= 1;
161  // B[6] |= (x & 0x01) << row; x >>= 1;
162  // B[5] |= (x & 0x01) << row; x >>= 1;
163  // B[4] |= (x & 0x01) << row; x >>= 1;
164  // B[3] |= (x & 0x01) << row; x >>= 1;
165  // B[2] |= (x & 0x01) << row; x >>= 1;
166  // B[1] |= (x & 0x01) << row; x >>= 1;
167  // B[0] |= (x & 0x01) << row; x >>= 1;
168  }
169 }
170 
173 __attribute__((always_inline)) inline void transpose8x1(unsigned char *A, unsigned char *B) {
174  uint32_t x, y, t;
175 
176  // Load the array and pack it into x and y.
177  y = *(unsigned int*)(A);
178  x = *(unsigned int*)(A+4);
179 
180  // pre-transform x
181  t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
182  t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
183 
184  // pre-transform y
185  t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
186  t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
187 
188  // final transform
189  t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
190  y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
191  x = t;
192 
193  *((uint32_t*)B) = y;
194  *((uint32_t*)(B+4)) = x;
195 }
196 
198 __attribute__((always_inline)) inline void transpose8x1_MSB(unsigned char *A, unsigned char *B) {
199  uint32_t x, y, t;
200 
201  // Load the array and pack it into x and y.
202  y = *(unsigned int*)(A);
203  x = *(unsigned int*)(A+4);
204 
205  // pre-transform x
206  t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
207  t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
208 
209  // pre-transform y
210  t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
211  t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
212 
213  // final transform
214  t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
215  y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
216  x = t;
217 
218  B[7] = y; y >>= 8;
219  B[6] = y; y >>= 8;
220  B[5] = y; y >>= 8;
221  B[4] = y;
222 
223  B[3] = x; x >>= 8;
224  B[2] = x; x >>= 8;
225  B[1] = x; x >>= 8;
226  B[0] = x; /* */
227 }
228 
230 template<int m, int n>
231 __attribute__((always_inline)) inline void transpose8(unsigned char *A, unsigned char *B) {
232  uint32_t x, y, t;
233 
234  // Load the array and pack it into x and y.
235  if(m == 1) {
236  y = *(unsigned int*)(A);
237  x = *(unsigned int*)(A+4);
238  } else {
239  x = (A[0]<<24) | (A[m]<<16) | (A[2*m]<<8) | A[3*m];
240  y = (A[4*m]<<24) | (A[5*m]<<16) | (A[6*m]<<8) | A[7*m];
241  }
242 
243  // pre-transform x
244  t = (x ^ (x >> 7)) & 0x00AA00AA; x = x ^ t ^ (t << 7);
245  t = (x ^ (x >>14)) & 0x0000CCCC; x = x ^ t ^ (t <<14);
246 
247  // pre-transform y
248  t = (y ^ (y >> 7)) & 0x00AA00AA; y = y ^ t ^ (t << 7);
249  t = (y ^ (y >>14)) & 0x0000CCCC; y = y ^ t ^ (t <<14);
250 
251  // final transform
252  t = (x & 0xF0F0F0F0) | ((y >> 4) & 0x0F0F0F0F);
253  y = ((x << 4) & 0xF0F0F0F0) | (y & 0x0F0F0F0F);
254  x = t;
255 
256  B[7*n] = y; y >>= 8;
257  B[6*n] = y; y >>= 8;
258  B[5*n] = y; y >>= 8;
259  B[4*n] = y;
260 
261  B[3*n] = x; x >>= 8;
262  B[2*n] = x; x >>= 8;
263  B[n] = x; x >>= 8;
264  B[0] = x;
265  // B[0]=x>>24; B[n]=x>>16; B[2*n]=x>>8; B[3*n]=x>>0;
266  // B[4*n]=y>>24; B[5*n]=y>>16; B[6*n]=y>>8; B[7*n]=y>>0;
267 }
268 
269 #endif
270 
271 FASTLED_NAMESPACE_END
272 
274 #endif
structure representing 8 bits of access
Definition: bitswap.h:16
central include file for FastLED, defines the CFastLED class/object
structure representing 32 bits of access
Definition: bitswap.h:31
__attribute__((always_inline)) inline void swapbits8(bitswap_type in
Do an 8byte by 8bit rotation.
Definition: fastled_delay.h:92
union containing a full 8 bytes to swap the bit orientation on
Definition: bitswap.h:67