diff --git a/QAPRSBase.cpp b/QAPRSBase.cpp index 9bfe331..6463f85 100644 --- a/QAPRSBase.cpp +++ b/QAPRSBase.cpp @@ -43,6 +43,9 @@ */ #include "QAPRSBase.h" +#include "delay.h" +#include "radio.h" +#include "init.h" QAPRSBase * QAPRSGlobalObject; /** @@ -66,7 +69,6 @@ void QAPRSBase::ax25SendHeaderBegin() { this->currentTone = QAPRSMark; //this->currentTone = QAPRSSpace; - for (uint8_t i=0;iax25HeaderFlagFieldCount;i++) { this->ax25SendByte(this->ax25FlagFieldValue); @@ -84,9 +86,9 @@ void QAPRSBase::ax25SendFooter() { * @see: http://www.tapr.org/pub_ax25.html#2.2.8 */ static uint8_t tmp; - tmp = (ax25CRC >> 8) ^ 0xff; + tmp = (uint8_t) ((ax25CRC >> 8) ^ 0xff); - this->ax25SendByte((this->ax25CRC) ^ 0xff); + this->ax25SendByte((uint8_t) ((this->ax25CRC) ^ 0xff)); this->ax25SendByte(tmp); this->ax25SendByte(this->ax25FlagFieldValue); this->disableTranssmision(); @@ -104,11 +106,11 @@ void QAPRSBase::ax25SendByte(uint8_t byte) { // zapisujemy sobie czy nadawany bit nie jest aby flagą - bo ją nadajemy w specjalny sposób - is_flag = byte == this->ax25FlagFieldValue; + is_flag = (uint8_t) (byte == this->ax25FlagFieldValue); for(i=0;i<8;i++){ // nadawanie od najmniejznaczacego bitu - ls_bit = byte & 1; + ls_bit = (uint8_t) (byte & 1); if (is_flag){ bit_stuffing_counter = 0; @@ -152,31 +154,52 @@ void QAPRSBase::ax25CalcCRC(uint8_t ls_bit) { * Przełącz aktualnie generowany ton. @see QAPRSSendingTone */ inline void QAPRSBase::toggleTone() { - this->currentTone = (this->currentTone == QAPRSMark) ? QAPRSSpace : QAPRSMark; + this->currentTone = (this->currentTone == QAPRSSpace) ? QAPRSMark : QAPRSSpace; + + TIM2->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); + + uint16_t used = TIM2->CNT; + this->timer1StartValue = (this->currentTone == QAPRSMark) ? MarkTimerValue : SpaceTimerValue; + + if (used >= this->timer1StartValue){ + this->timerInterruptHandler(); + } else { + TIM2->ARR = this->timer1StartValue - used; + TIM2->CNT = 0; + } + + TIM2->CR1 |= TIM_CR1_CEN; } /** * Inicjalizuj Timer1 który jest używany do generowania MARK i SPACE */ void QAPRSBase::initializeTimer1() { - //TODO: przepisać na STM32 -// noInterrupts(); -// TIMSK1 |= _BV(TOIE1); -// TCCR1A = 0; -// TCCR1C = 0; -// interrupts(); + #if defined(__arm__) + //TODO: przepisać na STM32 + #else + noInterrupts(); + TIMSK1 |= _BV(TOIE1); + TCCR1A = 0; + TCCR1C = 0; + interrupts(); + #endif + } /** * Inicjalizuj radio i piny. */ void QAPRSBase::initializeRadio() { - //TODO: przepisać na STM32 -// if (this->sensePin){ -// pinMode(abs(this->sensePin), INPUT); -// digitalWrite(abs(this->sensePin), LOW); -// } -// pinMode(abs(this->txEnablePin), OUTPUT); + #if defined(__arm__) + //TODO: przepisać na STM32 + #else + if (this->sensePin){ + pinMode(abs(this->sensePin), INPUT); + digitalWrite(abs(this->sensePin), LOW); + } + pinMode(abs(this->txEnablePin), OUTPUT); + #endif this->disableTranssmision(); this->initializeTimer1(); @@ -186,8 +209,17 @@ void QAPRSBase::initializeRadio() { * Włącz nadawanie. Metoda dodatkowo realizuje opóźnienie nadawania jesli ustawiono. @see QAPRSBase::setTxDelay */ void QAPRSBase::enableTransmission() { - //TODO: przepisać na STM32 - //digitalWrite(abs(this->txEnablePin), (this->txEnablePin > 0) ? HIGH : LOW); + #if defined(__arm__) + //TODO: przepisać na STM32 + #else + digitalWrite(abs(this->txEnablePin), (this->txEnablePin > 0) ? HIGH : LOW); + #endif + + radio_set_tx_frequency(APRS_FREQUENCY); + GPIO_SetBits(GPIOC, radioNSELpin); + radio_rw_register(0x71, 0b00010010, 1); + spi_deinit(); + this->enabled = 1; this->doTxDelay(); } @@ -195,8 +227,15 @@ void QAPRSBase::enableTransmission() { * Wyłącz nadawanie. */ void QAPRSBase::disableTranssmision() { - //TODO: przepisać na STM32 - //digitalWrite(abs(this->txEnablePin), (this->txEnablePin > 0) ? LOW : HIGH); + #if defined(__arm__) + //TODO: przepisać na STM32 + #else + digitalWrite(abs(this->txEnablePin), (this->txEnablePin > 0) ? LOW : HIGH); + #endif + spi_init(); + this->enabled = 0; + radio_set_tx_frequency(RTTY_FREQUENCY); + radio_rw_register(0x71, 0x00, 1); } /** @@ -225,7 +264,7 @@ QAPRSReturnCode QAPRSBase::send(char * from_addr, uint8_t from_ssid, char * to_a memset(bf->to, ' ', 6); strncpy(bf->to, to_addr, 6); bf->to_ssid = to_ssid; - bf->from_ssid = from_ssid > '@' ? from_ssid - 6 : from_ssid;; + bf->from_ssid = (uint8_t) (from_ssid > '@' ? from_ssid - 6 : from_ssid);; strcpy(bf->packet_content, packet_content); @@ -256,7 +295,7 @@ QAPRSReturnCode QAPRSBase::send(char* buffer, size_t length) { if (this->canTransmit()){ this->ax25SendHeaderBegin(); while(length--){ - this->ax25SendByte(*buffer); + this->ax25SendByte((uint8_t) *buffer); buffer++; } this->ax25SendFooter(); @@ -264,8 +303,11 @@ QAPRSReturnCode QAPRSBase::send(char* buffer, size_t length) { } else { // jesli nie mozna to czekamy 100ms i sprawdzamy ponownie // maks. czas oczekiwania to channelFreeWaitingMS - //TODO: przepisać na STM32 - //delay(100); + #if defined(__arm__) + _delay_ms(100); + #else + delay(100); + #endif timeout -= 100; } } @@ -305,9 +347,9 @@ QAPRSReturnCode QAPRSBase::send(char* from_addr, uint8_t from_ssid, char* to_add memset(bf->to, ' ', 6); strncpy(bf->to, to_addr, 6); bf->to_ssid = to_ssid; - bf->from_ssid = from_ssid > '@' ? from_ssid - 6 : from_ssid; + bf->from_ssid = (uint8_t) (from_ssid > '@' ? from_ssid - 6 : from_ssid); - uint8_t relay_size = strlen(relays); + uint8_t relay_size = (uint8_t) strlen(relays); strcpy((char*)(tmpData+sizeof(ax25CustomFrameHeader)), relays); uint8_t i; @@ -359,6 +401,7 @@ void QAPRSBase::init(int8_t sensePin, int8_t txEnablePin) { this->txEnablePin = txEnablePin; this->txDelay = this->defaultTxDelay; this->setVariant(); + this->timer1StartValue = MarkTimerValue; this->initializeRadio(); } @@ -409,7 +452,7 @@ void QAPRSBase::setToAddress(char* to_addr, uint8_t to_ssid) { * @param dst */ void QAPRSBase::parseRelays(const char* relays, char* dst) { - uint8_t relays_len = strlen(relays); + uint8_t relays_len = (uint8_t) strlen(relays); uint8_t relays_ptr = 0; uint8_t dst_ptr = 0; uint8_t fill_length = 0; @@ -422,11 +465,11 @@ void QAPRSBase::parseRelays(const char* relays, char* dst) { } // koniec elementu if (dst_ptr < 7){ - fill_length = 7 - dst_ptr; + fill_length = (uint8_t) (7 - dst_ptr); } else if (dst_ptr > 7 && dst_ptr < 7+7){ - fill_length = 7+7 - dst_ptr; + fill_length = (uint8_t) (7 + 7 - dst_ptr); } else if(dst_ptr > 7+7 && dst_ptr < 7+7+7){ - fill_length = 7+7+7 - dst_ptr; + fill_length = (uint8_t) (7 + 7 + 7 - dst_ptr); } while(fill_length){ dst[dst_ptr] = ' '; @@ -446,8 +489,11 @@ void QAPRSBase::parseRelays(const char* relays, char* dst) { */ void QAPRSBase::doTxDelay() { if (this->txDelay){ - //TODO: przepisać na STM32 - //delay(this->txDelay); + #if defined(__arm__) + _delay_ms(this->txDelay); + #else + delay(this->txDelay); + #endif } } @@ -479,11 +525,14 @@ void QAPRSBase::setRelays(char* relays) { * @param us */ void QAPRSBase::delayuSeconds(uint16_t us) { - //TODO: przepisać na STM32 - //unsigned long time = micros(); -// while(micros() - time < us){ -// //asm("nop"); -// } + #if defined(__arm__) + _delay_us(us, 1); + #else + unsigned long time = micros(); + while(micros() - time < us){ + //asm("nop"); + } + #endif } @@ -495,14 +544,31 @@ void QAPRSBase::setTxDelay(uint16_t txDelay) { this->txDelay = txDelay; } +void QAPRSBase::timerInterruptHandler() { + this->togglePin(); + TIM2->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); + + TIM2->ARR = this->timer1StartValue; + TIM2->CNT = 0; + + TIM2->CR1 |= TIM_CR1_CEN; +} + +void QAPRSBase::togglePin() { + if (this->pin){ + this->pin = 0; + GPIO_ResetBits(GPIOB, radioSDIpin); + } else { + this->pin = 1; + GPIO_SetBits(GPIOB, radioSDIpin); + } +} + +#if defined(__arm__) //TODO: przepisać na STM32 -//ISR (TIMER1_OVF_vect) // timer1 overflow interrupt -//{ -// QAPRSGlobalObject->timerInterruptHandler(); -//} - - - - - - +#else +ISR (TIMER1_OVF_vect) // timer1 overflow interrupt +{ + QAPRSGlobalObject->timerInterruptHandler(); +} +#endif diff --git a/QAPRSBase.h b/QAPRSBase.h index db8c5f2..eaaaa9a 100644 --- a/QAPRSBase.h +++ b/QAPRSBase.h @@ -58,7 +58,7 @@ private: /** * @brief ilosć bajtów synchronizacyjnych do nadania przed zawartoscią pakietu */ - static const uint8_t ax25HeaderFlagFieldCount1200 = 65; + static const uint8_t ax25HeaderFlagFieldCount1200 = 45; /** * @brief ilosć bajtów synchronizacyjnych do nadania przed zawartoscią pakietu */ @@ -73,8 +73,8 @@ private: */ static const uint8_t ax25FlagFieldValue = 0x7E; /** - * @brief Czas wysyłania podedynczego tonu. W ms. - * @details Czas calkowity powinien wynosic 833ms. Wartosć podana tutaj uwzględnia zwłokę związaną z wywoływaniem + * @brief Czas wysyłania podedynczego tonu. W us. + * @details Czas calkowity powinien wynosic 833us. Wartosć podana tutaj uwzględnia zwłokę związaną z wywoływaniem * funkcji itp. */ #if F_CPU == 16000000L @@ -82,7 +82,7 @@ private: #elif F_CPU == 8000000UL static const uint16_t toneSendTime1200 = 785; #else - static const uint16_t toneSendTime1200 = 815; + static const uint16_t toneSendTime1200 = 766; #endif /** * @brief Czas wysyłania podedynczego tonu. W ms. @@ -98,7 +98,7 @@ private: /** * @brief Domylslny czas pomiędzy włączeniem nadawania a rozpoczęciem generowania AFSK */ - static const uint16_t defaultTxDelay = 300; // 300 ms + static const uint16_t defaultTxDelay = 50; // 300 ms /** * @brief Pin Arduino na którym ustawiamy logiczną 1 w momencie nadawania */ @@ -132,7 +132,7 @@ private: */ char* relays[3*7]; - virtual uint8_t canTransmit(); + uint8_t canTransmit(); void ax25SendHeaderBegin(); void ax25SendByte(uint8_t byte); void ax25SendFooter(); @@ -147,18 +147,17 @@ protected: * @brief Obecnie generowany ton */ QAPRSSendingTone currentTone; - uint16_t _toneSendTime; /** * @brief Obecnie używany wariant */ QAPRSVariant variant; - virtual void initializeRadio(); - virtual void enableTransmission(); - virtual void disableTranssmision(); + void initializeRadio(); + void enableTransmission(); + void disableTranssmision(); - virtual void toggleTone(); - virtual void initializeTimer1(); + void toggleTone(); + void initializeTimer1(); void delayuSeconds(uint16_t us); void doTxDelay(); public: @@ -171,15 +170,26 @@ public: QAPRSReturnCode sendData(char * buffer); QAPRSReturnCode sendData(char * buffer, size_t length); - virtual void init(int8_t sensePin, int8_t txEnablePin); - virtual void init(int8_t sensePin, int8_t txEnablePin, char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * relays); + void init(int8_t sensePin, int8_t txEnablePin); + void init(int8_t sensePin, int8_t txEnablePin, char * from_addr, uint8_t from_ssid, char * to_addr, uint8_t to_ssid, char * relays); void setTxDelay(uint16_t txDelay); - virtual void timerInterruptHandler() {}; + void timerInterruptHandler(); void setFromAddress(char * from_addr, uint8_t from_ssid); void setToAddress(char * to_addr, uint8_t to_ssid); void setRelays(char * relays); - virtual void setVariant(QAPRSVariant variant = QAPRSVHF); + void setVariant(QAPRSVariant variant = QAPRSVHF); + +private: + static const uint16_t toneSendTime = 833; + static const uint16_t MarkTimerValue = (uint16_t) ((1000000 / ((1338)*2)) - 1); + static const uint16_t SpaceTimerValue = (uint16_t) ((1000000 / ((-20+2670)*2)) - 1); + void togglePin(); + uint8_t pin; +public: + uint8_t enabled; + uint16_t timer1StartValue; + uint16_t _toneSendTime; }; /** diff --git a/aprs.cpp b/aprs.cpp new file mode 100644 index 0000000..2e54958 --- /dev/null +++ b/aprs.cpp @@ -0,0 +1,51 @@ +// +// Created by Admin on 2017-01-09. +// + +#include "aprs.h" +#include "QAPRSBase.h" +#include "stdio.h" + + +QAPRSBase qaprs; + +void aprs_init(){ + qaprs.init(0, 0, (char *) "SQ5RWU", '0', (char *) "APZQAP", '0', (char *) "WIDE1-1"); +} + +void aprs_timer_handler() { + qaprs.timerInterruptHandler(); +} + +uint8_t aprs_is_active() { + return qaprs.enabled; +} +void aprs_test(uint16_t x) { + char packet_buffer[128]; + sprintf(packet_buffer, ":T %d", x); + qaprs.sendData(packet_buffer); +} + +void aprs_change_tone_time(uint16_t x) { + qaprs._toneSendTime = x; +} + +void t(){ +// // nadanie paketu typu komentarz +// packet_buffer = ":TEST TEST TEST de SQ5RWU"; +// // zmiana adresu źródłowego i ssida +// QAPRS.setFromAddress("SQ5R", '1'); +// QAPRS.sendData(packet_buffer); +// // nadanie pakietu z pozycja i symbolem wahadlowca +// packet_buffer = "!5215.68N/02057.48ES#"; +// // zmiana adresu źródłowego, ssida i ścieżki +// QAPRS.setFromAddress("SQ5RWU", '2'); +// QAPRS.setRelays("WIDE2-2"); +// QAPRS.sendData(packet_buffer); +// // nadanie danych pogodowych bez pozycji +// packet_buffer = "_07071805c025s009g008t030r000p000P000h00b10218"; +// // zmiana ścieżki +// QAPRS.setRelays("WIDE1-1"); +// QAPRS.sendData(packet_buffer); +// delay(5000); +} \ No newline at end of file diff --git a/aprs.h b/aprs.h new file mode 100644 index 0000000..60b18ba --- /dev/null +++ b/aprs.h @@ -0,0 +1,20 @@ +// +// Created by Admin on 2017-01-09. +// + +#ifndef STM32_RTTY_APRS_H +#define STM32_RTTY_APRS_H + +#ifdef __cplusplus +#include +extern "C" { +#endif + void aprs_init(); + void aprs_timer_handler(); + uint8_t aprs_is_active(); + void aprs_test(uint16_t x); + void aprs_change_tone_time(uint16_t x); +#ifdef __cplusplus +}; +#endif +#endif //STM32_RTTY_APRS_H diff --git a/config.h b/config.h index db92297..bb8737a 100644 --- a/config.h +++ b/config.h @@ -8,6 +8,7 @@ #define CALLSIGN "NO1LIC-1" // put your callsign here //*************frequency******************** #define RTTY_FREQUENCY 434.150f //Mhz middle frequency +#define APRS_FREQUENCY 432.500f //Mhz middle frequency //************rtty speed****************** si4032 #define RTTY_SPEED 300 //************rtty bits****************** si4032 @@ -15,7 +16,7 @@ //************rtty stop bits****************** si4032 #define RTTY_USE_2_STOP_BITS 0 //********* power definition************************** -#define Smoc 7 // PWR 0...7 0- MIN ... 7 - MAX +#define Smoc 1 // PWR 0...7 0- MIN ... 7 - MAX //*************************************************** //********** frame delay in msec********** diff --git a/delay.c b/delay.c index 875440f..c01ec82 100644 --- a/delay.c +++ b/delay.c @@ -1,48 +1,25 @@ -/* -* -* Copyright (C) Patryk Jaworski -* -* This program 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 -* (at your option) any later version. -* -* This program 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 this program. If not, see . -* -*/ - #include +#include +#include +#include #include "delay.h" -static inline void systick_stop() { - SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk); -} - -static inline void systick_start() { - SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; -} - - void delay_init() { - SysTick->CTRL &= ~(SysTick_CTRL_CLKSOURCE_Msk); // AHB / 8 = 10.5MHz - SysTick->LOAD = 1; // Tick every 1.047us + SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); } -void _delay_us(uint32_t us) { - systick_start(); - while (us != 0) { - while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) {} - --us; - } - systick_stop(); +void _delay_us(uint32_t us, uint8_t precise) { + SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk); + SysTick->VAL = us * 6; + SysTick->LOAD = us * 6; + SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk); + while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0) {} } inline void _delay_ms(uint32_t ms) { - _delay_us(ms * 1000); + while(ms-- > 0){ + _delay_us(1000, 0); + } } + + diff --git a/delay.h b/delay.h index 7e99ae5..ae245bd 100644 --- a/delay.h +++ b/delay.h @@ -1,29 +1,17 @@ -/* -* -* Copyright (C) Patryk Jaworski -* -* This program 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 -* (at your option) any later version. -* -* This program 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 this program. If not, see . -* -*/ - #ifndef __DELAY_H_ #define __DELAY_H_ +#ifdef __cplusplus +extern "C" { +#endif /** Initialize delay core - configure SysTick timer */ void delay_init(); -void _delay_us(uint32_t us); +void _delay_us(uint32_t us, uint8_t precise); + void _delay_ms(uint32_t ms); +#ifdef __cplusplus +} +#endif #endif diff --git a/docs/stm32f100c8t6b_en.CD00251732.pdf b/docs/stm32f100c8t6b_en.CD00251732.pdf new file mode 100644 index 0000000..6995fc6 Binary files /dev/null and b/docs/stm32f100c8t6b_en.CD00251732.pdf differ diff --git a/init.c b/init.c index 65e1a43..93f47b5 100644 --- a/init.c +++ b/init.c @@ -9,6 +9,8 @@ #include #include #include "init.h" +#include "radio.h" + SPI_InitTypeDef SPI_InitStructure; USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_Conf; @@ -17,7 +19,9 @@ DMA_InitTypeDef DMA_InitStructure; #define ADC1_DR_Address ((uint32_t)0x4001244C) - +#if defined(STM32F10X_CL) +#error "Bedzie problem z kwarcem!" +#endif void init_usart_gps(const uint32_t speed, const uint8_t enable_irq) { NVIC_DisableIRQ(USART1_IRQn); USART_ITConfig(USART1, USART_IT_RXNE, DISABLE); @@ -76,10 +80,10 @@ void RCC_Conf() { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); FLASH_SetLatency(FLASH_Latency_2); - RCC_HCLKConfig(RCC_SYSCLK_Div4); - RCC_PCLK2Config(RCC_HCLK_Div4); - RCC_PCLK1Config(RCC_HCLK_Div2); - RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); + RCC_HCLKConfig(RCC_SYSCLK_Div4); // 25 / 4 -> 6.25 + RCC_PCLK2Config(RCC_HCLK_Div4); // 6.25 / 4 + RCC_PCLK1Config(RCC_HCLK_Div2); // 6.25 / 2 + RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); // 25 while(RCC_GetSYSCLKSource() != 0x04); } } @@ -97,33 +101,28 @@ void init_port() GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOB, &GPIO_Conf); - GPIO_Conf.GPIO_Pin = GPIO_Pin_13 |GPIO_Pin_15; + // SPI2_SCK & SPI2_MOSI + GPIO_Conf.GPIO_Pin = GPIO_Pin_13 | radioSDIpin; GPIO_Conf.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOB, &GPIO_Conf); + + // SPI2_MISO GPIO_Conf.GPIO_Pin = GPIO_Pin_14; GPIO_Conf.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOB, &GPIO_Conf); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); - GPIO_Conf.GPIO_Pin = GPIO_Pin_13; + + // radioNSELpin + GPIO_Conf.GPIO_Pin = radioNSELpin; GPIO_Conf.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOC,&GPIO_Conf); - RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); - SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; - SPI_InitStructure.SPI_Mode = SPI_Mode_Master; - SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; - SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; - SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; - SPI_InitStructure.SPI_CRCPolynomial = 7; - SPI_Init(SPI2, &SPI_InitStructure); - SPI_SSOutputCmd(SPI2, ENABLE); - SPI_Cmd(SPI2, ENABLE); - SPI_InitStructure.SPI_Mode = SPI_Mode_Master; - SPI_Init(SPI2, &SPI_InitStructure); - GPIO_Conf.GPIO_Pin = GPIO_Pin_9; + + spi_init(); + + GPIO_Conf.GPIO_Pin = GPIO_Pin_9; GPIO_Conf.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; GPIO_Init(GPIOA, &GPIO_Conf); @@ -185,14 +184,45 @@ void init_port() ADC_SoftwareStartConvCmd(ADC1, ENABLE); // start conversion (will be endless as we are in continuous mode) } +void spi_init() { + GPIO_Conf.GPIO_Pin = radioSDIpin; + GPIO_Conf.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; + GPIO_Init(GPIOB, &GPIO_Conf); + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + SPI_Init(SPI2, &SPI_InitStructure); + SPI_SSOutputCmd(SPI2, ENABLE); + SPI_Cmd(SPI2, ENABLE); + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_Init(SPI2, &SPI_InitStructure); +} + +void spi_deinit() { + SPI_I2S_DeInit(SPI2); + GPIO_Conf.GPIO_Pin = radioSDIpin; + GPIO_Conf.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Conf.GPIO_Speed = GPIO_Speed_10MHz; + GPIO_Init(GPIOB, &GPIO_Conf); + +} + void init_timer(const int rtty_speed) { TIM_TimeBaseInitTypeDef TIM2_TimeBaseInitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM2,DISABLE); - TIM2_TimeBaseInitStruct.TIM_Prescaler = 600; + TIM2_TimeBaseInitStruct.TIM_Prescaler = 6/*0*/ - 1;// tick every 1/100000 s TIM2_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; - TIM2_TimeBaseInitStruct.TIM_Period = (uint16_t) ((10000 / rtty_speed) - 1); + TIM2_TimeBaseInitStruct.TIM_Period = (uint16_t) ((1000000 / rtty_speed) - 1); TIM2_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM2_TimeBaseInitStruct.TIM_RepetitionCounter = 0; diff --git a/init.h b/init.h index 4256468..f2d6bc0 100644 --- a/init.h +++ b/init.h @@ -1,6 +1,21 @@ __IO uint16_t ADCVal[2]; +#ifdef __cplusplus +extern "C" { +#endif + void NVIC_Conf(); + void RCC_Conf(); + void init_port(); + void init_timer(const int rtty_speed); + void init_usart_gps(const uint32_t speed, const uint8_t enable_irq); + +void spi_init(); + +void spi_deinit(); +#ifdef __cplusplus +} +#endif diff --git a/main.c b/main.c index f668c43..cbac849 100644 --- a/main.c +++ b/main.c @@ -20,7 +20,7 @@ #include "radio.h" #include "ublox.h" #include "delay.h" - +#include "aprs.h" ///////////////////////////// test mode ///////////// const unsigned char test = 0; // 0 - normal, 1 - short frame only cunter, height, flag char callsign[15] = {CALLSIGN}; @@ -49,8 +49,6 @@ volatile char *rtty_buf; unsigned char cun_off = 0; -void processGPS(); - /** * GPS data processing */ @@ -60,7 +58,7 @@ void USART1_IRQHandler(void) { }else if (USART_GetITStatus(USART1, USART_IT_ORE) != RESET) { USART_ReceiveData(USART1); } else { - USART_ReceiveData(USART1); + USART_ReceiveData(USART1); } } @@ -68,40 +66,45 @@ void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } - if (tx_on /*&& ++cun_rtty == 17*/) { - send_rtty_status = send_rtty((char *) rtty_buf); - if (send_rtty_status == rttyEnd) { - GPIO_SetBits(GPIOB, RED); - if (*(++rtty_buf) == 0) { - tx_on = 0; - tx_on_delay = tx_delay / (1000/RTTY_SPEED);//2500; - tx_enable = 0; - radio_disable_tx(); + if (aprs_is_active()){ + aprs_timer_handler(); + } else { + if (tx_on /*&& ++cun_rtty == 17*/) { + send_rtty_status = send_rtty((char *) rtty_buf); + if (send_rtty_status == rttyEnd) { + GPIO_SetBits(GPIOB, RED); + if (*(++rtty_buf) == 0) { + tx_on = 0; + tx_on_delay = tx_delay / (1000/RTTY_SPEED);//2500; + tx_enable = 0; + radio_disable_tx(); + } + } else if (send_rtty_status == rttyOne) { + radio_rw_register(0x73, 0x02, 1); + GPIO_SetBits(GPIOB, RED); + } else if (send_rtty_status == rttyZero) { + radio_rw_register(0x73, 0x00, 1); + GPIO_ResetBits(GPIOB, RED); } - } else if (send_rtty_status == rttyOne) { - radio_rw_register(0x73, 0x02, 1); - GPIO_SetBits(GPIOB, RED); - } else if (send_rtty_status == rttyZero) { - radio_rw_register(0x73, 0x00, 1); - GPIO_ResetBits(GPIOB, RED); + } + if (!tx_on && --tx_on_delay == 0) { + tx_enable = 1; + tx_on_delay--; + } + if (--cun == 0) { + if (pun) { + GPIO_ResetBits(GPIOB, GREEN); + pun = 0; + } else { + if (flaga & 0x80) { + GPIO_SetBits(GPIOB, GREEN); + } + pun = 1; + } + cun = 200; } } - if (!tx_on && --tx_on_delay == 0) { - tx_enable = 1; - tx_on_delay--; - } - if (--cun == 0) { - if (pun) { - GPIO_ResetBits(GPIOB, GREEN); - pun = 0; - } else { - if (flaga & 0x80) { - GPIO_SetBits(GPIOB, GREEN); - } - pun = 1; - } - cun = 200; - } + } int main(void) { @@ -114,7 +117,6 @@ int main(void) { init_timer(RTTY_SPEED); delay_init(); - ublox_init(); int8_t temperatura; @@ -147,7 +149,20 @@ int main(void) { tx_enable = 1; //tx_enable =0; //Button = ADCVal[1]; + aprs_init(); radio_enable_tx(); + uint16_t x = 760; + while (1){ + radio_enable_tx(); + USART_Cmd(USART1, DISABLE); + x+=1; + //aprs_change_tone_time(x); + aprs_test(x); + USART_Cmd(USART1, ENABLE); + + radio_disable_tx(); + _delay_ms(1000); + } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-noreturn" diff --git a/radio.c b/radio.c index c0b1456..88ed1c2 100644 --- a/radio.c +++ b/radio.c @@ -27,7 +27,7 @@ void radio_set_tx_frequency(const float freq_in_mhz) { uint8_t gen_div = 3; //Stała nie zmieniac uint16_t fc = (uint16_t) (((freq_in_mhz / ((SI4032_CLOCK / gen_div) * (hbsel + 1))) - fb - 24) * 64000); - radio_rw_register(0x72, 0, 1); + radio_rw_register(0x72, 10, 1); radio_rw_register(0x75, (uint8_t) (0b01000000 | (fb & 0b11111) | ((hbsel & 0b1) << 5)), 1); radio_rw_register(0x76, (uint8_t) (((uint16_t)fc >> 8) & 0xff), 1); diff --git a/radio.h b/radio.h index 54749e2..b89a3a0 100644 --- a/radio.h +++ b/radio.h @@ -10,17 +10,31 @@ #include #include -static const uint16_t radioNSELpin = GPIO_Pin_13; +static const uint16_t radioNSELpin = GPIO_Pin_13; // @ GPIOC +static const uint16_t radioSDIpin = GPIO_Pin_15; // @ GPIOB! static const uint8_t WR = 0x80; static const float SI4032_CLOCK = 26.0; +#ifdef __cplusplus +extern "C" { +#endif uint8_t _spi_sendrecv(const uint16_t data_word); + uint8_t radio_rw_register(const uint8_t register_addr, uint8_t value, uint8_t write); + void radio_set_tx_frequency(const float radio_set_tx_frequency); + void radio_disable_tx(); + void radio_soft_reset(); + void radio_enable_tx(); + int8_t radio_read_temperature(); +#ifdef __cplusplus +} +#endif + #endif //STM32_RTTY_RADIO_H