Created
July 15, 2023 15:43
-
-
Save pkage/870c9deab5973a9705cdb5add697c376 to your computer and use it in GitHub Desktop.
spi 20x6bit -> 20x8bit unstuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
// assumes little endian | |
void print_bits(size_t const size, void const * const ptr) | |
{ | |
unsigned char *b = (unsigned char*) ptr; | |
unsigned char byte; | |
int i, j; | |
for (i = size-1; i >= 0; i--) { | |
for (j = 7; j >= 0; j--) { | |
byte = (b[i] >> j) & 1; | |
printf("%u", byte); | |
} | |
} | |
puts(""); | |
} | |
int main(int argc, char** argv) { | |
// ## create the input buffer of 15 bytes | |
void* buf = malloc(15); | |
// ## fill the buffer | |
for (int i = 0; i < 15; i++) { | |
// a bit cursed but because i'm working with | |
// a void buffer i gotta do a bit of shenanigans | |
if (0 == i % 2) { | |
((char*)buf)[i] = 0b11111111; | |
} else { | |
((char*)buf)[i] = 0b00000000; | |
} | |
} | |
/*for (int i = 0; i < 15; i++) { | |
char c = ((char*)buf)[i]; | |
printf("%d: %d\n", i, c); | |
} */ | |
// ## unstuff 20 6 bit values | |
// each 24 bits has 4 six-bit values in 3 eight-bit values | |
// so we'll need to have 4 masks and the appropriate barrel shifts | |
// the way we'll do that is by using 4 uints as a mask, skipping three bytes forward after each cycle | |
unsigned int mask0 = 0b11111100000000000000000000000000; // shift R 8+6+6+6 = 26 | |
unsigned int mask1 = 0b00000011111100000000000000000000; // shift R 8+6+6 = 20 | |
unsigned int mask2 = 0b00000000000011111100000000000000; // shift R 8+6 = 14 | |
unsigned int mask3 = 0b00000000000000000011111100000000; // shift R 8 = 8 | |
// bit 0: using mask 0 | |
// | |
// v next window | |
// bytes : 0b11111100000011111100000011111100.... | |
// mask 0 : 0b11111100000000000000000000000000 | |
// bit 1: using mask 1 | |
// | |
// v next window | |
// bytes : 0b11111100000011111100000011111100.... | |
// mask 1 : 0b00000011111100000000000000000000 | |
// bit 2: using mask 2 | |
// | |
// v next window | |
// bytes : 0b11111100000011111100000011111100.... | |
// mask 2 : 0b00000000000011111100000000000000 | |
// bit 3: using mask 3 | |
// | |
// v next window | |
// bytes : 0b11111100000011111100000011111100.... | |
// mask 3 : 0b00000000000000000011111100000000 | |
// once we get back to the next phase, we can add 3 to the offset and start again | |
int output[20]; | |
unsigned int offset = 0; | |
for (int i = 0; i < 20; i++) { | |
int phase = i % 4; | |
unsigned int val, mask, shift; | |
// first, grab our byte window | |
unsigned int window = *((unsigned int*)(buf + offset)); | |
printf("\noffset: %u/phase %d, window:\n ", offset, phase); | |
print_bits(sizeof(unsigned int), &window); | |
// select mask and shift for each phase | |
if (phase == 0) { | |
mask = mask0; | |
shift = 26; | |
} else if (phase == 1) { | |
mask = mask1; | |
shift = 20; | |
} else if (phase == 2) { | |
mask = mask2; | |
shift = 14; | |
} else if (phase == 3) { | |
mask = mask3; | |
shift = 8; | |
// prep for next window | |
offset += 3; | |
} | |
val = window & mask; | |
printf("mask: "); | |
print_bits(sizeof(unsigned int), &mask); | |
printf("val: "); | |
print_bits(sizeof(unsigned int), &val); | |
val = val >> shift; | |
output[i] = val; | |
} | |
// ## print out the resulting array | |
for (int i = 0; i < 20; i++) { | |
char c = output[i]; | |
printf("%d: %d\n", i, c); | |
} | |
free(buf); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment