Compare commits
2 Commits
master
...
wspr-beaco
Author | SHA1 | Date |
---|---|---|
Sebastian | e9fe44fad0 | |
Sebastian | 4dd13016e4 |
|
@ -4,8 +4,8 @@ ISPPORT ?= /dev/kaboard
|
|||
|
||||
VERSION = 0.1
|
||||
|
||||
HEADERS = include/twi.h include/si5351.h include/wspr.h
|
||||
SRC = main.c twi.c si5351.c wspr.c
|
||||
HEADERS = include/twi.h include/timer.h include/uart.h include/si5351.h include/wspr.h
|
||||
SRC = main.c twi.c timer.c uart.c si5351.c wspr.c
|
||||
TARGET = cube-kl
|
||||
OBJDIR = bin
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef TIMER_H_
|
||||
#define TIMER_H_ TIMER_H_
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
extern volatile uint32_t timestamp;
|
||||
extern volatile uint16_t milliseconds;
|
||||
|
||||
/*
|
||||
* Timer setting:
|
||||
* MCU running at 16MHz:
|
||||
* Prescaler is 64 which results in 250000 ticks per second
|
||||
* Preloading the counter with 6 leads to 1000 overflow interrupts per second
|
||||
* or one overflow every millisecond.
|
||||
*/
|
||||
|
||||
static inline void timer_init(void) {
|
||||
TCNT0 = 6; //Preload for 250 ticks to overflow
|
||||
TIMSK |= (1 << TOIE0);
|
||||
TCCR0 = (1 << CS00) | (1 << CS01); // Prescaler 64
|
||||
timestamp = 0;
|
||||
milliseconds = 0;
|
||||
}
|
||||
|
||||
static inline void timer_set(uint32_t stamp) {
|
||||
TCCR0 &= ~((1 << CS00) | (1 << CS01)); // stop the timer
|
||||
|
||||
TCNT0 = 6; //Preload for 250 ticks to overflow
|
||||
timestamp = stamp;
|
||||
milliseconds = 0;
|
||||
|
||||
TCCR0 = (1 << CS00) | (1 << CS01); // Restart timer
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef UART_H_
|
||||
#define UART_H_ UART_H_
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <stdlib.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//#define BAUD 76800UL // baudrate
|
||||
#define BAUD 38400UL
|
||||
#define UART_TIMEOUT 100 // Timeout in ms
|
||||
|
||||
// Some calculations ...
|
||||
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // Rounding magic
|
||||
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Real baudrate
|
||||
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
|
||||
|
||||
#if ((BAUD_ERROR<950) || (BAUD_ERROR>1050)) // Make sure your UBRR_VAL will work
|
||||
#error Baudrate error is bigger then 1% !
|
||||
#endif
|
||||
|
||||
extern uint8_t uart_timed_out;
|
||||
|
||||
void uart_init(void);
|
||||
uint8_t uart_getc_timeout(void);
|
||||
uint8_t uart_get_line(char buffer[], uint8_t maxlen);
|
||||
|
||||
|
||||
static inline void uart_putc(uint8_t data) {
|
||||
UDR = data; // write byte to data register
|
||||
while (!(UCSRA & (1<< UDRE))); // waiting for the uart to finish transmission
|
||||
UCSRA |= (1 << UDRE);
|
||||
}
|
||||
|
||||
static inline void uart_puts(char *data) {
|
||||
uint8_t i;
|
||||
for(i = 0; i < strlen(data); i++) {
|
||||
uart_putc(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t uart_getc(void) {
|
||||
while (!(UCSRA & (1<<RXC)));
|
||||
return UDR;
|
||||
}
|
||||
|
||||
static inline uint8_t uart_has_timed_out(void) {
|
||||
return uart_timed_out;
|
||||
}
|
||||
|
||||
static inline void uart_clear_time_out(void) {
|
||||
uart_timed_out = 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1,28 +1,51 @@
|
|||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
|
||||
#include "timer.h"
|
||||
#include "uart.h"
|
||||
#include "twi.h"
|
||||
#include "si5351.h"
|
||||
#include "wspr.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
uart_init();
|
||||
twi_init();
|
||||
|
||||
timer_init();
|
||||
|
||||
sei();
|
||||
|
||||
si5351_init(25000000, 800000000, 500000000);
|
||||
si5351_ms_set_source(SI5351_MS0, SI5351_PLLA);
|
||||
|
||||
|
||||
|
||||
//si5351_ms_set_freq(SI5351_MS0, 7040100);
|
||||
//si5351_ms_enable_output(SI5351_MS0);
|
||||
//si5351_ms_write_params(SI5351_MS0, WSPR_SYMBOLS[3]);
|
||||
|
||||
|
||||
uint8_t wspr_buffer[WSPR_LENGTH];
|
||||
|
||||
wspr_encode("DL1SSK", "JN39", 27, wspr_buffer);
|
||||
wspr_transmit(SI5351_MS0, wspr_buffer);
|
||||
|
||||
char line[16];
|
||||
while(1) {
|
||||
uint8_t res = 0;
|
||||
while(res != 1) {
|
||||
uart_puts("?\n");
|
||||
res = uart_get_line(line, 16);
|
||||
}
|
||||
|
||||
uint32_t realtime = strtoul(line,NULL,10);
|
||||
timer_set(realtime);
|
||||
uart_puts("Time set\n");
|
||||
|
||||
while(timestamp % 120 != 1) {
|
||||
_delay_ms(25);
|
||||
}
|
||||
|
||||
wspr_transmit(SI5351_MS0, wspr_buffer);
|
||||
uart_puts("Transmission send\n");
|
||||
}
|
||||
|
||||
|
||||
while(1);
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
#/usr/bin/env python3
|
||||
import numpy as np
|
||||
|
||||
|
||||
from scipy.io import wavfile
|
||||
from scipy.misc import imread
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
|
||||
WIDTH = 640
|
||||
HEIGHT = 496
|
||||
|
||||
OUTPUT_RATE = 48000
|
||||
|
||||
VIS_START_FREQ = 1900
|
||||
VIS_START_DUR = 300
|
||||
VIS_PAUSE = 10
|
||||
VIS_ONE_FREQ = 1100
|
||||
VIS_ZERO_FREQ = 1300
|
||||
VIS_BIT_DUR = 30
|
||||
# Code 97 + even parity, lsb first
|
||||
VIS_BITS = [True, False, False, False, False, True, True, True]
|
||||
|
||||
SYNC_FREQ = 1200
|
||||
SYNC_DUR = 20
|
||||
|
||||
PORCH_DUR = 2.080
|
||||
|
||||
PIXEL_DUR = 0.382
|
||||
|
||||
COLOR_LOW_FREQ = 1500
|
||||
COLOR_HIGH_FREG = 2300
|
||||
|
||||
phase_acc = 0
|
||||
|
||||
|
||||
def sine_gen(freq):
|
||||
global phase_acc
|
||||
phase_inc = (2 * np.pi / OUTPUT_RATE) * freq
|
||||
phase_acc += phase_inc
|
||||
if phase_acc > 2 * np.pi:
|
||||
phase_acc = phase_acc - 2 * np.pi
|
||||
|
||||
return np.sin(phase_acc)
|
||||
|
||||
|
||||
samples_left = 0
|
||||
def make_tone(freq, duration, data):
|
||||
global samples_left
|
||||
samples = duration / 1000 * OUTPUT_RATE + samples_left
|
||||
sample_count = int(samples)
|
||||
samples_left = samples - sample_count
|
||||
|
||||
for i in range(0, sample_count):
|
||||
data += [sine_gen(freq)]
|
||||
|
||||
|
||||
|
||||
|
||||
def make_vis(samples):
|
||||
make_tone(VIS_START_FREQ, VIS_START_DUR, samples)
|
||||
make_tone(SYNC_FREQ, VIS_PAUSE, samples)
|
||||
make_tone(VIS_START_FREQ, VIS_START_DUR, samples)
|
||||
|
||||
make_tone(SYNC_FREQ, VIS_BIT_DUR, samples)
|
||||
for bit in VIS_BITS:
|
||||
if bit:
|
||||
make_tone(VIS_ONE_FREQ, VIS_BIT_DUR, samples)
|
||||
else:
|
||||
make_tone(VIS_ZERO_FREQ, VIS_BIT_DUR, samples)
|
||||
|
||||
make_tone(SYNC_FREQ, VIS_BIT_DUR, samples)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
image = imread('testcard.png', mode='YCbCr')
|
||||
|
||||
samples = []
|
||||
|
||||
make_vis(samples)
|
||||
|
||||
for y in range(0, int(HEIGHT/2)):
|
||||
make_tone(SYNC_FREQ, SYNC_DUR, samples)
|
||||
make_tone(COLOR_LOW_FREQ, PORCH_DUR, samples)
|
||||
|
||||
for x in range(0, WIDTH):
|
||||
lum = image[y*2, x, 0] / 255.0
|
||||
freq = COLOR_LOW_FREQ + lum * (COLOR_HIGH_FREG - COLOR_LOW_FREQ)
|
||||
make_tone(freq, PIXEL_DUR, samples)
|
||||
|
||||
for x in range(0, WIDTH):
|
||||
cr0 = image[y*2, x, 2] / 255.0
|
||||
cr1 = image[y*2 + 1, x, 2] / 255.0
|
||||
cr = (cr0 + cr1) / 2
|
||||
freq = COLOR_LOW_FREQ + cr * (COLOR_HIGH_FREG - COLOR_LOW_FREQ)
|
||||
make_tone(freq, PIXEL_DUR, samples)
|
||||
|
||||
for x in range(0, WIDTH):
|
||||
cb0 = image[y*2, x, 1] / 255.0
|
||||
cb1 = image[y*2 + 1, x, 1] / 255.0
|
||||
cb = (cb0 + cb1) / 2
|
||||
freq = COLOR_LOW_FREQ + cb * (COLOR_HIGH_FREG - COLOR_LOW_FREQ)
|
||||
make_tone(freq, PIXEL_DUR, samples)
|
||||
|
||||
for x in range(0, WIDTH):
|
||||
lum = image[y*2 + 1, x, 0] / 255.0
|
||||
freq = COLOR_LOW_FREQ + lum * (COLOR_HIGH_FREG - COLOR_LOW_FREQ)
|
||||
make_tone(freq, PIXEL_DUR, samples)
|
||||
|
||||
|
||||
samples = np.array(samples)
|
||||
|
||||
samples = samples * 0.75 * 32767
|
||||
samples = np.int16(samples)
|
||||
|
||||
wavfile.write("output.wav", OUTPUT_RATE, samples)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Binary file not shown.
Before Width: | Height: | Size: 32 KiB |
|
@ -0,0 +1,25 @@
|
|||
#/usr/bin/env python3
|
||||
|
||||
import serial
|
||||
import time
|
||||
|
||||
def main():
|
||||
ser = serial.Serial('/dev/kaboard', 38400, timeout=10)
|
||||
ser.flush()
|
||||
|
||||
while True:
|
||||
line = ser.readline()
|
||||
while len(line) == 0:
|
||||
line = ser.readline()
|
||||
|
||||
line = line.decode("ascii")[:-1]
|
||||
print("[%s] >> %s" % (time.strftime('%H:%M:%S'), line))
|
||||
if line == "?":
|
||||
timestamp = "%d\n" % int(time.time())
|
||||
print("[%s] << %s" % (time.strftime('%H:%M:%S'),timestamp[:-1]))
|
||||
ser.write(timestamp.encode('ascii'))
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Binary file not shown.
|
@ -0,0 +1,14 @@
|
|||
#include "timer.h"
|
||||
|
||||
volatile uint32_t timestamp;
|
||||
volatile uint16_t milliseconds;
|
||||
|
||||
ISR(TIMER0_OVF_vect) {
|
||||
TCNT0 = 6; //Preload for 250 ticks to overflow
|
||||
|
||||
milliseconds++;
|
||||
if(milliseconds > 999) {
|
||||
timestamp++;
|
||||
milliseconds = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
#include "uart.h"
|
||||
|
||||
uint8_t uart_timed_out = 0;
|
||||
|
||||
void uart_init(void) {
|
||||
UBRRH = UBRR_VAL >> 8; //Setting baudrate
|
||||
UBRRL = UBRR_VAL & 0xFF;
|
||||
|
||||
UCSRB |= (1<<TXEN) | (1<<RXEN); // UART TX
|
||||
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchronous 8N1
|
||||
|
||||
// flush receive buffer
|
||||
do
|
||||
{
|
||||
UDR;
|
||||
}
|
||||
while (UCSRA & (1 << RXC));
|
||||
|
||||
//reset tx and rx completeflags
|
||||
UCSRA = (1 << RXC) | (1 << TXC) | (1 << UDRE);
|
||||
}
|
||||
|
||||
uint8_t uart_getc_timeout(void) {
|
||||
uint8_t retries = UART_TIMEOUT;
|
||||
uint8_t delays = 0;
|
||||
|
||||
while (!(UCSRA & (1<<RXC)) && (retries > 0)) {
|
||||
if(delays == 0) {
|
||||
retries--;
|
||||
}
|
||||
delays = (delays + 1) % 250;
|
||||
_delay_us(4);
|
||||
}
|
||||
|
||||
if(retries > 0) {
|
||||
uart_timed_out = 0;
|
||||
return UDR;
|
||||
}
|
||||
|
||||
uart_timed_out = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t uart_get_line(char buffer[], uint8_t maxlen) {
|
||||
char t = 0;
|
||||
uint8_t pos = 0;
|
||||
buffer[0] = 0;
|
||||
|
||||
//maxlen needs to be at least big enough for one character + null byte.
|
||||
if(maxlen < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uart_clear_time_out();
|
||||
|
||||
while(pos < maxlen && t != '\n' && !uart_has_timed_out()) {
|
||||
t = uart_getc_timeout();
|
||||
buffer[pos] = t;
|
||||
pos++;
|
||||
}
|
||||
|
||||
// We passed the loop at least once, so pos can not be 0
|
||||
if(buffer[pos-1] != '\n') {
|
||||
return 0;
|
||||
}
|
||||
buffer[pos-1] = 0;
|
||||
return 1;
|
||||
}
|
Loading…
Reference in New Issue