123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- // STM32F100 and SI4032 RTTY transmitter
- // released under GPL v.2 by anonymous developer
- // enjoy and have a nice day
- // ver 1.5a
- #include <stm32f10x_gpio.h>
- #include <stm32f10x_tim.h>
- #include <stm32f10x_spi.h>
- #include <stm32f10x_tim.h>
- #include <stm32f10x_usart.h>
- #include <stm32f10x_adc.h>
- #include <stm32f10x_rcc.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <misc.h>
- #include "config.h"
- #include "delay.h"
- #include "f_rtty.h"
- #include "init.h"
- #include "radio.h"
- #include "ublox.h"
- #include "util.h"
- #include "satpredict.h"
- #include "morse.h"
- #define GREEN GPIO_Pin_7 // Inverted
- #define RED GPIO_Pin_8 // Think this is inverted too
- enum { STARTUP, RTTY, MORSE };
- volatile int current_mode = STARTUP;
- // Telemetry Data to Transmit
- unsigned int send_count;
- int voltage;
- int8_t si4032_temperature;
- GPSEntry gpsData;
- float tx_freq = TRANSMIT_FREQUENCY;
- char callsign[15] = {CALLSIGN};
- uint16_t CRC_rtty = 0x12ab;
- char buf_rtty[200];
- // Volatile Variables, used within interrupts.
- volatile int adc_bottom = 2000;
- volatile char flaga = 0; // GPS Status Flags
- volatile int led_enabled = 1; // Flag to disable LEDs at altitude.
- volatile unsigned char pun = 0;
- volatile unsigned int cun = 10;
- volatile unsigned char tx_on = 0;
- volatile unsigned int tx_on_delay;
- volatile unsigned char tx_enable = 0;
- rttyStates send_rtty_status = rttyZero;
- volatile char *tx_buffer;
- volatile uint16_t button_pressed = 0;
- volatile uint8_t disable_armed = 0;
- void collect_telemetry_data (void);
- void send_rtty_packet (void);
- uint16_t gps_CRC16_checksum (char *string);
- void morse_beacon (void);
- //
- // GPS data processing
- void USART1_IRQHandler (void)
- {
- if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
- ublox_handle_incoming_byte((uint8_t) USART_ReceiveData(USART1));
- else
- //if (USART_GetITStatus(USART1, USART_IT_ORE) != RESET)
- // USART_ReceiveData(USART1);
- //else /* wut */
- USART_ReceiveData(USART1);
- }
- //
- // Symbol Timing Interrupt
- // In here symbol transmission occurs.
- void TIM2_IRQHandler(void)
- {
- if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
- {
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
- //
- if (ALLOW_DISABLE_BY_BUTTON)
- {
- if (ADCVal[1] > adc_bottom)
- {
- button_pressed++;
- if (button_pressed > (BAUD_RATE / 3))
- {
- disable_armed = 1;
- GPIO_SetBits(GPIOB, RED);
- }
- }
- else
- {
- if (disable_armed) GPIO_SetBits(GPIOA, GPIO_Pin_12);
- button_pressed = 0;
- }
- if (button_pressed == 0)
- adc_bottom = ADCVal[1] * 1.1; // dynamical reference for power down level
- }
- //
- if (tx_on)
- {
- if (current_mode == RTTY)
- {
- send_rtty_status = send_rtty((char *) tx_buffer);
- if (!disable_armed)
- {
- if (send_rtty_status == rttyEnd)
- {
- if (led_enabled) GPIO_ResetBits(GPIOB, RED);
- if (*(++tx_buffer) == 0)
- {
- tx_on = 0;
- // Reset the TX Delay counter, which is decremented at the symbol rate.
- tx_on_delay = TX_DELAY / (1000/BAUD_RATE);
- tx_enable = 0;
- radio_disable_tx();
- }
- }
- if (send_rtty_status == rttyOne)
- {
- radio_rw_register(0x73, RTTY_DEVIATION, 1);
- if (led_enabled) GPIO_SetBits(GPIOB, RED);
- }
- if (send_rtty_status == rttyZero)
- {
- radio_rw_register(0x73, 0x00, 1);
- if (led_enabled) GPIO_ResetBits(GPIOB, RED);
- }
- }
- }
- } /* C should not look like LISP... */
- // Delay between Transmissions Logic.
- // tx_on_delay is set at the end of a RTTY transmission above, and counts down
- // at the interrupt rate. When it hits zero, we set tx_enable to 1, which allows
- // the main loop to continue.
- if (!tx_on && --tx_on_delay == 0)
- {
- tx_enable = 1;
- tx_on_delay--;
- }
- // Green LED Blinking Logic
- if (--cun == 0)
- {
- if (pun)
- {
- // Clear Green LED.
- if (led_enabled) GPIO_SetBits(GPIOB, GREEN);
- pun = 0;
- }
- else
- {
- // If we have GPS lock, set LED
- if (flaga & 0x80)
- if (led_enabled) GPIO_ResetBits(GPIOB, GREEN);
- pun = 1;
- }
- // Wait 200 symbols.
- cun = 200;
- }
- }
- }
- int main (void)
- {
- RCC_Conf();
- NVIC_Conf();
- init_port();
- init_timer (BAUD_RATE);
- delay_init();
- ublox_init();
- GPIO_SetBits (GPIOB, RED);
- GPIO_SetBits (GPIOB, GREEN); // NOTE - Green LED is inverted. (Reset to activate, Set to deactivate)
- USART_SendData (USART3, 0xc); /* ? */
- radio_soft_reset();
- radio_set_tx_frequency (tx_freq); // setting RTTY TX frequency
- radio_rw_register (0x6D, 00 | (TX_POWER & 0x0007), 1); // setting TX power
- radio_rw_register (0x71, 0x00, 1); // initial RTTY modulation
- radio_rw_register (0x13, 0x00, 1); // Was 0xF0(?) Temperature Value Offset
- radio_rw_register (0x12, 0x20, 1); // Temperature Sensor Calibration
- radio_rw_register (0x0f, 0x80, 1); // ADC configuration
- tx_buffer = buf_rtty;
- tx_on = 0;
- tx_enable = 1;
- // Why do we have to do this again?
- spi_init();
- radio_set_tx_frequency(tx_freq);
- radio_rw_register(0x71, 0x00, 1);
- init_timer(BAUD_RATE);
- radio_enable_tx();
- //
- int pass = 0;
- while (1)
- {
- if (tx_on == 0 && tx_enable)
- switch (current_mode)
- {
- case STARTUP:
- collect_telemetry_data();
- send_rtty_packet();
- current_mode = RTTY;
- break;
- case RTTY:
- radio_disable_tx();
- sat_update();
- tx_freq = TRANSMIT_FREQUENCY;
- #if 0
- for (int ind = 0; ind < numsats; ind++)
- if ((satstatus[ind].elevation > HORIZON)
- || (satstatus[ind].elevation > 0) && ((gpsData.alt_raw/1000) >= FLYING))
- tx_freq = satdata[ind].uplink;
- radio_set_tx_frequency(tx_freq); /* hopefully this is doable.. */
- radio_rw_register(0x71, 0x00, 1);
- current_mode = MORSE;
- #endif
- current_mode = STARTUP;
- break;
- case MORSE:
- morse_beacon ();
- current_mode = STARTUP;
- }
- else
- {
- NVIC_SystemLPConfig(NVIC_LP_SEVONPEND, DISABLE);
- __WFI();
- }
- pass++;
- }
- }
- void collect_telemetry_data (void)
- {
- send_count++;
- si4032_temperature = radio_read_temperature();
- voltage = ADCVal[0] * 600 / 4096;
- ublox_get_last_data(&gpsData);
- if (gpsData.fix >= 3)
- {
- flaga |= 0x80;
- if ((gpsData.alt_raw/1000) > 1000) /* Disable LEDs if altitude is > 1000m */
- led_enabled = 0; /* not living in Armidale again anyway.. */
- else
- led_enabled = 1;
- }
- else
- {
- flaga &= ~0x80; // No GPS fix.
- led_enabled = 1; // Enable LEDs when there is no GPS fix (i.e. during startup)
- gpsData.lat_raw = 0; // Null out lat / lon data to avoid spamming invalid positions
- gpsData.lon_raw = 0;
- }
- }
- void send_rtty_packet (void)
- {
- uint8_t lat_d = (uint8_t) abs(gpsData.lat_raw / 10000000);
- uint32_t lat_fl = (uint32_t) abs(abs(gpsData.lat_raw) - lat_d * 10000000) / 1000;
- uint8_t lon_d = (uint8_t) abs(gpsData.lon_raw / 10000000);
- uint32_t lon_fl = (uint32_t) abs(abs(gpsData.lon_raw) - lon_d * 10000000) / 1000;
- uint8_t speed_kph = (uint8_t)((float)gpsData.speed_raw*0.0036);
- sprintf(buf_rtty, "$$$$%s,%d,%02u:%02u:%02u,%s%d.%05ld,%s%d.%05ld,%ld,%d,%d,%d,%d",
- callsign, send_count, gpsData.hours, gpsData.minutes, gpsData.seconds,
- gpsData.lat_raw < 0 ? "-" : "", lat_d, lat_fl, gpsData.lon_raw < 0 ? "-" : "", lon_d, lon_fl,
- (gpsData.alt_raw / 1000), speed_kph, gpsData.sats_raw, voltage*10, si4032_temperature );
- CRC_rtty = string_CRC16_checksum(buf_rtty + 9); /* sensitive to the $$$$ stuff */
- sprintf(buf_rtty, "%s*%04X\n\n", buf_rtty, CRC_rtty & 0xffff);
- // if on the non-satellite frequency indicate what's being tx'd too
- // I hate the temporary RAM usage here.. :|
- if (tx_freq == TRANSMIT_FREQUENCY)
- for (int i = 0; i < numsats; i++)
- if ((satstatus[i].elevation > HORIZON)
- || ((satstatus[i].elevation > 0) && ((gpsData.alt_raw/1000) >= FLYING)))
- sprintf (buf_rtty, "%sSAT %s d=%f\n", buf_rtty, satdata[i].name, satstatus[i].dopplerhz);
- //
- tx_buffer = buf_rtty;
- start_bits = RTTY_PRE_START_BITS;
- radio_enable_tx();
- tx_on = 1;
- return;
- }
- void morse_beacon (void)
- {
- /* just testing satellite repeaters atm */
- send_morse ("EEEEE VK2CJB VK2CJB +");
- }
|