102 lines
2.9 KiB
C
102 lines
2.9 KiB
C
#include "adc.h"
|
|
#include "derivative.h"
|
|
#include "fft/fft.h"
|
|
#include "sstv.h"
|
|
#include "tftlcd.h"
|
|
#include "uart.h"
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
static q15_t data[FFT_N];
|
|
static q15_t buffer[BUF_M];
|
|
static q15_t *pData = &data[0];
|
|
|
|
static const float32_t color_re = (float32_t)(FREQ_RANGE) / (COLOR_SCALE - 1);
|
|
#define fre2lum(fre) (uint8_t)((fre - FREQ_BLACK) / color_re)
|
|
|
|
static uint16_t find_peak(uint16_t L, uint16_t R) {
|
|
q15_t peak = 0;
|
|
uint16_t index = 0;
|
|
for (uint16_t i = L; i <= R; i++)
|
|
if (data[i] > peak) {
|
|
index = i;
|
|
peak = data[i];
|
|
}
|
|
return index;
|
|
}
|
|
|
|
static uint32_t cSample = 0;
|
|
static uint16_t preLen = 0;
|
|
static void read_samples(uint32_t start, uint16_t len) {
|
|
int16_t offset = start - cSample;
|
|
if (offset >= 0) {
|
|
adc0_read_buf(pData, offset);
|
|
adc0_read_buf(pData, len);
|
|
} else {
|
|
for (uint16_t i = 0; i < -offset; i++) data[i] = buffer[preLen + offset + i];
|
|
adc0_read_buf(pData - offset, len + offset);
|
|
}
|
|
for (uint16_t i = 0; i < len; i++) buffer[i] = data[i];
|
|
|
|
cSample += offset + len;
|
|
preLen = len;
|
|
}
|
|
|
|
static void decode_martin1() {
|
|
uart_printf(UART_MSG, "Mode: 44 - Martin 1\r\n");
|
|
|
|
const uint16_t WIDTH = 240;
|
|
const uint16_t HEIGHT = 240;
|
|
|
|
const float32_t SCAN_TIME = 0.146432;
|
|
const float32_t SYNC_PULSE = 0.004862;
|
|
const float32_t SYNC_PORCH = 0.000572;
|
|
|
|
const float32_t CHAN_TIME = SYNC_PORCH + SCAN_TIME;
|
|
const float32_t LINE_TIME = SYNC_PULSE + SYNC_PORCH + CHAN_TIME;
|
|
const float32_t PIXEL_TIME = SCAN_TIME / WIDTH;
|
|
const float32_t CHAN_OFFSETS = SYNC_PULSE + SYNC_PORCH;
|
|
|
|
const float32_t FWHM = 2.34;
|
|
const float32_t HALF_SAMPLE_TIME = (PIXEL_TIME * FWHM) / 2;
|
|
const uint8_t len = (uint8_t)(HALF_SAMPLE_TIME * 2 * FS);
|
|
|
|
uint16_t idx, fre, rgb;
|
|
uint32_t start, cSampleI = 0;
|
|
float32_t cSampleF = 0;
|
|
|
|
char buf[15];
|
|
|
|
uart_printf(UART_MSG, "Start Decoding\r\n");
|
|
for (uint16_t h = 0; h < HEIGHT; h = (h + 1) % HEIGHT) {
|
|
string_format(buf, "Line: %3d/240", h);
|
|
LCD_ShowString(LCD_W - 8, 0, &buf[0], 16, 1, 0);
|
|
|
|
if (h) {
|
|
cSampleF += LINE_TIME * FS;
|
|
cSampleI = (uint32_t)round(cSampleF);
|
|
}
|
|
|
|
// RGB 565: 5 bit R, 6 bit G, 5 bit B
|
|
for (uint16_t w = 0; w < WIDTH; w++) {
|
|
start = (uint32_t)round(cSampleI + (CHAN_OFFSETS + w * PIXEL_TIME - HALF_SAMPLE_TIME) * FS);
|
|
read_samples(start, len);
|
|
FFT(pData, len);
|
|
idx = find_peak(119, 457); // 1875 - 7125 Hz
|
|
fre = FFT_BIN(idx, RE);
|
|
rgb = fre2lum(fre);
|
|
|
|
rgb = (uint16_t)(((rgb / 2) & 0x1F) << 11) // R
|
|
| (uint16_t)((rgb & 0x3F) << 5) // G
|
|
| (uint16_t)((rgb / 2) & 0x1F); // B
|
|
LCD_DrawPoint(h, w, rgb);
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8_t decode_sstv() {
|
|
decode_martin1();
|
|
return 0;
|
|
}
|