kopia lustrzana https://github.com/SP8EBC/ParaTNC
Code cleanup and some more documentation
rodzic
fddf182b6d
commit
7739296831
Plik diff jest za duży
Load Diff
|
@ -2,7 +2,6 @@ ParaTNC wersja 1.0-19082017
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. WSTĘP
|
||||
|
||||
ParaTNC jest oprogramowaniem wbudowanym (firmware) przeznaczonym do pracy na płytce STM32VLDISCOVERY w charakterze
|
||||
uniwersalnego radiomodemu/sterownika sieci APRS, wyposażonego w szereg funkcjonalności takich jak:
|
||||
|
||||
|
@ -19,7 +18,7 @@ do wykonania odpowienich kabli połączeniowch. stosowna instrukcja z pinoutami
|
|||
|
||||
|
||||
2. LICENCJA
|
||||
Warunki licencjonowania są zawarte w pliku LICENSE.
|
||||
Warunki licencjonowania są zawarte w pliku LICENSE.
|
||||
|
||||
|
||||
|
||||
|
@ -37,6 +36,10 @@ Włączenie funkcjonalności stacji pogodowej (przez odkomentowanie _METEO) auto
|
|||
zakomentowane jest #define _DIGI w pliku konfiguracyjnym. Komunikacja z komputerem odbywa się na prędkości 9600bps, a sam
|
||||
protokół KISS działa od samego początku pracy urządzenia i nie musi być w żaden sposób inicjalizowany ze strony PC.
|
||||
|
||||
Sterownik wysyła co 10 minut ramkę telemetryczną zawierającą informację o ilości odebranych, nadanych i powtórzonych
|
||||
pakietów APRS przez okres minionych 10 minut. Ilość nadanych ramek jest sumą powtórzonych ramek i ramek własnych
|
||||
wliczając w to ramki telemetrii. Co ok 75 minut nadawane są pełne opisy kanałów.
|
||||
|
||||
|
||||
|
||||
4. KOMPILACJA
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
Supply voltage can be applied either by miniUSB connector or +5V pin in right header. Use both metods are not allowed and
|
||||
can lead even to burning controler and/or power supply.
|
||||
|
||||
PC3 - PTT (default Open Drain)
|
||||
PA4 - DAC Output - signal from controller to radio
|
||||
PC1 - ADC input - signal from radio to controller. Schould be connected via 100nF in series capacitor and 10k-10k voltage
|
||||
divider to apply 1.65V (half od 3.3V) bias on ADC input
|
||||
|
||||
|
|
@ -10,13 +10,7 @@
|
|||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/*********************************************************************************************************************/
|
||||
void DMA1_Channel1_IRQHandler(void);
|
||||
/*********************************************************************************************************************/
|
||||
|
||||
/*********************************************************************************************************************/
|
||||
void AD_SetTimer(uint16_t period, uint16_t prescaler);
|
||||
/*********************************************************************************************************************/
|
||||
/*******************************************************************************************************/
|
||||
|
||||
/*********************************************************************************************************************/
|
||||
void AD_Init(Afsk *af);
|
||||
|
|
|
@ -14,205 +14,7 @@ volatile uint16_t ADCValue[16];
|
|||
uint16_t max_value;
|
||||
uint32_t samplecount;
|
||||
|
||||
/*********************************************************************************************************************/
|
||||
void DMA1_Channel1_IRQHandler(void) {
|
||||
/*********************************************************************************************************************/
|
||||
uint16_t sample;
|
||||
//DMA_ClearITPendingBit(DMA_IT_TC);
|
||||
DMA1->IFCR = DMA_IFCR_CTCIF1;
|
||||
|
||||
/*
|
||||
uint16_t sample = ( ADCValue[0] + ADCValue[1] + ADCValue[2] + ADCValue[3] +
|
||||
ADCValue[4] + ADCValue[5] + ADCValue[6] + ADCValue[7] +
|
||||
ADCValue[8] + ADCValue[9] + ADCValue[10] + ADCValue[11] +
|
||||
ADCValue[12] + ADCValue[13] + ADCValue[14] + ADCValue[15]
|
||||
) >> 2;
|
||||
*/
|
||||
|
||||
|
||||
sample = (( ADCValue[0] + ADCValue[1] + ADCValue[2] + ADCValue[3]) >> 1);
|
||||
|
||||
/*
|
||||
samplecount++;
|
||||
if (samplecount > 30000)
|
||||
{
|
||||
//printf("Max Value = %d \r\n", max_value);
|
||||
samplecount = 0;
|
||||
max_value = 0;
|
||||
|
||||
}
|
||||
|
||||
if (abs(sample - 4095) > max_value) max_value = abs(sample - 4095);
|
||||
*/
|
||||
|
||||
//Wyslanie probki do demodulatora
|
||||
//AFSK_ADC_ISR(adc_afsk, (int16_t)(sample - 8191));
|
||||
|
||||
AFSK_ADC_ISR(adc_afsk, (int16_t)(sample - 4095));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************************************/
|
||||
void AD_SetTimer(uint16_t period, uint16_t prescaler) {
|
||||
/*********************************************************************************************************************/
|
||||
|
||||
// TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
|
||||
//wlacznie sygnalu zegarowego Timer3
|
||||
RCC->APB1ENR |= RCC_APB1Periph_TIM3;
|
||||
|
||||
//DeInit Timer3
|
||||
RCC->APB1RSTR |= RCC_APB1Periph_TIM3;
|
||||
RCC->APB1RSTR &= ~RCC_APB1Periph_TIM3;
|
||||
|
||||
|
||||
/*
|
||||
TIM_TimeBaseStructure.TIM_Period = period - 1;
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = prescaler - 1;
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0 ;
|
||||
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
|
||||
|
||||
TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);
|
||||
*/
|
||||
|
||||
/*
|
||||
* TIMER3
|
||||
* - Clock Div = 0
|
||||
* - Counter Mode = UP
|
||||
* - Repetition Counter = 0
|
||||
* - Output Trigger = TRGO
|
||||
*/
|
||||
|
||||
TIM3->ARR = period - 1;
|
||||
TIM3->PSC = prescaler - 1;
|
||||
TIM3->RCR = 0;
|
||||
TIM3->CR2 = TIM_CR2_MMS_1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*********************************************************************************************************************/
|
||||
static void AD_Reset() {
|
||||
/*********************************************************************************************************************/
|
||||
|
||||
// ADC_InitTypeDef ADC_InitStructure;
|
||||
// DMA_InitTypeDef DMA_InitStructure;
|
||||
|
||||
|
||||
//Konfiguracja DMA
|
||||
//Umieszcze probki w ADCValue i po zebraniu probek wyzwala przerwanie
|
||||
//Aktualnie 16 probki (oversampling 2 bit)
|
||||
|
||||
/*
|
||||
DMA_DeInit(DMA1_Channel1);
|
||||
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address; //&(ADC1->DR);
|
||||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCValue;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
|
||||
// DMA_InitStructure.DMA_BufferSize = 16;
|
||||
DMA_InitStructure.DMA_BufferSize = 4;
|
||||
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||||
|
||||
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
|
||||
|
||||
// DMA_ClearITPendingBit(DMA_IT_TC);
|
||||
|
||||
// DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
|
||||
|
||||
// DMA_Cmd(DMA1_Channel1, ENABLE);
|
||||
*/
|
||||
|
||||
/*
|
||||
* DMA1 Channel1
|
||||
* - ADC1 -> MEMORY
|
||||
* - Memory Increment
|
||||
* - DMA Buffer Size = 4
|
||||
* - Peripheral Data Size = HalfWord
|
||||
* - Peripheral Data Size = HalfWord
|
||||
* - DMA Mode = Circular
|
||||
* - DMA Priority = High
|
||||
* - DMA M2M Disable
|
||||
* - IFCR = DMA_IT_TC
|
||||
*/
|
||||
|
||||
DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
|
||||
|
||||
DMA1->IFCR = DMA_IFCR_CTCIF1;
|
||||
|
||||
DMA1_Channel1->CNDTR = 4;
|
||||
DMA1_Channel1->CPAR = (uint32_t)ADC1_DR_Address; //&(ADC1->DR);
|
||||
DMA1_Channel1->CMAR = (uint32_t)&ADCValue;
|
||||
DMA1_Channel1->CCR |= DMA_CCR1_EN | DMA_CCR1_CIRC | DMA_CCR1_MINC | DMA_CCR1_PSIZE_0 | DMA_CCR1_MSIZE_0 | DMA_CCR1_PL_1 | DMA_IT_TC;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
//struktura inicjujaca
|
||||
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
|
||||
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
|
||||
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
|
||||
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO;
|
||||
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
|
||||
ADC_InitStructure.ADC_NbrOfChannel = 1;
|
||||
ADC_Init(ADC1, &ADC_InitStructure);
|
||||
|
||||
|
||||
// ADC_ExternalTrigConvCmd(ADC1, ENABLE);
|
||||
|
||||
// ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_1Cycles5) ;
|
||||
|
||||
//Wlasz DMA dla ADC1
|
||||
//ADC_DMACmd(ADC1, ENABLE);
|
||||
|
||||
// ADC1 ENABLE
|
||||
//ADC_Cmd(ADC1, ENABLE);
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//DeInit ADC1
|
||||
RCC->APB2RSTR |= RCC_APB2Periph_ADC1;
|
||||
RCC->APB2RSTR &= ~RCC_APB2Periph_ADC1;
|
||||
|
||||
/*
|
||||
* ADC1
|
||||
* - ADC Mode = Independent
|
||||
* - Scan Mode = DISABLE
|
||||
* - Continuous Mode = DISABLE
|
||||
* - External Trig = T3 TRGO
|
||||
* - NbrOfChannels = 1
|
||||
* - ADC Channel = 0
|
||||
* - ADC Sample Time = 1c5
|
||||
* - DMA = ENABLE
|
||||
*/
|
||||
|
||||
ADC1->CR1 = 0x00;
|
||||
ADC1->CR2 |= ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL_2;
|
||||
ADC1->SQR1 = 0x00;
|
||||
ADC1->SMPR1 = 0x00;
|
||||
|
||||
ADC1->CR2 |= ADC_CR2_ADON | ADC_CR2_DMA ;
|
||||
|
||||
//Kalibracja
|
||||
ADC1->CR2 |= ADC_CR2_RSTCAL;
|
||||
while (ADC1->CR2 & ADC_CR2_RSTCAL);
|
||||
|
||||
ADC1->CR2 |= ADC_CR2_CAL;
|
||||
while (ADC1->CR2 & ADC_CR2_CAL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************************************************/
|
||||
|
|
|
@ -55,124 +55,3 @@ void DACStartConfig(void) {
|
|||
DAC->SWTRIGR |= DAC_SWTRIGR_SWTRIG1;
|
||||
|
||||
}
|
||||
/*
|
||||
int ADCSendViaSerial(unsigned short int adc_val) {
|
||||
int i;
|
||||
char temp[10]; // pomiary
|
||||
char* endl = ";\n\r"; // pomiary
|
||||
adc_val &= 0xFFFF;
|
||||
for (i=0 ; i<10 ; i++)
|
||||
*(temp+i) = 0x00;
|
||||
int2string(adc_val, temp);
|
||||
strcpy(temp+5,endl);
|
||||
FixString(temp,8);
|
||||
SrlSendData(temp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitFilter(void) {
|
||||
int i;
|
||||
for(i=0;i<N;i++) {
|
||||
coeffloi[i]=2047*cos(2*3.1415*i/N);
|
||||
coeffloq[i]=2047*sin(2*3.1415*i/N);
|
||||
coeffhii[i]=2047*cos(2*3.1415*i/N*2200/1200);
|
||||
coeffhiq[i]=2047*sin(2*3.1415*i/N*2200/1200);
|
||||
}
|
||||
}
|
||||
|
||||
int SampleData(short int input) {
|
||||
int16_t i,d;
|
||||
int32_t outloi=0,outloq=0,outhii=0,outhiq=0,out=0;
|
||||
data[ptr]=input; ptr = (ptr+1)%N;
|
||||
for(i=0;i<N;i++) {
|
||||
d = data[(ptr+i)%N];
|
||||
outloi += d*coeffloi[i];
|
||||
outloq += d*coeffloq[i];
|
||||
outhii += d*coeffhii[i];
|
||||
outhiq += d*coeffhiq[i];
|
||||
}
|
||||
out = (outhii>>11)*(outhii>>11)+(outhiq>>11)*(outhiq>>11)
|
||||
-(outloi>>11)*(outloi>>11)-(outloq>>11)*(outloq>>11); // przesow o 11 bitow bo przetwornik ma 12 bitow
|
||||
return (out);
|
||||
}
|
||||
|
||||
int SynchroNRZI(unsigned char bit) {
|
||||
unsigned char temp;
|
||||
niesynchro_bity <<= 1; // przesuwanie zawartosci bitow niezsynchronizowanych zeby zrobic miejsce na nowy
|
||||
niesynchro_bity |= bit; // dodawanie do zmiennej nastepnego zsamplowanego bitu (bodu)
|
||||
if ((niesynchro_bity & 0x03) == 0x01 || (niesynchro_bity & 0x03) == 0x02) {
|
||||
// sprawdza czy nie zmienil sie przesylany bit (zmiana tonu)
|
||||
if (bit_faza <= 32 )
|
||||
// korekcja "fazy" dekodera
|
||||
bit_faza += 1;
|
||||
else
|
||||
bit_faza -= 1;
|
||||
}
|
||||
bit_faza += 8; // zwiekszanie "fazy" o 8 po kazdym niezsynchronizowanym bicie.
|
||||
// Ka<4B>dy z nich jest samplowany osiem razy
|
||||
if (bit_faza >= 64){
|
||||
// jezeli faza przekroczyla 64, czyli przetworzono 8 niezsynchronizowanych bitow.
|
||||
// Ka<4B>dy pojedynczy bit (a w zasadzie bod) jest samplowany 8 razy.
|
||||
bit_faza %= 64; // powracanie z "faz<61>" na poczatek. W przypadku gdy po ostatnim zwiekszeniu licznika
|
||||
// wyszlo powyzej 64 to nalezy wrocic do wartosci rownej (bit_faza - 64) tak aby nie
|
||||
// gubic synchronizacji
|
||||
synchro_bity <<= 1; // przesuwanie zsynchronizowanych do predkosci bodowej bitow o jeden
|
||||
nrzi_bity <<= 1;
|
||||
|
||||
temp = niesynchro_bity & 0x07; // ostatnie trzy samplowane bity
|
||||
if(temp == 0x07 || temp == 0x06 || temp == 0x05 || temp == 0x03)
|
||||
// jezeli z trzech ostatnich niesynchro bitow, dwa maja wartosc jeden
|
||||
// to mozna uznac ze odebrano jedynke
|
||||
synchro_bity |= 1;
|
||||
else; // jezeli nie to zero.
|
||||
// BITY SA KODOWANE PRZY UZYCIU NRZI!!!!!!! Ponizej dekodowanie
|
||||
if ((synchro_bity & 0x03) == 0x03 || (synchro_bity & 0x03) == 0x00)
|
||||
nrzi_bity |= 1; // jezeli dwa kolejne bity sa takie same to jeden
|
||||
else; // jezeli sa rozne to zero
|
||||
// if (nrzi_bity_c != 8)
|
||||
// nrzi_bity_c++; // jezeli nie odebrano jeszcze calego bajtu
|
||||
// else
|
||||
// nrzi_bity_c = 0; // w momencie odebrania calego bajtu zresetuj licznik
|
||||
if (nrzi_bity == 0x7E) {
|
||||
// ADCSendViaSerial(7);
|
||||
DCD = ~DCD;
|
||||
}
|
||||
else;
|
||||
// ADCSendViaSerial(synchro_bity);
|
||||
DeStuffing(nrzi_bity & 0x01);
|
||||
return nrzi_bity; // zwracanie odkodowanych z NRZI bitow
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/// 0x7E flaga naglowka
|
||||
|
||||
int DeStuffing(uint8_t bit) {
|
||||
// funkcja robi destuffing CIAGU BITOW. Przyjmuje wprawdzie 8 bitow ze zmiennej nrzi_bity
|
||||
// czyli niby jeden bajt, ale do kolejnej pozycji lini opozniajacej dolancza tylko ten najmniej znaczacy (najnowszy)
|
||||
if ( DCD > 0 ) {
|
||||
destuff_bity <<= 1;
|
||||
ADCSendViaSerial(destuff_bity);
|
||||
destuff_bity |= bit;
|
||||
if ((destuff_bity & 0x3f) == 0x3e) {
|
||||
destuff_bity >>=1;
|
||||
bit_counter--;
|
||||
}
|
||||
else;
|
||||
bit_counter++;
|
||||
if (bit_counter == 8 && PacketByteCounter < 70) {
|
||||
bit_counter = 0;
|
||||
Frame.RAWContent[PacketByteCounter] = (destuff_bity & 0xFF);
|
||||
PacketByteCounter++;
|
||||
// destuff_bity = 0;
|
||||
}
|
||||
if (PacketByteCounter == 70) {
|
||||
PacketByteCounter = 0;
|
||||
if (DCD == 0xFF)
|
||||
DCD = 0;
|
||||
}
|
||||
else;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
|
|
@ -22,7 +22,6 @@ Afsk *dac_afsk;
|
|||
void DA_Init(void) {
|
||||
/*********************************************************************************************************************/
|
||||
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
|
@ -39,6 +38,13 @@ void DA_Init(void) {
|
|||
GPIOC->BSRR |= GPIO_BSRR_BR3; //// bez sep
|
||||
#endif
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue