Compare commits

..
152 Commits
Author SHA1 Message Date
Andy CA6JAU 9410e724b8 Increasing TX buffer for NXDN 2018-02-18 12:21:20 -03:00
Jonathan Naylor 6f7b95a15c Merge branch 'master' into nxdn 2018-02-14 06:47:18 +00:00
Jonathan Naylor d5c2fe9280 Change the TX Delay calculation because of the longer symbol length. 2018-02-12 19:23:21 +00:00
Jonathan Naylor 450005d611 Merge pull request #152 from juribeparada/nxdn
Add NXDN 1031 Hz Test Pattern and Merge branch 'master' into nxdn
2018-02-12 15:34:13 +00:00
Andy CA6JAU 97a72f5b7f Fix Config.h overwrite for previous commit 2018-02-12 10:45:38 -03:00
Andy CA6JAU ce6d03ae13 Add NXDN 1031 Hz Test Pattern 2018-02-12 10:34:49 -03:00
Jonathan Naylor 23f7b6a750 Merge pull request #151 from juribeparada/master
Add DMR 1031 Hz Test Pattern support for DMO mode
2018-02-12 06:41:00 +00:00
Andy CA6JAU 36a4404c5c Merge branch 'master' into nxdn 2018-02-11 22:09:53 -03:00
Andy CA6JAU 66241f2f1b Add DMR 1031 Hz Test Pattern for DMO mode 2018-02-11 21:37:54 -03:00
Jonathan Naylor e5aab0f165 Merge pull request #150 from juribeparada/nxdn
Merge branch 'master' into nxdn
2018-02-11 08:41:20 +00:00
Andy CA6JAU 14a4dc2bf9 Merge branch 'master' into nxdn 2018-02-10 21:00:59 -03:00
Andy CA6JAU 42408d5a9a Merge remote-tracking branch 'g4klx/nxdn' into nxdn 2018-02-10 21:00:47 -03:00
Andy CA6JAU 55cb3945df Merge remote-tracking branch 'g4klx/master' 2018-02-10 20:59:56 -03:00
Jonathan Naylor a4a95ba5d0 Merge pull request #149 from juribeparada/master
Fixing inverse SINC TX filter for P25
2018-02-10 20:42:07 +00:00
Andy CA6JAU 8a1ac05df2 Fixing inverse SINC TX filter for P25 2018-02-10 14:44:30 -03:00
Jonathan Naylor 78ae7f3b33 Merge pull request #148 from juribeparada/devel
Add some additional idle frames after a DMR Abort
2018-02-09 22:16:25 +00:00
Jonathan Naylor c783d6d101 Merge pull request #147 from juribeparada/nxdn
Add SINC filter for NXDN modulator and new deviation values
2018-02-09 06:38:34 +00:00
Andy CA6JAU 3ea95ce53d Add SINC filter for NXDN modulator and new deviation values 2018-02-08 21:31:45 -03:00
Andy CA6JAU 16d978cea2 Merge remote-tracking branch 'g4klx/nxdn' into nxdn 2018-02-08 18:47:01 -03:00
Jonathan Naylor e43c992249 Merge pull request #146 from juribeparada/nxdn
Add inverse SINC filter for NXDN demodulator
2018-02-08 21:42:32 +00:00
Andy CA6JAU e78fc5b701 Merge remote-tracking branch 'g4klx/nxdn' into nxdn 2018-02-08 18:35:05 -03:00
Andy CA6JAU eebfc56013 Add inverse SINC filter for NXDN demodulator 2018-02-08 18:34:53 -03:00
Jonathan Naylor 1d4bd4e409 Make NXDN sync detection more lenient when receiving a transmission. 2018-02-08 18:40:23 +00:00
Jonathan Naylor 9f28d2f69a Small cleanup. 2018-02-07 21:02:07 +00:00
Andy CA6JAU 9c01a6328a Merge remote-tracking branch 'g4klx/nxdn' into nxdn 2018-02-07 17:32:54 -03:00
Jonathan Naylor 46528127dc Add support for NXDN 4800. 2018-02-07 20:25:16 +00:00
Jonathan Naylor b34d3c3dbd Revert "Start work on 4800 baud NXDN support."
This reverts commit a6b6219c6d.
2018-02-07 18:07:51 +00:00
Andy CA6JAU 2bc99deec2 Additional available data FIFO check 2018-02-07 13:55:15 -03:00
Jonathan Naylor a6b6219c6d Start work on 4800 baud NXDN support. 2018-02-07 07:52:18 +00:00
Andy CA6JAU caaf090b10 DMR abort counter for each slot 2018-02-05 22:36:05 -03:00
Andy CA6JAU 01b7641bd1 Merge remote-tracking branch 'g4klx/nxdn' into nxdn 2018-02-05 18:44:44 -03:00
Andy CA6JAU b42ddbbf42 Merge remote-tracking branch 'g4klx/master' 2018-02-05 18:41:35 -03:00
Jonathan Naylor f32b8dc4e8 Merge branch 'master' into nxdn 2018-02-05 20:06:46 +00:00
Jonathan Naylor 9e6a4ca6df Merge pull request #145 from juribeparada/master
Fix mistake reading COS input pin using STM32F4 and STM32F7
2018-02-05 14:12:11 +00:00
Andy CA6JAU 91e5d588b0 Fix mistake reading COS input pin using STM32F4 and STM32F7 2018-02-05 09:42:40 -03:00
Andy CA6JAU 555c308749 Updating DMR abort delay 2018-02-05 09:12:05 -03:00
Andy CA6JAU 7b88e883f9 Adding some additional idle frames after a DMR Abort 2018-02-03 20:10:25 -03:00
Andy CA6JAU e7b52023c6 Merge remote-tracking branch 'g4klx/master' 2018-02-03 20:04:52 -03:00
Jonathan Naylor e7a40343b1 Adjust NXDN deviation slightly. 2018-01-22 19:58:39 +00:00
Jonathan Naylor dfc262bbcd Changes based on first NXDN RF tests. 2018-01-18 21:25:26 +00:00
Jonathan Naylor 615c705044 Fix byte ordering for NXDN syncs. 2018-01-15 20:07:00 +00:00
Jonathan Naylor c59c32b350 Incorporate NXDN specification values for errors. 2018-01-11 19:47:23 +00:00
Jonathan Naylor d69df42de4 Add the NXDN TX preamble. 2018-01-11 18:29:58 +00:00
Jonathan Naylor 99dafe6327 Merge branch 'master' into nxdn 2018-01-11 07:27:52 +00:00
Jonathan Naylor 5da3c9352d Merge pull request #140 from juribeparada/nxdn
Fixing STM32F4 and STM32F7 pin definitions for NXDN
2018-01-11 07:22:39 +00:00
Jonathan Naylor fdc15b355f Merge pull request #139 from juribeparada/master
Reducing the bit error number for the EOT sequence (D-Star)
2018-01-11 07:21:23 +00:00
Andy CA6JAU 4f49f65a1c Fixing STM32F4 and STM32F7 pin definitions for NXDN 2018-01-11 01:50:41 -03:00
Andy CA6JAU d99e21f0f9 Reducing the bit error number for the EOT sequence (D-Star) 2018-01-10 20:04:29 -03:00
Jonathan Naylor 9b5bbee265 Add actual NXDN values. 2018-01-10 21:39:29 +00:00
Jonathan Naylor b5ca5e3839 NXDN first cut, not working yet. 2018-01-10 20:30:35 +00:00
Andy CA6JAU b988750e78 Merge remote-tracking branch 'g4klx/master' 2018-01-07 10:28:31 -03:00
Jonathan Naylor 78a51d416d Merge pull request #137 from sfowlr/master
STM32-DVM & MMDVM_POG RSSI bugfix
2018-01-07 13:28:01 +00:00
Jonathan Naylor 3a539e1243 Merge pull request #138 from juribeparada/master
Adding P25 1011 Hz Test Pattern
2018-01-07 13:27:42 +00:00
Andy CA6JAU db133c819e Add comments 2018-01-07 09:48:30 -03:00
Andy CA6JAU 02d5218baa Changing name DMR1KCAL to DMRCAL1K 2018-01-07 00:24:58 -03:00
Andy CA6JAU 394d0cbc6b Merge remote-tracking branch 'g4klx/master' 2018-01-07 00:07:35 -03:00
Andy CA6JAU b4456aed28 Adding P25 1011 Hz Test Pattern 2018-01-07 00:06:41 -03:00
Spencer Fowler 9e56268156 STM32-DVM & MMDVM_POG RSSI bugfix 2018-01-06 18:48:56 -06:00
Jonathan Naylor 94e65ba6cc Merge pull request #136 from juribeparada/master
Adding DMR 1031 Hz Test Pattern
2018-01-06 14:31:02 +00:00
Andy CA6JAU 2ec02e53e3 Fix comment and formatting 2018-01-06 11:05:43 -03:00
Andy CA6JAU c6e9227aee More cleanup and adding comments 2018-01-06 11:00:03 -03:00
Andy CA6JAU e1d1faea82 Code reordering and cleanup 2018-01-04 01:10:33 -03:00
Andy CA6JAU 4871ad1210 Adding DMR 1031 Hz Test Pattern 2018-01-03 00:55:14 -03:00
Jonathan Naylor 7b03336469 Merge pull request #134 from juribeparada/master
Adding 80 Hz square wave test signal support for MMDVMCal
2017-12-31 11:30:55 +00:00
Andy CA6JAU b846e5a7f3 Adding 80 Hz square wave test signal support 2017-12-30 20:47:48 -03:00
Andy CA6JAU ee1d512132 Merge remote-tracking branch 'g4klx/master' 2017-12-30 18:19:16 -03:00
Jonathan Naylor 628665175c Merge pull request #126 from juribeparada/devel
Adding support for MMDVM-Pi with STM32F722
2017-11-06 09:32:28 +00:00
Andy CA6JAU a921df7335 Separating linker script for F722 and F767 2017-11-04 15:28:38 -03:00
Andy CA6JAU 6bbc716e4b Fixing delay loop for all STM32F7 devices 2017-11-04 15:27:32 -03:00
Andy CA6JAU cf448158cb Adding support for MMDVM-Pi with STM32F722 2017-11-02 00:41:26 -03:00
Andy CA6JAU 6a6688ea8d Merge remote-tracking branch 'g4klx/master' 2017-11-01 21:01:30 -03:00
Andy CA6JAU c86ba51523 Merge remote-tracking branch 'g4klx/master' into devel 2017-11-01 21:01:07 -03:00
Jonathan Naylor a8eae44209 Merge pull request #125 from juribeparada/devel
Adding pin definitions for MMDVM-F4M Pi-Hat F0DEI board
2017-10-30 14:05:13 +00:00
Jonathan Naylor efa407a579 Add the optional RX DC Offset. 2017-10-28 12:45:04 +01:00
Andy CA6JAU b54dc34215 Fix mistake in Makefile 2017-10-22 22:55:35 -03:00
Andy CA6JAU 167296200d Adding pin definitions for MMDVM-F4M Pi-Hat F0DEI board 2017-10-22 22:48:16 -03:00
Andy CA6JAU ca6601ca6d Merge remote-tracking branch 'g4klx/master' 2017-10-22 21:00:03 -03:00
Jonathan Naylor 8d7b4ef84d Merge pull request #124 from juribeparada/master
Better way for sampling frequency calculation for MMDVM-Pi
2017-10-16 09:23:58 +01:00
Andy CA6JAU 2279162db5 Better way for sampling frequency calculation for MMDVM-Pi 2017-10-15 17:32:24 -03:00
Jonathan Naylor 9cfbdebc7b Merge pull request #122 from juribeparada/master
No external clock needed for MMDVM-Pi
2017-10-15 13:19:59 +01:00
Andy CA6JAU 7583446380 No external clock needed for MMDVM-Pi 2017-10-14 21:26:53 -03:00
Andy CA6JAU 94b4fe3fd6 Merge remote-tracking branch 'g4klx/master' 2017-10-02 14:21:30 -03:00
Jonathan Naylor d86b10fc1d Merge pull request #117 from juribeparada/master
Fix some comments for STM32F4XX & STM32F7XX
2017-10-02 16:33:22 +01:00
Andy CA6JAU 7996a45125 Fix some comments for STM32FXXX 2017-10-02 12:20:25 -03:00
Jonathan Naylor 655e7f8218 Merge pull request #115 from juribeparada/master
Separating STM32F4 and STM32F7 compilation in Makefile
2017-09-27 09:19:29 +01:00
Andy CA6JAU c2a3f83a9f Separating STM32F4 and STM32F7 compilation in Makefile 2017-09-24 20:52:05 -03:00
Andy CA6JAU 0505e76422 Removing cstddef include for better toolchain compatibility (F4 & F7 devices). Please update the Lib. 2017-09-23 12:47:43 -03:00
Andy CA6JAU 265828b127 Merge remote-tracking branch 'g4klx/master' 2017-09-23 12:32:53 -03:00
Jonathan Naylor 4134a656b0 Merge pull request #114 from phl0/CreateBinaryOnCompile
Create .bin on compile target instead of upload
2017-09-10 13:30:31 +01:00
phl0 cd0bd6e5c4 Create .bin on compile target instead of upload 2017-09-10 14:04:41 +02:00
Jonathan Naylor 418ce895cb Merge pull request #113 from juribeparada/master
Changing service LED pinout for F767
2017-09-07 07:14:44 +01:00
Andy CA6JAU 8a9510b48a Fixing pinout information for Nucleo64 F446 and Nucleo144 F767 2017-09-06 23:23:24 -03:00
Andy CA6JAU b22ada3fa2 Changing service LED pinout for F767 2017-09-06 23:02:02 -03:00
Andy CA6JAU b4ac4838fd Merge remote-tracking branch 'g4klx/master' 2017-09-04 00:18:16 -03:00
Jonathan Naylor 89000729d2 Merge pull request #112 from N4IRS/patch-1
Fix undefined reference
2017-08-31 08:37:52 +01:00
Steve Zingman abea72b4d5 Fix undefined reference
Fix undefined reference to `CIO::delayInt(unsigned int)' for LED test
2017-08-30 21:13:33 -04:00
Jonathan Naylor 76c3e5786c Merge pull request #111 from juribeparada/master
Adding LEDs selftest at start-up
2017-08-29 20:24:57 +01:00
Andy CA6JAU 793407fe16 Merge remote-tracking branch 'g4klx/master' 2017-08-29 14:52:24 -03:00
Andy CA6JAU 990bf2a16a Fix delay function for F767 2017-08-29 14:51:20 -03:00
Andy CA6JAU ea37f67b91 Adding conditional compilation for LED selftest 2017-08-29 14:39:16 -03:00
Andy CA6JAU a805652f48 Change the LED sequence 2017-08-29 08:48:20 -03:00
Andy CA6JAU eb4cd221b2 Changing LEDs sequence 2017-08-29 00:57:52 -03:00
Andy CA6JAU a244b86f36 Exclude PTT to avoid trigger the transmitter 2017-08-28 13:49:52 -03:00
Jonathan Naylor 56a12a61c2 Merge pull request #107 from phl0/fixYSF
Refactor variable initialization in YSFRX.h
2017-08-28 08:28:34 +01:00
phl0 595f38b796 Refactor variable initialization in YSFRX.h 2017-08-28 07:48:25 +02:00
Andy CA6JAU d6b7796c25 Merge remote-tracking branch 'g4klx/master' 2017-08-28 00:44:59 -03:00
Andy CA6JAU 70e1fd4264 Adding LEDs selftest at start-up 2017-08-28 00:43:24 -03:00
Jonathan Naylor 00bc8be152 Merge pull request #106 from juribeparada/master
Add support for STM32F767 (Nucleo-144 F767ZI)
2017-08-27 22:47:42 +01:00
Andy CA6JAU cce2cc3cfc Including F767 target into the Makefile 2017-08-27 16:28:08 -03:00
Andy CA6JAU 1f5a4f1ad7 Removing unnecessary “defined(STM32F4)” 2017-08-27 15:20:46 -03:00
Andy CA6JAU a60059bc90 Adding preliminary support for STM32F767 (Nucleo-144 F767ZI) 2017-08-24 22:24:27 -03:00
Andy CA6JAU 6c6b6c19fc Merge remote-tracking branch 'g4klx/master' 2017-08-24 21:22:45 -03:00
Jonathan Naylor 5b1075f0f7 Merge pull request #104 from juribeparada/master
Adding watchdog to host serial port
2017-08-20 15:41:04 +01:00
Andy CA6JAU 17007dd1e4 Merge remote-tracking branch 'g4klx/master' 2017-08-20 11:20:52 -03:00
Andy CA6JAU 8f317fd332 Adding watchdog to host serial port 2017-08-20 11:19:58 -03:00
Jonathan Naylor 1cee9e19c0 Add an adjustable transmit DC offset. 2017-08-20 12:07:05 +01:00
Andy CA6JAU 5b313b7cec Replace “GPIO_Speed_50MHz” definition for a better one “GPIO_Fast_Speed” (STM32F4) 2017-08-19 13:54:03 -03:00
Andy CA6JAU 8b52d372eb Merge remote-tracking branch 'g4klx/master' 2017-08-19 10:05:03 -03:00
Jonathan Naylor f4637585f6 Re-add the const qualifiers. 2017-08-18 10:57:47 +01:00
Jonathan Naylor 3e03fcff8e Fix the lengths in the DC removal code. 2017-08-18 10:42:41 +01:00
Jonathan Naylor 74682e7ac0 Optimise the DC offset code. 2017-08-18 10:27:23 +01:00
Andy CA6JAU 20cf355e7e Merge remote-tracking branch 'g4klx/master' 2017-08-13 17:17:25 -03:00
Jonathan Naylor 04ca97e5f8 Add enhancements suggested by IZ1MLT. 2017-08-13 18:51:09 +01:00
Jonathan Naylor 669acb99e8 Remove the DC blocker from DMR. 2017-07-31 21:54:26 +01:00
Jonathan Naylor ba81fa7396 Forgot this file. 2017-07-16 18:58:12 +01:00
Jonathan Naylor 8540964097 Remove any DC offset from before any further filtering takes place. 2017-07-16 18:57:15 +01:00
Jonathan Naylor 9d1ebc0f8f Small refactor. 2017-07-10 19:41:01 +01:00
Andy CA6JAU 786e57d043 Merge remote-tracking branch 'g4klx/master' 2017-07-09 16:57:37 -04:00
Jonathan Naylor 902b079de2 Merge pull request #100 from juribeparada/devel
DC estimator filter for all modes
2017-07-09 21:22:52 +01:00
Andy CA6JAU 54f54ab518 Remove unused variables 2017-07-09 15:02:30 -04:00
Andy CA6JAU f8d767913e Adding DC estimator filter for all modes 2017-07-06 00:51:46 -04:00
Jonathan Naylor 266db8bedb Merge pull request #99 from juribeparada/master
Workaround for stm32flash bug and STM32F446 Pi version
2017-07-04 20:03:28 +01:00
Andy CA6JAU 6c4496e034 Updating Coocox project file 2017-07-04 13:42:51 -04:00
Andy CA6JAU 8db83708ca Disabling default enabled SEND_RSSI_DATA and SERIAL_REPEATER for STM32F446 Pi version 2017-07-04 13:39:01 -04:00
Andy CA6JAU 7f45a0da83 Workaround for stm32flash bug and STM32F446 Pi version 2017-07-04 13:35:44 -04:00
Andy CA6JAU ce03ad4ab7 Merge remote-tracking branch 'g4klx/master' 2017-07-04 13:32:17 -04:00
Jonathan Naylor ae9e35ccad Merge pull request #98 from phl0/dev
Added some more description on pinouts of STM
2017-06-21 19:15:04 +01:00
phl0 9e5234539e Add pin number for STM32F4 discovery 2017-06-21 12:53:04 +02:00
phl0 dea7c714c0 Add pin numbers for morpho header 2017-06-21 12:44:53 +02:00
phl0 4690186812 Add pin numbers 2017-06-21 12:36:11 +02:00
Andy CA6JAU 399b6e1d85 Merge remote-tracking branch 'g4klx/master' 2017-06-18 10:01:50 -04:00
Jonathan Naylor c2ed9d4ae7 Merge pull request #97 from phl0/fixUpload
Fix Arduino Makefile to include GitVersion on upload
2017-06-06 12:08:31 +01:00
phl0 1dc23a4aa6 Fix Arduino Makefile to include GitVersion on upload 2017-06-06 10:50:53 +02:00
Jonathan Naylor 61b05dd5af Merge pull request #96 from N4IRS/master
Fix USART2 to USART1 after PR 94
2017-06-04 14:40:41 +01:00
Steve N4IRS 00a7f15011 Fix USART2 to USART1 after PR 94 2017-06-04 08:27:12 -04:00
Jonathan Naylor 8a5d5bc286 Merge pull request #93 from wojciechk8/mmdvm_pog_rev1
MMDVM_pog revision 1.0 changes
2017-06-03 17:19:38 +01:00
Jonathan Naylor c80c6a7797 Merge pull request #94 from sq6pog/master
Starting LED animation for MMDVM_pog board
2017-06-01 17:24:40 +01:00
SQ6POG 96c214c359 Added starting LED animation for MMDVM_pog board. 2017-06-01 17:05:29 +02:00
Wojciech Krutnik 6d5f098e41 Move host communication port from USART2 to USART1 2017-05-31 15:05:58 +02:00
Wojciech Krutnik e53aec348e Change port definition for bootloader (BL_PORT) in Makefile.CMSIS 2017-05-31 15:04:00 +02:00
Jonathan Naylor 9722c85585 Normalise the inverse-sinc lowpass filter to unity gain. 2017-05-05 08:10:36 +01:00
Jonathan Naylor 1a9c0d3ee7 Bump the version date. 2017-05-01 09:22:05 +01:00
42 changed files with 2883 additions and 383 deletions
+180 -6
View File
@@ -21,19 +21,190 @@
#include "Globals.h"
#include "CalDMR.h"
// Voice LC BS Header, CC: 1, srcID: 1, dstID: TG9
const uint8_t VH_1K[] = {0x00U,
0x00U, 0x20U, 0x08U, 0x08U, 0x02U, 0x38U, 0x15U, 0x00U, 0x2CU, 0xA0U, 0x14U,
0x60U, 0x84U, 0x6DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xDEU, 0x30U, 0x30U,
0x01U, 0x10U, 0x01U, 0x40U, 0x03U, 0xC0U, 0x13U, 0xC1U, 0x1EU, 0x80U, 0x6FU};
// Voice Term BS with LC, CC: 1, srcID: 1, dstID: TG9
const uint8_t VT_1K[] = {0x00U,
0x00U, 0x4FU, 0x08U, 0xDCU, 0x02U, 0x88U, 0x15U, 0x78U, 0x2CU, 0xD0U, 0x14U,
0xC0U, 0x84U, 0xADU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD9U, 0x65U, 0x24U,
0x02U, 0x28U, 0x06U, 0x20U, 0x0FU, 0x80U, 0x1BU, 0xC1U, 0x07U, 0x80U, 0x5CU};
// Voice LC MS Header, CC: 1, srcID: 1, dstID: TG9
const uint8_t VH_DMO1K[] = {0x00U,
0x00U, 0x20U, 0x08U, 0x08U, 0x02U, 0x38U, 0x15U, 0x00U, 0x2CU, 0xA0U, 0x14U,
0x60U, 0x84U, 0x6DU, 0x5DU, 0x7FU, 0x77U, 0xFDU, 0x75U, 0x7EU, 0x30U, 0x30U,
0x01U, 0x10U, 0x01U, 0x40U, 0x03U, 0xC0U, 0x13U, 0xC1U, 0x1EU, 0x80U, 0x6FU};
// Voice Term MS with LC, CC: 1, srcID: 1, dstID: TG9
const uint8_t VT_DMO1K[] = {0x00U,
0x00U, 0x4FU, 0x08U, 0xDCU, 0x02U, 0x88U, 0x15U, 0x78U, 0x2CU, 0xD0U, 0x14U,
0xC0U, 0x84U, 0xADU, 0x5DU, 0x7FU, 0x77U, 0xFDU, 0x75U, 0x79U, 0x65U, 0x24U,
0x02U, 0x28U, 0x06U, 0x20U, 0x0FU, 0x80U, 0x1BU, 0xC1U, 0x07U, 0x80U, 0x5CU};
// Voice coding data + FEC, 1031 Hz Test Pattern
const uint8_t VOICE_1K[] = {0x00U,
0xCEU, 0xA8U, 0xFEU, 0x83U, 0xACU, 0xC4U, 0x58U, 0x20U, 0x0AU, 0xCEU, 0xA8U,
0xFEU, 0x83U, 0xA0U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x0CU, 0xC4U, 0x58U,
0x20U, 0x0AU, 0xCEU, 0xA8U, 0xFEU, 0x83U, 0xACU, 0xC4U, 0x58U, 0x20U, 0x0AU};
// Embedded LC BS: CC: 1, srcID: 1, dstID: TG9
const uint8_t SYNCEMB_1K[6][7] = {
{0x07U, 0x55U, 0xFDU, 0x7DU, 0xF7U, 0x5FU, 0x70U}, // BS VOICE SYNC (audio seq 0)
{0x01U, 0x30U, 0x00U, 0x00U, 0x90U, 0x09U, 0x10U}, // EMB + Embedded LC1 (audio seq 1)
{0x01U, 0x70U, 0x00U, 0x90U, 0x00U, 0x07U, 0x40U}, // EMB + Embedded LC2 (audio seq 2)
{0x01U, 0x70U, 0x00U, 0x31U, 0x40U, 0x07U, 0x40U}, // EMB + Embedded LC3 (audio seq 3)
{0x01U, 0x50U, 0xA1U, 0x71U, 0xD1U, 0x70U, 0x70U}, // EMB + Embedded LC4 (audio seq 4)
{0x01U, 0x10U, 0x00U, 0x00U, 0x00U, 0x0EU, 0x20U}}; // EMB (audio seq 5)
// Embedded LC MS: CC: 1, srcID: 1, dstID: TG9
const uint8_t SYNCEMB_DMO1K[6][7] = {
{0x07U, 0xF7U, 0xD5U, 0xDDU, 0x57U, 0xDFU, 0xD0U}, // MS VOICE SYNC (audio seq 0)
{0x01U, 0x30U, 0x00U, 0x00U, 0x90U, 0x09U, 0x10U}, // EMB + Embedded LC1 (audio seq 1)
{0x01U, 0x70U, 0x00U, 0x90U, 0x00U, 0x07U, 0x40U}, // EMB + Embedded LC2 (audio seq 2)
{0x01U, 0x70U, 0x00U, 0x31U, 0x40U, 0x07U, 0x40U}, // EMB + Embedded LC3 (audio seq 3)
{0x01U, 0x50U, 0xA1U, 0x71U, 0xD1U, 0x70U, 0x70U}, // EMB + Embedded LC4 (audio seq 4)
{0x01U, 0x10U, 0x00U, 0x00U, 0x00U, 0x0EU, 0x20U}}; // EMB (audio seq 5)
// Short LC:
// TS1: dstID: 0, ACTIVITY_NONE
// TS2: dstID: TG9, ACTIVITY_VOICE
const uint8_t SHORTLC_1K[] = {0x33U, 0x3AU, 0xA0U, 0x30U, 0x00U, 0x55U, 0xA6U, 0x5FU, 0x50U};
CCalDMR::CCalDMR() :
m_transmit(false)
m_transmit(false),
m_state(DMRCAL1K_IDLE),
m_frame_start(0U),
m_dmr1k(),
m_audioSeq(0)
{
::memcpy(m_dmr1k, VOICE_1K, DMR_FRAME_LENGTH_BYTES + 1U);
}
void CCalDMR::process()
{
if (m_transmit) {
dmrTX.setCal(true);
dmrTX.process();
} else {
dmrTX.setCal(false);
switch (m_modemState) {
case STATE_DMRCAL:
case STATE_LFCAL:
if (m_transmit) {
dmrTX.setCal(true);
dmrTX.process();
} else {
dmrTX.setCal(false);
}
break;
case STATE_DMRCAL1K:
dmr1kcal();
break;
case STATE_DMRDMO1K:
dmrdmo1k();
break;
default:
break;
}
}
void CCalDMR::createData1k(uint8_t n)
{
for(uint8_t i = 0; i < 5U; i++)
m_dmr1k[i + 15U] = SYNCEMB_1K[n][i + 1U];
m_dmr1k[14U] &= 0xF0U;
m_dmr1k[20U] &= 0x0FU;
m_dmr1k[14U] |= SYNCEMB_1K[n][0] & 0x0FU;
m_dmr1k[20U] |= SYNCEMB_1K[n][6] & 0xF0U;
}
void CCalDMR::createDataDMO1k(uint8_t n)
{
for(uint8_t i = 0; i < 5U; i++)
m_dmr1k[i + 15U] = SYNCEMB_DMO1K[n][i + 1U];
m_dmr1k[14U] &= 0xF0U;
m_dmr1k[20U] &= 0x0FU;
m_dmr1k[14U] |= SYNCEMB_DMO1K[n][0] & 0x0FU;
m_dmr1k[20U] |= SYNCEMB_DMO1K[n][6] & 0xF0U;
}
void CCalDMR::dmr1kcal()
{
dmrTX.process();
uint16_t space = dmrTX.getSpace2();
if (space < 1U)
return;
switch (m_state) {
case DMRCAL1K_VH:
dmrTX.setColorCode(1U);
dmrTX.writeShortLC(SHORTLC_1K, 9U);
dmrTX.writeData2(VH_1K, DMR_FRAME_LENGTH_BYTES + 1U);
dmrTX.setStart(true);
m_state = DMRCAL1K_VOICE;
break;
case DMRCAL1K_VOICE:
createData1k(m_audioSeq);
dmrTX.writeData2(m_dmr1k, DMR_FRAME_LENGTH_BYTES + 1U);
if(m_audioSeq == 5U) {
m_audioSeq = 0U;
if(!m_transmit)
m_state = DMRCAL1K_VT;
} else
m_audioSeq++;
break;
case DMRCAL1K_VT:
dmrTX.writeData2(VT_1K, DMR_FRAME_LENGTH_BYTES + 1U);
m_frame_start = dmrTX.getFrameCount();
m_state = DMRCAL1K_WAIT;
break;
case DMRCAL1K_WAIT:
if (dmrTX.getFrameCount() > (m_frame_start + 30U)) {
dmrTX.setStart(false);
dmrTX.resetFifo2();
m_audioSeq = 0U;
m_state = DMRCAL1K_IDLE;
}
break;
default:
m_state = DMRCAL1K_IDLE;
break;
}
}
void CCalDMR::dmrdmo1k()
{
dmrDMOTX.process();
uint16_t space = dmrDMOTX.getSpace();
if (space < 1U)
return;
switch (m_state) {
case DMRCAL1K_VH:
dmrDMOTX.writeData(VH_DMO1K, DMR_FRAME_LENGTH_BYTES + 1U);
m_state = DMRCAL1K_VOICE;
break;
case DMRCAL1K_VOICE:
createDataDMO1k(m_audioSeq);
dmrDMOTX.writeData(m_dmr1k, DMR_FRAME_LENGTH_BYTES + 1U);
if(m_audioSeq == 5U) {
m_audioSeq = 0U;
if(!m_transmit)
m_state = DMRCAL1K_VT;
} else
m_audioSeq++;
break;
case DMRCAL1K_VT:
dmrDMOTX.writeData(VT_DMO1K, DMR_FRAME_LENGTH_BYTES + 1U);
m_state = DMRCAL1K_IDLE;
break;
default:
m_state = DMRCAL1K_IDLE;
m_audioSeq = 0U;
break;
}
}
@@ -44,6 +215,9 @@ uint8_t CCalDMR::write(const uint8_t* data, uint8_t length)
m_transmit = data[0U] == 1U;
if(m_transmit && m_state == DMRCAL1K_IDLE && (m_modemState == STATE_DMRCAL1K || m_modemState == STATE_DMRDMO1K))
m_state = DMRCAL1K_VH;
return 0U;
}
+17 -1
View File
@@ -23,16 +23,32 @@
#include "Config.h"
#include "DMRDefines.h"
enum DMRCAL1K {
DMRCAL1K_IDLE,
DMRCAL1K_VH,
DMRCAL1K_VOICE,
DMRCAL1K_VT,
DMRCAL1K_WAIT
};
class CCalDMR {
public:
CCalDMR();
void process();
void dmr1kcal();
void dmrdmo1k();
void createData1k(uint8_t n);
void createDataDMO1k(uint8_t n);
uint8_t write(const uint8_t* data, uint8_t length);
private:
bool m_transmit;
bool m_transmit;
DMRCAL1K m_state;
uint32_t m_frame_start;
uint8_t m_dmr1k[DMR_FRAME_LENGTH_BYTES + 1U];
uint8_t m_audioSeq;
};
#endif
+94
View File
@@ -0,0 +1,94 @@
/*
* Copyright (C) 2018 by Andy Uribe CA6JAU
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Config.h"
#include "Globals.h"
#include "CalNXDN.h"
// NXDN 1031 Hz Test Pattern, RAN: 1, Unit ID: 1, Dst Group ID: 1, Outbound Direction
const uint8_t NXDN_CAL1K[4][49] = {
{0x00U,
0xCDU, 0xF5U, 0x9DU, 0x5DU, 0x7CU, 0xFAU, 0x0AU, 0x6EU, 0x8AU, 0x23U, 0x56U, 0xE8U,
0x4CU, 0xAAU, 0xDEU, 0x8BU, 0x26U, 0xE4U, 0xF2U, 0x82U, 0x88U,
0xC6U, 0x8AU, 0x74U, 0x29U, 0xA4U, 0xECU, 0xD0U, 0x08U, 0x22U,
0xCEU, 0xA2U, 0xFCU, 0x01U, 0x8CU, 0xECU, 0xDAU, 0x0AU, 0xA0U,
0xEEU, 0x8AU, 0x7EU, 0x2BU, 0x26U, 0xCCU, 0xF8U, 0x8AU, 0x08U},
{0x00U,
0xCDU, 0xF5U, 0x9DU, 0x5DU, 0x7CU, 0x6DU, 0xBBU, 0x0EU, 0xB3U, 0xA4U, 0x26U, 0xA8U,
0x4CU, 0xAAU, 0xDEU, 0x8BU, 0x26U, 0xE4U, 0xF2U, 0x82U, 0x88U,
0xC6U, 0x8AU, 0x74U, 0x29U, 0xA4U, 0xECU, 0xD0U, 0x08U, 0x22U,
0xCEU, 0xA2U, 0xFCU, 0x01U, 0x8CU, 0xECU, 0xDAU, 0x0AU, 0xA0U,
0xEEU, 0x8AU, 0x7EU, 0x2BU, 0x26U, 0xCCU, 0xF8U, 0x8AU, 0x08U},
{0x00U,
0xCDU, 0xF5U, 0x9DU, 0x5DU, 0x76U, 0x3AU, 0x1BU, 0x4AU, 0x81U, 0xA8U, 0xE2U, 0x80U,
0x4CU, 0xAAU, 0xDEU, 0x8BU, 0x26U, 0xE4U, 0xF2U, 0x82U, 0x88U,
0xC6U, 0x8AU, 0x74U, 0x29U, 0xA4U, 0xECU, 0xD0U, 0x08U, 0x22U,
0xCEU, 0xA2U, 0xFCU, 0x01U, 0x8CU, 0xECU, 0xDAU, 0x0AU, 0xA0U,
0xEEU, 0x8AU, 0x7EU, 0x2BU, 0x26U, 0xCCU, 0xF8U, 0x8AU, 0x08U},
{0x00U,
0xCDU, 0xF5U, 0x9DU, 0x5DU, 0x74U, 0x28U, 0x83U, 0x02U, 0xB0U, 0x2DU, 0x07U, 0xE2U,
0x4CU, 0xAAU, 0xDEU, 0x8BU, 0x26U, 0xE4U, 0xF2U, 0x82U, 0x88U,
0xC6U, 0x8AU, 0x74U, 0x29U, 0xA4U, 0xECU, 0xD0U, 0x08U, 0x22U,
0xCEU, 0xA2U, 0xFCU, 0x01U, 0x8CU, 0xECU, 0xDAU, 0x0AU, 0xA0U,
0xEEU, 0x8AU, 0x7EU, 0x2BU, 0x26U, 0xCCU, 0xF8U, 0x8AU, 0x08U}};
CCalNXDN::CCalNXDN() :
m_transmit(false),
m_state(NXDNCAL1K_IDLE),
m_audioSeq(0U)
{
}
void CCalNXDN::process()
{
nxdnTX.process();
uint16_t space = nxdnTX.getSpace();
if (space < 1U)
return;
switch (m_state) {
case NXDNCAL1K_TX:
nxdnTX.writeData(NXDN_CAL1K[m_audioSeq], NXDN_FRAME_LENGTH_BYTES + 1U);
m_audioSeq = (m_audioSeq + 1U) % 4U;
if(!m_transmit)
m_state = NXDNCAL1K_IDLE;
break;
default:
m_state = NXDNCAL1K_IDLE;
m_audioSeq = 0U;
break;
}
}
uint8_t CCalNXDN::write(const uint8_t* data, uint8_t length)
{
if (length != 1U)
return 4U;
m_transmit = data[0U] == 1U;
if(m_transmit && m_state == NXDNCAL1K_IDLE)
m_state = NXDNCAL1K_TX;
return 0U;
}
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2018 by Andy Uribe CA6JAU
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(CALNXDN_H)
#define CALNXDN_H
#include "Config.h"
enum NXDNCAL1K {
NXDNCAL1K_IDLE,
NXDNCAL1K_TX
};
class CCalNXDN {
public:
CCalNXDN();
void process();
uint8_t write(const uint8_t* data, uint8_t length);
private:
bool m_transmit;
NXDNCAL1K m_state;
uint8_t m_audioSeq;
};
#endif
+97
View File
@@ -0,0 +1,97 @@
/*
* Copyright (C) 2018 by Andy Uribe CA6JAU
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Config.h"
#include "Globals.h"
#include "CalP25.h"
// Recommended 1011 Hz test pattern for P25 Phase 1 (ANSI/TIA-102.CAAA)
// NAC: 0x293, srcID: 1, dstID: TG1
unsigned char LDU1_1K[] = {0x00,
0x55, 0x75, 0xF5, 0xFF, 0x77, 0xFF, 0x29, 0x35, 0x54, 0x7B, 0xCB, 0x19, 0x4D, 0x0D, 0xCE, 0x24, 0xA1, 0x24,
0x0D, 0x43, 0x3C, 0x0B, 0xE1, 0xB9, 0x18, 0x44, 0xFC, 0xC1, 0x62, 0x96, 0x27, 0x60, 0xE4, 0xE2, 0x4A, 0x10,
0x90, 0xD4, 0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4C, 0xFC, 0x16, 0x29, 0x62, 0x76, 0x0E, 0xC0, 0x00, 0x00,
0x00, 0x00, 0x03, 0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x02, 0xF8, 0x6E, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x94,
0x89, 0xD8, 0x39, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x38, 0x24, 0xA1, 0x24, 0x35, 0x0C, 0xF0, 0x2F, 0x86, 0xE4,
0x18, 0x44, 0xFF, 0x05, 0x8A, 0x58, 0x9D, 0x83, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x70, 0xE2, 0x4A, 0x12, 0x40,
0xD4, 0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4F, 0xF0, 0x16, 0x29, 0x62, 0x76, 0x0E, 0x6D, 0xE5, 0xD5, 0x48,
0xAD, 0xE3, 0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x08, 0xF8, 0x6E, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x96, 0x24,
0xD8, 0x3B, 0xA1, 0x41, 0xC2, 0xD2, 0xBA, 0x38, 0x90, 0xA1, 0x24, 0x35, 0x0C, 0xF0, 0x2F, 0x86, 0xE4, 0x60,
0x44, 0xFF, 0x05, 0x8A, 0x58, 0x9D, 0x83, 0x94, 0xC8, 0xFB, 0x02, 0x35, 0xA4, 0xE2, 0x4A, 0x12, 0x43, 0x50,
0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4F, 0xF0, 0x58, 0x29, 0x62, 0x76, 0x0E, 0xC0, 0x00, 0x00, 0x00, 0x0C,
0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x0B, 0xE1, 0xB8, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x96, 0x27, 0x60, 0xE4};
unsigned char LDU2_1K[] = {0x00,
0x55, 0x75, 0xF5, 0xFF, 0x77, 0xFF, 0x29, 0x3A, 0xB8, 0xA4, 0xEF, 0xB0, 0x9A, 0x8A, 0xCE, 0x24, 0xA1, 0x24,
0x0D, 0x43, 0x3C, 0x0B, 0xE1, 0xB9, 0x18, 0x44, 0xFC, 0xC1, 0x62, 0x96, 0x27, 0x60, 0xEC, 0xE2, 0x4A, 0x10,
0x90, 0xD4, 0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4C, 0xFC, 0x16, 0x29, 0x62, 0x76, 0x0E, 0x40, 0x00, 0x00,
0x00, 0x00, 0x03, 0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x02, 0xF8, 0x6E, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x94,
0x89, 0xD8, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x24, 0xA1, 0x24, 0x35, 0x0C, 0xF0, 0x2F, 0x86, 0xE4,
0x18, 0x44, 0xFF, 0x05, 0x8A, 0x58, 0x9D, 0x83, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x4A, 0x12, 0x40,
0xD4, 0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4F, 0xF0, 0x16, 0x29, 0x62, 0x76, 0x0E, 0xE0, 0xE0, 0x00, 0x00,
0x00, 0x03, 0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x08, 0xF8, 0x6E, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x96, 0x24,
0xD8, 0x39, 0xAE, 0x8B, 0x48, 0xB6, 0x49, 0x38, 0x90, 0xA1, 0x24, 0x35, 0x0C, 0xF0, 0x2F, 0x86, 0xE4, 0x60,
0x44, 0xFF, 0x05, 0x8A, 0x58, 0x9D, 0x83, 0xB9, 0xA8, 0xF4, 0xF1, 0xFD, 0x60, 0xE2, 0x4A, 0x12, 0x43, 0x50,
0x33, 0xC0, 0xBE, 0x1B, 0x91, 0x84, 0x4F, 0xF0, 0x58, 0x29, 0x62, 0x76, 0x0E, 0x40, 0x00, 0x00, 0x00, 0x0C,
0x89, 0x28, 0x49, 0x0D, 0x43, 0x3C, 0x0B, 0xE1, 0xB8, 0x46, 0x11, 0x3F, 0xC1, 0x62, 0x96, 0x27, 0x60, 0xEC};
CCalP25::CCalP25() :
m_transmit(false),
m_state(P25CAL1K_IDLE)
{
}
void CCalP25::process()
{
p25TX.process();
uint16_t space = p25TX.getSpace();
if (space < 1U)
return;
switch (m_state) {
case P25CAL1K_LDU1:
p25TX.writeData(LDU1_1K, P25_LDU_FRAME_LENGTH_BYTES + 1U);
m_state = P25CAL1K_LDU2;
break;
case P25CAL1K_LDU2:
p25TX.writeData(LDU2_1K, P25_LDU_FRAME_LENGTH_BYTES + 1U);
if(!m_transmit)
m_state = P25CAL1K_IDLE;
else
m_state = P25CAL1K_LDU1;
break;
default:
m_state = P25CAL1K_IDLE;
break;
}
}
uint8_t CCalP25::write(const uint8_t* data, uint8_t length)
{
if (length != 1U)
return 4U;
m_transmit = data[0U] == 1U;
if(m_transmit && m_state == P25CAL1K_IDLE)
m_state = P25CAL1K_LDU1;
return 0U;
}
+45
View File
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2018 by Andy Uribe CA6JAU
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(CALP25_H)
#define CALP25_H
#include "Config.h"
#include "P25Defines.h"
enum P25CAL1K {
P25CAL1K_IDLE,
P25CAL1K_LDU1,
P25CAL1K_LDU2
};
class CCalP25 {
public:
CCalP25();
void process();
uint8_t write(const uint8_t* data, uint8_t length);
private:
bool m_transmit;
P25CAL1K m_state;
};
#endif
+1 -1
View File
@@ -27,7 +27,7 @@
// Frequencies such as 10.0 Mhz (48000 * 208.333) or 20 Mhz (48000 * 416.666) are not suitable.
//
// For 12 MHz
// #define EXTERNAL_OSC 12000000
#define EXTERNAL_OSC 12000000
// For 12.288 MHz
// #define EXTERNAL_OSC 12288000
// For 14.4 MHz
Regular → Executable
+51 -5
View File
@@ -54,6 +54,7 @@ const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
const uint32_t STARTUP_COUNT = 20U;
const uint32_t ABORT_COUNT = 6U;
CDMRTX::CDMRTX() :
m_fifo(),
@@ -69,6 +70,7 @@ m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_frameCount(0U),
m_abortCount(),
m_abort()
{
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
@@ -83,6 +85,9 @@ m_abort()
m_abort[0U] = false;
m_abort[1U] = false;
m_abortCount[0U] = 0U;
m_abortCount[1U] = 0U;
}
void CDMRTX::process()
@@ -210,10 +215,12 @@ uint8_t CDMRTX::writeAbort(const uint8_t* data, uint8_t length)
switch (data[0U]) {
case 1U:
m_abortCount[0U] = 0U;
m_abort[0U] = true;
return 0U;
case 2U:
m_abortCount[1U] = 0U;
m_abort[1U] = true;
return 0U;
@@ -227,6 +234,8 @@ void CDMRTX::setStart(bool start)
m_state = start ? DMRTXSTATE_SLOT1 : DMRTXSTATE_IDLE;
m_frameCount = 0U;
m_abortCount[0U] = 0U;
m_abortCount[1U] = 0U;
m_abort[0U] = false;
m_abort[1U] = false;
@@ -282,7 +291,7 @@ uint8_t CDMRTX::getSpace2() const
void CDMRTX::createData(uint8_t slotIndex)
{
if (m_fifo[slotIndex].getData() > 0U && m_frameCount >= STARTUP_COUNT) {
if (m_fifo[slotIndex].getData() >= DMR_FRAME_LENGTH_BYTES && m_frameCount >= STARTUP_COUNT && m_abortCount[slotIndex] >= ABORT_COUNT) {
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) {
m_poBuffer[i] = m_fifo[slotIndex].get();
m_markBuffer[i] = MARK_NONE;
@@ -302,18 +311,41 @@ void CDMRTX::createData(uint8_t slotIndex)
void CDMRTX::createCal()
{
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) {
m_poBuffer[i] = 0x5FU; // +3, +3, -3, -3 pattern for deviation cal.
m_markBuffer[i] = MARK_NONE;
// 1.2 kHz sine wave generation
if (m_modemState == STATE_DMRCAL) {
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) {
m_poBuffer[i] = 0x5FU; // +3, +3, -3, -3 pattern for deviation cal.
m_markBuffer[i] = MARK_NONE;
}
m_poLen = DMR_FRAME_LENGTH_BYTES;
}
// 80 Hz square wave generation
if (m_modemState == STATE_LFCAL) {
for (unsigned int i = 0U; i < 7U; i++) {
m_poBuffer[i] = 0x55U; // +3, +3, ... pattern
m_markBuffer[i] = MARK_NONE;
}
m_poBuffer[7U] = 0x5FU; // +3, +3, -3, -3 pattern
for (unsigned int i = 8U; i < 15U; i++) {
m_poBuffer[i] = 0xFFU; // -3, -3, ... pattern
m_markBuffer[i] = MARK_NONE;
}
m_poLen = 15U;
}
m_poLen = DMR_FRAME_LENGTH_BYTES;
m_poPtr = 0U;
}
void CDMRTX::createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex)
{
m_frameCount++;
m_abortCount[0U]++;
m_abortCount[1U]++;
if (m_cachPtr >= 12U)
m_cachPtr = 0U;
@@ -368,3 +400,17 @@ void CDMRTX::setColorCode(uint8_t colorCode)
slotType.encode(colorCode, DT_IDLE, m_idle);
}
void CDMRTX::resetFifo1()
{
m_fifo[0U].reset();
}
void CDMRTX::resetFifo2()
{
m_fifo[1U].reset();
}
uint32_t CDMRTX::getFrameCount()
{
return m_frameCount;
}
Regular → Executable
+5
View File
@@ -49,6 +49,10 @@ public:
void process();
void resetFifo1();
void resetFifo2();
uint32_t getFrameCount();
uint8_t getSpace1() const;
uint8_t getSpace2() const;
@@ -68,6 +72,7 @@ private:
uint16_t m_poLen;
uint16_t m_poPtr;
uint32_t m_frameCount;
uint32_t m_abortCount[2U];
bool m_abort[2U];
void createData(uint8_t slotIndex);
+13 -49
View File
@@ -28,15 +28,7 @@ const uint32_t PLLMAX = 0x10000U;
const uint32_t PLLINC = PLLMAX / DSTAR_RADIO_BIT_LENGTH;
const uint32_t INC = PLLINC / 32U;
const unsigned int MAX_SYNC_BITS = 50U * DSTAR_DATA_LENGTH_BITS;
const unsigned int SYNC_POS = 21U * DSTAR_DATA_LENGTH_BITS;
const unsigned int SYNC_SCAN_START = SYNC_POS - 3U;
const unsigned int SYNC_SCAN_END = SYNC_POS + 3U;
// Generated using [b, a] = butter(1, 0.001) in MATLAB
static q31_t DC_FILTER[] = {3367972, 0, 3367972, 0, 2140747704, 0}; // {b0, 0, b1, b2, -a1, -a2}
const uint32_t DC_FILTER_STAGES = 1U; // One Biquad stage
const unsigned int MAX_SYNC_BITS = 100U * DSTAR_DATA_LENGTH_BITS;
// D-Star bit order version of 0x55 0x55 0x6E 0x0A
const uint32_t FRAME_SYNC_DATA = 0x00557650U;
@@ -51,7 +43,7 @@ const uint8_t DATA_SYNC_ERRS = 2U;
// D-Star bit order version of 0x55 0x55 0xC8 0x7A
const uint32_t END_SYNC_DATA = 0xAAAA135EU;
const uint32_t END_SYNC_MASK = 0xFFFFFFFFU;
const uint8_t END_SYNC_ERRS = 3U;
const uint8_t END_SYNC_ERRS = 1U;
const uint8_t BIT_MASK_TABLE0[] = {0x7FU, 0xBFU, 0xDFU, 0xEFU, 0xF7U, 0xFBU, 0xFDU, 0xFEU};
const uint8_t BIT_MASK_TABLE1[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
@@ -261,16 +253,8 @@ m_pathMemory2(),
m_pathMemory3(),
m_fecOutput(),
m_rssiAccum(0U),
m_rssiCount(0U),
m_dcFilter(),
m_dcState()
m_rssiCount(0U)
{
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
m_dcFilter.numStages = DC_FILTER_STAGES;
m_dcFilter.pState = m_dcState;
m_dcFilter.pCoeffs = DC_FILTER;
m_dcFilter.postShift = 0;
}
void CDStarRX::reset()
@@ -287,23 +271,11 @@ void CDStarRX::reset()
void CDStarRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length)
{
q31_t dc_level = 0;
q31_t dcVals[20];
q31_t intSamp[20];
::arm_q15_to_q31((q15_t*)samples, intSamp, length);
::arm_biquad_cascade_df1_q31(&m_dcFilter, intSamp, dcVals, length);
for (uint8_t i = 0U; i < length; i++)
dc_level += dcVals[i];
dc_level /= length;
for (uint16_t i = 0U; i < length; i++) {
m_rssiAccum += rssi[i];
m_rssiCount++;
bool bit = samples[i] < (q15_t) (dc_level >> 16);
bool bit = samples[i] < 0;
if (bit != m_prev) {
if (m_pll < (PLLMAX / 2U))
@@ -373,7 +345,7 @@ void CDStarRX::processNone(bool bit)
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
m_rxBufferBits = 0U;
m_dataBits = 0U;
m_dataBits = MAX_SYNC_BITS;
m_rxState = DSRXS_DATA;
return;
}
@@ -402,8 +374,8 @@ void CDStarRX::processHeader(bool bit)
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
m_rxBufferBits = 0U;
m_rxState = DSRXS_DATA;
m_dataBits = SYNC_POS - DSTAR_DATA_LENGTH_BITS + 1U;
m_rxState = DSRXS_DATA;
m_dataBits = MAX_SYNC_BITS;
} else {
// The checksum failed, return to looking for syncs
m_rxState = DSRXS_NONE;
@@ -435,37 +407,29 @@ void CDStarRX::processData(bool bit)
// Fuzzy matching of the data sync bit sequence
bool syncSeen = false;
if (m_dataBits >= SYNC_SCAN_START && m_dataBits <= (SYNC_POS + 1U)) {
if (m_rxBufferBits >= (DSTAR_DATA_LENGTH_BITS - 3U)) {
if (countBits32((m_patternBuffer & DATA_SYNC_MASK) ^ DATA_SYNC_DATA) <= DATA_SYNC_ERRS) {
if (m_dataBits < SYNC_POS)
DEBUG2("DStarRX: found data sync in Data, early", SYNC_POS - m_dataBits);
else
DEBUG1("DStarRX: found data sync in Data");
m_rxBufferBits = DSTAR_DATA_LENGTH_BITS;
m_dataBits = 0U;
syncSeen = true;
m_dataBits = MAX_SYNC_BITS;
syncSeen = true;
}
}
// Check to see if the sync is arriving late
if (m_dataBits == SYNC_POS) {
if (m_rxBufferBits == DSTAR_DATA_LENGTH_BITS && !syncSeen) {
for (uint8_t i = 1U; i <= 3U; i++) {
uint32_t syncMask = DATA_SYNC_MASK >> i;
uint32_t syncData = DATA_SYNC_DATA >> i;
if (countBits32((m_patternBuffer & syncMask) ^ syncData) <= DATA_SYNC_ERRS) {
DEBUG2("DStarRX: found data sync in Data, late", i);
m_rxBufferBits -= i;
m_dataBits -= i;
break;
}
}
}
m_dataBits++;
m_dataBits--;
// We've not seen a data sync for too long, signal RXLOST and change to RX_NONE
if (m_dataBits >= MAX_SYNC_BITS) {
if (m_dataBits == 0U) {
DEBUG1("DStarRX: data sync timed out, lost lock");
io.setDecode(false);
-2
View File
@@ -53,8 +53,6 @@ private:
uint8_t m_fecOutput[42U];
uint32_t m_rssiAccum;
uint16_t m_rssiCount;
arm_biquad_casd_df1_inst_q31 m_dcFilter;
q31_t m_dcState[4];
void processNone(bool bit);
void processHeader(bool bit);
+23 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
*
* 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
@@ -19,8 +19,10 @@
#if !defined(GLOBALS_H)
#define GLOBALS_H
#if defined(STM32F4XX) || defined(STM32F4)
#if defined(STM32F4XX)
#include "stm32f4xx.h"
#elif defined(STM32F7XX)
#include "stm32f7xx.h"
#elif defined(STM32F105xC)
#include "stm32f1xx.h"
#include "STM32Utils.h"
@@ -30,7 +32,9 @@
#if defined(__SAM3X8E__) || defined(STM32F105xC)
#define ARM_MATH_CM3
#elif defined(STM32F4XX) || defined(STM32F4) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#elif defined(STM32F7XX)
#define ARM_MATH_CM7
#elif defined(STM32F4XX) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define ARM_MATH_CM4
#else
#error "Unknown processor type"
@@ -44,8 +48,14 @@ enum MMDVM_STATE {
STATE_DMR = 2,
STATE_YSF = 3,
STATE_P25 = 4,
STATE_NXDN = 5,
// Dummy states start at 90
STATE_NXDNCAL1K = 91,
STATE_DMRDMO1K = 92,
STATE_P25CAL1K = 93,
STATE_DMRCAL1K = 94,
STATE_LFCAL = 95,
STATE_RSSICAL = 96,
STATE_CWID = 97,
STATE_DMRCAL = 98,
@@ -64,9 +74,13 @@ enum MMDVM_STATE {
#include "YSFTX.h"
#include "P25RX.h"
#include "P25TX.h"
#include "NXDNRX.h"
#include "NXDNTX.h"
#include "CalDStarRX.h"
#include "CalDStarTX.h"
#include "CalDMR.h"
#include "CalP25.h"
#include "CalNXDN.h"
#include "CalRSSI.h"
#include "CWIdTX.h"
#include "Debug.h"
@@ -87,6 +101,7 @@ extern bool m_dstarEnable;
extern bool m_dmrEnable;
extern bool m_ysfEnable;
extern bool m_p25Enable;
extern bool m_nxdnEnable;
extern bool m_duplex;
@@ -112,9 +127,14 @@ extern CYSFTX ysfTX;
extern CP25RX p25RX;
extern CP25TX p25TX;
extern CNXDNRX nxdnRX;
extern CNXDNTX nxdnTX;
extern CCalDStarRX calDStarRX;
extern CCalDStarTX calDStarTX;
extern CCalDMR calDMR;
extern CCalP25 calP25;
extern CCalNXDN calNXDN;
extern CCalRSSI calRSSI;
extern CCWIdTX cwIdTX;
+241 -39
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015 by Jim Mclaughlin KI6ZUM
* Copyright (C) 2016 by Colin Durbridge G4EML
*
@@ -22,18 +22,34 @@
#include "Globals.h"
#include "IO.h"
// Generated using [b, a] = butter(1, 0.001) in MATLAB
static q31_t DC_FILTER[] = {3367972, 0, 3367972, 0, 2140747704, 0}; // {b0, 0, b1, b2, -a1, -a2}
const uint32_t DC_FILTER_STAGES = 1U; // One Biquad stage
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
static q15_t RRC_0_2_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
-553, -847, -731, -340, 104, 401, 0};
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
-553, -847, -731, -340, 104, 401, 0};
const uint16_t RRC_0_2_FILTER_LEN = 42U;
// Generated using rcosdesign(0.2, 8, 10, 'sqrt') in MATLAB
static q15_t NXDN_0_2_FILTER[] = {284, 198, 73, -78, -240, -393, -517, -590, -599, -533, -391, -181, 79, 364, 643, 880, 1041, 1097, 1026, 819,
483, 39, -477, -1016, -1516, -1915, -2150, -2164, -1914, -1375, -545, 557, 1886, 3376, 4946, 6502, 7946, 9184,
10134, 10731, 10935, 10731, 10134, 9184, 7946, 6502, 4946, 3376, 1886, 557, -545, -1375, -1914, -2164, -2150,
-1915, -1516, -1016, -477, 39, 483, 819, 1026, 1097, 1041, 880, 643, 364, 79, -181, -391, -533, -599, -590,
-517, -393, -240, -78, 73, 198, 284, 0};
const uint16_t NXDN_0_2_FILTER_LEN = 82U;
static q15_t NXDN_ISINC_FILTER[] = {790, -1085, -1073, -553, 747, 2341, 3156, 2152, -893, -4915, -7834, -7536, -3102, 4441, 12354, 17394, 17394,
12354, 4441, -3102, -7536, -7834, -4915, -893, 2152, 3156, 2341, 747, -553, -1073, -1085, 790};
const uint16_t NXDN_ISINC_FILTER_LEN = 32U;
// Generated using gaussfir(0.5, 4, 5) in MATLAB
static q15_t GAUSSIAN_0_5_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0};
const uint16_t GAUSSIAN_0_5_FILTER_LEN = 12U;
// One symbol boxcar filter
static q15_t BOXCAR_FILTER[] = {3000, 3000, 3000, 3000, 3000, 0};
static q15_t BOXCAR_FILTER[] = {12000, 12000, 12000, 12000, 12000, 0};
const uint16_t BOXCAR_FILTER_LEN = 6U;
const uint16_t DC_OFFSET = 2048U;
@@ -43,12 +59,20 @@ m_started(false),
m_rxBuffer(RX_RINGBUFFER_SIZE),
m_txBuffer(TX_RINGBUFFER_SIZE),
m_rssiBuffer(RX_RINGBUFFER_SIZE),
m_rrcFilter(),
m_dcFilter(),
m_dcState(),
m_dmrFilter(),
m_gaussianFilter(),
m_boxcarFilter(),
m_rrcState(),
m_nxdnFilter(),
m_nxdnISincFilter(),
m_ysfFilter(),
m_dmrState(),
m_gaussianState(),
m_boxcarState(),
m_nxdnState(),
m_nxdnISincState(),
m_ysfState(),
m_pttInvert(false),
m_rxLevel(128 * 128),
m_cwIdTXLevel(128 * 128),
@@ -56,6 +80,9 @@ m_dstarTXLevel(128 * 128),
m_dmrTXLevel(128 * 128),
m_ysfTXLevel(128 * 128),
m_p25TXLevel(128 * 128),
m_nxdnTXLevel(128 * 128),
m_rxDCOffset(DC_OFFSET),
m_txDCOffset(DC_OFFSET),
m_ledCount(0U),
m_ledValue(true),
m_detect(false),
@@ -64,13 +91,22 @@ m_dacOverflow(0U),
m_watchdog(0U),
m_lockout(false)
{
::memset(m_rrcState, 0x00U, 70U * sizeof(q15_t));
::memset(m_gaussianState, 0x00U, 40U * sizeof(q15_t));
::memset(m_boxcarState, 0x00U, 30U * sizeof(q15_t));
::memset(m_dmrState, 0x00U, 70U * sizeof(q15_t));
::memset(m_gaussianState, 0x00U, 40U * sizeof(q15_t));
::memset(m_boxcarState, 0x00U, 30U * sizeof(q15_t));
::memset(m_nxdnState, 0x00U, 110U * sizeof(q15_t));
::memset(m_nxdnISincState, 0x00U, 60U * sizeof(q15_t));
::memset(m_ysfState, 0x00U, 70U * sizeof(q15_t));
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN;
m_rrcFilter.pState = m_rrcState;
m_rrcFilter.pCoeffs = RRC_0_2_FILTER;
m_dcFilter.numStages = DC_FILTER_STAGES;
m_dcFilter.pState = m_dcState;
m_dcFilter.pCoeffs = DC_FILTER;
m_dcFilter.postShift = 0;
m_dmrFilter.numTaps = RRC_0_2_FILTER_LEN;
m_dmrFilter.pState = m_dmrState;
m_dmrFilter.pCoeffs = RRC_0_2_FILTER;
m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN;
m_gaussianFilter.pState = m_gaussianState;
@@ -80,7 +116,122 @@ m_lockout(false)
m_boxcarFilter.pState = m_boxcarState;
m_boxcarFilter.pCoeffs = BOXCAR_FILTER;
m_nxdnFilter.numTaps = NXDN_0_2_FILTER_LEN;
m_nxdnFilter.pState = m_nxdnState;
m_nxdnFilter.pCoeffs = NXDN_0_2_FILTER;
m_nxdnISincFilter.numTaps = NXDN_ISINC_FILTER_LEN;
m_nxdnISincFilter.pState = m_nxdnISincState;
m_nxdnISincFilter.pCoeffs = NXDN_ISINC_FILTER;
m_ysfFilter.numTaps = RRC_0_2_FILTER_LEN;
m_ysfFilter.pState = m_ysfState;
m_ysfFilter.pCoeffs = RRC_0_2_FILTER;
initInt();
selfTest();
}
void CIO::selfTest()
{
bool ledValue = false;
for (uint8_t i = 0; i < 6; i++) {
ledValue = !ledValue;
// We exclude PTT to avoid trigger the transmitter
setLEDInt(ledValue);
setCOSInt(ledValue);
#if defined(ARDUINO_MODE_PINS)
setDStarInt(ledValue);
setDMRInt(ledValue);
setYSFInt(ledValue);
setP25Int(ledValue);
setNXDNInt(ledValue);
#endif
delayInt(250);
}
#if defined(ARDUINO_MODE_PINS)
setDStarInt(true);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(true);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
delayInt(250);
setDStarInt(false);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
#endif
}
void CIO::start()
@@ -101,7 +252,7 @@ void CIO::process()
if (m_started) {
// Two seconds timeout
if (m_watchdog >= 48000U) {
if (m_modemState == STATE_DSTAR || m_modemState == STATE_DMR || m_modemState == STATE_YSF) {
if (m_modemState == STATE_DSTAR || m_modemState == STATE_DMR || m_modemState == STATE_YSF || m_modemState == STATE_P25 || m_modemState == STATE_NXDN) {
if (m_modemState == STATE_DMR && m_tx)
dmrTX.setStart(false);
m_modemState = STATE_IDLE;
@@ -149,7 +300,7 @@ void CIO::process()
if (m_detect && (sample == 0U || sample == 4095U))
m_adcOverflow++;
q15_t res1 = q15_t(sample) - DC_OFFSET;
q15_t res1 = q15_t(sample) - m_rxDCOffset;
q31_t res2 = res1 * m_rxLevel;
samples[i] = q15_t(__SSAT((res2 >> 15), 16));
}
@@ -157,71 +308,108 @@ void CIO::process()
if (m_lockout)
return;
q31_t dcLevel = 0;
q31_t dcValues[RX_BLOCK_SIZE];
q31_t q31Samples[RX_BLOCK_SIZE];
::arm_q15_to_q31(samples, q31Samples, RX_BLOCK_SIZE);
::arm_biquad_cascade_df1_q31(&m_dcFilter, q31Samples, dcValues, RX_BLOCK_SIZE);
for (uint8_t i = 0U; i < RX_BLOCK_SIZE; i++)
dcLevel += dcValues[i];
dcLevel /= RX_BLOCK_SIZE;
q15_t offset = q15_t(__SSAT((dcLevel >> 16), 16));;
q15_t dcSamples[RX_BLOCK_SIZE];
for (uint8_t i = 0U; i < RX_BLOCK_SIZE; i++)
dcSamples[i] = samples[i] - offset;
if (m_modemState == STATE_IDLE) {
if (m_dstarEnable) {
q15_t GMSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
if (m_p25Enable) {
q15_t P25Vals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
}
if (m_dmrEnable || m_ysfEnable) {
q15_t C4FSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
if (m_nxdnEnable) {
q15_t NXDNVals[RX_BLOCK_SIZE];
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
if (m_dmrEnable) {
if (m_duplex)
dmrIdleRX.samples(C4FSKVals, RX_BLOCK_SIZE);
else
dmrDMORX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE);
}
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
}
if (m_ysfEnable)
ysfRX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE);
if (m_ysfEnable) {
q15_t YSFVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_ysfFilter, dcSamples, YSFVals, RX_BLOCK_SIZE);
ysfRX.samples(YSFVals, rssi, RX_BLOCK_SIZE);
}
if (m_dmrEnable) {
q15_t DMRVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_dmrFilter, samples, DMRVals, RX_BLOCK_SIZE);
if (m_duplex)
dmrIdleRX.samples(DMRVals, RX_BLOCK_SIZE);
else
dmrDMORX.samples(DMRVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_DSTAR) {
if (m_dstarEnable) {
q15_t GMSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_DMR) {
if (m_dmrEnable) {
q15_t C4FSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
q15_t DMRVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_dmrFilter, samples, DMRVals, RX_BLOCK_SIZE);
if (m_duplex) {
// If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs
if (m_tx)
dmrRX.samples(C4FSKVals, rssi, control, RX_BLOCK_SIZE);
dmrRX.samples(DMRVals, rssi, control, RX_BLOCK_SIZE);
else
dmrIdleRX.samples(C4FSKVals, RX_BLOCK_SIZE);
dmrIdleRX.samples(DMRVals, RX_BLOCK_SIZE);
} else {
dmrDMORX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE);
dmrDMORX.samples(DMRVals, rssi, RX_BLOCK_SIZE);
}
}
} else if (m_modemState == STATE_YSF) {
if (m_ysfEnable) {
q15_t C4FSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
q15_t YSFVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_ysfFilter, dcSamples, YSFVals, RX_BLOCK_SIZE);
ysfRX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE);
ysfRX.samples(YSFVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_P25) {
if (m_p25Enable) {
q15_t P25Vals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_NXDN) {
if (m_nxdnEnable) {
q15_t NXDNVals[RX_BLOCK_SIZE];
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_DSTARCAL) {
q15_t GMSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
@@ -261,6 +449,9 @@ void CIO::write(MMDVM_STATE mode, q15_t* samples, uint16_t length, const uint8_t
case STATE_P25:
txLevel = m_p25TXLevel;
break;
case STATE_NXDN:
txLevel = m_nxdnTXLevel;
break;
default:
txLevel = m_cwIdTXLevel;
break;
@@ -269,7 +460,7 @@ void CIO::write(MMDVM_STATE mode, q15_t* samples, uint16_t length, const uint8_t
for (uint16_t i = 0U; i < length; i++) {
q31_t res1 = samples[i] * txLevel;
q15_t res2 = q15_t(__SSAT((res1 >> 15), 16));
uint16_t res3 = uint16_t(res2 + DC_OFFSET);
uint16_t res3 = uint16_t(res2 + m_txDCOffset);
// Detect DAC overflow
if (res3 > 4095U)
@@ -307,10 +498,11 @@ void CIO::setMode()
setDMRInt(m_modemState == STATE_DMR);
setYSFInt(m_modemState == STATE_YSF);
setP25Int(m_modemState == STATE_P25);
setNXDNInt(m_modemState == STATE_NXDN);
#endif
}
void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel)
void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, int16_t txDCOffset, int16_t rxDCOffset)
{
m_pttInvert = pttInvert;
@@ -320,6 +512,10 @@ void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rx
m_dmrTXLevel = q15_t(dmrTXLevel * 128);
m_ysfTXLevel = q15_t(ysfTXLevel * 128);
m_p25TXLevel = q15_t(p25TXLevel * 128);
m_nxdnTXLevel = q15_t(nxdnTXLevel * 128);
m_rxDCOffset = DC_OFFSET + rxDCOffset;
m_txDCOffset = DC_OFFSET + txDCOffset;
if (rxInvert)
m_rxLevel = -m_rxLevel;
@@ -329,6 +525,7 @@ void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rx
m_dmrTXLevel = -m_dmrTXLevel;
m_ysfTXLevel = -m_ysfTXLevel;
m_p25TXLevel = -m_p25TXLevel;
m_nxdnTXLevel = -m_nxdnTXLevel;
}
}
@@ -356,6 +553,11 @@ void CIO::resetWatchdog()
m_watchdog = 0U;
}
uint32_t CIO::getWatchdog()
{
return m_watchdog;
}
bool CIO::hasLockout() const
{
return m_lockout;
+23 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
*
* 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
@@ -42,7 +42,7 @@ public:
void interrupt();
void setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel);
void setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnLevel, int16_t txDCOffset, int16_t rxDCOffset);
void getOverflow(bool& adcOverflow, bool& dacOverflow);
@@ -52,6 +52,9 @@ public:
bool hasLockout() const;
void resetWatchdog();
uint32_t getWatchdog();
void selfTest();
private:
bool m_started;
@@ -60,12 +63,21 @@ private:
CSampleRB m_txBuffer;
CRSSIRB m_rssiBuffer;
arm_fir_instance_q15 m_rrcFilter;
arm_biquad_casd_df1_inst_q31 m_dcFilter;
q31_t m_dcState[4];
arm_fir_instance_q15 m_dmrFilter;
arm_fir_instance_q15 m_gaussianFilter;
arm_fir_instance_q15 m_boxcarFilter;
q15_t m_rrcState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
arm_fir_instance_q15 m_nxdnFilter;
arm_fir_instance_q15 m_nxdnISincFilter;
arm_fir_instance_q15 m_ysfFilter;
q15_t m_dmrState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
q15_t m_gaussianState[40U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare
q15_t m_boxcarState[30U]; // NoTaps + BlockSize - 1, 6 + 20 - 1 plus some spare
q15_t m_nxdnState[110U]; // NoTaps + BlockSize - 1, 82 + 20 - 1 plus some spare
q15_t m_nxdnISincState[60U]; // NoTaps + BlockSize - 1, 32 + 20 - 1 plus some spare
q15_t m_ysfState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
bool m_pttInvert;
q15_t m_rxLevel;
@@ -74,6 +86,10 @@ private:
q15_t m_dmrTXLevel;
q15_t m_ysfTXLevel;
q15_t m_p25TXLevel;
q15_t m_nxdnTXLevel;
uint16_t m_rxDCOffset;
uint16_t m_txDCOffset;
uint32_t m_ledCount;
bool m_ledValue;
@@ -101,6 +117,9 @@ private:
void setDMRInt(bool on);
void setYSFInt(bool on);
void setP25Int(bool on);
void setNXDNInt(bool on);
void delayInt(unsigned int dly);
};
#endif
+16 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015 by Jim Mclaughlin KI6ZUM
* Copyright (C) 2016 by Colin Durbridge G4EML
*
@@ -33,6 +33,7 @@
#define PIN_DMR 17
#define PIN_YSF 18
#define PIN_P25 19
#define PIN_NXDN 20
#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7)
#define ADC_ISR_EOC_Chan ADC_ISR_EOC7
#define ADC_CDR_Chan 7
@@ -46,6 +47,7 @@
#define PIN_DMR 8
#define PIN_YSF 7
#define PIN_P25 6
#define PIN_NXDN 5
#define ADC_CHER_Chan (1<<13) // ADC on Due pin A11 - Due AD13 - (1 << 13)
#define ADC_ISR_EOC_Chan ADC_ISR_EOC13
#define ADC_CDR_Chan 13
@@ -61,6 +63,7 @@
#define PIN_DMR 8
#define PIN_YSF 7
#define PIN_P25 6
#define PIN_NXDN 5
#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7)
#define ADC_ISR_EOC_Chan ADC_ISR_EOC7
#define ADC_CDR_Chan 7
@@ -95,6 +98,7 @@ void CIO::initInt()
pinMode(PIN_DMR, OUTPUT);
pinMode(PIN_YSF, OUTPUT);
pinMode(PIN_P25, OUTPUT);
pinMode(PIN_NXDN, OUTPUT);
#endif
}
@@ -226,4 +230,15 @@ void CIO::setP25Int(bool on)
digitalWrite(PIN_P25, on ? HIGH : LOW);
}
void CIO::setNXDNInt(bool on)
{
digitalWrite(PIN_NXDN, on ? HIGH : LOW);
}
void CIO::delayInt(unsigned int dly)
{
delay(dly);
}
#endif
+376 -51
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
* Copyright (C) 2016, 2017 by Andy Uribe CA6JAU
* Copyright (C) 2017 by Jonathan Naylor G4KLX
* Copyright (C) 2016,2017,2018 by Andy Uribe CA6JAU
* Copyright (C) 2017,2018 by Jonathan Naylor G4KLX
*
* 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
@@ -22,27 +22,28 @@
#include "Globals.h"
#include "IO.h"
#if defined(STM32F4XX) || defined(STM32F4)
#if defined(STM32F4XX) || defined(STM32F7XX)
#if defined(STM32F4_DISCOVERY)
/*
Pin definitions for STM32F4 Discovery Board:
PTT PB13 output
COSLED PA7 output
LED PD15 output
COS PA5 input
PTT PB13 output P1 Pin37
COSLED PA7 output P1 Pin17
LED PD15 output P1 Pin47
COS PA5 input P1 Pin15
DSTAR PD12 output
DMR PD13 output
YSF PD14 output
P25 PD11 output
DSTAR PD12 output P1 Pin44
DMR PD13 output P1 Pin45
YSF PD14 output P1 Pin46
P25 PD11 output P1 Pin43
NXDN PD10 output P1 Pin42
RX PA0 analog input
RSSI PA1 analog input
TX PA4 analog output
RX PA0 analog input P1 Pin12
RSSI PA1 analog input P1 Pin11
TX PA4 analog output P1 Pin16
EXT_CLK PA15 input
EXT_CLK PA15 input P2 Pin40
*/
#define PIN_COS GPIO_Pin_5
@@ -65,6 +66,10 @@ EXT_CLK PA15 input
#define PORT_P25 GPIOD
#define RCC_Per_P25 RCC_AHB1Periph_GPIOD
#define PIN_NXDN GPIO_Pin_10
#define PORT_NXDN GPIOD
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOD
#define PIN_DSTAR GPIO_Pin_12
#define PORT_DSTAR GPIOD
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOD
@@ -107,6 +112,7 @@ DSTAR PC7 output
DMR PC8 output
YSF PA8 output
P25 PC9 output
NXDN PB1 output
RX PA0 analog input
RSSI PA7 analog input
@@ -135,6 +141,160 @@ EXT_CLK PA15 input
#define PORT_P25 GPIOC
#define RCC_Per_P25 RCC_AHB1Periph_GPIOC
#define PIN_NXDN GPIO_Pin_1
#define PORT_NXDN GPIOB
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_7
#define PORT_DSTAR GPIOC
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOC
#define PIN_DMR GPIO_Pin_8
#define PORT_DMR GPIOC
#define RCC_Per_DMR RCC_AHB1Periph_GPIOC
#define PIN_YSF GPIO_Pin_8
#define PORT_YSF GPIOA
#define RCC_Per_YSF RCC_AHB1Periph_GPIOA
#define PIN_EXT_CLK GPIO_Pin_15
#define SRC_EXT_CLK GPIO_PinSource15
#define PORT_EXT_CLK GPIOA
#define PIN_RX GPIO_Pin_0
#define PIN_RX_CH ADC_Channel_0
#define PORT_RX GPIOA
#define RCC_Per_RX RCC_AHB1Periph_GPIOA
#define PIN_RSSI GPIO_Pin_7
#define PIN_RSSI_CH ADC_Channel_7
#define PORT_RSSI GPIOA
#define RCC_Per_RSSI RCC_AHB1Periph_GPIOA
#define PIN_TX GPIO_Pin_4
#define PIN_TX_CH DAC_Channel_1
#elif defined(STM32F722_PI)
/*
Pin definitions for STM32F722 Pi Board:
PTT PB13 output
COSLED PB14 output
LED PB15 output
COS PC0 input
DSTAR PC7 output
DMR PC8 output
YSF PA8 output
P25 PC9 output
NXDN PB1 output
RX PA0 analog input
RSSI PA7 analog input
TX PA4 analog output
EXT_CLK PA15 input
*/
#define PIN_COS GPIO_Pin_0
#define PORT_COS GPIOC
#define RCC_Per_COS RCC_AHB1Periph_GPIOC
#define PIN_PTT GPIO_Pin_13
#define PORT_PTT GPIOB
#define RCC_Per_PTT RCC_AHB1Periph_GPIOB
#define PIN_COSLED GPIO_Pin_14
#define PORT_COSLED GPIOB
#define RCC_Per_COSLED RCC_AHB1Periph_GPIOB
#define PIN_LED GPIO_Pin_15
#define PORT_LED GPIOB
#define RCC_Per_LED RCC_AHB1Periph_GPIOB
#define PIN_P25 GPIO_Pin_9
#define PORT_P25 GPIOC
#define RCC_Per_P25 RCC_AHB1Periph_GPIOC
#define PIN_NXDN GPIO_Pin_1
#define PORT_NXDN GPIOB
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_7
#define PORT_DSTAR GPIOC
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOC
#define PIN_DMR GPIO_Pin_8
#define PORT_DMR GPIOC
#define RCC_Per_DMR RCC_AHB1Periph_GPIOC
#define PIN_YSF GPIO_Pin_8
#define PORT_YSF GPIOA
#define RCC_Per_YSF RCC_AHB1Periph_GPIOA
#define PIN_EXT_CLK GPIO_Pin_15
#define SRC_EXT_CLK GPIO_PinSource15
#define PORT_EXT_CLK GPIOA
#define PIN_RX GPIO_Pin_0
#define PIN_RX_CH ADC_Channel_0
#define PORT_RX GPIOA
#define RCC_Per_RX RCC_AHB1Periph_GPIOA
#define PIN_RSSI GPIO_Pin_7
#define PIN_RSSI_CH ADC_Channel_7
#define PORT_RSSI GPIOA
#define RCC_Per_RSSI RCC_AHB1Periph_GPIOA
#define PIN_TX GPIO_Pin_4
#define PIN_TX_CH DAC_Channel_1
#elif defined(STM32F4_F4M)
/*
Pin definitions for MMDVM-F4M Pi-Hat F0DEI board:
PTT PB13 output
COSLED PB14 output
LED PB15 output
COS PC0 input
DSTAR PC7 output
DMR PC8 output
YSF PA8 output
P25 PC9 output
NXDN PB1 output
RX PA0 analog input
RSSI PA7 analog input
TX PA4 analog output
EXT_CLK PA15 input
*/
#define PIN_COS GPIO_Pin_0
#define PORT_COS GPIOC
#define RCC_Per_COS RCC_AHB1Periph_GPIOC
#define PIN_PTT GPIO_Pin_13
#define PORT_PTT GPIOB
#define RCC_Per_PTT RCC_AHB1Periph_GPIOB
#define PIN_COSLED GPIO_Pin_14
#define PORT_COSLED GPIOB
#define RCC_Per_COSLED RCC_AHB1Periph_GPIOB
#define PIN_LED GPIO_Pin_15
#define PORT_LED GPIOB
#define RCC_Per_LED RCC_AHB1Periph_GPIOB
#define PIN_P25 GPIO_Pin_9
#define PORT_P25 GPIOC
#define RCC_Per_P25 RCC_AHB1Periph_GPIOC
#define PIN_NXDN GPIO_Pin_1
#define PORT_NXDN GPIOB
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_7
#define PORT_DSTAR GPIOC
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOC
@@ -170,26 +330,28 @@ EXT_CLK PA15 input
/*
Pin definitions for STM32F4 Nucleo boards (ST Morpho header):
PTT PB13 output
COSLED PB14 output
LED PA5 output
COS PB15 input
PTT PB13 output CN10 Pin30
COSLED PB14 output CN10 Pin28
LED PA5 output CN10 Pin11
COS PB15 input CN10 Pin26
DSTAR PB10 output
DMR PB4 output
YSF PB5 output
P25 PB3 output
DSTAR PB10 output CN10 Pin25
DMR PB4 output CN10 Pin27
YSF PB5 output CN10 Pin29
P25 PB3 output CN10 Pin31
NXDN PA10 output CN10 Pin33
MDSTAR PC4 output
MDMR PC5 outout
MYSF PC2 output
MP25 PC3 output
MDSTAR PC4 output CN10 Pin34
MDMR PC5 output CN10 Pin6
MYSF PC2 output CN7 Pin35
MP25 PC3 output CN7 Pin37
MNXDN PC6 output CN10 Pin4
RX PA0 analog input
RSSI PA1 analog input
TX PA4 analog output
RX PA0 analog input CN7 Pin28
RSSI PA1 analog input CN7 Pin30
TX PA4 analog output CN7 Pin32
EXT_CLK PA15 input
EXT_CLK PA15 input CN7 Pin17
*/
#define PIN_COS GPIO_Pin_15
@@ -212,6 +374,10 @@ EXT_CLK PA15 input
#define PORT_P25 GPIOB
#define RCC_Per_P25 RCC_AHB1Periph_GPIOB
#define PIN_NXDN GPIO_Pin_10
#define PORT_NXDN GPIOA
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOA
#define PIN_DSTAR GPIO_Pin_10
#define PORT_DSTAR GPIOB
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOB
@@ -229,6 +395,10 @@ EXT_CLK PA15 input
#define PORT_MP25 GPIOC
#define RCC_Per_MP25 RCC_AHB1Periph_GPIOC
#define PIN_MNXDN GPIO_Pin_6
#define PORT_MNXDN GPIOC
#define RCC_Per_MNXDN RCC_AHB1Periph_GPIOC
#define PIN_MDSTAR GPIO_Pin_4
#define PORT_MDSTAR GPIOC
#define RCC_Per_MDSTAR RCC_AHB1Periph_GPIOC
@@ -263,21 +433,22 @@ EXT_CLK PA15 input
/*
Pin definitions for STM32F4 Nucleo boards (Arduino header):
PTT PB10 output
COSLED PB3 output
LED PB5 output
COS PB4 input
PTT PB10 output CN9 Pin7
COSLED PB3 output CN9 Pin4
LED PB5 output CN9 Pin5
COS PB4 input CN9 Pin6
DSTAR PA1 output
DMR PA4 output
YSF PB0 output
P25 PC1 output
DSTAR PA1 output CN8 Pin2
DMR PA4 output CN8 Pin3
YSF PB0 output CN8 Pin4
P25 PC1 output CN8 Pin5
NXDN PC0 output CN8 Pin6
RX PA0 analog input
RSSI PC0 analog input
TX PA5 analog output
RX PA0 analog input CN8 Pin1
RSSI PC0 analog input CN8 Pin6
TX PA5 analog output CN5 Pin6
EXT_CLK PB8 input
EXT_CLK PB8 input CN5 Pin10
*/
#define PIN_COS GPIO_Pin_4
@@ -300,6 +471,10 @@ EXT_CLK PB8 input
#define PORT_P25 GPIOC
#define RCC_Per_P25 RCC_AHB1Periph_GPIOC
#define PIN_NXDN GPIO_Pin_0
#define PORT_NXDN GPIOC
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOC
#define PIN_DSTAR GPIO_Pin_1
#define PORT_DSTAR GPIOA
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOA
@@ -333,8 +508,111 @@ EXT_CLK PB8 input
#error "Either STM32F4_NUCLEO_MORPHO_HEADER or STM32F4_NUCLEO_ARDUINO_HEADER need to be defined in Config.h"
#endif
#elif defined(STM32F7_NUCLEO)
/*
Pin definitions for STM32F7 Nucleo boards (ST Morpho header):
PTT PB13 output CN12 Pin30
COSLED PB14 output CN12 Pin28
LED PA5 output CN12 Pin11
COS PB15 input CN12 Pin26
DSTAR PB10 output CN12 Pin25
DMR PB4 output CN12 Pin27
YSF PB5 output CN12 Pin29
P25 PB3 output CN12 Pin31
NXDN PA10 output CN12 Pin33
MDSTAR PC4 output CN12 Pin34
MDMR PC5 output CN12 Pin6
MYSF PC2 output CN11 Pin35
MP25 PC3 output CN11 Pin37
MNXDN PC6 output CN12 Pin4
RX PA0 analog input CN11 Pin28
RSSI PA1 analog input CN11 Pin30
TX PA4 analog output CN11 Pin32
EXT_CLK PA15 input CN11 Pin17
*/
#define PIN_COS GPIO_Pin_15
#define PORT_COS GPIOB
#define RCC_Per_COS RCC_AHB1Periph_GPIOB
#define PIN_PTT GPIO_Pin_13
#define PORT_PTT GPIOB
#define RCC_Per_PTT RCC_AHB1Periph_GPIOB
#define PIN_COSLED GPIO_Pin_14
#define PORT_COSLED GPIOB
#define RCC_Per_COSLED RCC_AHB1Periph_GPIOB
#define PIN_LED GPIO_Pin_5
#define PORT_LED GPIOA
#define RCC_Per_LED RCC_AHB1Periph_GPIOA
#define PIN_P25 GPIO_Pin_3
#define PORT_P25 GPIOB
#define RCC_Per_P25 RCC_AHB1Periph_GPIOB
#define PIN_NXDN GPIO_Pin_10
#define PORT_NXDN GPIOA
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOA
#define PIN_DSTAR GPIO_Pin_10
#define PORT_DSTAR GPIOB
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOB
#define PIN_DMR GPIO_Pin_4
#define PORT_DMR GPIOB
#define RCC_Per_DMR RCC_AHB1Periph_GPIOB
#define PIN_YSF GPIO_Pin_5
#define PORT_YSF GPIOB
#define RCC_Per_YSF RCC_AHB1Periph_GPIOB
#if defined(STM32F4_NUCLEO_MODE_PINS)
#define PIN_MP25 GPIO_Pin_3
#define PORT_MP25 GPIOC
#define RCC_Per_MP25 RCC_AHB1Periph_GPIOC
#define PIN_MNXDN GPIO_Pin_6
#define PORT_MNXDN GPIOC
#define RCC_Per_MNXDN RCC_AHB1Periph_GPIOC
#define PIN_MDSTAR GPIO_Pin_4
#define PORT_MDSTAR GPIOC
#define RCC_Per_MDSTAR RCC_AHB1Periph_GPIOC
#define PIN_MDMR GPIO_Pin_5
#define PORT_MDMR GPIOC
#define RCC_Per_MDMR RCC_AHB1Periph_GPIOC
#define PIN_MYSF GPIO_Pin_2
#define PORT_MYSF GPIOC
#define RCC_Per_MYSF RCC_AHB1Periph_GPIOC
#endif
#define PIN_EXT_CLK GPIO_Pin_15
#define SRC_EXT_CLK GPIO_PinSource15
#define PORT_EXT_CLK GPIOA
#define PIN_RX GPIO_Pin_0
#define PIN_RX_CH ADC_Channel_0
#define PORT_RX GPIOA
#define RCC_Per_RX RCC_AHB1Periph_GPIOA
#define PIN_RSSI GPIO_Pin_1
#define PIN_RSSI_CH ADC_Channel_1
#define PORT_RSSI GPIOA
#define RCC_Per_RSSI RCC_AHB1Periph_GPIOA
#define PIN_TX GPIO_Pin_4
#define PIN_TX_CH DAC_Channel_1
#else
#error "Either STM32F4_DISCOVERY, STM32F4_PI or STM32F4_NUCLEO need to be defined"
#error "Either STM32F4_DISCOVERY, STM32F4_PI, STM32F722_PI, STM32F4_F4M, STM32F4_NUCLEO or STM32F7_NUCLEO need to be defined"
#endif
const uint16_t DC_OFFSET = 2048U;
@@ -355,7 +633,7 @@ void CIO::initInt()
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
@@ -407,6 +685,12 @@ void CIO::initInt()
GPIO_InitStruct.GPIO_Pin = PIN_P25;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(PORT_P25, &GPIO_InitStruct);
// NXDN pin
RCC_AHB1PeriphClockCmd(RCC_Per_NXDN, ENABLE);
GPIO_InitStruct.GPIO_Pin = PIN_NXDN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(PORT_NXDN, &GPIO_InitStruct);
#endif
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
@@ -433,6 +717,12 @@ void CIO::initInt()
GPIO_InitStruct.GPIO_Pin = PIN_MP25;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(PORT_MP25, &GPIO_InitStruct);
// NXDN mode pin
RCC_AHB1PeriphClockCmd(RCC_Per_MNXDN, ENABLE);
GPIO_InitStruct.GPIO_Pin = PIN_MNXDN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(PORT_MNXDN, &GPIO_InitStruct);
#endif
}
@@ -535,7 +825,7 @@ void CIO::startInt()
// Init the timer
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
#if defined(EXTERNAL_OSC)
#if defined(EXTERNAL_OSC) && !(defined(STM32F4_PI) || defined(STM32F722_PI))
// Configure a GPIO as external TIM2 clock source
GPIO_PinAFConfig(PORT_EXT_CLK, SRC_EXT_CLK, GPIO_AF_TIM2);
GPIO_InitStruct.GPIO_Pin = PIN_EXT_CLK;
@@ -547,19 +837,20 @@ void CIO::startInt()
TIM_TimeBaseStructInit (&timerInitStructure);
// TIM2 output frequency
#if defined(EXTERNAL_OSC)
#if defined(EXTERNAL_OSC) && !(defined(STM32F4_PI) || defined(STM32F722_PI))
timerInitStructure.TIM_Prescaler = (uint16_t) ((EXTERNAL_OSC/(2*SAMP_FREQ)) - 1);
timerInitStructure.TIM_Period = 1;
#else
timerInitStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock/(4*SAMP_FREQ)) - 1);
timerInitStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock/(6*SAMP_FREQ)) - 1);
timerInitStructure.TIM_Period = 2;
#endif
timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
timerInitStructure.TIM_Period = 1;
timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
timerInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &timerInitStructure);
#if defined(EXTERNAL_OSC)
#if defined(EXTERNAL_OSC) && !(defined(STM32F4_PI) || defined(STM32F722_PI))
// Enable external clock
TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);
#else
@@ -621,7 +912,7 @@ void CIO::interrupt()
bool CIO::getCOSInt()
{
return GPIO_ReadOutputDataBit(PORT_COS, PIN_COS) == Bit_SET;
return GPIO_ReadInputDataBit(PORT_COS, PIN_COS) == Bit_SET;
}
void CIO::setLEDInt(bool on)
@@ -671,4 +962,38 @@ void CIO::setP25Int(bool on)
#endif
}
void CIO::setNXDNInt(bool on)
{
GPIO_WriteBit(PORT_NXDN, PIN_NXDN, on ? Bit_SET : Bit_RESET);
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
GPIO_WriteBit(PORT_MNXDN, PIN_MNXDN, on ? Bit_SET : Bit_RESET);
#endif
}
// Simple delay function for STM32
// Example from: http://thehackerworkshop.com/?p=1209
void CIO::delayInt(unsigned int dly)
{
#if defined(STM32F7XX)
unsigned int loopsPerMillisecond = (SystemCoreClock/1000);
#else
unsigned int loopsPerMillisecond = (SystemCoreClock/1000) / 3;
#endif
for (; dly > 0; dly--)
{
asm volatile //this routine waits (approximately) one millisecond
(
"mov r3, %[loopsPerMillisecond] \n\t" //load the initial loop counter
"loop: \n\t"
"subs r3, #1 \n\t"
"bne loop \n\t"
: //empty output list
: [loopsPerMillisecond] "r" (loopsPerMillisecond) //input to the asm routine
: "r3", "cc" //clobber list
);
}
}
#endif
+76 -9
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
* Copyright (C) 2016, 2017 by Andy Uribe CA6JAU
* Copyright (C) 2017 by Jonathan Naylor G4KLX
* Copyright (C) 2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2017 by Wojciech Krutnik N0CALL
*
* This program is free software; you can redistribute it and/or modify
@@ -39,6 +39,7 @@ DSTAR PB7 output
DMR PB6 output
YSF PB8 output
P25 PB9 output
NXDN PB10 output
RX PB0 analog input (ADC1_8)
RSSI PB1 analog input (ADC2_9)
@@ -46,8 +47,8 @@ TX PA4 analog output (DAC_OUT1)
EXT_CLK PA15 input (AF: TIM2_CH1_ETR)
USART2_TXD PA2 output (AF)
USART2_RXD PA3 input (AF)
USART1_TXD PA9 output (AF)
USART1_RXD PA10 input (AF)
*/
@@ -76,6 +77,9 @@ USART2_RXD PA3 input (AF)
#define PIN_P25 9
#define PORT_P25 GPIOB
#define BB_P25 *((bitband_t)BITBAND_PERIPH(&PORT_P25->ODR, PIN_P25))
#define PIN_NXDN 10
#define PORT_NXDN GPIOB
#define BB_NXDN *((bitband_t)BITBAND_PERIPH(&PORT_NXDN->ODR, PIN_NXDN))
#define PIN_RX 0
#define PIN_RX_ADC_CH 8
@@ -91,10 +95,10 @@ USART2_RXD PA3 input (AF)
#define SRC_EXT_CLK 15
#define PORT_EXT_CLK GPIOA
#define PIN_USART2_TXD 2
#define PORT_USART2_TXD GPIOA
#define PIN_USART2_RXD 3
#define PORT_USART2_RXD GPIOA
#define PIN_USART1_TXD 9
#define PORT_USART1_TXD GPIOA
#define PIN_USART1_RXD 10
#define PORT_USART1_RXD GPIOA
#else // defined(STM32F1_POG)
#error "Either STM32F1_POG, or sth need to be defined"
@@ -143,6 +147,46 @@ void GPIOConfigPin(GPIO_TypeDef *port_ptr, uint32_t pin, uint32_t mode_cnf_value
*cr_ptr = cr_value; // save localized value to CRL / CRL
}
#if defined(STM32F1_POG)
void FancyLEDEffect()
{
bitband_t foo[] = {&BB_LED, &BB_COSLED, &BB_PTT, &BB_DMR, &BB_DSTAR, &BB_YSF, &BB_P25};
for(int i=0; i<7; i++){
*foo[i] = 0x01;
}
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1);
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
delay(SystemCoreClock/1000*100);
for(int i=0; i<7; i++){
*foo[i] = 0x00;
}
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
delay(SystemCoreClock/1000*20);
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
delay(SystemCoreClock/1000*10);
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
*foo[0] = 0x01;
for(int i=1; i<7; i++){
delay(SystemCoreClock/1000*10);
*foo[i-1] = 0x00;
*foo[i] = 0x01;
}
for(int i=5; i>=0; i--){
delay(SystemCoreClock/1000*10);
*foo[i+1] = 0x00;
*foo[i] = 0x01;
}
delay(SystemCoreClock/1000*10);
*foo[5+1-6] = 0x00;
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
delay(SystemCoreClock/1000*10);
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1|GPIO_CRL_CNF0_1);
delay(SystemCoreClock/1000*50);
}
#endif
static inline void GPIOInit()
{
@@ -174,6 +218,7 @@ static inline void GPIOInit()
GPIOConfigPin(PORT_DMR, PIN_DMR, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_YSF, PIN_YSF, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_P25, PIN_P25, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_NXDN, PIN_NXDN, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_RX, PIN_RX, 0);
#if defined(SEND_RSSI_DATA)
@@ -188,8 +233,8 @@ static inline void GPIOInit()
#endif
#endif
GPIOConfigPin(PORT_USART2_TXD, PIN_USART2_TXD, GPIO_CRL_MODE0_1|GPIO_CRL_CNF0_1);
GPIOConfigPin(PORT_USART2_RXD, PIN_USART2_RXD, GPIO_CRL_CNF0_0);
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1|GPIO_CRL_CNF0_1);
GPIOConfigPin(PORT_USART1_RXD, PIN_USART1_RXD, GPIO_CRL_CNF0_0);
AFIO->MAPR = (AFIO->MAPR & ~AFIO_MAPR_SWJ_CFG) | AFIO_MAPR_SWJ_CFG_1;
}
@@ -250,6 +295,9 @@ static inline void ADCInit()
// Trigger first conversion
ADC1->CR2 |= ADC_CR2_ADON;
#if defined(SEND_RSSI_DATA)
ADC2->CR2 |= ADC_CR2_ADON;
#endif
}
@@ -295,6 +343,9 @@ void CIO::initInt()
GPIOInit();
ADCInit();
DACInit();
#if defined(STM32F1_POG)
FancyLEDEffect();
#endif
}
void CIO::startInt()
@@ -312,10 +363,16 @@ void CIO::interrupt()
uint16_t rawRSSI = 0U;
bitband_t eoc = (bitband_t)BITBAND_PERIPH(&ADC1->SR, ADC_SR_EOS_Pos);
bitband_t adon = (bitband_t)BITBAND_PERIPH(&ADC1->CR2, ADC_CR2_ADON_Pos);
#if defined(SEND_RSSI_DATA)
bitband_t rssi_adon = (bitband_t)BITBAND_PERIPH(&ADC2->CR2, ADC_CR2_ADON_Pos);
#endif
if (*eoc) {
// trigger next conversion
*adon = 1;
#if defined(SEND_RSSI_DATA)
*rssi_adon = 1;
#endif
m_txBuffer.get(sample, control);
DAC->DHR12R1 = sample; // Send the value to the DAC
@@ -372,4 +429,14 @@ void CIO::setP25Int(bool on)
BB_P25 = !!on;
}
void CIO::setNXDNInt(bool on)
{
BB_NXDN = !!on;
}
void CIO::delayInt(unsigned int dly)
{
delay(dly);
}
#endif
+13 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
*
* 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
@@ -34,6 +34,7 @@
#define PIN_DMR 10
#define PIN_YSF 11
#define PIN_P25 12
#define PIN_NXDN 8
#define PIN_ADC 5 // A0, Pin 14
#define PIN_RSSI 4 // Teensy 3.5/3.6, A16, Pin 35. Teensy 3.1/3.2, A17, Pin 28
@@ -63,6 +64,7 @@ void CIO::initInt()
pinMode(PIN_DMR, OUTPUT);
pinMode(PIN_YSF, OUTPUT);
pinMode(PIN_P25, OUTPUT);
pinMode(PIN_NXDN, OUTPUT);
#endif
}
@@ -210,4 +212,14 @@ void CIO::setP25Int(bool on)
digitalWrite(PIN_P25, on ? HIGH : LOW);
}
void CIO::setNXDNInt(bool on)
{
digitalWrite(PIN_NXDN, on ? HIGH : LOW);
}
void CIO::delayInt(unsigned int dly)
{
delay(dly);
}
#endif
+20 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Mathis Schmieder DB9MAT
* Copyright (C) 2016 by Colin Durbridge G4EML
*
@@ -18,7 +18,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if defined(STM32F4XX) || defined(STM32F4) || defined(STM32F105xC)
#if defined(STM32F4XX) || defined(STM32F7XX) || defined(STM32F105xC)
#include "Config.h"
#include "Globals.h"
@@ -30,6 +30,7 @@ bool m_dstarEnable = true;
bool m_dmrEnable = true;
bool m_ysfEnable = true;
bool m_p25Enable = true;
bool m_nxdnEnable = true;
bool m_duplex = true;
@@ -52,9 +53,14 @@ CYSFTX ysfTX;
CP25RX p25RX;
CP25TX p25TX;
CNXDNRX nxdnRX;
CNXDNTX nxdnTX;
CCalDStarRX calDStarRX;
CCalDStarTX calDStarTX;
CCalDMR calDMR;
CCalP25 calP25;
CCalNXDN calNXDN;
CCalRSSI calRSSI;
CCWIdTX cwIdTX;
@@ -90,14 +96,23 @@ void loop()
if (m_p25Enable && m_modemState == STATE_P25)
p25TX.process();
if (m_nxdnEnable && m_modemState == STATE_NXDN)
nxdnTX.process();
if (m_modemState == STATE_DSTARCAL)
calDStarTX.process();
if (m_modemState == STATE_DMRCAL)
if (m_modemState == STATE_DMRCAL || m_modemState == STATE_LFCAL || m_modemState == STATE_DMRCAL1K || m_modemState == STATE_DMRDMO1K)
calDMR.process();
if (m_modemState == STATE_IDLE)
cwIdTX.process();
if (m_modemState == STATE_P25CAL1K)
calP25.process();
if (m_modemState == STATE_NXDNCAL1K)
calNXDN.process();
if (m_modemState == STATE_IDLE)
cwIdTX.process();
}
int main()
@@ -109,4 +124,3 @@ int main()
}
#endif
+17 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
@@ -27,6 +27,7 @@ bool m_dstarEnable = true;
bool m_dmrEnable = true;
bool m_ysfEnable = true;
bool m_p25Enable = true;
bool m_nxdnEnable = true;
bool m_duplex = true;
@@ -49,9 +50,14 @@ CYSFTX ysfTX;
CP25RX p25RX;
CP25TX p25TX;
CNXDNRX nxdnRX;
CNXDNTX nxdnTX;
CCalDStarRX calDStarRX;
CCalDStarTX calDStarTX;
CCalDMR calDMR;
CCalP25 calP25;
CCalNXDN calNXDN;
CCalRSSI calRSSI;
CCWIdTX cwIdTX;
@@ -87,12 +93,21 @@ void loop()
if (m_p25Enable && m_modemState == STATE_P25)
p25TX.process();
if (m_nxdnEnable && m_modemState == STATE_NXDN)
nxdnTX.process();
if (m_modemState == STATE_DSTARCAL)
calDStarTX.process();
if (m_modemState == STATE_DMRCAL)
if (m_modemState == STATE_DMRCAL || m_modemState == STATE_LFCAL || m_modemState == STATE_DMRCAL1K || m_modemState == STATE_DMRDMO1K)
calDMR.process();
if (m_modemState == STATE_P25CAL1K)
calP25.process();
if (m_modemState == STATE_NXDNCAL1K)
calNXDN.process();
if (m_modemState == STATE_IDLE)
cwIdTX.process();
}
-2
View File
@@ -98,8 +98,6 @@
<Define name="HSE_VALUE=12000000"/>
<Define name="STM32F4_PI"/>
<Define name="ARDUINO_MODE_PINS"/>
<Define name="SEND_RSSI_DATA"/>
<Define name="SERIAL_REPEATER"/>
</DefinedSymbols>
</Compile>
<Link useDefault="0">
+218 -85
View File
@@ -1,4 +1,4 @@
# Copyright (C) 2016 by Andy Uribe CA6JAU
# Copyright (C) 2016,2017 by Andy Uribe CA6JAU
# Copyright (C) 2016 by Jim McLaughlin KI6ZUM
# This program is free software; you can redistribute it and/or modify
@@ -15,6 +15,54 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# MMDVM source files
MMDVM_PATH=.
# STM32 library paths
F4_LIB_PATH=./STM32F4XX_Lib
F7_LIB_PATH=./STM32F7XX_Lib
# MCU external clock frequency (Hz)
CLK_MMDVM_PI=12000000
CLK_NUCLEO=8000000
# Directory Structure
BINDIR=bin
OBJDIR_F4=obj_f4
OBJDIR_F7=obj_f7
# Output files
BINELF_F4=mmdvm_f4.elf
BINHEX_F4=mmdvm_f4.hex
BINBIN_F4=mmdvm_f4.bin
BINELF_F7=mmdvm_f7.elf
BINHEX_F7=mmdvm_f7.hex
BINBIN_F7=mmdvm_f7.bin
# Header directories
INC_F4= . $(F4_LIB_PATH)/CMSIS/Include/ $(F4_LIB_PATH)/Device/ $(F4_LIB_PATH)/STM32F4xx_StdPeriph_Driver/include/
INCLUDES_F4=$(INC_F4:%=-I%)
INC_F7= . $(F7_LIB_PATH)/CMSIS/Include/ $(F7_LIB_PATH)/Device/ $(F7_LIB_PATH)/STM32F7xx_StdPeriph_Driver/inc/
INCLUDES_F7=$(INC_F7:%=-I%)
# CMSIS libraries
INCLUDES_LIBS_F4=$(F4_LIB_PATH)/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a
INCLUDES_LIBS_F7=$(F7_LIB_PATH)/CMSIS/Lib/GCC/libarm_cortexM7lfsp_math.a
# STM32F4 Standard Peripheral Libraries source path
STD_LIB_F4=$(F4_LIB_PATH)/STM32F4xx_StdPeriph_Driver/source
# STM32F7 Standard Peripheral Libraries source path
STD_LIB_F7=$(F7_LIB_PATH)/STM32F7xx_StdPeriph_Driver/src
# STM32F4 system source path
SYS_DIR_F4=$(F4_LIB_PATH)/Device
STARTUP_DIR_F4=$(F4_LIB_PATH)/Device/startup
# STM32F7 system source path
SYS_DIR_F7=$(F7_LIB_PATH)/Device
STARTUP_DIR_F7=$(F7_LIB_PATH)/Device/startup
# GNU ARM Embedded Toolchain
CC=arm-none-eabi-gcc
CXX=arm-none-eabi-g++
@@ -27,163 +75,248 @@ NM=arm-none-eabi-nm
SIZE=arm-none-eabi-size
A2L=arm-none-eabi-addr2line
# Directory Structure
BINDIR=bin
# Find source files
# "SystemRoot" is only defined in Windows
ifdef SYSTEMROOT
ASOURCES=$(shell dir /S /B *.s)
CSOURCES=$(shell dir /S /B *.c)
CXXSOURCES=$(shell dir /S /B *.cpp)
CLEANCMD=del /S *.o *.hex *.bin *.elf GitVersion.h
MDBIN=md $@
MDDIRS=md $@
else ifdef SystemRoot
ASOURCES=$(shell dir /S /B *.s)
CSOURCES=$(shell dir /S /B *.c)
CXXSOURCES=$(shell dir /S /B *.cpp)
CLEANCMD=del /S *.o *.hex *.bin *.elf GitVersion.h
MDBIN=md $@
MDDIRS=md $@
else
ASOURCES=$(shell find . -name '*.s')
CSOURCES=$(shell find . -name '*.c')
CXXSOURCES=$(shell find . -name '*.cpp')
CLEANCMD=rm -f $(OBJECTS) $(BINDIR)/$(BINELF) $(BINDIR)/$(BINHEX) $(BINDIR)/$(BINBIN) GitVersion.h
MDBIN=mkdir $@
CLEANCMD=rm -f $(OBJ_F4) $(OBJ_F7) $(BINDIR)/*.hex $(BINDIR)/*.bin $(BINDIR)/*.elf GitVersion.h
MDDIRS=mkdir $@
endif
# Default reference oscillator frequencies
ifndef $(OSC)
ifeq ($(MAKECMDGOALS),pi)
OSC=12000000
OSC=$(CLK_MMDVM_PI)
else ifeq ($(MAKECMDGOALS),pi-f722)
OSC=$(CLK_MMDVM_PI)
else
OSC=8000000
OSC=$(CLK_NUCLEO)
endif
endif
# Find header directories
INC= . STM32F4XX_Lib/CMSIS/Include/ STM32F4XX_Lib/Device/ STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/
INCLUDES=$(INC:%=-I%)
# Build object lists
CXXSRC=$(wildcard $(MMDVM_PATH)/*.cpp)
CSRC_STD_F4=$(wildcard $(STD_LIB_F4)/*.c)
SYS_F4=$(wildcard $(SYS_DIR_F4)/*.c)
STARTUP_F4=$(wildcard $(STARTUP_DIR_F4)/*.c)
CSRC_STD_F7=$(wildcard $(STD_LIB_F7)/*.c)
SYS_F7=$(wildcard $(SYS_DIR_F7)/*.c)
STARTUP_F7=$(wildcard $(STARTUP_DIR_F7)/*.c)
OBJ_F4=$(CXXSRC:$(MMDVM_PATH)/%.cpp=$(OBJDIR_F4)/%.o) $(CSRC_STD_F4:$(STD_LIB_F4)/%.c=$(OBJDIR_F4)/%.o) $(SYS_F4:$(SYS_DIR_F4)/%.c=$(OBJDIR_F4)/%.o) $(STARTUP_F4:$(STARTUP_DIR_F4)/%.c=$(OBJDIR_F4)/%.o)
OBJ_F7=$(CXXSRC:$(MMDVM_PATH)/%.cpp=$(OBJDIR_F7)/%.o) $(CSRC_STD_F7:$(STD_LIB_F7)/%.c=$(OBJDIR_F7)/%.o) $(SYS_F7:$(SYS_DIR_F7)/%.c=$(OBJDIR_F7)/%.o) $(STARTUP_F7:$(STARTUP_DIR_F7)/%.c=$(OBJDIR_F7)/%.o)
# Find libraries
INCLUDES_LIBS=STM32F4XX_Lib/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a
LINK_LIBS=
# MCU flags
MCFLAGS_F4=-mcpu=cortex-m4 -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb-interwork
MCFLAGS_F7=-mcpu=cortex-m7 -mthumb -mlittle-endian -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb-interwork
# Create object list
OBJECTS=$(ASOURCES:%.s=%.o)
OBJECTS+=$(CSOURCES:%.c=%.o)
OBJECTS+=$(CXXSOURCES:%.cpp=%.o)
# Define output files ELF & IHEX
BINELF=outp.elf
BINHEX=outp.hex
BINBIN=outp.bin
# MCU FLAGS
MCFLAGS=-mcpu=cortex-m4 -mthumb -mlittle-endian \
-mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb-interwork
# COMPILE FLAGS
# Compile flags
# STM32F4 Discovery board:
DEFS_DIS=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40_41xxx -DSTM32F4_DISCOVERY -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# Pi board:
DEFS_PI=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_PI -DARDUINO_MODE_PINS -DSEND_RSSI_DATA -DSERIAL_REPEATER -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# STM32F4 Nucleo 446 board:
# MMDVM-Pi board:
DEFS_PI=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_PI -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# MMDVM-F4M F0DEI board:
DEFS_F4M=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_F4M -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# STM32F4 Nucleo-64 F446RE board:
DEFS_NUCLEO=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_NUCLEO -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# STM32F7 Nucleo-144 F767ZI board:
DEFS_NUCLEO_F767=-DUSE_HAL_DRIVER -DSTM32F767xx -DSTM32F7XX -DSTM32F7_NUCLEO -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# MMDVM-Pi F722 board:
DEFS_PI_F722=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_PI -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
CFLAGS=-c $(MCFLAGS) $(INCLUDES)
CXXFLAGS=-c $(MCFLAGS) $(INCLUDES)
# Build compiler flags
CFLAGS_F4=-c $(MCFLAGS_F4) $(INCLUDES_F4)
CXXFLAGS_F4=-c $(MCFLAGS_F4) $(INCLUDES_F4)
CFLAGS_F7=-c $(MCFLAGS_F7) $(INCLUDES_F7)
CXXFLAGS_F7=-c $(MCFLAGS_F7) $(INCLUDES_F7)
# LINKER FLAGS
LDSCRIPT=stm32f4xx_link.ld
LDFLAGS =-T $(LDSCRIPT) $(MCFLAGS) --specs=nosys.specs $(INCLUDES_LIBS) $(LINK_LIBS)
# Linker flags
LDFLAGS_F4 =-T stm32f4xx_link.ld $(MCFLAGS_F4) --specs=nosys.specs $(INCLUDES_LIBS_F4)
LDFLAGS_F767 =-T stm32f767_link.ld $(MCFLAGS_F7) --specs=nosys.specs $(INCLUDES_LIBS_F7)
LDFLAGS_F722 =-T stm32f722_link.ld $(MCFLAGS_F7) --specs=nosys.specs $(INCLUDES_LIBS_F7)
# Common flags
CFLAGS=-Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS
CXXFLAGS=-Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS
LDFLAGS=-Os --specs=nano.specs
# Build Rules
.PHONY: all release dis pi nucleo debug clean
.PHONY: all release dis pi pi_f722 f4m nucleo f767 clean
# Default target: STM32F4 Nucleo F446RE board
# Default target: Nucleo-64 F446RE board
all: nucleo
pi: GitVersion.h
pi: CFLAGS+=$(DEFS_PI) -Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS
pi: CXXFLAGS+=$(DEFS_PI) -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS
pi: LDFLAGS+=-Os --specs=nano.specs
pi: release
pi: CFLAGS+=$(CFLAGS_F4) $(DEFS_PI)
pi: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_PI)
pi: LDFLAGS+=$(LDFLAGS_F4)
pi: release_f4
pi-f722: GitVersion.h
pi-f722: CFLAGS+=$(CFLAGS_F7) $(DEFS_PI_F722)
pi-f722: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_PI_F722)
pi-f722: LDFLAGS+=$(LDFLAGS_F722)
pi-f722: release_f7
f4m: GitVersion.h
f4m: CFLAGS+=$(CFLAGS_F4) $(DEFS_F4M)
f4m: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_F4M)
f4m: LDFLAGS+=$(LDFLAGS_F4)
f4m: release_f4
nucleo: GitVersion.h
nucleo: CFLAGS+=$(DEFS_NUCLEO) -Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS
nucleo: CXXFLAGS+=$(DEFS_NUCLEO) -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS
nucleo: LDFLAGS+=-Os --specs=nano.specs
nucleo: release
nucleo: CFLAGS+=$(CFLAGS_F4) $(DEFS_NUCLEO)
nucleo: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_NUCLEO)
nucleo: LDFLAGS+=$(LDFLAGS_F4)
nucleo: release_f4
dis: GitVersion.h
dis: CFLAGS+=$(DEFS_DIS) -Os -ffunction-sections -fdata-sections -fno-builtin -Wno-implicit -DCUSTOM_NEW -DNO_EXCEPTIONS
dis: CXXFLAGS+=$(DEFS_DIS) -Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -fno-rtti -DCUSTOM_NEW -DNO_EXCEPTIONS
dis: LDFLAGS+=-Os --specs=nano.specs
dis: release
dis: CFLAGS+=$(CFLAGS_F4) $(DEFS_DIS)
dis: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_DIS)
dis: LDFLAGS+=$(LDFLAGS_F4)
dis: release_f4
debug: CFLAGS+=-g
debug: CXXFLAGS+=-g
debug: LDFLAGS+=-g
debug: release
f767: GitVersion.h
f767: CFLAGS+=$(CFLAGS_F7) $(DEFS_NUCLEO_F767)
f767: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_NUCLEO_F767)
f767: LDFLAGS+=$(LDFLAGS_F767)
f767: release_f7
release: $(BINDIR)
release: $(BINDIR)/$(BINHEX)
release: $(BINDIR)/$(BINBIN)
release_f4: $(BINDIR)
release_f4: $(OBJDIR_F4)
release_f4: $(BINDIR)/$(BINHEX_F4)
release_f4: $(BINDIR)/$(BINBIN_F4)
release_f7: $(BINDIR)
release_f7: $(OBJDIR_F7)
release_f7: $(BINDIR)/$(BINHEX_F7)
release_f7: $(BINDIR)/$(BINBIN_F7)
$(BINDIR):
$(MDBIN)
$(MDDIRS)
$(BINDIR)/$(BINHEX): $(BINDIR)/$(BINELF)
$(OBJDIR_F4):
$(MDDIRS)
$(OBJDIR_F7):
$(MDDIRS)
$(BINDIR)/$(BINHEX_F4): $(BINDIR)/$(BINELF_F4)
$(CP) -O ihex $< $@
@echo "Objcopy from ELF to IHEX complete!\n"
$(BINDIR)/$(BINBIN): $(BINDIR)/$(BINELF)
$(BINDIR)/$(BINBIN_F4): $(BINDIR)/$(BINELF_F4)
$(CP) -O binary $< $@
@echo "Objcopy from ELF to BINARY complete!\n"
$(BINDIR)/$(BINELF): $(OBJECTS)
$(CXX) $(OBJECTS) $(LDFLAGS) -o $@
$(BINDIR)/$(BINELF_F4): $(OBJ_F4)
$(CXX) $(OBJ_F4) $(LDFLAGS) -o $@
@echo "Linking complete!\n"
$(SIZE) $(BINDIR)/$(BINELF)
$(SIZE) $(BINDIR)/$(BINELF_F4)
%.o: %.cpp
$(BINDIR)/$(BINHEX_F7): $(BINDIR)/$(BINELF_F7)
$(CP) -O ihex $< $@
@echo "Objcopy from ELF to IHEX complete!\n"
$(BINDIR)/$(BINBIN_F7): $(BINDIR)/$(BINELF_F7)
$(CP) -O binary $< $@
@echo "Objcopy from ELF to BINARY complete!\n"
$(BINDIR)/$(BINELF_F7): $(OBJ_F7)
$(CXX) $(OBJ_F7) $(LDFLAGS) -o $@
@echo "Linking complete!\n"
$(SIZE) $(BINDIR)/$(BINELF_F7)
$(OBJDIR_F4)/%.o: $(MMDVM_PATH)/%.cpp
$(CXX) $(CXXFLAGS) $< -o $@
@echo "Compiled "$<"!\n"
%.o: %.c
$(OBJDIR_F7)/%.o: $(MMDVM_PATH)/%.cpp
$(CXX) $(CXXFLAGS) $< -o $@
@echo "Compiled "$<"!\n"
$(OBJDIR_F4)/%.o: $(STD_LIB_F4)/%.c
$(CC) $(CFLAGS) $< -o $@
@echo "Compiled "$<"!\n"
%.o: %.s
$(OBJDIR_F7)/%.o: $(STD_LIB_F7)/%.c
$(CC) $(CFLAGS) $< -o $@
@echo "Assambled "$<"!\n"
@echo "Compiled "$<"!\n"
$(OBJDIR_F4)/%.o: $(SYS_DIR_F4)/%.c
$(CC) $(CFLAGS) $< -o $@
@echo "Compiled "$<"!\n"
$(OBJDIR_F4)/%.o: $(STARTUP_DIR_F4)/%.c
$(CC) $(CFLAGS) $< -o $@
@echo "Compiled "$<"!\n"
$(OBJDIR_F7)/%.o: $(SYS_DIR_F7)/%.c
$(CC) $(CFLAGS) $< -o $@
@echo "Compiled "$<"!\n"
$(OBJDIR_F7)/%.o: $(STARTUP_DIR_F7)/%.c
$(CC) $(CFLAGS) $< -o $@
@echo "Compiled "$<"!\n"
clean:
$(CLEANCMD)
deploy:
ifneq ($(wildcard /usr/bin/openocd),)
/usr/bin/openocd -f /usr/share/openocd/scripts/board/stm32f4discovery.cfg -c "program bin/$(BINELF) verify reset exit"
/usr/bin/openocd -f /usr/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/share/openocd/scripts/target/stm32f4x.cfg -c "program bin/$(BINELF_F4) verify reset exit"
endif
ifneq ($(wildcard /usr/local/bin/openocd),)
/usr/local/bin/openocd -f /usr/local/share/openocd/scripts/board/stm32f4discovery.cfg -c "program bin/$(BINELF) verify reset exit"
/usr/local/bin/openocd -f /usr/local/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/local/share/openocd/scripts/target/stm32f4x.cfg -c "program bin/$(BINELF_F4) verify reset exit"
endif
ifneq ($(wildcard /opt/openocd/bin/openocd),)
/opt/openocd/bin/openocd -f /opt/openocd/share/openocd/scripts/board/stm32f4discovery.cfg -c "program bin/$(BINELF) verify reset exit"
/opt/openocd/bin/openocd -f /opt/openocd/share/openocd/scripts/interface/stlink-v2-1.cfg -f /opt/openocd/share/openocd/scripts/target/stm32f4x.cfg -c "program bin/$(BINELF_F4) verify reset exit"
endif
deploy-f7:
ifneq ($(wildcard /usr/bin/openocd),)
/usr/bin/openocd -f /usr/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/share/openocd/scripts/target/stm32f7x.cfg -c "program bin/$(BINELF_F7) verify reset exit"
endif
ifneq ($(wildcard /usr/local/bin/openocd),)
/usr/local/bin/openocd -f /usr/local/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/local/share/openocd/scripts/target/stm32f7x.cfg -c "program bin/$(BINELF_F7) verify reset exit"
endif
ifneq ($(wildcard /opt/openocd/bin/openocd),)
/opt/openocd/bin/openocd -f /opt/openocd/share/openocd/scripts/interface/stlink-v2-1.cfg -f /opt/openocd/share/openocd/scripts/target/stm32f7x.cfg -c "program bin/$(BINELF_F7) verify reset exit"
endif
deploy-pi:
ifneq ($(wildcard /usr/local/bin/stm32flash),)
-/usr/local/bin/stm32flash -i 20,-21,21:-20,21 /dev/ttyAMA0
/usr/local/bin/stm32flash -v -w bin/outp.bin -g 0x0 -R -c /dev/ttyAMA0
-/usr/local/bin/stm32ld /dev/ttyAMA0 57600 bin/$(BINBIN_F4)
/usr/local/bin/stm32flash -v -w bin/$(BINBIN_F4) -g 0x0 -R -c /dev/ttyAMA0
endif
ifneq ($(wildcard /usr/bin/stm32flash),)
-/usr/bin/stm32flash -i 20,-21,21:-20,21 /dev/ttyAMA0
/usr/bin/stm32flash -v -w bin/outp.bin -g 0x0 -R -c /dev/ttyAMA0
-/usr/bin/stm32ld /dev/ttyAMA0 57600 bin/$(BINBIN_F4)
/usr/bin/stm32flash -v -w bin/$(BINBIN_F4) -g 0x0 -R -c /dev/ttyAMA0
endif
deploy-f4m: deploy-pi
deploy-pi-f7:
ifneq ($(wildcard /usr/local/bin/stm32flash),)
-/usr/local/bin/stm32flash -i 20,-21,21:-20,21 /dev/ttyAMA0
-/usr/local/bin/stm32ld /dev/ttyAMA0 57600 bin/$(BINBIN_F7)
/usr/local/bin/stm32flash -v -w bin/$(BINBIN_F7) -g 0x0 -R -c /dev/ttyAMA0
endif
ifneq ($(wildcard /usr/bin/stm32flash),)
-/usr/bin/stm32flash -i 20,-21,21:-20,21 /dev/ttyAMA0
-/usr/bin/stm32ld /dev/ttyAMA0 57600 bin/$(BINBIN_F7)
/usr/bin/stm32flash -v -w bin/$(BINBIN_F7) -g 0x0 -R -c /dev/ttyAMA0
endif
# Export the current git version if the index file exists, else 000...
+2 -3
View File
@@ -93,8 +93,7 @@ default:
#This rule is good to just make sure stuff compiles, without having to wait
#for bossac.
compile: GitVersion.h
compile: $(TMPDIR)/$(PROJNAME).elf
compile: GitVersion.h $(TMPDIR)/$(PROJNAME).elf $(TMPDIR)/$(PROJNAME).bin
#This is a make rule template to create object files from the source files.
# arg 1=src file
@@ -175,7 +174,7 @@ $(TMPDIR)/$(PROJNAME).bin: $(TMPDIR)/$(PROJNAME).elf
$(OBJCOPY) -O binary $< $@
#upload to the arduino by first resetting it (stty) and the running bossac
upload: $(TMPDIR)/$(PROJNAME).bin
upload: compile
stty -F /dev/$(PORT) cs8 1200 hupcl
$(ADIR)/packages/arduino/tools/bossac/1.6.1-arduino/bossac -i --port=$(PORT) -U false -e -w $(VERIFY) -b $(TMPDIR)/$(PROJNAME).bin -R
+2 -2
View File
@@ -39,7 +39,7 @@ OBJDIR:=obj
BINDIR:=bin
# Port definition for programming via bootloader (using stm32flash)
BL_PORT:=/dev/ttyUSB0
BL_PORT:=ttyUSB0
@@ -102,7 +102,7 @@ program: $(HEX) $(ELF)
.PHONY: program_bl
program_bl: $(HEX) $(ELF)
stm32flash -w $(HEX) -v $(BL_PORT)
stm32flash -w $(HEX) -v /dev/$(BL_PORT)
$(SIZE) $(ELF)
.PHONY: run
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(NXDNDEFINES_H)
#define NXDNDEFINES_H
const unsigned int NXDN_RADIO_SYMBOL_LENGTH = 10U; // At 24 kHz sample rate
const unsigned int NXDN_FRAME_LENGTH_BITS = 384U;
const unsigned int NXDN_FRAME_LENGTH_BYTES = NXDN_FRAME_LENGTH_BITS / 8U;
const unsigned int NXDN_FRAME_LENGTH_SYMBOLS = NXDN_FRAME_LENGTH_BITS / 2U;
const unsigned int NXDN_FRAME_LENGTH_SAMPLES = NXDN_FRAME_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH;
const unsigned int NXDN_FSW_LENGTH_BITS = 20U;
const unsigned int NXDN_FSW_LENGTH_SYMBOLS = NXDN_FSW_LENGTH_BITS / 2U;
const unsigned int NXDN_FSW_LENGTH_SAMPLES = NXDN_FSW_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH;
const uint8_t NXDN_FSW_BYTES[] = {0xCDU, 0xF5U, 0x90U};
const uint8_t NXDN_FSW_BYTES_MASK[] = {0xFFU, 0xFFU, 0xF0U};
const uint8_t NXDN_FSW_BYTES_LENGTH = 3U;
const uint32_t NXDN_FSW_BITS = 0x000CDF59U;
const uint32_t NXDN_FSW_BITS_MASK = 0x000FFFFFU;
// C D F 5 9
// 11 00 11 01 11 11 01 01 10 01
// -3 +1 -3 +3 -3 -3 +3 +3 -1 +3
const int8_t NXDN_FSW_SYMBOLS_VALUES[] = {-3, +1, -3, +3, -3, -3, +3, +3, -1, +3};
const uint16_t NXDN_FSW_SYMBOLS = 0x014DU;
const uint16_t NXDN_FSW_SYMBOLS_MASK = 0x03FFU;
#endif
+405
View File
@@ -0,0 +1,405 @@
/*
* Copyright (C) 2009-2018 by Jonathan Naylor G4KLX
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Config.h"
#include "Globals.h"
#include "NXDNRX.h"
#include "Utils.h"
const q15_t SCALING_FACTOR = 18750; // Q15(0.55)
const uint8_t MAX_FSW_BIT_START_ERRS = 1U;
const uint8_t MAX_FSW_BIT_RUN_ERRS = 3U;
const uint8_t MAX_FSW_SYMBOLS_ERRS = 2U;
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
const uint8_t NOAVEPTR = 99U;
const uint16_t NOENDPTR = 9999U;
const unsigned int MAX_FSW_FRAMES = 5U + 1U;
CNXDNRX::CNXDNRX() :
m_state(NXDNRXS_NONE),
m_bitBuffer(),
m_buffer(),
m_bitPtr(0U),
m_dataPtr(0U),
m_startPtr(NOENDPTR),
m_endPtr(NOENDPTR),
m_fswPtr(NOENDPTR),
m_minFSWPtr(NOENDPTR),
m_maxFSWPtr(NOENDPTR),
m_maxCorr(0),
m_lostCount(0U),
m_countdown(0U),
m_centre(),
m_centreVal(0),
m_threshold(),
m_thresholdVal(0),
m_averagePtr(NOAVEPTR),
m_rssiAccum(0U),
m_rssiCount(0U)
{
}
void CNXDNRX::reset()
{
m_state = NXDNRXS_NONE;
m_dataPtr = 0U;
m_bitPtr = 0U;
m_maxCorr = 0;
m_averagePtr = NOAVEPTR;
m_startPtr = NOENDPTR;
m_endPtr = NOENDPTR;
m_fswPtr = NOENDPTR;
m_minFSWPtr = NOENDPTR;
m_maxFSWPtr = NOENDPTR;
m_centreVal = 0;
m_thresholdVal = 0;
m_lostCount = 0U;
m_countdown = 0U;
m_rssiAccum = 0U;
m_rssiCount = 0U;
}
void CNXDNRX::samples(const q15_t* samples, uint16_t* rssi, uint8_t length)
{
for (uint8_t i = 0U; i < length; i++) {
q15_t sample = samples[i];
m_rssiAccum += rssi[i];
m_rssiCount++;
m_bitBuffer[m_bitPtr] <<= 1;
if (sample < 0)
m_bitBuffer[m_bitPtr] |= 0x01U;
m_buffer[m_dataPtr] = sample;
switch (m_state) {
case NXDNRXS_DATA:
processData(sample);
break;
default:
processNone(sample);
break;
}
m_dataPtr++;
if (m_dataPtr >= NXDN_FRAME_LENGTH_SAMPLES)
m_dataPtr = 0U;
m_bitPtr++;
if (m_bitPtr >= NXDN_RADIO_SYMBOL_LENGTH)
m_bitPtr = 0U;
}
}
void CNXDNRX::processNone(q15_t sample)
{
bool ret = correlateFSW();
if (ret) {
// On the first sync, start the countdown to the state change
if (m_countdown == 0U) {
m_rssiAccum = 0U;
m_rssiCount = 0U;
io.setDecode(true);
io.setADCDetection(true);
m_averagePtr = NOAVEPTR;
m_countdown = 5U;
}
}
if (m_countdown > 0U)
m_countdown--;
if (m_countdown == 1U) {
m_minFSWPtr = m_fswPtr + NXDN_FRAME_LENGTH_SAMPLES - 1U;
if (m_minFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES)
m_minFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES;
m_maxFSWPtr = m_fswPtr + 1U;
if (m_maxFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES)
m_maxFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES;
m_state = NXDNRXS_DATA;
m_countdown = 0U;
}
}
void CNXDNRX::processData(q15_t sample)
{
if (m_minFSWPtr < m_maxFSWPtr) {
if (m_dataPtr >= m_minFSWPtr && m_dataPtr <= m_maxFSWPtr)
correlateFSW();
} else {
if (m_dataPtr >= m_minFSWPtr || m_dataPtr <= m_maxFSWPtr)
correlateFSW();
}
if (m_dataPtr == m_endPtr) {
// Only update the centre and threshold if they are from a good sync
if (m_lostCount == MAX_FSW_FRAMES) {
m_minFSWPtr = m_fswPtr + NXDN_FRAME_LENGTH_SAMPLES - 1U;
if (m_minFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES)
m_minFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES;
m_maxFSWPtr = m_fswPtr + 1U;
if (m_maxFSWPtr >= NXDN_FRAME_LENGTH_SAMPLES)
m_maxFSWPtr -= NXDN_FRAME_LENGTH_SAMPLES;
}
calculateLevels(m_startPtr, NXDN_FRAME_LENGTH_SYMBOLS);
DEBUG4("NXDNRX: sync found pos/centre/threshold", m_fswPtr, m_centreVal, m_thresholdVal);
uint8_t frame[NXDN_FRAME_LENGTH_BYTES + 3U];
samplesToBits(m_startPtr, NXDN_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
// We've not seen a data sync for too long, signal RXLOST and change to RX_NONE
m_lostCount--;
if (m_lostCount == 0U) {
DEBUG1("NXDNRX: sync timed out, lost lock");
io.setDecode(false);
io.setADCDetection(false);
serial.writeNXDNLost();
m_state = NXDNRXS_NONE;
m_endPtr = NOENDPTR;
m_averagePtr = NOAVEPTR;
m_countdown = 0U;
m_maxCorr = 0;
} else {
frame[0U] = m_lostCount == (MAX_FSW_FRAMES - 1U) ? 0x01U : 0x00U;
writeRSSIData(frame);
m_maxCorr = 0;
}
}
}
bool CNXDNRX::correlateFSW()
{
if (countBits32((m_bitBuffer[m_bitPtr] & NXDN_FSW_SYMBOLS_MASK) ^ NXDN_FSW_SYMBOLS) <= MAX_FSW_SYMBOLS_ERRS) {
uint16_t ptr = m_dataPtr + NXDN_FRAME_LENGTH_SAMPLES - NXDN_FSW_LENGTH_SAMPLES + NXDN_RADIO_SYMBOL_LENGTH;
if (ptr >= NXDN_FRAME_LENGTH_SAMPLES)
ptr -= NXDN_FRAME_LENGTH_SAMPLES;
q31_t corr = 0;
q15_t min = 16000;
q15_t max = -16000;
for (uint8_t i = 0U; i < NXDN_FSW_LENGTH_SYMBOLS; i++) {
q15_t val = m_buffer[ptr];
if (val > max)
max = val;
if (val < min)
min = val;
switch (NXDN_FSW_SYMBOLS_VALUES[i]) {
case +3:
corr -= (val + val + val);
break;
case +1:
corr -= val;
break;
case -1:
corr += val;
break;
default: // -3
corr += (val + val + val);
break;
}
ptr += NXDN_RADIO_SYMBOL_LENGTH;
if (ptr >= NXDN_FRAME_LENGTH_SAMPLES)
ptr -= NXDN_FRAME_LENGTH_SAMPLES;
}
if (corr > m_maxCorr) {
if (m_averagePtr == NOAVEPTR) {
m_centreVal = (max + min) >> 1;
q31_t v1 = (max - m_centreVal) * SCALING_FACTOR;
m_thresholdVal = q15_t(v1 >> 15);
}
uint16_t startPtr = m_dataPtr + NXDN_FRAME_LENGTH_SAMPLES - NXDN_FSW_LENGTH_SAMPLES + NXDN_RADIO_SYMBOL_LENGTH;
if (startPtr >= NXDN_FRAME_LENGTH_SAMPLES)
startPtr -= NXDN_FRAME_LENGTH_SAMPLES;
uint8_t sync[NXDN_FSW_BYTES_LENGTH];
samplesToBits(startPtr, NXDN_FSW_LENGTH_SYMBOLS, sync, 0U, m_centreVal, m_thresholdVal);
uint8_t maxErrs;
if (m_state == NXDNRXS_NONE)
maxErrs = MAX_FSW_BIT_START_ERRS;
else
maxErrs = MAX_FSW_BIT_RUN_ERRS;
uint8_t errs = 0U;
for (uint8_t i = 0U; i < NXDN_FSW_BYTES_LENGTH; i++)
errs += countBits8((sync[i] & NXDN_FSW_BYTES_MASK[i]) ^ NXDN_FSW_BYTES[i]);
if (errs <= maxErrs) {
m_maxCorr = corr;
m_lostCount = MAX_FSW_FRAMES;
m_fswPtr = m_dataPtr;
m_startPtr = startPtr;
m_endPtr = m_dataPtr + NXDN_FRAME_LENGTH_SAMPLES - NXDN_FSW_LENGTH_SAMPLES - 1U;
if (m_endPtr >= NXDN_FRAME_LENGTH_SAMPLES)
m_endPtr -= NXDN_FRAME_LENGTH_SAMPLES;
return true;
}
}
}
return false;
}
void CNXDNRX::calculateLevels(uint16_t start, uint16_t count)
{
q15_t maxPos = -16000;
q15_t minPos = 16000;
q15_t maxNeg = 16000;
q15_t minNeg = -16000;
for (uint16_t i = 0U; i < count; i++) {
q15_t sample = m_buffer[start];
if (sample > 0) {
if (sample > maxPos)
maxPos = sample;
if (sample < minPos)
minPos = sample;
} else {
if (sample < maxNeg)
maxNeg = sample;
if (sample > minNeg)
minNeg = sample;
}
start += NXDN_RADIO_SYMBOL_LENGTH;
if (start >= NXDN_FRAME_LENGTH_SAMPLES)
start -= NXDN_FRAME_LENGTH_SAMPLES;
}
q15_t posThresh = (maxPos + minPos) >> 1;
q15_t negThresh = (maxNeg + minNeg) >> 1;
q15_t centre = (posThresh + negThresh) >> 1;
q15_t threshold = posThresh - centre;
DEBUG5("NXDNRX: pos/neg/centre/threshold", posThresh, negThresh, centre, threshold);
if (m_averagePtr == NOAVEPTR) {
for (uint8_t i = 0U; i < 16U; i++) {
m_centre[i] = centre;
m_threshold[i] = threshold;
}
m_averagePtr = 0U;
} else {
m_centre[m_averagePtr] = centre;
m_threshold[m_averagePtr] = threshold;
m_averagePtr++;
if (m_averagePtr >= 16U)
m_averagePtr = 0U;
}
m_centreVal = 0;
m_thresholdVal = 0;
for (uint8_t i = 0U; i < 16U; i++) {
m_centreVal += m_centre[i];
m_thresholdVal += m_threshold[i];
}
m_centreVal >>= 4;
m_thresholdVal >>= 4;
}
void CNXDNRX::samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold)
{
for (uint16_t i = 0U; i < count; i++) {
q15_t sample = m_buffer[start] - centre;
if (sample < -threshold) {
WRITE_BIT1(buffer, offset, false);
offset++;
WRITE_BIT1(buffer, offset, true);
offset++;
} else if (sample < 0) {
WRITE_BIT1(buffer, offset, false);
offset++;
WRITE_BIT1(buffer, offset, false);
offset++;
} else if (sample < threshold) {
WRITE_BIT1(buffer, offset, true);
offset++;
WRITE_BIT1(buffer, offset, false);
offset++;
} else {
WRITE_BIT1(buffer, offset, true);
offset++;
WRITE_BIT1(buffer, offset, true);
offset++;
}
start += NXDN_RADIO_SYMBOL_LENGTH;
if (start >= NXDN_FRAME_LENGTH_SAMPLES)
start -= NXDN_FRAME_LENGTH_SAMPLES;
}
}
void CNXDNRX::writeRSSIData(uint8_t* data)
{
#if defined(SEND_RSSI_DATA)
if (m_rssiCount > 0U) {
uint16_t rssi = m_rssiAccum / m_rssiCount;
data[49U] = (rssi >> 8) & 0xFFU;
data[50U] = (rssi >> 0) & 0xFFU;
serial.writeNXDNData(data, NXDN_FRAME_LENGTH_BYTES + 3U);
} else {
serial.writeNXDNData(data, NXDN_FRAME_LENGTH_BYTES + 1U);
}
#else
serial.writeNXDNData(data, NXDN_FRAME_LENGTH_BYTES + 1U);
#endif
m_rssiAccum = 0U;
m_rssiCount = 0U;
}
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(NXDNRX_H)
#define NXDNRX_H
#include "Config.h"
#include "NXDNDefines.h"
enum NXDNRX_STATE {
NXDNRXS_NONE,
NXDNRXS_DATA
};
class CNXDNRX {
public:
CNXDNRX();
void samples(const q15_t* samples, uint16_t* rssi, uint8_t length);
void reset();
private:
NXDNRX_STATE m_state;
uint16_t m_bitBuffer[NXDN_RADIO_SYMBOL_LENGTH];
q15_t m_buffer[NXDN_FRAME_LENGTH_SAMPLES];
uint16_t m_bitPtr;
uint16_t m_dataPtr;
uint16_t m_startPtr;
uint16_t m_endPtr;
uint16_t m_fswPtr;
uint16_t m_minFSWPtr;
uint16_t m_maxFSWPtr;
q31_t m_maxCorr;
uint16_t m_lostCount;
uint8_t m_countdown;
q15_t m_centre[16U];
q15_t m_centreVal;
q15_t m_threshold[16U];
q15_t m_thresholdVal;
uint8_t m_averagePtr;
uint32_t m_rssiAccum;
uint16_t m_rssiCount;
void processNone(q15_t sample);
void processData(q15_t sample);
bool correlateFSW();
void calculateLevels(uint16_t start, uint16_t count);
void samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
void writeRSSIData(uint8_t* data);
};
#endif
+170
View File
@@ -0,0 +1,170 @@
/*
* Copyright (C) 2009-2018 by Jonathan Naylor G4KLX
* Copyright (C) 2017 by Andy Uribe CA6JAU
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Config.h"
#include "Globals.h"
#include "NXDNTX.h"
#include "NXDNDefines.h"
// Generated using rcosdesign(0.2, 8, 10, 'sqrt') in MATLAB
static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 850, 592, 219, -234, -720, -1179, -1548, -1769, -1795, -1597, -1172,
-544, 237, 1092, 1927, 2637, 3120, 3286, 3073, 2454, 1447, 116, -1431, -3043, -4544, -5739, -6442,
-6483, -5735, -4121, -1633, 1669, 5651, 10118, 14822, 19484, 23810, 27520, 30367, 32156, 32767,
32156, 30367, 27520, 23810, 19484, 14822, 10118, 5651, 1669, -1633, -4121, -5735, -6483, -6442,
-5739, -4544, -3043, -1431, 116, 1447, 2454, 3073, 3286, 3120, 2637, 1927, 1092, 237, -544, -1172,
-1597, -1795, -1769, -1548, -1179, -720, -234, 219, 592, 850}; // numTaps = 90, L = 10
const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
static q15_t NXDN_SINC_FILTER[] = {572, -1003, -253, 254, 740, 1290, 1902, 2527, 3090, 3517, 3747, 3747, 3517, 3090, 2527, 1902,
1290, 740, 254, -253, -1003, 572};
const uint16_t NXDN_SINC_FILTER_LEN = 22U;
const q15_t NXDN_LEVELA = 735;
const q15_t NXDN_LEVELB = 245;
const q15_t NXDN_LEVELC = -245;
const q15_t NXDN_LEVELD = -735;
const uint8_t NXDN_PREAMBLE[] = {0x57U, 0x75U, 0xFDU};
const uint8_t NXDN_SYNC = 0x5FU;
CNXDNTX::CNXDNTX() :
m_buffer(2000U),
m_modFilter(),
m_sincFilter(),
m_modState(),
m_sincState(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(240U) // 200ms
{
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
::memset(m_sincState, 0x00U, 70U * sizeof(q15_t));
m_modFilter.L = NXDN_RADIO_SYMBOL_LENGTH;
m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN;
m_modFilter.pCoeffs = RRC_0_2_FILTER;
m_modFilter.pState = m_modState;
m_sincFilter.numTaps = NXDN_SINC_FILTER_LEN;
m_sincFilter.pState = m_sincState;
m_sincFilter.pCoeffs = NXDN_SINC_FILTER;
}
void CNXDNTX::process()
{
if (m_buffer.getData() == 0U && m_poLen == 0U)
return;
if (m_poLen == 0U) {
if (!m_tx) {
for (uint16_t i = 0U; i < m_txDelay; i++)
m_poBuffer[m_poLen++] = NXDN_SYNC;
m_poBuffer[m_poLen++] = NXDN_PREAMBLE[0U];
m_poBuffer[m_poLen++] = NXDN_PREAMBLE[1U];
m_poBuffer[m_poLen++] = NXDN_PREAMBLE[2U];
} else {
for (uint8_t i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++) {
uint8_t c = m_buffer.get();
m_poBuffer[m_poLen++] = c;
}
}
m_poPtr = 0U;
}
if (m_poLen > 0U) {
uint16_t space = io.getSpace();
while (space > (4U * NXDN_RADIO_SYMBOL_LENGTH)) {
uint8_t c = m_poBuffer[m_poPtr++];
writeByte(c);
space -= 4U * NXDN_RADIO_SYMBOL_LENGTH;
if (m_poPtr >= m_poLen) {
m_poPtr = 0U;
m_poLen = 0U;
return;
}
}
}
}
uint8_t CNXDNTX::writeData(const uint8_t* data, uint8_t length)
{
if (length != (NXDN_FRAME_LENGTH_BYTES + 1U))
return 4U;
uint16_t space = m_buffer.getSpace();
if (space < NXDN_FRAME_LENGTH_BYTES)
return 5U;
for (uint8_t i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++)
m_buffer.put(data[i + 1U]);
return 0U;
}
void CNXDNTX::writeByte(uint8_t c)
{
q15_t inBuffer[4U];
q15_t intBuffer[NXDN_RADIO_SYMBOL_LENGTH * 4U];
q15_t outBuffer[NXDN_RADIO_SYMBOL_LENGTH * 4U];
const uint8_t MASK = 0xC0U;
for (uint8_t i = 0U; i < 4U; i++, c <<= 2) {
switch (c & MASK) {
case 0xC0U:
inBuffer[i] = NXDN_LEVELA;
break;
case 0x80U:
inBuffer[i] = NXDN_LEVELB;
break;
case 0x00U:
inBuffer[i] = NXDN_LEVELC;
break;
default:
inBuffer[i] = NXDN_LEVELD;
break;
}
}
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, intBuffer, 4U);
::arm_fir_fast_q15(&m_sincFilter, intBuffer, outBuffer, NXDN_RADIO_SYMBOL_LENGTH * 4U);
io.write(STATE_NXDN, outBuffer, NXDN_RADIO_SYMBOL_LENGTH * 4U);
}
void CNXDNTX::setTXDelay(uint8_t delay)
{
m_txDelay = 300U + uint16_t(delay) * 6U; // 500ms + tx delay
if (m_txDelay > 1200U)
m_txDelay = 1200U;
}
uint8_t CNXDNTX::getSpace() const
{
return m_buffer.getSpace() / NXDN_FRAME_LENGTH_BYTES;
}
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(NXDNTX_H)
#define NXDNTX_H
#include "Config.h"
#include "SerialRB.h"
class CNXDNTX {
public:
CNXDNTX();
uint8_t writeData(const uint8_t* data, uint8_t length);
void process();
void setTXDelay(uint8_t delay);
uint8_t getSpace() const;
private:
CSerialRB m_buffer;
arm_fir_interpolate_instance_q15 m_modFilter;
arm_fir_instance_q15 m_sincFilter;
q15_t m_modState[16U]; // blockSize + phaseLength - 1, 4 + 9 - 1 plus some spare
q15_t m_sincState[70U]; // NoTaps + BlockSize - 1, 22 + 40 - 1 plus some spare
uint8_t m_poBuffer[1200U];
uint16_t m_poLen;
uint16_t m_poPtr;
uint16_t m_txDelay;
void writeByte(uint8_t c);
};
#endif
+5 -7
View File
@@ -30,12 +30,10 @@ static q15_t RC_0_2_FILTER[] = {-897, -1636, -1840, -1278, 0, 1613, 2936, 3310,
-3011, 0, 2315, 3310, 2936, 1613, 0, -1278, -1840, -1636, -897, 0}; // numTaps = 40, L = 5
const uint16_t RC_0_2_FILTER_PHASE_LEN = 8U; // phaseLength = numTaps/L
// Generated in MATLAB using the following commands, and then normalised for unity gain
// shape2 = 'Inverse-sinc Lowpass';
// d2 = fdesign.interpolator(1, shape2);
// h2 = design(d2, 'SystemObject', true);
static q15_t LOWPASS_FILTER[] = {1376, -2393, 4584, -8933, 22325, 22325, -8933, 4584, -2393, 1376};
const uint16_t LOWPASS_FILTER_LEN = 10U;
static q15_t LOWPASS_FILTER[] = {124, -188, -682, 1262, 556, -621, -1912, -911, 2058, 3855, 1234, -4592, -7692, -2799,
8556, 18133, 18133, 8556, -2799, -7692, -4592, 1234, 3855, 2058, -911, -1912, -621,
556, 1262, -682, -188, 124};
const uint16_t LOWPASS_FILTER_LEN = 32U;
const q15_t P25_LEVELA = 1260;
const q15_t P25_LEVELB = 420;
@@ -56,7 +54,7 @@ m_poPtr(0U),
m_txDelay(240U) // 200ms
{
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
::memset(m_lpState, 0x00U, 70U * sizeof(q15_t));
::memset(m_lpState, 0x00U, 60U * sizeof(q15_t));
m_modFilter.L = P25_RADIO_SYMBOL_LENGTH;
m_modFilter.phaseLength = RC_0_2_FILTER_PHASE_LEN;
+1 -1
View File
@@ -40,7 +40,7 @@ private:
arm_fir_interpolate_instance_q15 m_modFilter;
arm_fir_instance_q15 m_lpFilter;
q15_t m_modState[16U]; // blockSize + phaseLength - 1, 4 + 9 - 1 plus some spare
q15_t m_lpState[70U]; // NoTaps + BlockSize - 1, 44 + 20 - 1 plus some spare
q15_t m_lpState[60U]; // NoTaps + BlockSize - 1, 32 + 20 - 1 plus some spare
uint8_t m_poBuffer[1200U];
uint16_t m_poLen;
uint16_t m_poPtr;
+3 -2
View File
@@ -21,9 +21,10 @@ Boston, MA 02110-1301, USA.
#if !defined(RSSIRB_H)
#define RSSIRB_H
#if defined(STM32F4XX) || defined(STM32F4)
#if defined(STM32F4XX)
#include "stm32f4xx.h"
#include <cstddef>
#elif defined(STM32F7XX)
#include "stm32f7xx.h"
#elif defined(STM32F105xC)
#include "stm32f1xx.h"
#include <cstddef>
+3 -2
View File
@@ -21,9 +21,10 @@ Boston, MA 02110-1301, USA.
#if !defined(SAMPLERB_H)
#define SAMPLERB_H
#if defined(STM32F4XX) || defined(STM32F4)
#if defined(STM32F4XX)
#include "stm32f4xx.h"
#include <cstddef>
#elif defined(STM32F7XX)
#include "stm32f7xx.h"
#elif defined(STM32F105xC)
#include "stm32f1xx.h"
#include <cstddef>
+187 -26
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013,2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2013,2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
@@ -60,6 +60,9 @@ const uint8_t MMDVM_P25_HDR = 0x30U;
const uint8_t MMDVM_P25_LDU = 0x31U;
const uint8_t MMDVM_P25_LOST = 0x32U;
const uint8_t MMDVM_NXDN_DATA = 0x40U;
const uint8_t MMDVM_NXDN_LOST = 0x41U;
const uint8_t MMDVM_ACK = 0x70U;
const uint8_t MMDVM_NAK = 0x7FU;
@@ -73,9 +76,9 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U;
#if defined(EXTERNAL_OSC)
#define DESCRIPTION "MMDVM 20170406 TCXO (D-Star/DMR/System Fusion/P25/RSSI/CW Id)"
#define DESCRIPTION "MMDVM 20170501 TCXO (D-Star/DMR/System Fusion/P25/NXDN/RSSI/CW Id)"
#else
#define DESCRIPTION "MMDVM 20170406 (D-Star/DMR/System Fusion/P25/RSSI/CW Id)"
#define DESCRIPTION "MMDVM 20170501 (D-Star/DMR/System Fusion/P25/NXDN/RSSI/CW Id)"
#endif
#if defined(GITVERSION)
@@ -143,6 +146,8 @@ void CSerialPort::getStatus()
reply[3U] |= 0x04U;
if (m_p25Enable)
reply[3U] |= 0x08U;
if (m_nxdnEnable)
reply[3U] |= 0x10U;
reply[4U] = uint8_t(m_modemState);
@@ -197,7 +202,12 @@ void CSerialPort::getStatus()
else
reply[10U] = 0U;
writeInt(1U, reply, 11);
if (m_nxdnEnable)
reply[11U] = nxdnTX.getSpace();
else
reply[11U] = 0U;
writeInt(1U, reply, 12);
}
void CSerialPort::getVersion()
@@ -221,7 +231,7 @@ void CSerialPort::getVersion()
uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
{
if (length < 13U)
if (length < 16U)
return 4U;
bool rxInvert = (data[0U] & 0x01U) == 0x01U;
@@ -236,6 +246,7 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
bool dmrEnable = (data[1U] & 0x02U) == 0x02U;
bool ysfEnable = (data[1U] & 0x04U) == 0x04U;
bool p25Enable = (data[1U] & 0x08U) == 0x08U;
bool nxdnEnable = (data[1U] & 0x10U) == 0x10U;
uint8_t txDelay = data[2U];
if (txDelay > 50U)
@@ -243,7 +254,7 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
MMDVM_STATE modemState = MMDVM_STATE(data[3U]);
if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_P25 && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL && modemState != STATE_RSSICAL)
if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_P25 && modemState != STATE_NXDN && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL && modemState != STATE_RSSICAL && modemState != STATE_LFCAL && modemState != STATE_DMRCAL1K && modemState != STATE_P25CAL1K && modemState != STATE_DMRDMO1K && modemState != STATE_NXDNCAL1K)
return 4U;
if (modemState == STATE_DSTAR && !dstarEnable)
return 4U;
@@ -253,6 +264,8 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
return 4U;
if (modemState == STATE_P25 && !p25Enable)
return 4U;
if (modemState == STATE_NXDN && !nxdnEnable)
return 4U;
uint8_t rxLevel = data[4U];
@@ -268,18 +281,25 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
uint8_t ysfTXLevel = data[11U];
uint8_t p25TXLevel = data[12U];
int16_t txDCOffset = int16_t(data[13U]) - 128;
int16_t rxDCOffset = int16_t(data[14U]) - 128;
uint8_t nxdnTXLevel = data[15U];
m_modemState = modemState;
m_dstarEnable = dstarEnable;
m_dmrEnable = dmrEnable;
m_ysfEnable = ysfEnable;
m_p25Enable = p25Enable;
m_nxdnEnable = nxdnEnable;
m_duplex = !simplex;
dstarTX.setTXDelay(txDelay);
ysfTX.setTXDelay(txDelay);
p25TX.setTXDelay(txDelay);
dmrDMOTX.setTXDelay(txDelay);
nxdnTX.setTXDelay(txDelay);
dmrTX.setColorCode(colorCode);
dmrRX.setColorCode(colorCode);
@@ -289,7 +309,7 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
ysfTX.setLoDev(ysfLoDev);
io.setParameters(rxInvert, txInvert, pttInvert, rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel);
io.setParameters(rxInvert, txInvert, pttInvert, rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel, nxdnTXLevel, txDCOffset, rxDCOffset);
io.start();
@@ -306,7 +326,7 @@ uint8_t CSerialPort::setMode(const uint8_t* data, uint8_t length)
if (modemState == m_modemState)
return 0U;
if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_P25 && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL && modemState != STATE_RSSICAL)
if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_P25 && modemState != STATE_NXDN && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL && modemState != STATE_RSSICAL && modemState != STATE_LFCAL && modemState != STATE_DMRCAL1K && modemState != STATE_P25CAL1K && modemState != STATE_DMRDMO1K && modemState != STATE_NXDNCAL1K)
return 4U;
if (modemState == STATE_DSTAR && !m_dstarEnable)
return 4U;
@@ -316,6 +336,8 @@ uint8_t CSerialPort::setMode(const uint8_t* data, uint8_t length)
return 4U;
if (modemState == STATE_P25 && !m_p25Enable)
return 4U;
if (modemState == STATE_NXDN && !m_nxdnEnable)
return 4U;
setMode(modemState);
@@ -330,6 +352,7 @@ void CSerialPort::setMode(MMDVM_STATE modemState)
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_DSTAR:
@@ -339,6 +362,7 @@ void CSerialPort::setMode(MMDVM_STATE modemState)
dmrRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_YSF:
@@ -348,6 +372,7 @@ void CSerialPort::setMode(MMDVM_STATE modemState)
dmrRX.reset();
dstarRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_P25:
@@ -357,6 +382,17 @@ void CSerialPort::setMode(MMDVM_STATE modemState)
dmrRX.reset();
dstarRX.reset();
ysfRX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_NXDN:
DEBUG1("Mode set to NXDN");
dmrIdleRX.reset();
dmrDMORX.reset();
dmrRX.reset();
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
cwIdTX.reset();
break;
case STATE_DSTARCAL:
@@ -367,6 +403,7 @@ void CSerialPort::setMode(MMDVM_STATE modemState)
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_DMRCAL:
@@ -377,6 +414,7 @@ void CSerialPort::setMode(MMDVM_STATE modemState)
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_RSSICAL:
@@ -387,6 +425,62 @@ void CSerialPort::setMode(MMDVM_STATE modemState)
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_LFCAL:
DEBUG1("Mode set to 80 Hz Calibrate");
dmrIdleRX.reset();
dmrDMORX.reset();
dmrRX.reset();
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_DMRCAL1K:
DEBUG1("Mode set to DMR BS 1031 Hz Calibrate");
dmrIdleRX.reset();
dmrDMORX.reset();
dmrRX.reset();
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_P25CAL1K:
DEBUG1("Mode set to P25 1011 Hz Calibrate");
dmrIdleRX.reset();
dmrDMORX.reset();
dmrRX.reset();
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_DMRDMO1K:
DEBUG1("Mode set to DMR MS 1031 Hz Calibrate");
dmrIdleRX.reset();
dmrDMORX.reset();
dmrRX.reset();
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_NXDNCAL1K:
DEBUG1("Mode set to NXDN 1031 Hz Calibrate");
dmrIdleRX.reset();
dmrDMORX.reset();
dmrRX.reset();
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
default:
@@ -421,6 +515,10 @@ void CSerialPort::process()
m_ptr = 1U;
m_len = 0U;
}
else {
m_ptr = 0U;
m_len = 0U;
}
} else if (m_ptr == 1U) {
// Handle the frame length
m_len = m_buffer[m_ptr] = c;
@@ -466,8 +564,12 @@ void CSerialPort::process()
case MMDVM_CAL_DATA:
if (m_modemState == STATE_DSTARCAL)
err = calDStarTX.write(m_buffer + 3U, m_len - 3U);
if (m_modemState == STATE_DMRCAL)
if (m_modemState == STATE_DMRCAL || m_modemState == STATE_LFCAL || m_modemState == STATE_DMRCAL1K || m_modemState == STATE_DMRDMO1K)
err = calDMR.write(m_buffer + 3U, m_len - 3U);
if (m_modemState == STATE_P25CAL1K)
err = calP25.write(m_buffer + 3U, m_len - 3U);
if (m_modemState == STATE_NXDNCAL1K)
err = calNXDN.write(m_buffer + 3U, m_len - 3U);
if (err == 0U) {
sendACK();
} else {
@@ -643,11 +745,25 @@ void CSerialPort::process()
}
break;
case MMDVM_NXDN_DATA:
if (m_nxdnEnable) {
if (m_modemState == STATE_IDLE || m_modemState == STATE_NXDN)
err = nxdnTX.writeData(m_buffer + 3U, m_len - 3U);
}
if (err == 0U) {
if (m_modemState == STATE_IDLE)
setMode(STATE_NXDN);
} else {
DEBUG2("Received invalid NXDN data", err);
sendNAK(err);
}
break;
#if defined(SERIAL_REPEATER)
case MMDVM_SERIAL: {
for (uint8_t i = 3U; i < m_len; i++)
m_repeat.put(m_buffer[i]);
}
for (uint8_t i = 3U; i < m_len; i++)
m_repeat.put(m_buffer[i]);
}
break;
#endif
@@ -663,23 +779,28 @@ void CSerialPort::process()
}
}
if (io.getWatchdog() >= 48000U) {
m_ptr = 0U;
m_len = 0U;
}
#if defined(SERIAL_REPEATER)
// Write any outgoing serial data
uint16_t space = m_repeat.getData();
if (space > 0U) {
int avail = availableForWriteInt(3U);
if (avail < space)
space = avail;
// Write any outgoing serial data
uint16_t space = m_repeat.getData();
if (space > 0U) {
int avail = availableForWriteInt(3U);
if (avail < space)
space = avail;
for (uint16_t i = 0U; i < space; i++) {
uint8_t c = m_repeat.get();
writeInt(3U, &c, 1U);
}
}
for (uint16_t i = 0U; i < space; i++) {
uint8_t c = m_repeat.get();
writeInt(3U, &c, 1U);
}
}
// Read any incoming serial data
while (availableInt(3U))
readInt(3U);
// Read any incoming serial data
while (availableInt(3U))
readInt(3U);
#endif
}
@@ -905,6 +1026,46 @@ void CSerialPort::writeP25Lost()
writeInt(1U, reply, 3);
}
void CSerialPort::writeNXDNData(const uint8_t* data, uint8_t length)
{
if (m_modemState != STATE_NXDN && m_modemState != STATE_IDLE)
return;
if (!m_nxdnEnable)
return;
uint8_t reply[130U];
reply[0U] = MMDVM_FRAME_START;
reply[1U] = 0U;
reply[2U] = MMDVM_NXDN_DATA;
uint8_t count = 3U;
for (uint8_t i = 0U; i < length; i++, count++)
reply[count] = data[i];
reply[1U] = count;
writeInt(1U, reply, count);
}
void CSerialPort::writeNXDNLost()
{
if (m_modemState != STATE_NXDN && m_modemState != STATE_IDLE)
return;
if (!m_nxdnEnable)
return;
uint8_t reply[3U];
reply[0U] = MMDVM_FRAME_START;
reply[1U] = 3U;
reply[2U] = MMDVM_NXDN_LOST;
writeInt(1U, reply, 3);
}
void CSerialPort::writeCalData(const uint8_t* data, uint8_t length)
{
if (m_modemState != STATE_DSTARCAL)
+5 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
*
* 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
@@ -47,6 +47,9 @@ public:
void writeP25Ldu(const uint8_t* data, uint8_t length);
void writeP25Lost();
void writeNXDNData(const uint8_t* data, uint8_t length);
void writeNXDNLost();
void writeCalData(const uint8_t* data, uint8_t length);
void writeRSSIData(const uint8_t* data, uint8_t length);
@@ -80,3 +83,4 @@ private:
};
#endif
+3 -2
View File
@@ -21,9 +21,10 @@ Boston, MA 02110-1301, USA.
#if !defined(SERIALRB_H)
#define SERIALRB_H
#if defined(STM32F4XX) || defined(STM32F4)
#if defined(STM32F4XX)
#include "stm32f4xx.h"
#include <cstddef>
#elif defined(STM32F7XX)
#include "stm32f7xx.h"
#elif defined(STM32F105xC)
#include "stm32f1xx.h"
#include <cstddef>
+44 -35
View File
@@ -27,17 +27,17 @@
Pin definitions:
- Host communication:
USART1 - TXD PA9 - RXD PA10 (Pi board)
USART2 - TXD PA2 - RXD PA3 (Nucleo board)
USART1 - TXD PA9 - RXD PA10 (MMDVM-Pi board, MMDVM-Pi F722 board, MMDVM-F4M board)
USART2 - TXD PA2 - RXD PA3 (Nucleo64 F446RE board, Morpho or Arduino header)
USART3 - TXD PC10 - RXD PC11 (Discovery board)
USART3 - TXD PD8 - RXD PD9 (Nucleo144 F767ZI board)
- Serial repeater:
USART1 - TXD PA9 - RXD PA10 (Nucleo with Arduino header)
UART5 - TXD PC12 - RXD PD2 (Discovery, Pi and Nucleo with Morpho header)
UART5 - TXD PC12 - RXD PD2 (Discovery, MMDVM-Pi, MMDVM-Pi F722 board, MMDVM-F4M board, Nucleo64 with Morpho header and Nucleo144 F767ZI)
*/
#if defined(STM32F4XX) || defined(STM32F4)
#if defined(STM32F4XX) || defined(STM32F7XX)
#define TX_SERIAL_FIFO_SIZE 512U
#define RX_SERIAL_FIFO_SIZE 512U
@@ -50,9 +50,8 @@ extern "C" {
}
/* ************* USART1 ***************** */
#if defined(STM32F4_PI) || (defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER))
#if defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || (defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER))
volatile uint32_t intcount1;
volatile uint8_t TXSerialfifo1[TX_SERIAL_FIFO_SIZE];
volatile uint8_t RXSerialfifo1[RX_SERIAL_FIFO_SIZE];
volatile uint16_t TXSerialfifohead1, TXSerialfifotail1;
@@ -139,7 +138,6 @@ void USART1_IRQHandler()
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
intcount1++;
}
if (USART_GetITStatus(USART1, USART_IT_TXE)) {
@@ -186,7 +184,7 @@ void InitUSART1(int speed)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // Tx | Rx
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure USART baud rate
@@ -245,7 +243,6 @@ void WriteUSART1(const uint8_t* data, uint16_t length)
/* ************* USART2 ***************** */
#if defined(STM32F4_NUCLEO)
volatile uint32_t intcount2;
volatile uint8_t TXSerialfifo2[TX_SERIAL_FIFO_SIZE];
volatile uint8_t RXSerialfifo2[RX_SERIAL_FIFO_SIZE];
volatile uint16_t TXSerialfifohead2, TXSerialfifotail2;
@@ -332,7 +329,6 @@ void USART2_IRQHandler()
}
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
intcount2++;
}
if (USART_GetITStatus(USART2, USART_IT_TXE)) {
@@ -379,7 +375,7 @@ void InitUSART2(int speed)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // Tx | Rx
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure USART baud rate
@@ -436,9 +432,8 @@ void WriteUSART2(const uint8_t* data, uint16_t length)
#endif
/* ************* USART3 ***************** */
#if defined(STM32F4_DISCOVERY) || defined(STM32F4_PI)
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
volatile uint32_t intcount3;
volatile uint8_t TXSerialfifo3[TX_SERIAL_FIFO_SIZE];
volatile uint8_t RXSerialfifo3[RX_SERIAL_FIFO_SIZE];
volatile uint16_t TXSerialfifohead3, TXSerialfifotail3;
@@ -525,7 +520,6 @@ void USART3_IRQHandler()
}
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
intcount3++;
}
if (USART_GetITStatus(USART3, USART_IT_TXE)) {
@@ -547,17 +541,34 @@ void USART3_IRQHandler()
}
}
#if defined(STM32F7_NUCLEO)
// USART3 - TXD PD8 - RXD PD9
#define USART3_GPIO_PinSource_TX GPIO_PinSource8
#define USART3_GPIO_PinSource_RX GPIO_PinSource9
#define USART3_GPIO_Pin_TX GPIO_Pin_8
#define USART3_GPIO_Pin_RX GPIO_Pin_9
#define USART3_GPIO_PORT GPIOD
#define USART3_RCC_Periph RCC_AHB1Periph_GPIOD
#else
// USART3 - TXD PC10 - RXD PC11
#define USART3_GPIO_PinSource_TX GPIO_PinSource10
#define USART3_GPIO_PinSource_RX GPIO_PinSource11
#define USART3_GPIO_Pin_TX GPIO_Pin_10
#define USART3_GPIO_Pin_RX GPIO_Pin_11
#define USART3_GPIO_PORT GPIOC
#define USART3_RCC_Periph RCC_AHB1Periph_GPIOC
#endif
void InitUSART3(int speed)
{
// USART3 - TXD PC10 - RXD PC11
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB1PeriphClockCmd(USART3_RCC_Periph, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);
GPIO_PinAFConfig(USART3_GPIO_PORT, USART3_GPIO_PinSource_TX, GPIO_AF_USART3);
GPIO_PinAFConfig(USART3_GPIO_PORT, USART3_GPIO_PinSource_RX, GPIO_AF_USART3);
// USART IRQ init
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
@@ -571,9 +582,9 @@ void InitUSART3(int speed)
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // Tx | Rx
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = USART3_GPIO_Pin_TX | USART3_GPIO_Pin_RX; // Tx | Rx
GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;
GPIO_Init(USART3_GPIO_PORT, &GPIO_InitStructure);
// Configure USART baud rate
USART_StructInit(&USART_InitStructure);
@@ -631,7 +642,6 @@ void WriteUSART3(const uint8_t* data, uint16_t length)
/* ************* UART5 ***************** */
#if !(defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER))
volatile uint32_t intcount5;
volatile uint8_t TXSerialfifo5[TX_SERIAL_FIFO_SIZE];
volatile uint8_t RXSerialfifo5[RX_SERIAL_FIFO_SIZE];
volatile uint16_t TXSerialfifohead5, TXSerialfifotail5;
@@ -718,7 +728,6 @@ void UART5_IRQHandler()
}
USART_ClearITPendingBit(UART5, USART_IT_RXNE);
intcount5++;
}
if (USART_GetITStatus(UART5, USART_IT_TXE)) {
@@ -766,7 +775,7 @@ void InitUART5(int speed)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // Tx
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // Rx
@@ -830,9 +839,9 @@ void CSerialPort::beginInt(uint8_t n, int speed)
{
switch (n) {
case 1U:
#if defined(STM32F4_DISCOVERY)
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
InitUSART3(speed);
#elif defined(STM32F4_PI)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI)
InitUSART1(speed);
#elif defined(STM32F4_NUCLEO)
InitUSART2(speed);
@@ -854,9 +863,9 @@ int CSerialPort::availableInt(uint8_t n)
{
switch (n) {
case 1U:
#if defined(STM32F4_DISCOVERY)
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
return AvailUSART3();
#elif defined(STM32F4_PI)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI)
return AvailUSART1();
#elif defined(STM32F4_NUCLEO)
return AvailUSART2();
@@ -876,9 +885,9 @@ int CSerialPort::availableForWriteInt(uint8_t n)
{
switch (n) {
case 1U:
#if defined(STM32F4_DISCOVERY)
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
return AvailForWriteUSART3();
#elif defined(STM32F4_PI)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI)
return AvailForWriteUSART1();
#elif defined(STM32F4_NUCLEO)
return AvailForWriteUSART2();
@@ -898,9 +907,9 @@ uint8_t CSerialPort::readInt(uint8_t n)
{
switch (n) {
case 1U:
#if defined(STM32F4_DISCOVERY)
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
return ReadUSART3();
#elif defined(STM32F4_PI)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI)
return ReadUSART1();
#elif defined(STM32F4_NUCLEO)
return ReadUSART2();
@@ -920,11 +929,11 @@ void CSerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool
{
switch (n) {
case 1U:
#if defined(STM32F4_DISCOVERY)
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
WriteUSART3(data, length);
if (flush)
TXSerialFlush3();
#elif defined(STM32F4_PI)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI)
WriteUSART1(data, length);
if (flush)
TXSerialFlush1();
+30 -29
View File
@@ -26,10 +26,11 @@
Pin definitions (configuration in IOSTM_CMSIS.c):
- Host communication:
USART2 - TXD PA2 - RXD PA3
USART1 - TXD PA9 - RXD PA10
*/
#if defined(STM32F1)
// BaudRate calculator macro
@@ -42,22 +43,22 @@ USART2 - TXD PA2 - RXD PA3
#define USART_BUFFER_SIZE 256U
DECLARE_RINGBUFFER_TYPE(USARTBuffer, USART_BUFFER_SIZE);
/* ************* USART2 ***************** */
static volatile USARTBuffer_t txBuffer2={.size=USART_BUFFER_SIZE};
static volatile USARTBuffer_t rxBuffer2={.size=USART_BUFFER_SIZE};
/* ************* USART1 ***************** */
static volatile USARTBuffer_t txBuffer1={.size=USART_BUFFER_SIZE};
static volatile USARTBuffer_t rxBuffer1={.size=USART_BUFFER_SIZE};
extern "C" {
bitband_t txe = (bitband_t)BITBAND_PERIPH(&USART2->SR, USART_SR_TXE_Pos);
bitband_t rxne = (bitband_t)BITBAND_PERIPH(&USART2->SR, USART_SR_RXNE_Pos);
bitband_t txeie = (bitband_t)BITBAND_PERIPH(&USART2->CR1, USART_CR1_TXEIE_Pos);
bitband_t txe = (bitband_t)BITBAND_PERIPH(&USART1->SR, USART_SR_TXE_Pos);
bitband_t rxne = (bitband_t)BITBAND_PERIPH(&USART1->SR, USART_SR_RXNE_Pos);
bitband_t txeie = (bitband_t)BITBAND_PERIPH(&USART1->CR1, USART_CR1_TXEIE_Pos);
RAMFUNC void USART2_IRQHandler()
RAMFUNC void USART1_IRQHandler()
{
/* Transmitting data */
if(*txe){
if(!(RINGBUFF_EMPTY(txBuffer2))){
USART2->DR = RINGBUFF_READ(txBuffer2);
if(!(RINGBUFF_EMPTY(txBuffer1))){
USART1->DR = RINGBUFF_READ(txBuffer1);
}else{ /* Buffer empty */
*txeie = 0; /* Don't send further data */
}
@@ -65,42 +66,42 @@ extern "C" {
/* Receiving data */
if(*rxne){
RINGBUFF_WRITE(rxBuffer2, USART2->DR);
RINGBUFF_WRITE(rxBuffer1, USART1->DR);
}
}
}
void USART2Init(int speed)
void USART1Init(int speed)
{
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
USART2->BRR = USART_BRR(36000000UL, speed);
USART1->BRR = USART_BRR(72000000UL, speed);
USART2->CR1 = USART_CR1_UE | USART_CR1_TE |
USART1->CR1 = USART_CR1_UE | USART_CR1_TE |
USART_CR1_RE | USART_CR1_RXNEIE; // Enable USART and RX interrupt
NVIC_EnableIRQ(USART2_IRQn);
NVIC_EnableIRQ(USART1_IRQn);
}
RAMFUNC void USART2TxData(const uint8_t* data, uint16_t length)
RAMFUNC void USART1TxData(const uint8_t* data, uint16_t length)
{
NVIC_DisableIRQ(USART2_IRQn);
NVIC_DisableIRQ(USART1_IRQn);
/* Check remaining space in buffer */
if(RINGBUFF_COUNT(txBuffer2) + length > RINGBUFF_SIZE(txBuffer2)){
NVIC_EnableIRQ(USART2_IRQn);
if(RINGBUFF_COUNT(txBuffer1) + length > RINGBUFF_SIZE(txBuffer1)){
NVIC_EnableIRQ(USART1_IRQn);
return;
}
/* Append data to buffer */
while(length--){
RINGBUFF_WRITE(txBuffer2, *(data++));
RINGBUFF_WRITE(txBuffer1, *(data++));
}
/* Start sending data */
USART2->CR1 |= USART_CR1_TXEIE;
USART1->CR1 |= USART_CR1_TXEIE;
NVIC_EnableIRQ(USART2_IRQn);
NVIC_EnableIRQ(USART1_IRQn);
}
@@ -110,7 +111,7 @@ void CSerialPort::beginInt(uint8_t n, int speed)
{
switch (n) {
case 1U:
USART2Init(speed);
USART1Init(speed);
break;
default:
break;
@@ -121,7 +122,7 @@ int CSerialPort::availableInt(uint8_t n)
{
switch (n) {
case 1U:
return !RINGBUFF_EMPTY(rxBuffer2);
return !RINGBUFF_EMPTY(rxBuffer1);
default:
return false;
}
@@ -131,7 +132,7 @@ uint8_t CSerialPort::readInt(uint8_t n)
{
switch (n) {
case 1U:
return RINGBUFF_READ(rxBuffer2);
return RINGBUFF_READ(rxBuffer1);
default:
return 0U;
}
@@ -139,15 +140,15 @@ uint8_t CSerialPort::readInt(uint8_t n)
void CSerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush)
{
bitband_t tc = (bitband_t)BITBAND_PERIPH(&USART2->SR, USART_SR_TC_Pos);
bitband_t tc = (bitband_t)BITBAND_PERIPH(&USART1->SR, USART_SR_TC_Pos);
switch (n) {
case 1U:
USART2TxData(data, length);
USART1TxData(data, length);
*tc = 0;
if (flush) {
while (!RINGBUFF_EMPTY(txBuffer2) || !tc)
while (!RINGBUFF_EMPTY(txBuffer1) || !tc)
;
}
break;
+3 -2
View File
@@ -19,9 +19,10 @@
#if !defined(UTILS_H)
#define UTILS_H
#if defined(STM32F4XX) || defined(STM32F4)
#if defined(STM32F4XX)
#include "stm32f4xx.h"
#include <cstddef>
#elif defined(STM32F7XX)
#include "stm32f7xx.h"
#elif defined(STM32F105xC)
#include "stm32f1xx.h"
#include <cstddef>
+1 -1
View File
@@ -43,9 +43,9 @@ private:
uint16_t m_dataPtr;
uint16_t m_startPtr;
uint16_t m_endPtr;
uint16_t m_syncPtr;
uint16_t m_minSyncPtr;
uint16_t m_maxSyncPtr;
uint16_t m_syncPtr;
q31_t m_maxCorr;
uint16_t m_lostCount;
uint8_t m_countdown;
+137
View File
@@ -0,0 +1,137 @@
/*
* Copyright (C) 2017 by Andy Uribe CA6JAU
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Required amount of heap and stack */
_min_heap_size = 0x1000;
_min_stack_size = 0x0800;
/* The entry point in the interrupt vector table */
ENTRY(Reset_Handler)
/* Memory areas */
MEMORY
{
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* FLASH */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K /* Main RAM */
}
/* Stack start address (end of 256K RAM) */
_estack = ORIGIN(RAM) + LENGTH(RAM);
SECTIONS
{
.text :
{
/* The interrupt vector table */
. = ALIGN(4);
KEEP(*(.isr_vector .isr_vector.*))
/* The program code */
. = ALIGN(4);
*(.text .text*)
*(.rodata .rodata*)
/* ARM-Thumb code */
*(.glue_7) *(.glue_7t)
. = ALIGN(4);
KEEP(*(.init))
KEEP(*(.fini))
/* EABI C++ global constructors support */
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
/* EABI C++ global constructors support */
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
/* EABI C++ global constructors support */
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
} > ROM
/* ARM sections containing exception unwinding information */
.ARM.extab : {
__extab_start = .;
*(.ARM.extab* .gnu.linkonce.armextab.*)
__extab_end = .;
} > ROM
/* ARM index entries for section unwinding */
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > ROM
/* Start address for the initialization values of the .data section */
_sidata = .;
/* The .data section (initialized data) */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = . ; /* Start address for the .data section */
*(.data .data*)
. = ALIGN(4);
_edata = . ; /* End address for the .data section */
} > RAM
/* The .bss section (uninitialized data) */
.bss :
{
. = ALIGN(4);
_sbss = .; /* Start address for the .bss section */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = . ; /* End address for the .bss section */
__bss_end__ = _ebss;
} > RAM
/* Space for heap and stack */
.heap_stack :
{
end = . ; /* 'end' symbol defines heap location */
_end = end ;
. = . + _min_heap_size; /* Additional space for heap and stack */
. = . + _min_stack_size;
} > RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}
+137
View File
@@ -0,0 +1,137 @@
/*
* Copyright (C) 2017 by Andy Uribe CA6JAU
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Required amount of heap and stack */
_min_heap_size = 0x1000;
_min_stack_size = 0x0800;
/* The entry point in the interrupt vector table */
ENTRY(Reset_Handler)
/* Memory areas */
MEMORY
{
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 2048K /* FLASH */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 512K /* Main RAM */
}
/* Stack start address (end of 512K RAM) */
_estack = ORIGIN(RAM) + LENGTH(RAM);
SECTIONS
{
.text :
{
/* The interrupt vector table */
. = ALIGN(4);
KEEP(*(.isr_vector .isr_vector.*))
/* The program code */
. = ALIGN(4);
*(.text .text*)
*(.rodata .rodata*)
/* ARM-Thumb code */
*(.glue_7) *(.glue_7t)
. = ALIGN(4);
KEEP(*(.init))
KEEP(*(.fini))
/* EABI C++ global constructors support */
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
/* EABI C++ global constructors support */
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
/* EABI C++ global constructors support */
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
} > ROM
/* ARM sections containing exception unwinding information */
.ARM.extab : {
__extab_start = .;
*(.ARM.extab* .gnu.linkonce.armextab.*)
__extab_end = .;
} > ROM
/* ARM index entries for section unwinding */
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > ROM
/* Start address for the initialization values of the .data section */
_sidata = .;
/* The .data section (initialized data) */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = . ; /* Start address for the .data section */
*(.data .data*)
. = ALIGN(4);
_edata = . ; /* End address for the .data section */
} > RAM
/* The .bss section (uninitialized data) */
.bss :
{
. = ALIGN(4);
_sbss = .; /* Start address for the .bss section */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = . ; /* End address for the .bss section */
__bss_end__ = _ebss;
} > RAM
/* Space for heap and stack */
.heap_stack :
{
end = . ; /* 'end' symbol defines heap location */
_end = end ;
. = . + _min_heap_size; /* Additional space for heap and stack */
. = . + _min_stack_size;
} > RAM
/* Remove information from the standard libraries */
/DISCARD/ :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
}