summaryrefslogtreecommitdiff
path: root/software/hhd70dongle.old/hhd70dongle.c
diff options
context:
space:
mode:
Diffstat (limited to 'software/hhd70dongle.old/hhd70dongle.c')
-rw-r--r--software/hhd70dongle.old/hhd70dongle.c438
1 files changed, 438 insertions, 0 deletions
diff --git a/software/hhd70dongle.old/hhd70dongle.c b/software/hhd70dongle.old/hhd70dongle.c
new file mode 100644
index 0000000..f28886d
--- /dev/null
+++ b/software/hhd70dongle.old/hhd70dongle.c
@@ -0,0 +1,438 @@
+/*
+ *
+ * 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) 2012 Bernhard Tittelbach <xro@realraum.at>
+ * 2015 Christian Pointner <equinox@mur.at>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+#include <avr/io.h>
+#include <avr/wdt.h>
+#include <util/delay.h>
+#include <stdio.h>
+#include <avr/interrupt.h>
+//#include <avr/power.h>
+
+#include "led.h"
+#include "util.h"
+#include "usbio.h"
+
+#include "hhd70.h"
+#include "c1101lib.h"
+#include "cc1101_defines.h"
+
+//todo: move to separte File:
+
+// If TTX_EN goes high, ~ <=500ms before TTX CW Sender forcefully disables our RX/TX Signal Path
+//IF TTX_EN goes low, we have ~ 1min (Beacon Interval) until the next CW Beacon is sent and our RX/TX Signal Path is forcefully disabled
+// Beacon Interval Time can be measured by counting with an interrupt triggered by RTC_SECONDS Input
+//#define TTX_EN <port>
+//#define RTC_SECONDS <port>
+
+
+#define CPU_PRESCALE(n) do { CLKPR = 0x80; CLKPR = (n); } while(0)
+char read_buffer[64]; // buffer for reading usb signals
+char write_buffer[64]; // buffer for writing usb signals
+
+//TODOs:
+//* make adc work ?
+// * remove code duplications
+// * speed up and simplify code
+// * make as much use of sleep modes as possible
+// * use adc noise canceler (i.e. automatic sampling during cpu sleep)
+// * read atmega temp
+// * safely save state in eeprom (2 memory regions, only use the one with the "written successfully bit" which is written last)
+// * what if c1101 resets spuriously and clears it's settings ? -> check peridically ?
+
+bool enable_tx_part=false;
+bool enable_rx_part=false;
+bool enable_beacon_part=false;
+
+void print_part_status(void)
+{
+ printf("OOK Beacon: ");
+ printf(((enable_beacon_part)? "Enabled": "Disabled") );
+ printf("\r\n");
+ printf("RX-Part: ");
+ printf(((enable_rx_part)? "Enabled": "Disabled") );
+ printf("\r\n");
+ printf("TX-Part: ");
+ printf(((enable_tx_part)? "Enabled": "Disabled") );
+ printf("\r\n");
+}
+
+//void generate_morse_code_sequence(char *msg, *cw_buffer, uint16_t buffer_len)
+//{
+ //char cw_short[2] = {1,1};
+ //char cw_long[2] = {1,3};
+ //char cw_space[2] = {0, 1};
+ //char cw_letterspace[2] = {0,3};
+ //char cw_wordspace[2] = {0, 7};
+//}
+
+void beacon_enable(void)
+{
+ c1101_spi_strobe_command(CC1101_CMD_STX);
+ hhd70_palna_txmode();
+}
+
+void beacon_on(void)
+{
+ hhd70_set_OOK_GDO0_high();
+ led_on();
+}
+
+void beacon_off(void)
+{
+ led_off();
+ hhd70_set_OOK_GDO0_low();
+}
+
+void beacon_disable(void)
+{
+ hhd70_palna_rxmode();
+ c1101_spi_strobe_command(CC1101_CMD_SIDLE);
+}
+
+int main(void)
+{
+ MCUSR &= ~(1 << WDRF);
+ wdt_disable(); // FIXME: disable WatchDog for now, but use it later...
+ CPU_PRESCALE(0); //cpu_init
+
+ led_init();
+ usbio_init();
+
+ hhd70_init();
+ DDRB &= ~(1<<DDB5); // set PB5/ADC12 to INPUT (c1101 temp sensor)
+ sei(); //set enable global interrupt
+
+ printf("hhd70dongle ready\r\n");
+
+ _delay_ms(500);
+ c1101_spi_strobe_command(CC1101_CMD_SRES); // reset c1101
+ //c1101 init now happens after pressing B, S or E
+
+ hhd70_palna_rxmode();
+ hhd70_bias_set(255);
+
+ enable_tx_part=false;
+ enable_rx_part=false;
+ enable_beacon_part=false;
+ int8_t fdev_m = 1;
+ int8_t fdev_e = 1;
+ uint32_t prev_ook_freq = c1101_getCurrentCarrierFrequencyHz();
+
+ //char mursat_beacon[256];
+ //for(int i=0;i<sizeof(mursat_beacon);++i) {
+ // mursat_beacon[i] = 0xFF;
+ //}
+
+ for(;;)
+ {
+ int16_t num_bytes_received = usbio_bytes_received();
+ while(num_bytes_received > 0)
+ {
+ int16_t recv_byte = fgetc(stdin);
+ num_bytes_received--;
+ if (recv_byte == EOF)
+ continue;
+ if ((char) recv_byte == '!')
+ {
+ printf("resetting\r\n");
+ wdt_enable(WDTO_500MS);
+ reset();
+ }
+ else if ((char) recv_byte == 'N') {
+ enable_tx_part=false;
+ enable_rx_part=false;
+ enable_beacon_part=false;
+ c1101_spi_strobe_command(CC1101_CMD_SRES); // reset c1101
+ hhd70_palna_rxmode();
+ print_part_status();
+ led_off();
+ }
+ else if ((char) recv_byte == 'B')
+ {
+ enable_beacon_part = !enable_beacon_part;
+ if (enable_beacon_part)
+ {
+ enable_rx_part=false;
+ enable_tx_part=false;
+ c1101_init_ook_beacon();
+
+ printf("CC1101 enabling Beacon with Power: %3d (0x%02X)\r\n", (int)c1101_ook_power_get(), (int)c1101_ook_power_get_raw());
+
+ beacon_enable();
+ beacon_on();
+ }
+ print_part_status();
+ }
+ else if ((char) recv_byte == 'E')
+ {
+ enable_rx_part = !enable_rx_part;
+ if (enable_rx_part)
+ {
+ enable_beacon_part=false;
+ c1101_init();
+ }
+ print_part_status();
+ }
+ else if ((char) recv_byte == 'S')
+ {
+ enable_tx_part = !enable_tx_part;
+ if (enable_tx_part)
+ {
+ enable_beacon_part=false;
+ c1101_init();
+ }
+ print_part_status();
+ }
+ else if ((char) recv_byte == 'R')
+ {
+ c1101_spi_dump_registers();
+ print_part_status();
+ }
+ else if ((char) recv_byte == 'D' || (char) recv_byte == 'd')
+ {
+ printf("FSK Freq Deviation Now: %u0 Hz\r\n", c1101_setFSKDeviationFromCarrier(fdev_m, fdev_e));
+ if ((char) recv_byte == 'd')
+ {
+ fdev_m--;
+ if (fdev_m < 0)
+ {
+ fdev_e = (fdev_e - 1) % 8;
+ if (fdev_e < 0)
+ fdev_e = 7;
+ fdev_m = 7;
+ }
+ fdev_m %= 8;
+ }
+ else
+ {
+ fdev_m++;
+ if (fdev_m > 7)
+ fdev_e = (fdev_e + 1) % 8;
+ fdev_m %= 8;
+ }
+ }
+ else if ((char) recv_byte == '+' || (char) recv_byte == '-' || (char) recv_byte == '#' || (char) recv_byte == '_' || (char) recv_byte == ':' || (char) recv_byte == '.' || (char) recv_byte == 'f'|| (char) recv_byte == '?')
+ {
+ int32_t change_freq = 0;
+ switch (recv_byte)
+ {
+ case '+':
+ change_freq = 1000000;
+ break;
+ case '-':
+ change_freq = -1000000;
+ break;
+ case '#':
+ change_freq = 10000000;
+ break;
+ case '_':
+ change_freq = -10000000;
+ break;
+ case ':':
+ change_freq = 100000;
+ break;
+ case '.':
+ change_freq = -100000;
+ break;
+ case 'f':
+ printf("Setting Frequency to previously adjusted value.\r\n");
+ c1101_setFrequency(prev_ook_freq);
+ break;
+ case '?':
+ //just show current frequency
+ break;
+ }
+ if (change_freq != 0)
+ {
+ if (enable_beacon_part) beacon_off();
+ beacon_disable();
+
+ printf("Frequency %s by %lu KHz - ", (change_freq > 0 ? "up" : "down"), (change_freq > 0 ? 1 : -1) * change_freq / 1000);
+ c1101_changeFrequencyByRelativeValue(change_freq);
+ prev_ook_freq = c1101_getCurrentCarrierFrequencyHz();
+
+ if (enable_beacon_part) {
+ beacon_enable();
+ beacon_on();
+ }
+ }
+ uint32_t hz = c1101_getCurrentCarrierFrequencyHz();
+ uint16_t mhz = hz / 1000000;
+ uint16_t khz = (hz % 1000000)/1000;
+ hz %= 1000;
+ printf("Frequency is now: %d.%03d%03d MHz\r\n", mhz, khz, (uint16_t)hz);
+ }
+ else if ((char) recv_byte == 'p')
+ {
+ hhd70_bias_dec();
+ printf("Bias Power is now: %d\r\n", hhd70_bias_get());
+ }
+ else if ((char) recv_byte == 'P')
+ {
+ hhd70_bias_inc();
+ printf("Bias Power is now: %d\r\n", hhd70_bias_get());
+ }
+ else if ((char) recv_byte == 'o')
+ {
+ if (enable_beacon_part) beacon_off();
+ beacon_disable();
+
+ c1101_ook_power_dec();
+ printf("CC1101 Power is now: %3d (0x%02X)\r\n", (int)c1101_ook_power_get(), (int)c1101_ook_power_get_raw());
+
+ if (enable_beacon_part) {
+ beacon_enable();
+ beacon_on();
+ }
+ }
+ else if ((char) recv_byte == 'O')
+ {
+ if (enable_beacon_part) beacon_off();
+ beacon_disable();
+
+ c1101_ook_power_inc();
+ printf("CC1101 Power is now: %3d (0x%02X)\r\n", (int)c1101_ook_power_get(), (int)c1101_ook_power_get_raw());
+
+ if (enable_beacon_part) {
+ beacon_enable();
+ beacon_on();
+ }
+ }
+ else if ((char) recv_byte == ' ')
+ {
+ if (enable_beacon_part) {
+ hhd70_set_OOK_GDO0_toggle();
+ }
+ }
+ }
+
+
+ usbio_task();
+
+ if (enable_rx_part)
+ {
+
+ c1101_spi_strobe_command(CC1101_CMD_SRX); // enter RX - Mode
+ _delay_ms(1000);
+
+ if (hhd70_rx_data_available())
+ {
+ led_on();
+ printf("RX: GDO2 pin HIGH\r\n");
+ printf("c1101 rx bytes:");
+ debug_sprint_int16hex(write_buffer, c1101_spi_read_register(CC1101_REG_RO_RXBYTES));
+ printf("%s", write_buffer);
+ printf("\r\n");
+ c1101_recieveData();
+ led_off();
+ }
+
+ printf("c1101 rssi: ");
+ debug_sprint_int16hex(write_buffer, c1101_spi_read_register(CC1101_REG_RO_RSSI));
+ printf("%s", write_buffer);
+ printf("\r\n");
+ printf("c1101 tx bytes: ");
+ debug_sprint_int16hex(write_buffer, c1101_spi_read_register(CC1101_REG_RO_TXBYTES));
+ printf("%s", write_buffer);
+ printf("\r\n");
+ printf("c1101 rx bytes: ");
+ int16_t num_rx_bytes = c1101_spi_read_register(CC1101_REG_RO_RXBYTES);
+ debug_sprint_int16hex(write_buffer, num_rx_bytes);
+ printf("%s", write_buffer);
+ printf("\r\n");
+
+
+ //~ if (num_rx_bytes > 0)
+ //~ {
+ //~ led_on();
+ //~ printf("RX Buffer Non-Empty\r\n");
+ //~ c1101_recieveData();
+ //~ led_off();
+ //~ }
+
+// printf("c1101 status byte: ");
+// debug_sprint_int16hex(write_buffer, c1101_getStatus());
+// printf("%s", write_buffer);
+// printf("\r\n");
+
+ }
+
+ if (enable_tx_part)
+ {
+ /* write_buffer[0]='T'; */
+ /* write_buffer[1]='e'; */
+ /* write_buffer[2]='m'; */
+ /* write_buffer[3]='p'; */
+ /* write_buffer[4]='s'; */
+ /* write_buffer[5]=':'; */
+ /* adc_on(); */
+ /* _delay_ms(250); */
+ /* printf("temp c1101: "); */
+ /* debug_sprint_int16hex(write_buffer+6, c1101_measureTemp()); */
+ /* printf("%s", write_buffer+6); */
+ /* printf("\r\n"); */
+ /* _delay_ms(250); */
+ /* printf("temp atmega: "); */
+ /* debug_sprint_int16hex(write_buffer+10, adc_read(ADCMUX_ADC12)); */
+ /* printf("%s", write_buffer+10); */
+ /* printf("\r\n"); */
+ /* adc_off(); */
+ /* _delay_ms(250); */
+ /* led_on(); */
+ /* printf("TX Data: String\r\n"); */
+ /* c1101_transmitData_infPktMode("OE6EOF test mur.sat GFSK r:9k6 fdev:11kHz 1234567890123456789012345678901234567890 End of Test",93); */
+ /* led_off(); */
+ /* _delay_ms(100); */
+ /* led_on(); */
+ /* printf("TX Data: Temps\r\n"); */
+ /* c1101_transmitData_infPktMode((char*) write_buffer,14); */
+ /* led_off(); */
+ }
+
+/* if (enable_beacon_part)
+ {
+ //char mursat_beacon[8] = {0b11101110, 0b11100010, 0b00111010, 0b10101000, 0b10001110, 0b11101110, 0b00101011, 0b10100000}; //OE6EOF
+ printf("OOK Sending Beacon\r\n");
+ led_on();
+ //c1101_transmitData_infPktMode(mursat_beacon,sizeof(mursat_beacon));
+ hhd70_palna_txmode();
+ c1101_spi_strobe_command(CC1101_CMD_STX);
+ hhd70_set_OOK_GDO0_high();
+ _delay_ms(1000);
+ led_off();
+ hhd70_set_OOK_GDO0_low();
+ c1101_spi_strobe_command(CC1101_CMD_SIDLE);
+ hhd70_palna_rxmode();
+ _delay_ms(200);
+ }*/
+ }
+}