Skip to content

Instantly share code, notes, and snippets.

@Mictronics
Last active March 21, 2018 20:29
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 Mictronics/7aff25e832a67d51a5ea9b767419829b to your computer and use it in GitHub Desktop.
Save Mictronics/7aff25e832a67d51a5ea9b767419829b to your computer and use it in GitHub Desktop.
Creates sinus and cosinus lookup tables for IQ signal generation for AD9361 (ADALM-Pluto) simulating TX channel settings.
/*
* Creates sinus and cosinus lookup tables for IQ signal generation
* for AD9361 (ADALM-Pluto) simulating TX channel settings.
*
* channel_convert_inverse Converts I or Q sample from host format into hardware format.
* channel_convert Converts I or Q sample from hardware format into host format.
*
* See https://github.com/analogdevicesinc/libiio/blob/master/channel.c
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <iio.h>
static void byte_swap(uint8_t *dst, const uint8_t *src, size_t len) {
size_t i;
for (i = 0; i < len; i++)
dst[i] = src[len - i - 1];
}
static void shift_bits(uint8_t *dst, size_t shift, size_t len, bool left) {
size_t i, shift_bytes = shift / 8;
shift %= 8;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
if (!left)
#else
if (left)
#endif
{
if (shift_bytes) {
memmove(dst, dst + shift_bytes, len - shift_bytes);
memset(dst + len - shift_bytes, 0, shift_bytes);
}
if (shift) {
for (i = 0; i < len; i++) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
dst[i] >>= shift;
if (i < len - 1)
dst[i] |= dst[i + 1] << (8 - shift);
#else
dst[i] <<= shift;
if (i < len - 1)
dst[i] |= dst[i + 1] >> (8 - shift);
#endif
}
}
} else {
if (shift_bytes) {
memmove(dst + shift_bytes, dst, len - shift_bytes);
memset(dst, 0, shift_bytes);
}
if (shift) {
for (i = len; i > 0; i--) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
dst[i - 1] <<= shift;
if (i > 1)
dst[i - 1] |= dst[i - 2] >> (8 - shift);
#else
dst[i - 1] >>= shift;
if (i > 1)
dst[i - 1] |= dst[i - 2] << (8 - shift);
#endif
}
}
}
}
static void sign_extend(uint8_t *dst, size_t bits, size_t len) {
size_t upper_bytes = ((len * 8 - bits) / 8);
uint8_t msb, msb_bit = 1 << ((bits - 1) % 8);
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
msb = dst[len - 1 - upper_bytes] & msb_bit;
if (upper_bytes)
memset(dst + len - upper_bytes, msb ? 0xff : 0x00, upper_bytes);
if (msb)
dst[len - 1 - upper_bytes] |= ~(msb_bit - 1);
else
dst[len - 1 - upper_bytes] &= (msb_bit - 1);
#else
/* XXX: untested */
msb = dst[upper_bytes] & msb_bit;
if (upper_bytes)
memset(dst, msb ? 0xff : 0x00, upper_bytes);
if (msb)
dst[upper_bytes] |= ~(msb_bit - 1);
#endif
}
static void mask_upper_bits(uint8_t *dst, size_t bits, size_t len) {
size_t i;
/* Clear upper bits */
if (bits % 8)
dst[bits / 8] &= (1 << (bits % 8)) - 1;
/* Clear upper bytes */
for (i = (bits + 7) / 8; i < len; i++)
dst[i] = 0;
}
void channel_convert_inverse(void *dst, const void *src) {
uintptr_t src_ptr = (uintptr_t) src, dst_ptr = (uintptr_t) dst;
unsigned int len = 16 / 8;
ptrdiff_t end = len * 1;
uintptr_t end_ptr = dst_ptr + end;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
bool swap = false;
#else
bool swap = !false;
#endif
uint8_t buf[1024];
/* Somehow I doubt we will have samples of 8192 bits each. */
if (len > sizeof (buf))
return;
for (dst_ptr = (uintptr_t) dst; dst_ptr < end_ptr;
src_ptr += len, dst_ptr += len) {
memcpy(buf, (const void *) src_ptr, len);
mask_upper_bits(buf, 16, len);
if (0)
shift_bits(buf, 0, len, true);
if (len == 1 || !swap)
memcpy((void *) dst_ptr, buf, len);
else
byte_swap((void *) dst_ptr, buf, len);
}
}
void channel_convert(void *dst, const void *src) {
uintptr_t src_ptr = (uintptr_t) src, dst_ptr = (uintptr_t) dst;
unsigned int len = 16 / 8;
ptrdiff_t end = len * 1;
uintptr_t end_ptr = src_ptr + end;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
bool swap = false;
#else
bool swap = !false;
#endif
for (src_ptr = (uintptr_t) src; src_ptr < end_ptr;
src_ptr += len, dst_ptr += len) {
if (len == 1 || !swap)
memcpy((void *) dst_ptr, (const void *) src_ptr, len);
else
byte_swap((void *) dst_ptr, (const void *) src_ptr,
len);
if (0)
shift_bits((void *) dst_ptr, 0, len, false);
if (!true) {
if (true)
sign_extend((void *) dst_ptr, 16, len);
else
mask_upper_bits((void *) dst_ptr, 16, len);
}
}
}
/*
*
*/
int main(int argc, char** argv) {
const int amp = 32767;
const double steps = 512.0;
const double d2r = M_PI /180;
const double rad = (360.0 / steps) * d2r;
short in, out;
printf("\nconst int sinTable512[] = {\n");
for(int i = 0; i < steps; i++) {
in = (short)(sin(i * rad) * amp);
channel_convert_inverse(&out, &in);
printf("%d, ", (int)out);
if(i%16 == 15){
printf("\n");
}
}
printf("};\n\nconst int cosTable512[] = {\n");
for(int i = 0; i < steps; i++) {
in = (short)(cos(i * rad) * amp);
channel_convert_inverse(&out, &in);
printf("%d, ", (int)out);
if(i%16 == 15){
printf("\n");
}
}
printf("};\n");
return (EXIT_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment