Source

psk31 / psk.c

/** \file
 * Implement a PSK31 encoder.
 *
 * 8-bit output of 
 */
#include "WProgram.h"
#include "sin-table.h"
#include "varicode.h"

static const char msg[] = "ny3u KD4ISF QSO cq 0123456789\n";

static uint8_t phase;



static void output_bit(unsigned bit)
{
	// Phase shift on zero-bits
	if (!bit)
		phase = (phase + 64) & 127;

	// 833 Hz / 31.25 Hz == 27 cycles per bit
	const uint16_t bit_width = 27 * 128;

	for (uint16_t i = 0 ; i < bit_width ; i++)
	{
#if 1
		const uint8_t s = sin_table[phase++ & 127];
#else
		const uint8_t s = bit ? 0x3F : 0x00;
#endif

		uint8_t spin = 32;
		while(spin--)
			PORTB = s;
	}
}


static void output_word(uint16_t word)
{
	while (word)
	{
		unsigned bit = word & 0x80;
		word <<= 1;

		output_bit(bit);
	}

	// We've sent one zero bit already; send the last zero bit too
	output_bit(0);
}

		
static void psk_main(void)
{
	// Port B has 6 bits of output on pins 8-13
	DDRB = 0x3F;

	// Clock is 16 MHz
	// 512 Hz sine wave is 32768 instructions per cycle
	// 6 bits of output == 64 steps from 0 to 1
	// 128 steps in the sin table above
	// 32768 / 128 == 256 instructions per step

	uint8_t i = 0;
	while (1)
	{
		unsigned char c = msg[i++];
		if (c == '\0')
		{
			i = 0;
			continue;
		}

		uint16_t word = varicode[c];
		output_word(word);
	}
}