/* * * mur.sat * * Somewhen in the year 20xx, mur.at will have a nano satellite launched * into a low earth orbit (310 km above the surface of our planet). The * satellite itself is a TubeSat personal satellite kit, developed and * launched by interorbital systems. mur.sat is a joint venture of mur.at, * ESC im Labor and realraum. * * Please visit the project hompage at sat.mur.at for further information. * * * Copyright (C) 2013-2015 Christian Pointner * * This file is part of mur.sat. * * mur.sat is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * mur.sat is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with mur.sat. If not, see . * */ #include #include #include #include #include #include "led.h" #include "util.h" #include "usbio.h" #include "rda1846.h" #include "rda1846_defines.h" #define DEFAULT_FREQ_2M 145900 #define DEFAULT_FREQ_1M5 230000 #define DEFAULT_FREQ_70CM 437525 int32_t default_freq = DEFAULT_FREQ_2M; int32_t current_freq_kHz = DEFAULT_FREQ_2M; int8_t current_volume = 0; static void reset_rda(void) { printf("soft resetting RDA1846.\r\n"); rda1846_soft_reset(); current_freq_kHz = default_freq = DEFAULT_FREQ_2M; } static void reinit_rda(void) { printf("initializing RDA1846.\r\n"); rda1846_reg_init(); current_freq_kHz = default_freq = DEFAULT_FREQ_2M; } static void set_default_freq(void) { current_freq_kHz = default_freq; printf("setting frequency to %d.%03d MHz .. ", (uint16_t)(current_freq_kHz / 1000), (uint16_t)(current_freq_kHz % 1000)); if(rda1846_set_freq_kHz(current_freq_kHz)) printf("error\r\n"); else printf("ok\r\n"); } static int32_t print_actual_freq(void) { int32_t f = rda1846_get_freq_kHz(); if(f < 0) printf("actual frequency: NaN MHz\r\n"); else printf("actual frequency: %d.%03d MHz\r\n", (uint16_t)(f / 1000), (uint16_t)(f % 1000)); return f; } static void update_current_freq(void) { printf("setting frequency to %d.%03d MHz .. ", (uint16_t)(current_freq_kHz / 1000), (uint16_t)(current_freq_kHz % 1000)); rda1846_state_t old_state = rda1846_get_state(); if(old_state == receive || old_state == transmit) rda1846_idle(); if(rda1846_set_freq_kHz(current_freq_kHz)) printf("error .. "); else printf("ok .. "); if(old_state == receive) rda1846_receive(); else if(old_state == transmit) rda1846_transmit(); if(current_freq_kHz != rda1846_get_freq_kHz()) { printf("NACK!\r\n"); print_actual_freq(); } else { printf("ACK\r\n"); } } static void set_band(rf_band_t b) { printf("setting band to %s\r\n", rda1846_rf_band_to_string(b)); rda1846_set_band(b); if(b == b_2m) default_freq = DEFAULT_FREQ_2M; else if(b == b_1m5) default_freq = DEFAULT_FREQ_1M5; else if(b == b_70cm) default_freq = DEFAULT_FREQ_70CM; set_default_freq(); } static void set_bw(channel_bw_t bw) { printf("setting bandwidth to %s\r\n", rda1846_channel_bw_to_string(bw)); rda1846_set_bw(bw); } static void print_status(void) { printf("current state: %s\r\n", rda1846_state_to_string(rda1846_get_state())); int16_t rssi = rda1846_get_rssi(); printf("rssi: "); if(rssi < 0) { printf("-"); rssi*=-1; } printf("%d.%03d dB\r\n", (uint16_t)(rssi / 8), (uint16_t)((rssi % 8)*125)); int16_t vssi = rda1846_get_vssi(); if(vssi < 0) printf("vssi: NaN mV\r\n"); else printf("vssi: %d mV\r\n", vssi); uint16_t flags = rda1846_get_flags(); if(flags == 0xFFFF) printf("flags: ERROR\r\n"); else printf("flags: %04X\r\n", flags); int8_t vol = rda1846_get_volume(); if(vol > 0) printf("volume: NaN dB\r\n"); else printf("volume: %d dB\r\n", vol); printf("rf band: %s\r\n", rda1846_rf_band_to_string(rda1846_get_band())); print_actual_freq(); printf("bandwidth: %s\r\n", rda1846_channel_bw_to_string(rda1846_get_bw())); } static void print_dtmf(void) { uint8_t idx1, idx2, code, valid; uint16_t raw = rda1846_get_dtmf(&idx1, &idx2, &code, &valid); if(raw == 0xFFFF) printf("DTMF: ERROR\r\n"); else printf("DTMF: raw=0x%04X, tone1=%d, tone2=%d, code=0x%02X, valid=%d\r\n", raw, idx1, idx2, code, valid); rda1846_clear_int(); } static void update_vol(void) { printf("setting volume to %d dB\r\n", current_volume); rda1846_set_volume(current_volume); } static void inc_vol(void) { current_volume = (current_volume >= 0) ? 0 : current_volume + 1; update_vol(); } static void dec_vol(void) { current_volume = (current_volume <= -30) ? -30 : current_volume - 1; update_vol(); } static void handle_cmd(uint8_t cmd) { switch(cmd) { case '0': led_off(); printf("led OFF\r\n"); break; case '1': led_on(); printf("led ON\r\n"); break; case 't': led_toggle(); printf("led TOGGLE\r\n"); break; case '!': rda1846_soft_reset(); reset2bootloader(); break; case 'r': reset_rda(); break; case 'i': reinit_rda(); break; case '2': set_band(b_2m); break; case '3': set_band(b_1m5); break; case '7': set_band(b_70cm); break; case 'b': set_bw(bw_12k5); break; case 'B': set_bw(bw_25k); break; case 'F': set_default_freq(); break; case '#': current_freq_kHz+=100; update_current_freq(); break; case '+': current_freq_kHz+=10; update_current_freq(); break; case ':': current_freq_kHz+=1; update_current_freq(); break; case '.': current_freq_kHz-=1; update_current_freq(); break; case '-': current_freq_kHz-=10; update_current_freq(); break; case '_': current_freq_kHz-=100; update_current_freq(); break; case 'P': rda1846_powerdown(); print_status(); break; case 'I': rda1846_idle(); print_status(); break; case 'R': rda1846_receive(); print_status(); break; case 'T': rda1846_transmit(); print_status(); break; case 'v': dec_vol(); break; case 'V': inc_vol(); break; case 'g': rda1846_gpio_off(); printf("GPIO off\r\n"); break; case 'G': rda1846_gpio_default(); printf("GPIO to defaults\r\n"); break; case '5': rda1846_gpio_55(); break; case 'a': rda1846_gpio_AA(); break; case 'f': print_actual_freq(); break; case 's': print_status(); break; case 'd': print_dtmf(); break; case 'D': rda1846_dump_register(); break; default: printf("\r\n"); return; } } int main(void) { MCUSR &= ~(1 << WDRF); wdt_disable(); cpu_init(); led_init(); usbio_init(); rda1846_init(); sei(); for(;;) { int16_t BytesReceived = usbio_bytes_received(); while(BytesReceived > 0) { int ReceivedByte = fgetc(stdin); if(ReceivedByte != EOF) { handle_cmd(ReceivedByte); } BytesReceived--; } usbio_task(); } }