APRSuino/create_sinus_tables.py

111 lines
3.6 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
import math
import os
BAUD = 1200
BAUD_MARK = 1200
BAUD_SPACE = 2200
N_SHIFTS = BAUD // math.gcd(BAUD, BAUD_MARK, BAUD_SPACE)
sinus1200 = []
sinus2200 = []
for t in range(int(1000000/BAUD_MARK)):
sinus1200.append(int((math.sin((t * BAUD_MARK / 1000000) * 2*math.pi) + 1) * 128))
for t in range(int(1000000/BAUD_SPACE)):
sinus2200.append(int((math.sin((t * BAUD_SPACE / 1000000) * 2*math.pi) + 1) * 128))
phaseShift1200 = [int((N_SHIFTS-i) * 1000000 / (6*BAUD_MARK)) % len(sinus1200) for i in range(N_SHIFTS)]
phaseShift2200 = [int((N_SHIFTS-i) * 1000000 / (6*BAUD_SPACE)) % len(sinus2200) for i in range(N_SHIFTS)]
with open(os.path.join(os.path.dirname(__file__), 'include/afsk_sinus.hpp'), 'w') as f:
f.write(f'''
#include <avr/pgmspace.h>
#define BAUD {BAUD}
#define BAUD_MARK {BAUD_MARK}
#define BAUD_SPACE {BAUD_SPACE}
#define INV_BAUD {int(1000000/BAUD)}
#define N_SHIFTS {N_SHIFTS}
#define N_SINUS_1200 {len(sinus1200)}
#define N_SINUS_2200 {len(sinus2200)}
2023-04-27 01:00:05 +02:00
#define SKEW_ROUNDS {round(abs(1/(int(1000000/BAUD)-1000000/BAUD)))}
const PROGMEM uint8_t SINUS1200[] = {{ {', '.join([str(i) for i in sinus1200])} }};
const PROGMEM uint8_t SINUS2200[] = {{ {', '.join([str(i) for i in sinus2200])} }};
const size_t PS1200[] = {{ {', '.join([str(i) for i in phaseShift1200])} }};
const size_t PS2200[] = {{ {', '.join([str(i) for i in phaseShift2200])} }};
2023-04-27 01:00:05 +02:00
uint8_t timeskew = 0;
void sendOne(uint32_t *us, uint8_t *phaseShift) {{
uint32_t t;
2023-04-27 01:00:05 +02:00
while ((t = micros() - *us) < INV_BAUD + (timeskew == 0)) {{
OUT_PORT = (pgm_read_byte(&SINUS1200[ (PS1200[*phaseShift] + t) % N_SINUS_1200 ]) >> 4) | (OUT_PORT & 0xf0);
}}
2023-04-27 01:00:05 +02:00
*us += INV_BAUD + (timeskew == 0);
timeskew = (timeskew + 1) % SKEW_ROUNDS;
}}
void sendZero(uint32_t *us, uint8_t *phaseShift) {{
uint32_t t;
2023-04-27 01:00:05 +02:00
while ((t = micros() - *us) < INV_BAUD + (timeskew == 0)) {{
OUT_PORT = (pgm_read_byte(&SINUS2200[ (PS2200[*phaseShift] + t) % N_SINUS_2200 ]) >> 4) | (OUT_PORT & 0xf0);
}}
*phaseShift = (*phaseShift + 1) % N_SHIFTS;
2023-04-27 01:00:05 +02:00
*us += INV_BAUD + (timeskew == 0);
timeskew = (timeskew + 1) % SKEW_ROUNDS;
}}
void setZero() {{
// Setting all to LOW rather than what 0b1000000 (which would be a signal amplitude of 0) saves about 2mA @ R = 550 ohms
//OUT_PORT = (pgm_read_byte(&SINUS2200[0]) >> 4) | (OUT_PORT & 0xf0);
OUT_PORT &= 0xf0;
}}
''')
2023-04-27 01:00:05 +02:00
# from matplotlib import pyplot as plt
#
# phase_shift = 0
# time_skew = 0
#
# signal = []
# skew_corrected_signal = []
#
#
# def one():
# global phase_shift, time_skew
# for i in range(int(1000000/BAUD)):
# signal.append(sinus1200[int((phaseShift1200[phase_shift]+i) % len(sinus1200))])
# for i in range(int(1000000/BAUD)+(time_skew == 0)):
# skew_corrected_signal.append(sinus1200[int((phaseShift1200[phase_shift]+i) % len(sinus1200))])
# time_skew = (time_skew + 1) % 3
#
# def zero():
# global phase_shift, time_skew
# for i in range(int(1000000/BAUD)):
# signal.append(sinus2200[int((phaseShift2200[phase_shift]+i) % len(sinus2200))])
# for i in range(int(1000000/BAUD)+(time_skew == 0)):
# skew_corrected_signal.append(sinus2200[int((phaseShift2200[phase_shift]+i) % len(sinus2200))])
# phase_shift = (phase_shift + 1) % len(phaseShift2200)
# time_skew = (time_skew + 1) % 3
#
#
# for i in range(200):
# if i % 3 == 0:
# one()
# else:
# zero()
#
#
# plt.plot(signal, color='blue')
# plt.plot(skew_corrected_signal, color='purple')
# plt.vlines([i*int(1000000/BAUD) for i in range(21)], ymin=0, ymax=255, color='red')
# plt.show()