00001
00124
00125 #include <18f2525.h>
00126 #device ADC=10
00127
00128
00129
00130 #fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOLVP
00131
00132
00133 #include <stdlib.h>
00134 #include <string.h>
00135
00136
00137
00138
00139 #use delay(clock=19200000)
00140
00141
00142 #use rs232(baud=57600, xmit=PIN_B7, rcv=PIN_B6, STREAM=PC_HOST)
00143
00144
00145 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
00146
00147 #use i2c (master, scl=PIN_C3, sda=PIN_C4)
00148
00149 #use fast_io(A)
00150 #use fast_io(B)
00151 #use fast_io(C)
00152
00153
00154
00155
00156
00158 typedef boolean bool_t;
00159
00161 typedef signed int8 int8_t;
00162
00164 typedef unsigned int8 uint8_t;
00165
00167 typedef signed int16 int16_t;
00168
00170 typedef unsigned int16 uint16_t;
00171
00173 typedef signed int32 int32_t;
00174
00176 typedef unsigned int32 uint32_t;
00177
00178
00179
00180
00181
00182
00184 #define IO_LED PIN_A2
00185
00187 #define IO_PS0 PIN_A3
00188
00190 #define IO_PTT PIN_A4
00191
00193 #define IO_UPDATE PIN_A5
00194
00196 #define IO_CS PIN_B0
00197
00199 #define IO_GPS_PWR PIN_B1
00200
00202 #define IO_PS1 PIN_C0
00203
00205 #define IO_OSK PIN_C2
00206
00208 #define IO_GPS_TXD PIN_C6
00209
00210
00211
00213 enum DDS_MODE
00214 {
00216 DDS_MODE_NOT_INITIALIZED,
00217
00219 DDS_MODE_POWERDOWN,
00220
00222 DDS_MODE_AFSK,
00223
00225 DDS_MODE_FSK
00226 };
00227
00228 void ddsInit();
00229 void ddsSetAmplitude (uint8_t amplitude);
00230 void ddsSetOutputScale (uint16_t amplitude);
00231 void ddsSetFSKFreq (uint32_t ftw0, uint32_t ftw1);
00232 void ddsSetFreq (uint32_t freq);
00233 void ddsSetFTW (uint32_t ftw);
00234 void ddsSetMode (DDS_MODE mode);
00235
00236 void flashErase();
00237 uint8_t flashGetByte ();
00238 void flashReadBlock(uint32_t address, uint8_t *block, uint16_t length);
00239 void flashSendByte(uint8_t value);
00240 void flashSendAddress(uint32_t address);
00241 void flashWriteBlock(uint32_t address, uint8_t *block, uint8_t length);
00242
00244 enum GPS_FIX_TYPE
00245 {
00247 GPS_NO_FIX,
00248
00250 GPS_2D_FIX,
00251
00253 GPS_3D_FIX
00254 };
00255
00257 typedef struct
00258 {
00260 bool_t updateFlag;
00261
00263 uint8_t month;
00264
00266 uint8_t day;
00267
00269 uint8_t hours;
00270
00272 uint8_t minutes;
00273
00275 uint8_t seconds;
00276
00278 uint16_t year;
00279
00281 int32_t latitude;
00282
00284 int32_t longitude;
00285
00287 int32_t altitudeCM;
00288
00290 int32_t altitudeFeet;
00291
00293 uint16_t vSpeed;
00294
00296 uint16_t hSpeed;
00297
00299 uint16_t heading;
00300
00302 uint16_t dop;
00303
00305 uint16_t status;
00306
00308 uint8_t trackedSats;
00309
00311 uint8_t visibleSats;
00312 } GPSPOSITION_STRUCT;
00313
00314 void gpsInit();
00315 bool_t gpsIsReady();
00316 GPS_FIX_TYPE gpsGetFixType();
00317 int32_t gpsGetPeakAltitude();
00318 void gpsPowerOn();
00319 bool_t gpsSetup();
00320 void gpsUpdate();
00321
00322 int16_t lm92GetTemp();
00323
00325 enum LOG_TYPE
00326 {
00328 LOG_BOOTED = 0xb4,
00329
00331 LOG_COORD = 0xa5,
00332
00334 LOG_TEMPERATURE = 0x96,
00335
00337 LOG_VOLTAGE = 0x87
00338 };
00339
00340 void logInit();
00341 uint32_t logGetAddress();
00342 void logType (LOG_TYPE type);
00343 void logUint8 (uint8_t value);
00344 void logInt16 (int16_t value);
00345
00346 bool_t serialHasData();
00347 void serialInit();
00348 uint8_t serialRead();
00349 void serialUpdate();
00350
00351 uint16_t sysCRC16(uint8_t *buffer, uint8_t length, uint16_t crc);
00352 void sysInit();
00353 void sysLogVoltage();
00354
00356 #define TIME_DUTYCYCLE_0 0
00357
00359 #define TIME_DUTYCYCLE_10 1
00360
00362 #define TIME_DUTYCYCLE_70 7
00363
00364 uint8_t timeGetTicks();
00365 void timeInit();
00366 void timeSetDutyCycle (uint8_t dutyCycle);
00367 void timeUpdate();
00368
00370 enum TNC_DATA_MODE
00371 {
00373 TNC_MODE_STANDBY,
00374
00376 TNC_MODE_1200_AFSK,
00377
00379 TNC_MODE_9600_FSK
00380 };
00381
00382 void tncInit();
00383 bool_t tncIsFree();
00384 void tncHighRate(bool_t state);
00385 void tncSetMode (TNC_DATA_MODE dataMode);
00386 void tnc1200TimerTick();
00387 void tnc9600TimerTick();
00388 void tncTxByte (uint8_t value);
00389 void tncTxPacket(TNC_DATA_MODE dataMode);
00390
00399
00400 uint16_t adcMainBusVolt;
00401
00403 #define ADC_REF 0
00404
00406 #define ADC_MAINBUS 1
00407
00409 #define MAIN_BUS_VOLT_OFFSET 20
00410
00414 void adcInit()
00415 {
00416
00417 setup_adc_ports(AN0_TO_AN1);
00418 setup_adc( ADC_CLOCK_DIV_32 );
00419
00420
00421 adcMainBusVolt = 0;
00422 }
00423
00429 uint16_t adcGetMainBusVolt()
00430 {
00431 uint32_t volts;
00432
00433 volts = (uint32_t) (adcMainBusVolt >> 3);
00434
00435 volts = (volts * 330l) / 1023l;
00436
00437 return (uint16_t) volts + MAIN_BUS_VOLT_OFFSET;
00438 }
00439
00445 uint16_t adcRawBusVolt()
00446 {
00447 set_adc_channel(ADC_MAINBUS);
00448 delay_us(50);
00449 return read_adc();
00450 }
00451
00457 uint16_t adcRawRefVolt()
00458 {
00459 set_adc_channel(ADC_REF);
00460 delay_us(50);
00461 return read_adc();
00462 }
00463
00467 void adcUpdate(void)
00468 {
00469
00470 set_adc_channel(ADC_MAINBUS);
00471 delay_us(50);
00472 adcMainBusVolt = read_adc() + adcMainBusVolt - (adcMainBusVolt >> 3);
00473 }
00474
00486
00487 #define DIAG_BYTES_PER_LINE 32
00488
00492 void diagEraseFlash()
00493 {
00494
00495 fprintf (PC_HOST, "Are you sure (yes)? ");
00496
00497 if (fgetc(PC_HOST) != 'y')
00498 return;
00499
00500 if (fgetc(PC_HOST) != 'e')
00501 return;
00502
00503 if (fgetc(PC_HOST) != 's')
00504 return;
00505
00506 if (fgetc(PC_HOST) != 13)
00507 return;
00508
00509
00510 fprintf (PC_HOST, "Erasing flash...");
00511
00512 flashErase();
00513
00514 fprintf (PC_HOST, "done.\n\r");
00515 }
00516
00520 void diagMenu()
00521 {
00522
00523 fprintf (PC_HOST, "Options: (e)rase Flash, (r)ead Flash\n\r");
00524 fprintf (PC_HOST, " Toggle (L)ED\n\r");
00525 fprintf (PC_HOST, " (P)TT - Push To Transmit\n\r");
00526 fprintf (PC_HOST, " (f)requencey down, (F)requency up - 1KHz step\n\r");
00527 fprintf (PC_HOST, " (c)hannel down, (C)hannel up - 25KHz step\n\r");
00528 fprintf (PC_HOST, " (a)mplitude down, (A)mplitude up - 0.5 dB steps\n\r");
00529 fprintf (PC_HOST, " e(x)it engineering mode\n\r");
00530 }
00531
00535 void diagReadFlash()
00536 {
00537 bool_t dataFoundFlag, userStopFlag;
00538 uint8_t i, buffer[DIAG_BYTES_PER_LINE];
00539 uint32_t address;
00540
00541
00542 address = 0x0000;
00543 userStopFlag = false;
00544
00545 do
00546 {
00547
00548 flashReadBlock (address, buffer, DIAG_BYTES_PER_LINE);
00549
00550
00551 dataFoundFlag = false;
00552
00553
00554 fprintf (PC_HOST, "%08lx ", address);
00555
00556
00557 for (i = 0; i < DIAG_BYTES_PER_LINE; ++i)
00558 {
00559 fprintf (PC_HOST, "%02x", buffer[i]);
00560
00561
00562 if (buffer[i] != 0xff)
00563 dataFoundFlag = true;
00564
00565
00566 if (kbhit(PC_HOST))
00567 userStopFlag = true;
00568 }
00569
00570
00571 fprintf (PC_HOST, "\n\r");
00572
00573
00574 address += DIAG_BYTES_PER_LINE;
00575 } while (dataFoundFlag && !userStopFlag);
00576
00577
00578 if (userStopFlag)
00579 fprintf (PC_HOST, "User aborted download!\n\r");
00580 }
00581
00582 void diag1PPS()
00583 {
00584 uint16_t timeStamp, lastTimeStamp;
00585
00586 lastTimeStamp = 0x0000;
00587
00588 gpsPowerOn();
00589
00590 for (;;)
00591 {
00592 timeStamp = CCP_2;
00593
00594 if (timeStamp != lastTimeStamp)
00595 {
00596 delay_ms (10);
00597
00598 timeStamp = CCP_2;
00599
00600 fprintf (PC_HOST, "%lu %lu\n\r", timeStamp, (timeStamp - lastTimeStamp));
00601
00602 lastTimeStamp = timeStamp;
00603 }
00604 }
00605 }
00606
00610 void diagPort()
00611 {
00612 bool_t diagDoneFlag, ledFlag, paFlag, showSettingsFlag;
00613 uint8_t command, amplitude;
00614 uint32_t freqHz;
00615
00616
00617 if (!input(PIN_B6))
00618 return;
00619
00620 fprintf (PC_HOST, "Engineering Mode\n\r");
00621 fprintf (PC_HOST, "Application Built %s %s\n\r", __DATE__, __TIME__);
00622
00623
00624 ledFlag = false;
00625 output_bit (IO_LED, ledFlag);
00626
00627
00628 diagDoneFlag = false;
00629
00630
00631 paFlag = false;
00632
00633
00634 showSettingsFlag = false;
00635
00636
00637 freqHz = 445950000;
00638 amplitude = 0;
00639
00640
00641 while (!diagDoneFlag)
00642 {
00643
00644 command = fgetc(PC_HOST);
00645
00646
00647 switch (command)
00648 {
00649 case 'e':
00650 diagEraseFlash();
00651 logInit();
00652 break;
00653
00654 case 'l':
00655 case 'L':
00656 ledFlag = (ledFlag ? false : true);
00657 output_bit (IO_LED, ledFlag);
00658 break;
00659
00660 case 'h':
00661 case 'H':
00662 case '?':
00663 diagMenu();
00664 break;
00665
00666 case 'r':
00667 diagReadFlash();
00668 break;
00669
00670 case 't':
00671 tncHighRate (true);
00672 fprintf (PC_HOST, "Set high rate TNC.\n\r");
00673 break;
00674
00675 case 'f':
00676 freqHz -= 1000;
00677 ddsSetFreq (freqHz);
00678
00679
00680 showSettingsFlag = true;
00681 break;
00682
00683 case 'F':
00684 freqHz += 1000;
00685 ddsSetFreq (freqHz);
00686
00687
00688 showSettingsFlag = true;
00689 break;
00690
00691 case 'c':
00692 freqHz -= 25000;
00693 ddsSetFreq (freqHz);
00694
00695
00696 showSettingsFlag = true;
00697 break;
00698
00699 case 'C':
00700 freqHz += 25000;
00701 ddsSetFreq (freqHz);
00702
00703
00704 showSettingsFlag = true;
00705 break;
00706
00707 case 'p':
00708 case 'P':
00709 ddsSetFreq (freqHz);
00710
00711 paFlag = (paFlag ? false : true);
00712 output_bit (IO_PTT, paFlag);
00713 output_bit (IO_OSK, paFlag);
00714
00715 if (paFlag)
00716 {
00717 ddsSetMode (DDS_MODE_AFSK);
00718 ddsSetAmplitude (amplitude);
00719 } else
00720 ddsSetMode (DDS_MODE_POWERDOWN);
00721
00722 break;
00723
00724 case 'a':
00725 if (amplitude != 200)
00726 {
00727 amplitude += 5;
00728 ddsSetAmplitude (amplitude);
00729
00730
00731 showSettingsFlag = true;
00732 }
00733 break;
00734
00735 case 'A':
00736 if (amplitude != 0)
00737 {
00738 amplitude -= 5;
00739 ddsSetAmplitude (amplitude);
00740
00741
00742 showSettingsFlag = true;
00743 }
00744 break;
00745
00746 case 'g':
00747 diag1PPS();
00748 break;
00749
00750 case 'x':
00751 diagDoneFlag = true;
00752 break;
00753
00754 default:
00755 fprintf (PC_HOST, "Invalid command. (H)elp for menu.\n\r");
00756 break;
00757 }
00758
00759
00760 if (showSettingsFlag)
00761 {
00762 showSettingsFlag = false;
00763
00764 fprintf (PC_HOST, "%03ld.%03ld MHz ", freqHz / 1000000, (freqHz / 1000) % 1000);
00765 fprintf (PC_HOST, "%d.%01ddBc\n\r", amplitude / 10, amplitude % 10);
00766
00767 }
00768
00769 }
00770
00771
00772 fprintf (PC_HOST, "Exit diagnostic mode.\n\r");
00773
00774 return;
00775 }
00776
00788
00789 #define DDS_AD9954_CFR1 0x00
00790
00792 #define DDS_AD9954_CFR2 0x01
00793
00795 #define DDS_AD9954_ASF 0x02
00796
00798 #define DDS_AD9954_ARR 0x03
00799
00801 #define DDS_AD9954_FTW0 0x04
00802
00804 #define DDS_AD9954_FTW1 0x06
00805
00807 #define DDS_AD9954_NLSCW 0x07
00808
00810 #define DDS_AD9954_PLSCW 0x08
00811
00813 #define DDS_AD9954_RWCW0 0x07
00814
00816 #define DDS_AD9954_RWCW1 0x08
00817
00819 #define DDS_RAM 0x0b
00820
00822 DDS_MODE ddsMode;
00823
00825 #define DDS_FREQ_TO_FTW_DIGITS 9
00826
00828 const uint32_t DDS_MULT[DDS_FREQ_TO_FTW_DIGITS] = { 11, 7, 7, 3, 4, 8, 4, 9, 1 };
00829
00831 const uint32_t DDS_DIVISOR[DDS_FREQ_TO_FTW_DIGITS - 1] = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
00832
00834 const uint16_t DDS_AMP_TO_SCALE[] =
00835 {
00836 16383, 15467, 14601, 13785, 13013, 12286, 11598, 10949, 10337, 9759, 9213, 8697,
00837 8211, 7752, 7318, 6909, 6522, 6157, 5813, 5488, 5181, 4891, 4617, 4359, 4115, 3885, 3668, 3463,
00838 3269, 3086, 2913, 2750, 2597, 2451, 2314, 2185, 2062, 1947, 1838, 1735, 1638
00839 };
00840
00841
00843 const uint32_t freqTable[256] =
00844 {
00845 955418300, 955419456, 955420611, 955421765, 955422916, 955424065, 955425210, 955426351,
00846 955427488, 955428618, 955429743, 955430861, 955431971, 955433073, 955434166, 955435249,
00847 955436322, 955437385, 955438435, 955439474, 955440500, 955441513, 955442511, 955443495,
00848 955444464, 955445417, 955446354, 955447274, 955448176, 955449061, 955449926, 955450773,
00849 955451601, 955452408, 955453194, 955453960, 955454704, 955455426, 955456126, 955456803,
00850 955457457, 955458088, 955458694, 955459276, 955459833, 955460366, 955460873, 955461354,
00851 955461809, 955462238, 955462641, 955463017, 955463366, 955463688, 955463983, 955464250,
00852 955464489, 955464701, 955464884, 955465040, 955465167, 955465266, 955465337, 955465380,
00853 955465394, 955465380, 955465337, 955465266, 955465167, 955465040, 955464884, 955464701,
00854 955464489, 955464250, 955463983, 955463688, 955463366, 955463017, 955462641, 955462238,
00855 955461809, 955461354, 955460873, 955460366, 955459833, 955459276, 955458694, 955458088,
00856 955457457, 955456803, 955456126, 955455426, 955454704, 955453960, 955453194, 955452408,
00857 955451601, 955450773, 955449926, 955449061, 955448176, 955447274, 955446354, 955445417,
00858 955444464, 955443495, 955442511, 955441513, 955440500, 955439474, 955438435, 955437385,
00859 955436322, 955435249, 955434166, 955433073, 955431971, 955430861, 955429743, 955428618,
00860 955427488, 955426351, 955425210, 955424065, 955422916, 955421765, 955420611, 955419456,
00861 955418300, 955417144, 955415989, 955414836, 955413684, 955412535, 955411390, 955410249,
00862 955409113, 955407982, 955406857, 955405740, 955404629, 955403528, 955402435, 955401351,
00863 955400278, 955399216, 955398165, 955397126, 955396100, 955395088, 955394089, 955393105,
00864 955392136, 955391183, 955390246, 955389326, 955388424, 955387540, 955386674, 955385827,
00865 955385000, 955384192, 955383406, 955382640, 955381896, 955381174, 955380474, 955379797,
00866 955379143, 955378513, 955377906, 955377324, 955376767, 955376235, 955375728, 955375246,
00867 955374791, 955374362, 955373959, 955373583, 955373234, 955372912, 955372618, 955372350,
00868 955372111, 955371900, 955371716, 955371560, 955371433, 955371334, 955371263, 955371220,
00869 955371206, 955371220, 955371263, 955371334, 955371433, 955371560, 955371716, 955371900,
00870 955372111, 955372350, 955372618, 955372912, 955373234, 955373583, 955373959, 955374362,
00871 955374791, 955375246, 955375728, 955376235, 955376767, 955377324, 955377906, 955378513,
00872 955379143, 955379797, 955380474, 955381174, 955381896, 955382640, 955383406, 955384192,
00873 955385000, 955385827, 955386674, 955387540, 955388424, 955389326, 955390246, 955391183,
00874 955392136, 955393105, 955394089, 955395088, 955396100, 955397126, 955398165, 955399216,
00875 955400278, 955401351, 955402435, 955403528, 955404629, 955405740, 955406857, 955407982,
00876 955409113, 955410249, 955411390, 955412535, 955413684, 955414836, 955415989, 955417144
00877 };
00878
00882 void ddsInit()
00883 {
00884
00885 setup_spi( SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4 | SPI_XMIT_L_TO_H );
00886
00887
00888 ddsMode = DDS_MODE_NOT_INITIALIZED;
00889
00890
00891 ddsSetMode (DDS_MODE_POWERDOWN);
00892
00893
00894 ddsSetOutputScale (0x3fff);
00895
00896
00897 output_low (IO_CS);
00898 spi_write (DDS_AD9954_CFR2);
00899
00900 spi_write (0x00);
00901 spi_write (0x00);
00902 spi_write (0x9c);
00903 output_high (IO_CS);
00904
00905
00906 output_low (IO_CS);
00907 spi_write (DDS_AD9954_ARR);
00908
00909 spi_write (83);
00910 output_high (IO_CS);
00911
00912
00913 output_high (IO_UPDATE);
00914 output_low (IO_UPDATE);
00915 }
00916
00923 void ddsSetOutputScale (uint16_t scale)
00924 {
00925
00926 output_low (IO_CS);
00927 spi_write (DDS_AD9954_ASF);
00928
00929 spi_write ((scale >> 8) & 0xff);
00930 spi_write (scale & 0xff);
00931
00932 output_high (IO_CS);
00933
00934
00935 output_high (IO_UPDATE);
00936 output_low (IO_UPDATE);
00937 }
00938
00945 void ddsSetAmplitude (uint8_t amplitude)
00946 {
00947
00948 if (amplitude > 200)
00949 return;
00950
00951
00952 ddsSetOutputScale (DDS_AMP_TO_SCALE[amplitude / 5]);
00953
00954
00955 output_low (IO_OSK);
00956 delay_ms(25);
00957
00958 output_high (IO_OSK);
00959 delay_ms(25);
00960 }
00961
00967 void ddsSetFTW (uint32_t ftw)
00968 {
00969
00970 output_low (IO_CS);
00971 spi_write (DDS_AD9954_FTW0);
00972
00973 spi_write ((ftw >> 24) & 0xff);
00974 spi_write ((ftw >> 16) & 0xff);
00975 spi_write ((ftw >> 8) & 0xff);
00976 spi_write (ftw & 0xff);
00977
00978 output_high (IO_CS);
00979
00980
00981 output_high (IO_UPDATE);
00982 output_low (IO_UPDATE);
00983 }
00984
00991 void ddsSetFreq(uint32_t freq)
00992 {
00993 uint8_t i;
00994 uint32_t ftw;
00995
00996
00997 ftw = freq * DDS_MULT[0];
00998
00999 for (i = 0; i < DDS_FREQ_TO_FTW_DIGITS - 1; ++i)
01000 ftw += (freq * DDS_MULT[i+1]) / DDS_DIVISOR[i];
01001
01002 ddsSetFTW (ftw);
01003 }
01004
01012 void ddsSetFSKFreq (uint32_t ftw0, uint32_t ftw1)
01013 {
01014
01015 output_low (IO_CS);
01016 spi_write (DDS_AD9954_FTW0);
01017
01018 spi_write ((ftw0 >> 24) & 0xff);
01019 spi_write ((ftw0 >> 16) & 0xff);
01020 spi_write ((ftw0 >> 8) & 0xff);
01021 spi_write (ftw0 & 0xff);
01022
01023 output_high (IO_CS);
01024
01025
01026 output_low (IO_CS);
01027 spi_write (DDS_AD9954_FTW1);
01028
01029 spi_write ((ftw1 >> 24) & 0xff);
01030 spi_write ((ftw1 >> 16) & 0xff);
01031 spi_write ((ftw1 >> 8) & 0xff);
01032 spi_write (ftw1 & 0xff);
01033
01034 output_high (IO_CS);
01035
01036
01037 output_high (IO_UPDATE);
01038 output_low (IO_UPDATE);
01039 }
01040
01046 void ddsSetMode (DDS_MODE mode)
01047 {
01048
01049 ddsMode = mode;
01050
01051 switch (mode)
01052 {
01053 case DDS_MODE_POWERDOWN:
01054
01055 output_low (IO_CS);
01056 spi_write (DDS_AD9954_CFR1);
01057
01058 spi_write (0x00);
01059 spi_write (0x00);
01060 spi_write (0x00);
01061 spi_write (0xf0);
01062 output_high (IO_CS);
01063 break;
01064
01065 case DDS_MODE_AFSK:
01066
01067 output_low (IO_CS);
01068 spi_write (DDS_AD9954_CFR1);
01069
01070 spi_write (0x03);
01071 spi_write (0x00);
01072 spi_write (0x00);
01073 spi_write (0x40);
01074 output_high (IO_CS);
01075 break;
01076
01077 case DDS_MODE_FSK:
01078
01079 output_low (IO_CS);
01080 spi_write (DDS_AD9954_CFR1);
01081
01082 spi_write (0x03);
01083 spi_write (0x00);
01084 spi_write (0x00);
01085 spi_write (0x40);
01086 output_high (IO_CS);
01087
01088
01089
01090
01091
01092
01093 output_low (IO_CS);
01094 spi_write (DDS_AD9954_NLSCW);
01095
01096 spi_write (1);
01097 spi_write (0x00);
01098 spi_write (0x00);
01099 spi_write (0x00);
01100 spi_write (250);
01101 output_high (IO_CS);
01102
01103
01104 output_low (IO_CS);
01105 spi_write (DDS_AD9954_PLSCW);
01106
01107 spi_write (1);
01108 spi_write (0x00);
01109 spi_write (0x00);
01110 spi_write (0x00);
01111 spi_write (250);
01112 output_high (IO_CS);
01113 break;
01114 }
01115
01116
01117 output_high (IO_UPDATE);
01118 output_low (IO_UPDATE);
01119 }
01120
01131
01132 #define FLASH_CS PIN_B3
01133
01135 #define FLASH_CLK PIN_B5
01136
01138 #define FLASH_D PIN_B4
01139
01141 #define FLASH_Q PIN_B2
01142
01148 bool_t flashIsWriteInProgress()
01149 {
01150 uint8_t status;
01151
01152 output_low (FLASH_CS);
01153
01154
01155 flashSendByte (0x05);
01156
01157 status = flashGetByte();
01158
01159 output_high (FLASH_CS);
01160
01161 return (((status & 0x01) == 0x01) ? true : false);
01162 }
01163
01171 void flashReadBlock(uint32_t address, uint8_t *block, uint16_t length)
01172 {
01173 uint16_t i;
01174
01175 output_low (FLASH_CS);
01176
01177
01178 flashSendByte (0x03);
01179 flashSendAddress (address);
01180
01181 for (i = 0; i < length; ++i)
01182 *block++ = flashGetByte();
01183
01184 output_high (FLASH_CS);
01185 }
01186
01194 void flashWriteBlock(uint32_t address, uint8_t *block, uint8_t length)
01195 {
01196 uint8_t i;
01197
01198 output_low (FLASH_CS);
01199
01200 flashSendByte (0x06);
01201 output_high (FLASH_CS);
01202
01203 output_low (FLASH_CS);
01204
01205 flashSendByte (0x02);
01206 flashSendAddress (address);
01207
01208 for (i = 0; i < length; ++i)
01209 {
01210
01211 flashSendByte (*block++);
01212
01213
01214 ++address;
01215
01216
01217 if ((address & 0xff) == 0x00)
01218 {
01219 output_high (FLASH_CS);
01220
01221
01222 while (flashIsWriteInProgress());
01223
01224 output_low (FLASH_CS);
01225
01226 flashSendByte (0x06);
01227 output_high (FLASH_CS);
01228
01229 output_low (FLASH_CS);
01230
01231 flashSendByte (0x02);
01232 flashSendAddress (address);
01233 }
01234 }
01235
01236 output_high (FLASH_CS);
01237
01238
01239 while (flashIsWriteInProgress());
01240 }
01241
01245 void flashErase()
01246 {
01247 output_low (FLASH_CS);
01248
01249 flashSendByte (0x06);
01250 output_high (FLASH_CS);
01251
01252 output_low (FLASH_CS);
01253
01254 flashSendByte (0xc7);
01255 output_high (FLASH_CS);
01256
01257 while (flashIsWriteInProgress());
01258 }
01259
01267 uint8_t flashGetByte()
01268 {
01269 uint8_t i, value;
01270
01271 value = 0;
01272
01273
01274 for (i = 0; i < 8; ++i)
01275 {
01276
01277 output_high (FLASH_CLK);
01278
01279
01280 value = value << 1;
01281
01282 if (input (FLASH_Q))
01283 value = value | 0x01;
01284
01285 output_low (FLASH_CLK);
01286 }
01287
01288 return value;
01289 }
01290
01294 void flashInit()
01295 {
01296
01297 output_high (FLASH_CS);
01298 output_low (FLASH_CLK);
01299 output_low (FLASH_D);
01300 }
01301
01309 void flashSendByte(uint8_t value)
01310 {
01311 uint8_t i;
01312
01313
01314 for (i = 0; i < 8; ++i)
01315 {
01316
01317 if ((value & 0x80) == 0x80)
01318 output_high (FLASH_D);
01319 else
01320 output_low (FLASH_D);
01321
01322
01323 value = value << 1;
01324
01325
01326 output_high (FLASH_CLK);
01327 output_low (FLASH_CLK);
01328 }
01329 }
01330
01338 void flashSendAddress(uint32_t address)
01339 {
01340 uint8_t i;
01341
01342
01343 for (i = 0; i < 24; ++i)
01344 {
01345
01346 if ((address & 0x800000) == 0x800000)
01347 output_high (FLASH_D);
01348 else
01349 output_low (FLASH_D);
01350
01351
01352 address = address << 1;
01353
01354
01355 output_high (FLASH_CLK);
01356 output_low (FLASH_CLK);
01357 }
01358 }
01359
01370
01371 #define GPS_BUFFER_SIZE 50
01372
01374 enum GPS_PARSE_STATE_MACHINE
01375 {
01377 GPS_START1,
01378
01380 GPS_START2,
01381
01383 GPS_COMMAND1,
01384
01386 GPS_COMMAND2,
01387
01389 GPS_READMESSAGE,
01390
01392 GPS_CHECKSUMMESSAGE,
01393
01395 GPS_EOMCR,
01396
01398 GPS_EOMLF
01399 };
01400
01402 uint8_t gpsIndex;
01403
01405 GPS_PARSE_STATE_MACHINE gpsParseState;
01406
01408 uint8_t gpsBuffer[GPS_BUFFER_SIZE];
01409
01411 int32_t gpsPeakAltitude;
01412
01414 uint8_t gpsChecksum;
01415
01417 GPSPOSITION_STRUCT gpsPosition;
01418
01424 GPS_FIX_TYPE gpsGetFixType()
01425 {
01426
01427 switch (gpsPosition.status & 0xe000)
01428 {
01429 case 0xe000:
01430 return GPS_3D_FIX;
01431
01432 case 0xc000:
01433 return GPS_2D_FIX;
01434
01435 default:
01436 return GPS_NO_FIX;
01437 }
01438 }
01439
01445 int32_t gpsGetPeakAltitude()
01446 {
01447 return gpsPeakAltitude;
01448 }
01449
01453 void gpsInit()
01454 {
01455
01456 gpsParseState = GPS_START1;
01457
01458
01459 gpsPeakAltitude = 0;
01460
01461
01462 memset (&gpsPosition, 0, sizeof(GPSPOSITION_STRUCT));
01463
01464
01465 setup_timer_3(T3_INTERNAL | T3_DIV_BY_1);
01466 setup_ccp2 (CCP_CAPTURE_RE | CCP_USE_TIMER3);
01467 }
01468
01475 bool_t gpsIsReady()
01476 {
01477 if (gpsPosition.updateFlag)
01478 {
01479 gpsPosition.updateFlag = false;
01480 return true;
01481 }
01482
01483 return false;
01484 }
01485
01494 uint8_t gpsNMEAChecksum (uint8_t *buffer, uint8_t length)
01495 {
01496 uint8_t i, checksum;
01497
01498 checksum = 0;
01499
01500 for (i = 0; i < length; ++i)
01501 checksum ^= buffer[i];
01502
01503 return checksum;
01504 }
01505
01512 bool_t gpsSetup()
01513 {
01514 uint8_t startTime, retryCount;
01515
01516
01517 startTime = timeGetTicks();
01518 retryCount = 0;
01519
01520 while (++retryCount < 10)
01521 {
01522
01523 gpsUpdate();
01524
01525
01526 if (gpsIsReady())
01527 {
01528 timeSetDutyCycle (TIME_DUTYCYCLE_10);
01529 return true;
01530 }
01531
01532 if (timeGetTicks() > startTime)
01533 {
01534 puts ("@@Hb\001\053\015\012");
01535 startTime += 10;
01536 }
01537
01538 }
01539
01540 return false;
01541 }
01542
01546 void gpsParsePositionMessage()
01547 {
01548
01549
01550 gpsPosition.updateFlag = true;
01551
01552 gpsPosition.month = gpsBuffer[0];
01553 gpsPosition.day = gpsBuffer[1];
01554 gpsPosition.year = ((uint16_t) gpsBuffer[2] << 8) | gpsBuffer[3];
01555 gpsPosition.hours = gpsBuffer[4];
01556 gpsPosition.minutes = gpsBuffer[5];
01557 gpsPosition.seconds = gpsBuffer[6];
01558 gpsPosition.latitude = ((int32) gpsBuffer[11] << 24) | ((int32) gpsBuffer[12] << 16) | ((int32) gpsBuffer[13] << 8) | (int32) gpsBuffer[14];
01559 gpsPosition.longitude = ((int32) gpsBuffer[15] << 24) | ((int32) gpsBuffer[16] << 16) | ((int32) gpsBuffer[17] << 8) | gpsBuffer[18];
01560 gpsPosition.altitudeCM = ((int32) gpsBuffer[19] << 24) | ((int32) gpsBuffer[20] << 16) | ((int32) gpsBuffer[21] << 8) | gpsBuffer[22];
01561 gpsPosition.altitudeFeet = gpsPosition.altitudeCM * 100l / 3048l;
01562 gpsPosition.vSpeed = ((uint16_t) gpsBuffer[27] << 8) | gpsBuffer[28];
01563 gpsPosition.hSpeed = ((uint16_t) gpsBuffer[29] << 8) | gpsBuffer[30];
01564 gpsPosition.heading = ((uint16_t) gpsBuffer[31] << 8) | gpsBuffer[32];
01565 gpsPosition.dop = ((uint16_t) gpsBuffer[33] << 8) | gpsBuffer[34];
01566 gpsPosition.visibleSats = gpsBuffer[35];
01567 gpsPosition.trackedSats = gpsBuffer[36];
01568 gpsPosition.status = ((uint16_t) gpsBuffer[37] << 8) | gpsBuffer[38];
01569
01570
01571 if (gpsGetFixType() == GPS_3D_FIX)
01572 if (gpsPosition.altitudeFeet > gpsPeakAltitude)
01573 gpsPeakAltitude = gpsPosition.altitudeFeet;
01574 }
01575
01579 void gpsPowerOn()
01580 {
01581
01582 output_high (IO_GPS_PWR);
01583
01584
01585 #asm
01586 bsf 0xFAB.7
01587 #endasm
01588 }
01589
01593 void gpsPowerOff()
01594 {
01595
01596 #asm
01597 bcf 0xFAB.7
01598 #endasm
01599
01600
01601 output_low (IO_GPS_PWR);
01602 }
01603
01607 void gpsUpdate()
01608 {
01609 uint8_t value;
01610
01611
01612
01613 while (serialHasData())
01614 {
01615
01616 value = serialRead();
01617
01618
01619 switch (gpsParseState)
01620 {
01621 case GPS_START1:
01622 if (value == '@')
01623 gpsParseState = GPS_START2;
01624 break;
01625
01626 case GPS_START2:
01627 if (value == '@')
01628 gpsParseState = GPS_COMMAND1;
01629 else
01630 gpsParseState = GPS_START1;
01631 break;
01632
01633 case GPS_COMMAND1:
01634 if (value == 'H')
01635 gpsParseState = GPS_COMMAND2;
01636 else
01637 gpsParseState = GPS_START1;
01638 break;
01639
01640 case GPS_COMMAND2:
01641 if (value == 'b')
01642 {
01643 gpsParseState = GPS_READMESSAGE;
01644 gpsIndex = 0;
01645 gpsChecksum = 0;
01646 gpsChecksum ^= 'H';
01647 gpsChecksum ^= 'b';
01648 } else
01649 gpsParseState = GPS_START1;
01650 break;
01651
01652 case GPS_READMESSAGE:
01653 gpsChecksum ^= value;
01654 gpsBuffer[gpsIndex++] = value;
01655
01656 if (gpsIndex == 47)
01657 gpsParseState = GPS_CHECKSUMMESSAGE;
01658
01659 break;
01660
01661 case GPS_CHECKSUMMESSAGE:
01662 if (gpsChecksum == value)
01663 gpsParseState = GPS_EOMCR;
01664 else
01665 gpsParseState = GPS_START1;
01666 break;
01667
01668 case GPS_EOMCR:
01669 if (value == 13)
01670 gpsParseState = GPS_EOMLF;
01671 else
01672 gpsParseState = GPS_START1;
01673 break;
01674
01675 case GPS_EOMLF:
01676
01677 if (value == 10)
01678 gpsParsePositionMessage();
01679
01680 gpsParseState = GPS_START1;
01681 break;
01682 }
01683 }
01684 }
01685
01697
01698 #define LOG_WRITE_BUFFER_SIZE 40
01699
01701 uint32_t logAddress;
01702
01704 uint8_t logBuffer[LOG_WRITE_BUFFER_SIZE];
01705
01707 uint8_t logIndex;
01708
01715 uint32_t logGetAddress()
01716 {
01717 return logAddress;
01718 }
01719
01724 void logFlush()
01725 {
01726
01727 if (logIndex != 0)
01728 {
01729 flashWriteBlock (logAddress, logBuffer, logIndex);
01730 logAddress += logIndex;
01731 logIndex = 0;
01732 }
01733 }
01734
01738 void logInit()
01739 {
01740 uint8_t buffer[8];
01741 bool_t endFound;
01742
01743 fprintf (PC_HOST, "Searching for end of flash log...");
01744
01745 logAddress = 0x0000;
01746 endFound = false;
01747
01748
01749 do
01750 {
01751
01752 flashReadBlock (logAddress, buffer, 1);
01753
01754
01755 switch (buffer[0])
01756 {
01757 case LOG_BOOTED:
01758 logAddress += 7;
01759 break;
01760
01761 case LOG_COORD:
01762 logAddress += 26;
01763 break;
01764
01765 case LOG_TEMPERATURE:
01766 logAddress += 3;
01767 break;
01768
01769 case LOG_VOLTAGE:
01770 logAddress += 5;
01771 break;
01772
01773 case 0xff:
01774 endFound = true;
01775 break;
01776
01777 default:
01778 ++logAddress;
01779 }
01780 } while (logAddress < 0x100000 && !endFound);
01781
01782 fprintf (PC_HOST, "done. Log contains %ld bytes.\n\r", logAddress);
01783
01784 logIndex = 0;
01785 }
01786
01792 void logType (LOG_TYPE type)
01793 {
01794
01795 if (logAddress >= 0x100000)
01796 return;
01797
01798
01799 logFlush();
01800
01801
01802 logBuffer[0] = type;
01803 logIndex = 1;
01804 }
01805
01811 void logUint8 (uint8_t value)
01812 {
01813 logBuffer[logIndex++] = value;
01814 }
01815
01821 void logInt16 (int16_t value)
01822 {
01823 logBuffer[logIndex++] = (value >> 8) & 0xff;
01824 logBuffer[logIndex++] = value & 0xff;
01825 }
01826
01832 void logUint16 (uint16_t value)
01833 {
01834 logBuffer[logIndex++] = (value >> 8) & 0xff;
01835 logBuffer[logIndex++] = value & 0xff;
01836 }
01837
01843 void logInt32 (int32_t value)
01844 {
01845 logBuffer[logIndex++] = (value >> 24) & 0xff;
01846 logBuffer[logIndex++] = (value >> 16) & 0xff;
01847 logBuffer[logIndex++] = (value >> 8) & 0xff;
01848 logBuffer[logIndex++] = value & 0xff;
01849 }
01850
01866 int16_t lm92GetTemp()
01867 {
01868 int16_t value;
01869 int32_t temp;
01870
01871
01872 set_tris_c (0x9a);
01873
01874
01875 i2c_start();
01876 i2c_write(0x97);
01877 value = ((int16_t) i2c_read() << 8);
01878 value = value | ((int16_t) i2c_read() & 0x00f8);
01879 i2c_stop();
01880
01881
01882 set_tris_c (0x82);
01883
01884
01885
01886
01887
01888
01889 temp = (int32_t) value;
01890 temp = ((temp * 9l) / 64l) + 320;
01891
01892 return (int16_t) temp;
01893 }
01894
01906
01907 #define SERIAL_BUFFER_SIZE 64
01908
01910 #define SERIAL_BUFFER_MASK 0x3f
01911
01913 uint8_t serialHead;
01914
01916 uint8_t serialTail;
01917
01919 uint8_t serialBuffer[SERIAL_BUFFER_SIZE];
01920
01926 bool_t serialHasData()
01927 {
01928 if (serialHead == serialTail)
01929 return false;
01930
01931 return true;
01932 }
01933
01937 void serialInit()
01938 {
01939 serialHead = 0;
01940 serialTail = 0;
01941 }
01942
01948 uint8_t serialRead()
01949 {
01950 uint8_t value;
01951
01952
01953 if (serialHead == serialTail)
01954 return 0;
01955
01956
01957 value = serialBuffer[serialTail];
01958
01959
01960 serialTail = (serialTail + 1) & SERIAL_BUFFER_MASK;
01961
01962 return value;
01963 }
01964
01968 void serialUpdate()
01969 {
01970
01971 while (kbhit())
01972 {
01973
01974 serialBuffer[serialHead] = getc();
01975
01976
01977 serialHead = (serialHead + 1) & SERIAL_BUFFER_MASK;
01978 }
01979 }
01980
02001 uint16_t sysCRC16(uint8_t *buffer, uint8_t length, uint16_t crc)
02002 {
02003 uint8_t i, bit, value;
02004
02005 for (i = 0; i < length; ++i)
02006 {
02007 value = buffer[i];
02008
02009 for (bit = 0; bit < 8; ++bit)
02010 {
02011 crc ^= (value & 0x01);
02012 crc = ( crc & 0x01 ) ? ( crc >> 1 ) ^ 0x8408 : ( crc >> 1 );
02013 value = value >> 1;
02014 }
02015 }
02016
02017 return crc ^ 0xffff;
02018 }
02019
02023 void sysInit()
02024 {
02025 gpsPowerOff ();
02026 output_high (IO_LED);
02027
02028 output_high (IO_CS);
02029 output_low (IO_PS1);
02030 output_low (IO_PS0);
02031 output_low (IO_OSK);
02032 output_low (IO_UPDATE);
02033 output_low (IO_PTT);
02034 output_low (IO_GPS_TXD);
02035
02036
02037 set_tris_a (0xc3);
02038 set_tris_b (0x44);
02039 set_tris_c (0x82);
02040
02041
02042 fprintf (PC_HOST, "System booted.\n\r");
02043 }
02044
02048 void sysLogGPSData()
02049 {
02050
02051 logType (LOG_COORD);
02052 logUint8 (gpsPosition.hours);
02053 logUint8 (gpsPosition.minutes);
02054 logUint8 (gpsPosition.seconds);
02055 logInt32 (gpsPosition.latitude);
02056 logInt32 (gpsPosition.longitude);
02057 logInt32 (gpsPosition.altitudeCM);
02058
02059 logUint16 (gpsPosition.vSpeed);
02060 logUint16 (gpsPosition.hSpeed);
02061 logUint16 (gpsPosition.heading);
02062
02063 logUint16 (gpsPosition.status);
02064
02065 logUint8 ((uint8_t) (gpsPosition.dop & 0xff));
02066 logUint8 ((uint8_t) ((gpsPosition.visibleSats << 4) | gpsPosition.trackedSats));
02067 }
02068
02072 void sysLogVoltage()
02073 {
02074 logType (LOG_VOLTAGE);
02075 logUint16 (adcRawBusVolt());
02076 logUint16 (adcRawRefVolt());
02077 }
02078
02089
02090 uint8_t timeTicks;
02091
02093 uint16_t timeInterruptCount;
02094
02096 uint8_t time100ms;
02097
02099 uint8_t timeSeconds;
02100
02102 uint8_t timeMinutes;
02103
02105 uint8_t timeHours;
02106
02108 uint8_t timeDutyCycle;
02109
02111 uint16_t timeCompare;
02112
02114 uint16_t timeNCO;
02115
02117 uint16_t timeNCOFreq;
02118
02120 uint8_t timeLowRateCount;
02121
02123 TNC_DATA_MODE tncDataMode;
02124
02126 bool_t timeUpdateFlag;
02127
02129 bool_t timeRunFlag;
02130
02132 #define TIME_RATE 125
02133
02139 uint8_t timeGetTicks()
02140 {
02141 return timeTicks;
02142 }
02143
02147 void timeInit()
02148 {
02149 timeTicks = 0;
02150 timeInterruptCount = 0;
02151 time100mS = 0;
02152 timeSeconds = 0;
02153 timeMinutes = 0;
02154 timeHours = 0;
02155 timeDutyCycle = TIME_DUTYCYCLE_70;
02156 timeCompare = TIME_RATE;
02157 timeUpdateFlag = false;
02158 timeNCO = 0x00;
02159 timeLowRateCount = 0;
02160 timeNCOFreq = 0x2000;
02161 tncDataMode = TNC_MODE_STANDBY;
02162 timeRunFlag = false;
02163
02164
02165 CCP_1 = TIME_RATE;
02166 set_timer1(timeCompare);
02167 setup_ccp1( CCP_COMPARE_INT );
02168 setup_timer_1( T1_INTERNAL | T1_DIV_BY_4 );
02169 }
02170
02176 bool_t timeIsUpdate()
02177 {
02178 if (timeUpdateFlag)
02179 {
02180 timeUpdateFlag = false;
02181 return true;
02182 }
02183
02184 return false;
02185 }
02186
02192 void timeSetDutyCycle (uint8_t dutyCycle)
02193 {
02194 timeDutyCycle = dutyCycle;
02195 }
02196
02201 void timeSetRunFlag()
02202 {
02203 timeRunFlag = true;
02204 }
02205
02206 #INT_CCP1
02207
02210 void timeUpdate()
02211 {
02212
02213 timeCompare += TIME_RATE;
02214 CCP_1 = timeCompare;
02215
02216 switch (tncDataMode)
02217 {
02218 case TNC_MODE_STANDBY:
02219 break;
02220
02221 case TNC_MODE_1200_AFSK:
02222 ddsSetFTW (freqTable[timeNCO >> 8]);
02223
02224 timeNCO += timeNCOFreq;
02225
02226 if (++timeLowRateCount == 8)
02227 {
02228 timeLowRateCount = 0;
02229 tnc1200TimerTick();
02230 }
02231 break;
02232
02233 case TNC_MODE_9600_FSK:
02234 tnc9600TimerTick();
02235 break;
02236 }
02237
02238
02239 serialUpdate();
02240
02241
02242 if (++timeInterruptCount == 960)
02243 {
02244 timeInterruptCount = 0;
02245
02246
02247 ++timeTicks;
02248
02249
02250 if (++time100mS == 10)
02251 {
02252 time100mS = 0;
02253
02254
02255 timeUpdateFlag = true;
02256
02257
02258 if (timeRunFlag)
02259 if (++timeSeconds == 60)
02260 {
02261 timeSeconds = 0;
02262
02263 if (++timeMinutes == 60)
02264 {
02265 timeMinutes = 0;
02266 ++timeHours;
02267 }
02268 }
02269 }
02270
02271
02272 if (time100mS >= timeDutyCycle)
02273 output_low (IO_LED);
02274 else
02275 output_high (IO_LED);
02276 }
02277 }
02278
02289
02290 #define TNC_TX_DELAY 45
02291
02293 #define TNC_BUFFER_SIZE 80
02294
02296 enum TNC_TX_1200BPS_STATE
02297 {
02299 TNC_TX_READY,
02300
02302 TNC_TX_SYNC,
02303
02305 TNC_TX_HEADER,
02306
02308 TNC_TX_DATA,
02309
02311 TNC_TX_END
02312 };
02313
02315 enum TNC_MESSAGE_TYPE
02316 {
02318 TNC_BOOT_MESSAGE,
02319
02321 TNC_STATUS,
02322
02324 TNC_GGA,
02325
02327 TNC_RMC
02328 };
02329
02332 uint8_t TNC_AX25_HEADER[30] = {
02333 'A' << 1, 'P' << 1, 'R' << 1, 'S' << 1, ' ' << 1, ' ' << 1, 0x60, \
02334 'K' << 1, 'D' << 1, '7' << 1, 'L' << 1, 'M' << 1, 'O' << 1, 0x76, \
02335 'G' << 1, 'A' << 1, 'T' << 1, 'E' << 1, ' ' << 1, ' ' << 1, 0x60, \
02336 'W' << 1, 'I' << 1, 'D' << 1, 'E' << 1, '3' << 1, ' ' << 1, 0x67, \
02337 0x03, 0xf0 };
02338
02339
02341 uint8_t tncTxBit;
02342
02344 TNC_TX_1200BPS_STATE tncMode;
02345
02347 uint8_t tncBitCount;
02348
02350 uint8_t tncShift;
02351
02353 uint8_t tncIndex;
02354
02356 uint8_t tncLength;
02357
02359 uint8_t tncBitStuff;
02360
02362 uint8_t *tncBufferPnt;
02363
02365 TNC_MESSAGE_TYPE tncPacketType;
02366
02368 uint8_t tncBuffer[TNC_BUFFER_SIZE];
02369
02371 bool_t tncHighRateFlag;
02372
02376 void tncInit()
02377 {
02378 tncTxBit = 0;
02379 tncMode = TNC_TX_READY;
02380 tncPacketType = TNC_BOOT_MESSAGE;
02381 tncHighRateFlag = false;
02382 }
02383
02389 bool_t tncIsFree()
02390 {
02391 if (tncMode == TNC_TX_READY)
02392 return true;
02393
02394 return false;
02395 }
02396
02397 void tncHighRate(bool_t state)
02398 {
02399 tncHighRateFlag = state;
02400 }
02401
02407 void tncSetMode(TNC_DATA_MODE dataMode)
02408 {
02409 switch (dataMode)
02410 {
02411 case TNC_MODE_1200_AFSK:
02412 ddsSetMode (DDS_MODE_AFSK);
02413 break;
02414
02415 case TNC_MODE_9600_FSK:
02416 ddsSetMode (DDS_MODE_FSK);
02417
02418
02419 ddsSetFSKFreq (955382980, 955453621);
02420 break;
02421 }
02422
02423 tncDataMode = dataMode;
02424 }
02425
02434 bool_t tncIsTimeSlot (uint8_t timeSeconds)
02435 {
02436 if (tncHighRateFlag)
02437 {
02438 if ((timeSeconds % 5) == 0)
02439 return true;
02440
02441 return false;
02442 }
02443
02444 switch (timeSeconds)
02445 {
02446 case 7:
02447 case 25:
02448 case 37:
02449 case 55:
02450 return true;
02451
02452 default:
02453 return false;
02454 }
02455 }
02456
02461 void tnc1200TimerTick()
02462 {
02463
02464 if (tncTxBit == 0x00)
02465 timeNCOFreq = 0x2000;
02466 else
02467 timeNCOFreq = 0x3aab;
02468
02469 switch (tncMode)
02470 {
02471 case TNC_TX_READY:
02472
02473 tncTxBit = (tncTxBit == 0 ? 1 : 0);
02474 break;
02475
02476 case TNC_TX_SYNC:
02477
02478
02479 if ((tncShift & 0x01) == 0x00)
02480 if (tncTxBit == 0)
02481 tncTxBit = 1;
02482 else
02483 tncTxBit = 0;
02484
02485
02486 if (++tncBitCount == 8)
02487 {
02488 tncBitCount = 0;
02489 tncShift = 0x7e;
02490
02491
02492
02493 if (++tncIndex == TNC_TX_DELAY)
02494 {
02495 tncIndex = 0;
02496 tncShift = TNC_AX25_HEADER[0];
02497 tncBitStuff = 0;
02498 tncMode = TNC_TX_HEADER;
02499 }
02500 } else
02501 tncShift = tncShift >> 1;
02502 break;
02503
02504 case TNC_TX_HEADER:
02505
02506 if (tncBitStuff == 0x1f)
02507 {
02508 if (tncTxBit == 0)
02509 tncTxBit = 1;
02510 else
02511 tncTxBit = 0;
02512
02513 tncBitStuff = 0x00;
02514 return;
02515 }
02516
02517
02518
02519 if ((tncShift & 0x01) == 0x00)
02520 if (tncTxBit == 0)
02521 tncTxBit = 1;
02522 else
02523 tncTxBit = 0;
02524
02525
02526
02527 tncBitStuff = ((tncBitStuff << 1) | (tncShift & 0x01)) & 0x1f;
02528
02529
02530 if (++tncBitCount == 8)
02531 {
02532 tncBitCount = 0;
02533
02534
02535 if (++tncIndex == sizeof(TNC_AX25_HEADER))
02536 {
02537 tncIndex = 0;
02538 tncShift = tncBuffer[0];
02539 tncMode = TNC_TX_DATA;
02540 } else
02541 tncShift = TNC_AX25_HEADER[tncIndex];
02542
02543 } else
02544 tncShift = tncShift >> 1;
02545
02546 break;
02547
02548 case TNC_TX_DATA:
02549
02550 if (tncBitStuff == 0x1f)
02551 {
02552 if (tncTxBit == 0)
02553 tncTxBit = 1;
02554 else
02555 tncTxBit = 0;
02556
02557 tncBitStuff = 0x00;
02558 return;
02559 }
02560
02561
02562
02563 if ((tncShift & 0x01) == 0x00)
02564 if (tncTxBit == 0)
02565 tncTxBit = 1;
02566 else
02567 tncTxBit = 0;
02568
02569
02570
02571 tncBitStuff = ((tncBitStuff << 1) | (tncShift & 0x01)) & 0x1f;
02572
02573
02574 if (++tncBitCount == 8)
02575 {
02576 tncBitCount = 0;
02577
02578
02579 if (++tncIndex == tncLength)
02580 {
02581 tncIndex = 0;
02582 tncShift = 0x7e;
02583 tncMode = TNC_TX_END;
02584 } else
02585 tncShift = tncBuffer[tncIndex];
02586
02587 } else
02588 tncShift = tncShift >> 1;
02589
02590 break;
02591
02592 case TNC_TX_END:
02593
02594
02595 if ((tncShift & 0x01) == 0x00)
02596 if (tncTxBit == 0)
02597 tncTxBit = 1;
02598 else
02599 tncTxBit = 0;
02600
02601
02602 if (++tncBitCount == 8)
02603 {
02604 tncBitCount = 0;
02605 tncShift = 0x7e;
02606
02607
02608 if (++tncIndex == 2)
02609 {
02610 tncMode = TNC_TX_READY;
02611
02612
02613 tncDataMode = TNC_MODE_STANDBY;
02614
02615
02616 output_low (IO_OSK);
02617 output_low (IO_PTT);
02618 ddsSetMode (DDS_MODE_POWERDOWN);
02619
02620 return;
02621 }
02622 } else
02623 tncShift = tncShift >> 1;
02624
02625 break;
02626 }
02627 }
02628
02632 void tnc9600TimerTick()
02633 {
02634
02635 }
02636
02644 void tncTxByte (uint8_t character)
02645 {
02646 *tncBufferPnt++ = character;
02647 ++tncLength;
02648 }
02649
02654 void tncNMEATime()
02655 {
02656
02657 printf (tncTxByte, "%02d%02d%02d,", gpsPosition.hours, gpsPosition.minutes, gpsPosition.seconds);
02658 }
02659
02664 void tncNMEAFix()
02665 {
02666 uint8_t dirChar;
02667 uint32_t coord, coordMin;
02668
02669
02670 coord = gpsPosition.latitude;
02671
02672 if (gpsPosition.latitude < 0)
02673 {
02674 coord = gpsPosition.latitude * -1;
02675 dirChar = 'S';
02676 } else {
02677 coord = gpsPosition.latitude;
02678 dirChar = 'N';
02679 }
02680
02681 coordMin = (coord % 3600000) / 6;
02682 printf (tncTxByte, "%02ld%02ld.%04ld,%c,", (uint32_t) (coord / 3600000), (uint32_t) (coordMin / 10000), (uint32_t) (coordMin % 10000), dirChar);
02683
02684
02685
02686 if (gpsPosition.longitude < 0)
02687 {
02688 coord = gpsPosition.longitude * - 1;
02689 dirChar = 'W';
02690 } else {
02691 coord = gpsPosition.longitude;
02692 dirChar = 'E';
02693 }
02694
02695 coordMin = (coord % 3600000) / 6;
02696 printf (tncTxByte, "%03ld%02ld.%04ld,%c,", (uint32_t) (coord / 3600000), (uint32_t) (coordMin / 10000), (uint32_t) (coordMin % 10000), dirChar);
02697
02698 }
02699
02704 void tncGPGGAPacket()
02705 {
02706
02707 printf (tncTxByte, "$GPGGA,");
02708
02709
02710 tncNMEATime();
02711
02712
02713 tncNMEAFix();
02714
02715
02716 if (gpsGetFixType() != GPS_NO_FIX)
02717 printf (tncTxByte, "1,");
02718 else
02719 printf (tncTxByte, "0,");
02720
02721
02722 printf (tncTxByte, "%02d,", gpsPosition.trackedSats);
02723
02724
02725 printf (tncTxByte, "%ld.%01ld,", gpsPosition.dop / 10, gpsPosition.dop % 10);
02726
02727
02728 printf (tncTxByte, "%ld.%02ld,M,,M,,", (int32_t) (gpsPosition.altitudeCM / 100l), (int32_t) (gpsPosition.altitudeCM % 100));
02729
02730
02731 printf (tncTxByte, "*%02X", gpsNMEAChecksum(tncBuffer + 1, tncLength - 1));
02732 }
02733
02738 void tncGPRMCPacket()
02739 {
02740 uint32_t temp;
02741
02742
02743 printf (tncTxByte, "$GPRMC,");
02744
02745
02746 tncNMEATime();
02747
02748
02749 if (gpsGetFixType() != GPS_NO_FIX)
02750 printf (tncTxByte, "A,");
02751 else
02752 printf (tncTxByte, "V,");
02753
02754
02755 tncNMEAFix();
02756
02757
02758 temp = (int32_t) gpsPosition.hSpeed * 75000 / 385826;
02759 printf (tncTxByte, "%ld.%ld,%ld.%ld,", (int16_t) (temp / 10), (int16_t) (temp % 10), gpsPosition.heading / 10, gpsPosition.heading % 10);
02760
02761
02762 printf (tncTxByte, "%02d%02d%02ld,,", gpsPosition.day, gpsPosition.month, gpsPosition.year % 100);
02763
02764
02765 printf (tncTxByte, "*%02X", gpsNMEAChecksum(tncBuffer + 1, tncLength - 1));
02766 }
02767
02772 void tncStatusPacket(int16_t temperature)
02773 {
02774 uint16_t voltage;
02775
02776
02777 printf (tncTxByte, ">ANSR ");
02778
02779
02780 printf (tncTxByte, "%02U:%02U:%02U ", timeHours, timeMinutes, timeSeconds);
02781
02782
02783 printf (tncTxByte, "%ld' ", gpsPosition.altitudeFeet);
02784
02785
02786 printf (tncTxByte, "%ld'pk ", gpsGetPeakAltitude());
02787
02788
02789 printf (tncTxByte, "%lu.%lu", gpsPosition.dop / 10, gpsPosition.dop % 10);
02790
02791
02792 switch (gpsGetFixType())
02793 {
02794 case GPS_NO_FIX:
02795 printf (tncTxByte, "dop ");
02796 break;
02797
02798 case GPS_2D_FIX:
02799 printf (tncTxByte, "hdop ");
02800 break;
02801
02802 case GPS_3D_FIX:
02803 printf (tncTxByte, "pdop ");
02804 break;
02805 }
02806
02807
02808 printf (tncTxByte, "%utrk ", gpsPosition.trackedSats);
02809
02810
02811 voltage = adcGetMainBusVolt();
02812 printf (tncTxByte, "%lu.%02luvdc ", voltage / 100, voltage % 100);
02813
02814
02815 printf (tncTxByte, "%ld.%01ldF ", temperature / 10, abs(temperature % 10));
02816
02817
02818 printf (tncTxByte, "www.kd7lmo.net");
02819 }
02820
02827 void tncTxPacket(TNC_DATA_MODE dataMode)
02828 {
02829 int16_t temperature;
02830 uint16_t crc;
02831
02832
02833 if (tncMode != TNC_TX_READY)
02834 return;
02835
02836
02837 sysLogVoltage();
02838
02839
02840 temperature = lm92GetTemp();
02841
02842
02843 logType (LOG_TEMPERATURE);
02844 logInt16 (temperature);
02845
02846
02847 tncSetMode (dataMode);
02848
02849
02850 tncBufferPnt = tncBuffer;
02851
02852
02853 tncLength = 0;
02854
02855
02856 switch (tncPacketType)
02857 {
02858 case TNC_BOOT_MESSAGE:
02859 printf (tncTxByte, ">ANSR Pico Beacon - V3.05");
02860
02861
02862 tncPacketType = TNC_STATUS;
02863 break;
02864
02865 case TNC_STATUS:
02866 tncStatusPacket(temperature);
02867
02868
02869 tncPacketType = TNC_GGA;
02870 break;
02871
02872 case TNC_GGA:
02873 tncGPGGAPacket();
02874
02875
02876 tncPacketType = TNC_RMC;
02877 break;
02878
02879 case TNC_RMC:
02880 tncGPRMCPacket();
02881
02882
02883 tncPacketType = TNC_STATUS;
02884 break;
02885 }
02886
02887
02888 printf (tncTxByte, "\015");
02889
02890
02891 crc = sysCRC16(TNC_AX25_HEADER, sizeof(TNC_AX25_HEADER), 0xffff);
02892 crc = sysCRC16(tncBuffer, tncLength, crc ^ 0xffff);
02893
02894
02895 *tncBufferPnt++ = crc & 0xff;
02896 *tncBufferPnt = (crc >> 8) & 0xff;
02897
02898
02899 tncLength += 2;
02900
02901
02902 tncBitCount = 0;
02903 tncShift = 0x7e;
02904 tncTxBit = 0;
02905 tncIndex = 0;
02906 tncMode = TNC_TX_SYNC;
02907
02908
02909 output_high (IO_PTT);
02910
02911
02912 delay_ms (10);
02913
02914
02915 output_high (IO_OSK);
02916
02917
02918 sysLogVoltage();
02919 }
02920
02923 uint32_t counter;
02924
02925 uint8_t bitIndex;
02926 uint8_t streamIndex;
02927 uint8_t value;
02928
02929 uint8_t bitStream[] = { 0x10, 0x20, 0x30 };
02930
02931 void init()
02932 {
02933 counter = 0;
02934 bitIndex = 0;
02935 streamIndex = 0;
02936 value = bitStream[0];
02937 }
02938
02939 void test()
02940 {
02941 counter += 0x10622d;
02942
02943 CCP_1 = (uint16_t) ((counter >> 16) & 0xffff);
02944
02945 if ((value & 0x80) == 0x80)
02946 setup_ccp1 (CCP_COMPARE_SET_ON_MATCH);
02947 else
02948 setup_ccp1 (CCP_COMPARE_CLR_ON_MATCH);
02949
02950 if (++bitIndex == 8)
02951 {
02952 bitIndex = 0;
02953
02954 if (++streamIndex == sizeof(bitStream))
02955 {
02956 streamIndex = 0;
02957 }
02958
02959 value = bitStream[streamIndex];
02960 } else
02961 value = value << 1;
02962 }
02963
02964
02965 void main()
02966 {
02967 uint8_t i, utcSeconds, lockLostCounter;
02968
02969 test();
02970
02971
02972 sysInit();
02973
02974
02975 delay_ms (100);
02976
02977
02978 adcInit();
02979 flashInit();
02980 gpsInit();
02981 logInit();
02982 timeInit();
02983 serialInit();
02984 tncInit();
02985
02986
02987 ddsInit();
02988
02989
02990 output_low (IO_LED);
02991
02992
02993 diagPort();
02994
02995
02996 enable_interrupts(GLOBAL);
02997 enable_interrupts(INT_CCP1);
02998
02999
03000 gpsPowerOn();
03001
03002
03003 delay_ms (250);
03004
03005
03006 while (!gpsSetup());
03007
03008
03009 for (i = 0; i < 32; ++i)
03010 adcUpdate();
03011
03012
03013 logType (LOG_BOOTED);
03014 logUint8 (gpsPosition.month);
03015 logUint8 (gpsPosition.day);
03016 logUint8 (gpsPosition.year & 0xff);
03017
03018 logUint8 (gpsPosition.hours);
03019 logUint8 (gpsPosition.minutes);
03020 logUint8 (gpsPosition.seconds);
03021
03022
03023 tncTxPacket(TNC_MODE_1200_AFSK);
03024
03025
03026 lockLostCounter = 5;
03027 utcSeconds = 55;
03028
03029
03030 for (;;)
03031 {
03032
03033 gpsUpdate();
03034
03035 if (gpsIsReady())
03036 {
03037
03038 if (gpsGetFixType() == GPS_3D_FIX)
03039 timeSetRunFlag();
03040
03041
03042 if (tncIsTimeSlot(gpsPosition.seconds))
03043 tncTxPacket(TNC_MODE_1200_AFSK);
03044
03045
03046 utcSeconds = gpsPosition.seconds;
03047
03048
03049 lockLostCounter = 0;
03050
03051
03052 sysLogGPSData();
03053 }
03054
03055
03056 if (timeIsUpdate())
03057 {
03058
03059 if (++utcSeconds == 60)
03060 utcSeconds = 0;
03061
03062
03063
03064 if (lockLostCounter == 5)
03065 {
03066 if (tncIsTimeSlot(utcSeconds))
03067 tncTxPacket(TNC_MODE_1200_AFSK);
03068 } else
03069 ++lockLostCounter;
03070
03071
03072 adcUpdate();
03073
03074 if (timeHours == 5 && timeMinutes == 0 && timeSeconds == 0)
03075 gpsPowerOff();
03076
03077 }
03078
03079 }
03080 }
03081
03082