Skip to content

Instantly share code, notes, and snippets.

@pkage
Created July 15, 2023 15:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pkage/870c9deab5973a9705cdb5add697c376 to your computer and use it in GitHub Desktop.
Save pkage/870c9deab5973a9705cdb5add697c376 to your computer and use it in GitHub Desktop.
spi 20x6bit -> 20x8bit unstuff
#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