Files
@ 0e169f68c994
Branch filter:
Location: seniordesign-firmware/master/master/lib/afsk.c - annotation
0e169f68c994
6.6 KiB
text/plain
Added support for UART1, added numerous fixes. Introduction of GPS has caused several difficulties. Lowering baud rate to 4800 has made problems worse, probably change back to 115200 baud and disable serial1 interrupts when AFSK transmitting / logging.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc c79b24c96a83 c79b24c96a83 9716361162e0 9716361162e0 b6a1b8d502cc c79b24c96a83 c79b24c96a83 c273f4602167 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c273f4602167 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 02b6a488f4ee c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 f6804d996c04 c273f4602167 c273f4602167 c273f4602167 c79b24c96a83 c79b24c96a83 0e169f68c994 0e169f68c994 c273f4602167 0e169f68c994 0e169f68c994 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 b6a1b8d502cc b6a1b8d502cc 02b6a488f4ee 83e403019e80 c273f4602167 c273f4602167 b6a1b8d502cc b6a1b8d502cc 02b6a488f4ee 83e403019e80 83e403019e80 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 b6a1b8d502cc b6a1b8d502cc c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc b6a1b8d502cc c273f4602167 c273f4602167 b6a1b8d502cc b6a1b8d502cc c273f4602167 c273f4602167 b6a1b8d502cc b6a1b8d502cc c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 b6a1b8d502cc b6a1b8d502cc f6804d996c04 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 c273f4602167 b6a1b8d502cc b6a1b8d502cc 83e403019e80 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 c273f4602167 c273f4602167 83e403019e80 c79b24c96a83 c79b24c96a83 c79b24c96a83 c79b24c96a83 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee b6a1b8d502cc b6a1b8d502cc 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 83e403019e80 83e403019e80 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 83e403019e80 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 02b6a488f4ee 0e169f68c994 dc66341db814 02b6a488f4ee dc66341db814 | /*
* Master Firmware: AFSK Generation
*
* Wireless Observational Modular Aerial Network
*
* Ethan Zonca
* Matthew Kanning
* Kyle Ripperger
* Matthew Kroening
*
*/
#include "../config.h"
#include "afsk.h"
#include <stdint.h>
#include <stdbool.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
PROGMEM extern const uint8_t afsk_sine_table[512] = {
127, 129, 130, 132, 133, 135, 136, 138, 139, 141, 143, 144, 146, 147, 149, 150, 152, 153, 155, 156, 158,
159, 161, 163, 164, 166, 167, 168, 170, 171, 173, 174, 176, 177, 179, 180, 182, 183, 184, 186, 187, 188,
190, 191, 193, 194, 195, 197, 198, 199, 200, 202, 203, 204, 205, 207, 208, 209, 210, 211, 213, 214, 215,
216, 217, 218, 219, 220, 221, 223, 224, 225, 226, 227, 228, 228, 229, 230, 231, 232, 233, 234, 235, 236,
236, 237, 238, 239, 239, 240, 241, 242, 242, 243, 244, 244, 245, 245, 246, 247, 247, 248, 248, 249, 249,
249, 250, 250, 251, 251, 251, 252, 252, 252, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254,
254, 254, 255, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, 253, 253, 252, 252, 252, 251,
251, 251, 250, 250, 249, 249, 249, 248, 248, 247, 247, 246, 245, 245, 244, 244, 243, 242, 242, 241, 240,
239, 239, 238, 237, 236, 236, 235, 234, 233, 232, 231, 230, 229, 228, 228, 227, 226, 225, 224, 223, 221,
220, 219, 218, 217, 216, 215, 214, 213, 211, 210, 209, 208, 207, 205, 204, 203, 202, 200, 199, 198, 197,
195, 194, 193, 191, 190, 188, 187, 186, 184, 183, 182, 180, 179, 177, 176, 174, 173, 171, 170, 168, 167,
166, 164, 163, 161, 159, 158, 156, 155, 153, 152, 150, 149, 147, 146, 144, 143, 141, 139, 138, 136, 135,
133, 132, 130, 129, 127, 125, 124, 122, 121, 119, 118, 116, 115, 113, 111, 110, 108, 107, 105, 104, 102,
101, 99, 98, 96, 95, 93, 91, 90, 88, 87, 86, 84, 83, 81, 80, 78, 77, 75, 74, 72, 71,
70, 68, 67, 66, 64, 63, 61, 60, 59, 57, 56, 55, 54, 52, 51, 50, 49, 47, 46, 45, 44,
43, 41, 40, 39, 38, 37, 36, 35, 34, 33, 31, 30, 29, 28, 27, 26, 26, 25, 24, 23, 22,
21, 20, 19, 18, 18, 17, 16, 15, 15, 14, 13, 12, 12, 11, 10, 10, 9, 9, 8, 7, 7,
6, 6, 5, 5, 5, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11,
12, 12, 13, 14, 15, 15, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28,
29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 43, 44, 45, 46, 47, 49, 50, 51, 52,
54, 55, 56, 57, 59, 60, 61, 63, 64, 66, 67, 68, 70, 71, 72, 74, 75, 77, 78, 80, 81,
83, 84, 86, 87, 88, 90, 91, 93, 95, 96, 98, 99, 101, 102, 104, 105, 107, 108, 110, 111, 113,
115, 116, 118, 119, 121, 122, 124, 125
};
static inline uint8_t afsk_read_sample(int phase)
{
return pgm_read_byte_near(afsk_sine_table + phase);
}
volatile uint16_t phase = 10;
volatile uint16_t phasedelta = 3300;
extern const uint16_t TABLE_SIZE = sizeof(afsk_sine_table);
// constants
#define MODEM_CLOCK_RATE F_CPU
#define PLAYBACK_RATE MODEM_CLOCK_RATE / 256 // Fast PWM
#define BAUD_RATE 1200
//#define SAMPLES_PER_BAUD PLAYBACK_RATE / BAUD_RATE // = 36
//#define SAMPLES_PER_BAUD 36
#define SAMPLES_PER_BAUD 36
// phase offset of 1800 gives ~1900 Hz
// phase offset of 3300 gives ~2200 Hz
//#define PHASE_DELTA_1200 1800
//#define PHASE_DELTA_2200 2200
#define PHASE_DELTA_1200 1800
#define PHASE_DELTA_2200 3300
// Module globals
volatile unsigned char current_byte;
volatile unsigned char current_sample_in_baud; // 1 bit = SAMPLES_PER_BAUD samples
volatile bool go = false;
volatile unsigned int packet_pos; // Next bit to be sent out
volatile unsigned int afsk_packet_size = 10;
volatile const uint8_t *afsk_packet;
void afsk_ptt_off()
{
// turn ptt off
PORTA &= ~(1<<PA5);
}
void afsk_ptt_on()
{
// turn the ptt on... possibly delay based on spec
PORTA |= (1<<PA5);
_delay_ms(5); // from datasheet
}
ISR(TIMER2_OVF_vect)
{
if (go) {
// If done sending packet
if (packet_pos == afsk_packet_size)
{
go = false; // End of transmission
afsk_timer_stop(); // Disable modem
afsk_ptt_off(); // Release PTT
return; // done
}
// If sent SAMPLES_PER_BAUD already, go to the next bit
if (current_sample_in_baud == 0) // Load up next bit
{
if ((packet_pos & 7) == 0) // Load up next byte
{
current_byte = afsk_packet[packet_pos >> 3];
}
else
{
current_byte = current_byte / 2; // ">>1" forces int conversion
}
if ((current_byte & 1) == 0)
{
// Toggle tone (1200 <> 2200)
phasedelta ^= (PHASE_DELTA_1200 ^ PHASE_DELTA_2200);
}
}
phase += phasedelta;
uint8_t s = afsk_read_sample((phase >> 7) & (TABLE_SIZE - 1));
afsk_output_sample(s);
if(++current_sample_in_baud == SAMPLES_PER_BAUD)
{
current_sample_in_baud = 0;
packet_pos++;
}
}
}
void afsk_output_sample(uint8_t s)
{
OCR2A = s;
}
void afsk_timer_start()
{
// Clear the overflow flag, so that the interrupt doesn't go off
// immediately and overrun the next one (p.163).
TIFR2 |= _BV(TOV2); // Yeah, writing a 1 clears the flag.
// Enable interrupt when TCNT2 reaches TOP (0xFF) (p.151, 163)
TIMSK2 |= _BV(TOIE2);
}
void afsk_timer_stop()
{
// Resting duty cycle
// Output 0v (could be 255/2, which is 0v after coupling... doesn't really matter)
OCR2A = 0x80;
// Disable playback interrupt
TIMSK2 &= ~_BV(TOIE2);
}
// External
void afsk_start()
{
phasedelta = PHASE_DELTA_1200;
phase = 0;
packet_pos = 0;
current_sample_in_baud = 0;
go = true;
// Key the radio
afsk_ptt_on();
// Start transmission
afsk_timer_start();
}
int afsk_busy()
{
return go;
}
void afsk_send(const uint8_t *buffer, int len)
{
afsk_packet_size = len;
afsk_packet = buffer;
}
void afsk_setup()
{
// Source timer2 from clkIO (datasheet p.164)
ASSR &= ~(_BV(EXCLK) | _BV(AS2));
// Set fast PWM mode with TOP = 0xff: WGM22:0 = 3 (p.150)
TCCR2A |= _BV(WGM21) | _BV(WGM20);
TCCR2B &= ~_BV(WGM22);
// Do non-inverting PWM on pin OC2A
TCCR2A = (TCCR2A | _BV(COM2A1)) & ~(_BV(COM2A0) | _BV(COM2B1) | _BV(COM2B0));
// No prescaler (p.162)
TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20);
// Enable interrupt when TCNT2 reaches TOP (0xFF) (p.151, 163)
//TIMSK2 |= _BV(TOIE2);
TIMSK2 |= 0b00000001;
// FIXME TODO
DDRD = 0xff;
PORTD = 0xff;
// todo: init radio, maybe in main
while(afsk_busy());
}
|