Compare commits

..
729 Commits
Author SHA1 Message Date
Jonathan Naylor 6d67b9f104 Merge branch 'master' into AX25 2020-08-03 13:08:48 +01:00
Jonathan Naylor fb85505433 Merge pull request #296 from msraya/patch-1
YSF pictures can go through modem
2020-08-03 08:43:11 +01:00
Manuel Sánchez Raya 823b91c97d Update YSFRX.cpp
Lower MAX_SYNC_FRAMES to 2, so decoder can recover and Yaesu pictures can pass through the modem without problem.
2020-08-03 09:17:07 +02:00
Jonathan Naylor 0fca178bd7 Merge branch 'master' into AX25 2020-07-28 12:37:07 +01:00
Jonathan Naylor a60ecb3e57 Merge pull request #295 from n0mjs710/master
Added pin definition for FM mode LED (WA0EDA Boards)
2020-07-21 16:21:08 +01:00
Cort Buffington a2978d9e91 Removed a local change to not contaminate the repo 2020-07-21 08:27:02 -05:00
Cort Buffington e304f5cce2 Added pin assignment for FM mode LED (WA0EDA) 2020-07-21 08:19:18 -05:00
Jonathan Naylor 99a7df7c13 Merge pull request #294 from n0mjs710/master
Add support for WA0EDA MTR2000 & MASTR III boards
2020-07-21 06:08:08 +01:00
Cort Buffington 6dfe1a9271 Add support for WA0EDA MTR2000 & MASTR3 boards 2020-07-20 17:11:29 -05:00
Jonathan Naylor d5e9b5a315 Merge branch 'master' into AX25 2020-07-15 08:49:40 +01:00
Jonathan Naylor 1ac0628c1c Improve the code efficiency slightly. 2020-07-14 14:54:47 +01:00
Jonathan Naylor dc41fd83d2 Test the use of a reverse burst at the end of a transmission. 2020-07-14 12:20:42 +01:00
Jonathan Naylor 20013e3adc Make Use COS As Lockout a run-time parameter and allow for different access modes. 2020-07-13 17:13:01 +01:00
Jonathan Naylor 8f8dc92a14 Merge branch 'master' into AX25 2020-07-12 15:24:50 +01:00
Jonathan Naylor ccdbe126e0 Fix the timeout tones. 2020-07-12 15:22:35 +01:00
Jonathan Naylor 4ff057069b Merge branch 'master' into AX25 2020-07-12 10:48:20 +01:00
Jonathan Naylor f8d8f85841 Small simplification of the timeout tones. 2020-07-12 10:47:43 +01:00
Jonathan Naylor 2da28ede64 Increase the maximum AX25 frame size. 2020-06-24 13:14:10 +01:00
Jonathan Naylor a7ac55795d Fix obvious AX25 TX data bug. 2020-06-24 12:46:27 +01:00
Jonathan Naylor 835ef46aef Bump the version date. 2020-06-24 11:16:02 +01:00
Jonathan Naylor 3de10fe98b First version of the AX25 TX functionality. 2020-06-24 11:14:02 +01:00
Jonathan Naylor 7ad70d04a4 Add a dummy AX25 transmit function and make AX25 RX changes. 2020-06-23 10:34:19 +01:00
Jonathan Naylor e210062365 Add the twist processing to the AX25 RX. 2020-06-21 21:40:40 +01:00
Jonathan Naylor f9fcdc5292 Begin adding AX25 TX. 2020-06-21 19:16:02 +01:00
Jonathan Naylor 33d922b8c2 Handle the incoming data offset correctly. 2020-06-19 13:27:45 +01:00
Jonathan Naylor 114c2bcb15 Handle extended packet lengths. 2020-06-19 13:16:47 +01:00
Jonathan Naylor 6dbda2795a Miscalculated the address length. 2020-06-17 22:40:09 +01:00
Jonathan Naylor 6a80d0ec09 Fix minimum packet size. 2020-06-17 22:33:13 +01:00
Jonathan Naylor 0e8f20e1cc Bump the version date. 2020-06-17 16:02:15 +01:00
Jonathan Naylor af11be16dc First woring AX.25 decoder (in simulation). 2020-06-17 15:28:41 +01:00
Jonathan Naylor e332dbba8e Add the correct CCITT checksum table. 2020-06-11 12:59:30 +01:00
Jonathan Naylor 746d915bf9 Rescale one of the filters for the MMDVM sample rate. 2020-06-11 12:14:36 +01:00
Jonathan Naylor c896cf823e Add mobilinkd copyright. 2020-06-11 10:04:09 +01:00
Jonathan Naylor c2959466fd Code complete, but untested. 2020-06-11 10:02:11 +01:00
Jonathan Naylor 121c76f3d8 More filtering added. 2020-06-10 16:38:10 +01:00
Jonathan Naylor 22cb16f831 Add more frame processing. 2020-06-10 16:09:45 +01:00
Jonathan Naylor 57e18e337f Add the seperate AX25Frame class. 2020-06-10 13:53:18 +01:00
Jonathan Naylor e1d1ac4a4d More work on adding AX.25 decoding. 2020-06-10 12:07:04 +01:00
Jonathan Naylor 64fe59382f Start on the actual AX.25 demodulator. 2020-06-09 14:57:06 +01:00
Jonathan Naylor a2e2853241 Begin AX.25 development. 2020-06-08 15:02:12 +01:00
Jonathan Naylor 598d32287d Add alternate FM LEDs for the POG board. 2020-06-01 16:55:13 +01:00
Jonathan Naylor 53d8cfa360 Revert IOSTM_CMSIS.cpp to 5c9abf2 2020-06-01 16:51:59 +01:00
Jonathan Naylor 7fabddd7f1 Update the README file. 2020-05-21 11:11:19 +01:00
Jonathan Naylor 2cf2ce4dfa Fix the TX Hang handling. 2020-05-20 15:16:12 +01:00
Jonathan Naylor 5f29808b80 Set the COS LED correctly. 2020-05-19 12:09:44 +01:00
Jonathan Naylor 063b21f999 Try and make the closing callsign appear. 2020-05-18 11:09:56 +01:00
Jonathan Naylor 89b8641955 Merge pull request #278 from shawnchain/drcc_serial_bugfix
Drcc serial bugfix
2020-05-18 06:34:09 +01:00
Shawn Chain 6397c720e8 Generate bin map file for analysis 2020-05-18 12:19:22 +08:00
Shawn Chain 50c1e5aa3f update pin defs for drcc/nqf board 2020-05-18 12:18:44 +08:00
Shawn Chain 970d02773f Fix serial no write bug on DRCC board 2020-05-18 12:18:17 +08:00
Jonathan Naylor ff375abb0e Hold off the mode change until the ack and callsign have been
transmitted.
2020-05-14 12:10:37 +01:00
Jonathan Naylor 7169836621 Merge branch 'master' into FM 2020-05-13 12:01:19 +01:00
Jonathan Naylor c84d227242 Merge branch 'master' into TXHang 2020-05-13 12:00:23 +01:00
Jonathan Naylor 8e52bdcc5c Merge branch 'master' into FM 2020-05-13 10:30:46 +01:00
Jonathan Naylor 1332c6544b Merge pull request #271 from shawnchain/fix_led_alternate_macro_names
Fix led alternate macro names
2020-05-13 09:36:05 +01:00
Shawn Chain 703ed2628d Init FM led/mode GPIO pin 2020-05-13 16:28:05 +08:00
Shawn Chain f3943a7888 fix wrong macro name for LED/MODE pin 2020-05-13 16:27:12 +08:00
Jonathan Naylor 737454281a Merge pull request #270 from shawnchain/add_nqf_board_pin_defs_header
pin header file for nqf board
2020-05-13 08:43:19 +01:00
Shawn Chain 1aef42bb21 add missing header files for nqf board 2020-05-13 15:28:08 +08:00
Jonathan Naylor 9550299e4d Merge pull request #268 from shawnchain/drcc_dvm_nqf_board_support
Supports drcc_dvm_nqf board
2020-05-13 07:46:58 +01:00
Shawn Chain f8879e1f25 Supports drcc_dvm_nqf board 2020-05-13 13:51:02 +08:00
Jonathan Naylor 43e00bbe1d Merge pull request #266 from shawnchain/io_pins_def_for_each_board_type
Extract the IO pins defs from IOSTM.cpp to separate files
2020-05-12 16:28:04 +01:00
Shawn Chain f31b682625 Extract the IO pins defs from IOSTM.cpp to separate files 2020-05-12 23:21:05 +08:00
Jonathan Naylor 66feb9d50b Merge branch 'master' into FM 2020-05-12 15:48:44 +01:00
Jonathan Naylor 0b14b0b73f Merge pull request #265 from shawnchain/mode_led_fm_fix
fix compile error if no MODE_LEDS defined
2020-05-12 15:48:22 +01:00
Shawn Chain 50706c6f09 fix compile error if no MODE_LEDS defined 2020-05-12 22:44:15 +08:00
Jonathan Naylor 435544f7a1 Add CTCSS hysteresis. 2020-05-12 13:55:30 +01:00
Jonathan Naylor 75e32e1b71 Merge branch 'master' into FM 2020-05-11 13:41:37 +01:00
Jonathan Naylor 7ebc4044f9 Remove Coocox file. 2020-05-11 13:41:10 +01:00
Jonathan Naylor c54c13c146 Merge branch 'master' into FM 2020-05-11 13:33:49 +01:00
phl0 17a3743cd8 Add GPIO and LEDs for FM mode 2020-05-11 14:27:23 +02:00
Jonathan Naylor 4cba5931f4 Loosen the conditions for returning to STATE_IDLE 2020-05-10 21:29:01 +01:00
Jonathan Naylor d0062a55f8 Rescale the FM calibration output. 2020-05-10 17:31:21 +01:00
Jonathan Naylor 66ea3ad0d1 Only use the CTCSS delay when not using COS. 2020-05-10 17:15:54 +01:00
Jonathan Naylor 85acdc7121 Merge pull request #259 from F4FXL/FM
Fix stuck on TX
2020-05-10 17:06:26 +01:00
Geoffrey Merck a2518e99f2 Fix stuck on TX 2020-05-10 17:29:17 +02:00
Jonathan Naylor 3bb7cde322 Add input audio delay to match the CTCSS decoder results. 2020-05-09 13:01:02 +01:00
Jonathan Naylor fa29a27695 Ensure all output audio is flushed before leaving FM state. 2020-05-09 12:53:50 +01:00
Jonathan Naylor e30eb3adaf Reduce the output buffer loading. 2020-05-08 17:18:26 +01:00
Jonathan Naylor 9b0fed975c Buffer output after adding some initial silence. 2020-05-08 15:48:03 +01:00
Jonathan Naylor 5ca9313db8 Merge pull request #248 from F4FXL/FM
Make the FM chain RX Level independant
2020-05-08 09:18:58 +01:00
Geoffrey Merck feff1ee2c7 remove emphasis 2020-05-08 09:04:28 +02:00
Geoffrey Merck 77e0deee76 Make whole FM chain RX level independant 2020-05-08 09:01:00 +02:00
Jonathan Naylor 61ae1fc83a Add transmit hangs to NXDN and P25. 2020-05-06 17:42:46 +01:00
Jonathan Naylor eb9c0dfd93 Allow for the inversion of COS levels. 2020-05-06 11:34:04 +01:00
Jonathan Naylor 79a09e61fa Add the dot to the FM keyer. 2020-05-05 21:02:56 +01:00
Jonathan Naylor 9978a75651 Merge branch 'master' into FM 2020-05-05 21:01:15 +01:00
Jonathan Naylor bd16d13531 Add the dot to the CW Id. 2020-05-05 21:00:36 +01:00
Jonathan Naylor f00d729264 Merge pull request #246 from F4FXL/bugfix/STM32F1_POG
Bug Fixes for the STM32F1_POG and derivatives
2020-05-05 10:17:03 +01:00
Geoffrey Merck a4ddc2a060 Merge remote-tracking branch 'upstream/FM' into bugfix/STM32F1_POG 2020-05-05 11:02:27 +02:00
Geoffrey Merck a938c8b708 Reduce buffer size 2020-05-05 10:48:44 +02:00
Jonathan Naylor aa7a484c7a Allow the start callsign to occur when the kerchunk timer has latched. 2020-05-04 22:18:51 +01:00
Jonathan Naylor 915be8c279 Calculate the AckMinTime accurately. 2020-05-04 22:06:57 +01:00
Geoffrey Merck 87feadd451 Better LED management 2020-05-04 19:12:45 +02:00
Geoffrey Merck 419ab89ee9 Merge branch 'bugfix/STM32F1_POG' of https://github.com/F4FXL/MMDVM into bugfix/STM32F1_POG 2020-05-04 16:44:25 +02:00
Geoffrey Merck fcdb582893 Change FM LED Pin 2020-05-04 16:43:08 +02:00
Geoffrey Merck 5e85565208 Fix compile isue 2020-05-04 15:26:17 +02:00
Geoffrey Merck 2d876b8d8e Fix Fancy LED effect accessing unused ports 2020-05-03 15:36:10 +02:00
Jonathan Naylor 4feca3c5b7 Clock the timers seperately. 2020-05-03 13:08:33 +01:00
Jonathan Naylor f8e119c26b Set the modem state in SET_CONFIG. 2020-05-02 17:37:47 +01:00
Jonathan Naylor edddbedd4b Fix compilation issues. 2020-05-02 15:46:36 +01:00
Jonathan Naylor baa4f7aa4c Last minute tidy-ups. 2020-05-02 14:47:43 +01:00
Jonathan Naylor de3c257f79 Bump the version date. 2020-05-01 18:47:15 +01:00
Jonathan Naylor b027e1d1bf Merge pull request #243 from F4FXL/FM
Fix CTCSS value is different when using RXLevel 50 to 99
2020-05-01 17:04:05 +01:00
Geoffrey Merck 0a5c496a3a Fix CTCSS value is different when using RXLevel 50 to 99 2020-05-01 17:56:45 +02:00
Jonathan Naylor 5b32fecc0a Remove the pre- and de-emphasis and the downsampler. 2020-04-30 11:39:04 +01:00
Jonathan Naylor 92a4db9886 Merge pull request #242 from g4klx/revert-241-FM
Revert "Change emphasis time constant to 750µS"
2020-04-30 11:23:42 +01:00
Jonathan Naylor cc785e3225 Revert "Change emphasis time constant to 750µS" 2020-04-30 11:23:19 +01:00
Jonathan Naylor be0690e587 Merge pull request #241 from F4FXL/FM
Change emphasis time constant to 750µS
2020-04-30 09:38:24 +01:00
Geoffrey Merck 69e39e36b0 Change emphasis time constant to 750µS 2020-04-30 10:26:04 +02:00
Jonathan Naylor b2f33fd4d2 Bump the version date. 2020-04-29 21:51:12 +01:00
Jonathan Naylor 200199c5d4 Reduce the CPU load slightly. 2020-04-29 20:59:48 +01:00
Jonathan Naylor 1465d6f91d Merge pull request #240 from F4FXL/FM
Add resmaplign/packing and Pre and De emphasis
2020-04-29 20:45:02 +01:00
Geoffrey Merck 373aed13c8 Restore Passband 2020-04-29 20:43:01 +02:00
Geoffrey Merck b23620ede3 Add de and pre emphasis 2020-04-29 20:42:20 +02:00
Geoffrey Merck da87afc8d4 Move helper script to separate folder 2020-04-29 20:41:41 +02:00
Geoffrey Merck 626a280d27 Add filter chrachertitics comment 2020-04-29 18:24:15 +02:00
Geoffrey Merck 4b267c2e1e Move downsampling tap point 2020-04-28 22:35:06 +02:00
Geoffrey Merck cf18f95a92 Add Downsampling 2020-04-28 21:37:06 +02:00
Jonathan Naylor dac0f26e5d Rename RXBoost to RFAudioBoost. 2020-04-28 14:43:40 +01:00
Jonathan Naylor 13993891ec Merge pull request #239 from m0vse/FM
Change FM cal levels
2020-04-28 09:55:31 +01:00
m0vse 849c2a0f50 Change FM cal levels 2020-04-28 09:51:11 +01:00
Jonathan Naylor 172ac615a8 Rescale the output. 2020-04-27 14:59:33 +01:00
Jonathan Naylor 30031d8e95 Increase the output level. 2020-04-27 14:53:41 +01:00
Jonathan Naylor b2de5defa4 Tweak the values slightly. 2020-04-27 14:47:17 +01:00
Jonathan Naylor 177c7548ae Merge pull request #237 from m0vse/FM
Add FM Cal modes
2020-04-27 14:35:53 +01:00
m0vse b9bfc36e6f Remove commented code 2020-04-27 14:32:16 +01:00
m0vse 980c529107 Merge remote-tracking branch 'upstream/FM' into FM 2020-04-27 14:19:12 +01:00
m0vse 5156ca13b7 Add FM Cal modes 2020-04-27 14:18:42 +01:00
Jonathan Naylor d08a3690b0 Double the signal level to the CTCSS decoder. 2020-04-27 13:07:03 +01:00
Jonathan Naylor e8ed77241c Simplify the calculations. 2020-04-27 12:05:55 +01:00
Jonathan Naylor 82dcc44a2d Merge pull request #235 from F4FXL/FM
Move division to CTCSSRX, change sample unscaling to 1/rxLevel
2020-04-27 10:27:51 +01:00
Geoffrey Merck 93a8e63233 Remove m_rxLevel 2020-04-27 11:26:19 +02:00
Geoffrey Merck 4ffaa62855 Move division to CTCSSRX, change sample unscaling to 1/rxLevel 2020-04-27 11:16:06 +02:00
Jonathan Naylor f9530ee82a Pass the RX level to the FM controller. 2020-04-26 22:01:11 +01:00
Jonathan Naylor d66c6d7f9c Fix the multiplication. 2020-04-26 15:24:51 +01:00
Jonathan Naylor 458a3d2d24 Bump the version date. 2020-04-26 13:22:16 +01:00
Jonathan Naylor 6f4c19c006 Convert to Q47 arithmetic. 2020-04-26 13:02:43 +01:00
Jonathan Naylor a31cf3d6f8 Convert the CTCSS TX tones to Q31 from Q15. 2020-04-26 12:07:10 +01:00
Jonathan Naylor 3fb0631953 Merge pull request #233 from F4FXL/FM
Remove IO from CTCSSRX
2020-04-26 11:45:44 +01:00
Geoffrey Merck 028d0cf609 Add q31_t cast 2020-04-26 12:38:23 +02:00
Geoffrey Merck 6824d5662a Remove dependency to IO in CTCSSRX 2020-04-26 12:24:05 +02:00
Jonathan Naylor 1bc8726046 Merge pull request #232 from F4FXL/bugfix/FM_CTCSS_TX
Fix invalid values passed to arm_sin_q15
2020-04-26 08:16:20 +01:00
Jonathan Naylor 05c8c130b6 Merge pull request #231 from F4FXL/feature/FM_Normalized_CTCSS_Threshold
CTCSS threshold is level agnostic
2020-04-26 08:15:15 +01:00
Geoffrey Merck 5051a13711 Fix invalid values passed to arm_sin_q15 2020-04-26 08:16:08 +02:00
Geoffrey Merck 103116e410 Add debug essage when CTCSS status changes 2020-04-26 07:26:35 +02:00
Geoffrey Merck d973238596 CTCSS threshold is level agnostic, experimental
(cherry picked from commit d2d50e21e1)
2020-04-26 06:58:27 +02:00
Jonathan Naylor 4d664c4aa4 Merge pull request #230 from g4klx/revert-229-FM
Revert "Make CTCSS threshold RXLevel and RXBoost agnostic"
2020-04-25 23:48:25 +01:00
Jonathan Naylor bd4096b6be Revert "Make CTCSS threshold RXLevel and RXBoost agnostic" 2020-04-25 23:48:02 +01:00
Jonathan Naylor f92d93772c Merge branch 'FM' of https://github.com/g4klx/MMDVM into FM 2020-04-25 22:32:37 +01:00
Jonathan Naylor b963b2b848 Add optional over deviation blanking. 2020-04-25 22:32:10 +01:00
Jonathan Naylor 9dadb51f11 Merge pull request #229 from F4FXL/FM
Make CTCSS threshold RXLevel and RXBoost agnostic
2020-04-25 22:13:09 +01:00
Geoffrey Merck 23cf22d87d remove Debug info 2020-04-25 23:07:41 +02:00
Geoffrey Merck d2d50e21e1 CTCSS threshold is level agnostic, experimental 2020-04-25 22:12:16 +02:00
Jonathan Naylor 8c38fdb36d Clean out the CTCSS decoder coefficient before initialising. 2020-04-25 17:37:37 +01:00
Jonathan Naylor 4fe1c11250 Remove memory leak and other configuration funnies. 2020-04-25 17:29:10 +01:00
Jonathan Naylor 394ab8dfd1 Merge pull request #228 from m0vse/FM
Fix for Ack/Callsign corruption in FM branch
2020-04-25 16:24:10 +01:00
m0vse 5295e0bdc3 Fix for Ack/Callsign corruption 2020-04-25 16:13:13 +01:00
Jonathan Naylor c638dbe55a Merge branch 'FM' of https://github.com/g4klx/MMDVM into FM 2020-04-25 15:17:53 +01:00
Jonathan Naylor 6ac6deba10 Add two more FM parameters. 2020-04-25 15:17:11 +01:00
Jonathan Naylor d2ce76fe89 Merge pull request #227 from F4FXL/FM
Fix STM32F10X compile complaining about duplicate stuff
2020-04-25 08:12:03 +01:00
Geoffrey Merck 0b27ec5443 Fix STM32F10X compile complaining about duplicate stuff 2020-04-25 08:05:31 +02:00
Jonathan Naylor 868d33ebd2 Rescale the CTCSS TX level. 2020-04-24 15:00:40 +01:00
Jonathan Naylor 9fab1e0823 Rescale some of the tone levels. 2020-04-24 13:13:25 +01:00
Jonathan Naylor 242bc7b322 Bump the version date. 2020-04-24 12:54:50 +01:00
Jonathan Naylor e5c25f55fe Remove the FM RX level. 2020-04-24 12:51:10 +01:00
Jonathan Naylor 33f88344c3 Run the holdoff timer permamnently. 2020-04-24 12:15:58 +01:00
Jonathan Naylor 103d937152 Remove unneeded line. 2020-04-24 11:52:47 +01:00
Jonathan Naylor e721dedf1e Merge pull request #225 from F4FXL/FM
Add FM Filtering
2020-04-24 08:46:45 +01:00
Geoffrey Merck 176e067ab9 Merge branch 'FM' of https://github.com/F4FXL/MMDVM into FM 2020-04-24 09:41:14 +02:00
Geoffrey Merck 2057ef5206 clean up 2020-04-24 09:40:06 +02:00
Geoffrey Merck 5c2659deaa Add FM filtering 2020-04-24 09:40:06 +02:00
Geoffrey Merck 4f9d5a8c70 3rd order IIR 2020-04-24 09:40:06 +02:00
Geoffrey Merck 8ecd8b67f4 Using 2 stage IIR filter 2020-04-24 09:40:06 +02:00
Geoffrey Merck 22c40e1d96 Remove bit roation 2020-04-24 09:40:03 +02:00
Geoffrey Merck a720ceeb54 clean up 2020-04-24 09:21:13 +02:00
Geoffrey Merck f8d082e2dd Add FM filtering 2020-04-24 09:10:50 +02:00
Geoffrey Merck 507a4bf64c 3rd order IIR 2020-04-23 22:37:29 +02:00
Jonathan Naylor 7a75db2aeb Remove the bit shift of the sample. 2020-04-23 21:30:41 +01:00
Geoffrey Merck ce0aebce48 Using 2 stage IIR filter 2020-04-23 21:16:52 +02:00
Geoffrey Merck 906de3ad11 Remove bit roation 2020-04-23 21:16:20 +02:00
Jonathan Naylor bf5ad25609 A working fixed point Goertzel based on simulations. 2020-04-23 12:36:34 +01:00
Jonathan Naylor f19009b132 Allow for two levels of the callsign. 2020-04-22 22:10:34 +01:00
Jonathan Naylor 526a53cd8c Use fixed point for the Goertzel algorithm. 2020-04-22 17:40:01 +01:00
Jonathan Naylor 57730d7f81 Implement an efficient FIR filter. 2020-04-22 14:37:23 +01:00
Jonathan Naylor f936bc6fe8 Use a shorter filter. 2020-04-22 14:15:07 +01:00
Jonathan Naylor 3f1f1d1586 Small tidy-ups. 2020-04-22 14:08:34 +01:00
Jonathan Naylor 7940025095 Merge pull request #223 from F4FXL/FM
One loop to rule them all !
2020-04-22 13:30:56 +01:00
Geoffrey Merck 63847ebe62 One loop to rule them all !
Change CFM::Samples and CFMCTCSSRX::process to be able to process all
stuff in one and only loop.
2020-04-22 11:04:27 +02:00
Jonathan Naylor 03f5056236 Small code cleanups. 2020-04-21 22:30:28 +01:00
Jonathan Naylor 23ff29c8f1 Merge pull request #222 from F4FXL/FM
Almost working FM
2020-04-21 22:09:58 +01:00
Geoffrey Merck 1b0229ca6c Attemp to do filtering 2020-04-21 23:03:30 +02:00
Geoffrey Merck ae6cbcd9e7 Minor clean up 2020-04-21 22:43:59 +02:00
Geoffrey Merck 1c599138ad GetAudio do not take any arguments 2020-04-21 22:00:11 +02:00
Geoffrey Merck 9170c398be Reenable CTCSS 2020-04-21 21:36:30 +02:00
Geoffrey Merck 04fd9838b5 Fix state machine wrong kerchunk 2020-04-21 21:00:09 +02:00
Geoffrey Merck 8d340cbfba (almost) One loop to rule all the samples
Avoid looping over and over the samples. One
2020-04-21 20:38:02 +02:00
Geoffrey Merck 87c3b57ae4 Stripping ut stuff, testing 2020-04-21 18:45:11 +02:00
Geoffrey Merck 7befef2f4a Avoid looping samples 2 times, convert each sample on the fly 2020-04-21 18:41:27 +02:00
Geoffrey Merck b2dcbb2df8 Merge remote-tracking branch 'upstream/FM' into FM 2020-04-21 07:03:35 +02:00
Jonathan Naylor 0a51b4c34e Store FM output in a ring buffer. 2020-04-20 21:57:21 +01:00
Geoffrey Merck 3b653dca6a Merge remote-tracking branch 'upstream/FM' into FM 2020-04-20 20:49:58 +02:00
Jonathan Naylor 046a1de51a Reduce the size of the main FM filter. 2020-04-20 13:54:11 +01:00
Jonathan Naylor ae58f8eb64 Don't square the threshold value. 2020-04-20 13:28:07 +01:00
Geoffrey Merck e4c351d5d0 delete old BS 2020-04-20 07:46:03 +02:00
Geoffrey Merck 0b0a59497f Merge branch 'FM' of https://github.com/F4FXL/MMDVM into FM 2020-04-20 07:43:07 +02:00
Geoffrey Merck 939b019592 delete old BS 2020-04-20 07:42:39 +02:00
Geoffrey Merck 3d54519dbf add CTCSS decoder 2020-04-20 07:42:39 +02:00
Geoffrey Merck 94f566aacc Add Goertzel 2020-04-20 07:42:39 +02:00
Geoffrey Merck a765e863c0 delete old BS 2020-04-20 07:42:39 +02:00
Geoffrey Merck 9e552ba1ab add CTCSS decoder 2020-04-20 07:39:19 +02:00
Geoffrey Merck b03fead62d Add Goertzel 2020-04-20 07:39:19 +02:00
Geoffrey Merck 2825c25607 Merge remote-tracking branch 'upstream/FM' into FM 2020-04-20 07:23:59 +02:00
Jonathan Naylor 5ed8eeda6f Allow kerchunk audio to pass through. 2020-04-19 21:40:51 +01:00
Jonathan Naylor 1aef1a39f2 Revert the CTCSS decoder to floats. 2020-04-19 21:21:10 +01:00
Jonathan Naylor a310bf0547 Adjust the coefficients again. 2020-04-19 19:46:44 +01:00
Geoffrey Merck 116b51bd8d delete old BS 2020-04-19 20:45:14 +02:00
Geoffrey Merck c05e7bf873 Merge branch 'FM' of https://github.com/F4FXL/MMDVM into FM 2020-04-19 20:44:18 +02:00
Geoffrey Merck c14ae56e2d delete old BS 2020-04-19 20:43:50 +02:00
Geoffrey Merck 32a71bfbf6 Use long based algorithm 2020-04-19 20:42:57 +02:00
Geoffrey Merck 7435074c0f add CTCSS decoder 2020-04-19 19:34:47 +02:00
Geoffrey Merck ec202d7fb9 Add Goertzel 2020-04-19 19:34:47 +02:00
Jonathan Naylor 6575cba982 Rescale the coefficient. 2020-04-19 17:59:04 +01:00
Jonathan Naylor a17bd9cc1d Don't scale up the sample values. 2020-04-19 17:37:24 +01:00
Jonathan Naylor f7e5c2436c Convert the Goertzel algorithm to Q15 and Q31. 2020-04-19 16:52:11 +01:00
Jonathan Naylor 85816d5bec Re-add COS. 2020-04-18 16:59:25 +01:00
Jonathan Naylor ebdba2bdb9 Convert to using floats. 2020-04-18 16:48:30 +01:00
Jonathan Naylor 6d5b864cba Start the Goertzel development. 2020-04-18 16:07:52 +01:00
Jonathan Naylor c8a450b00d Ensure all timers are stopped when we leave FM mode. 2020-04-18 15:51:49 +01:00
Jonathan Naylor 61ccd79c5f Set up the FM mode pins, partially. 2020-04-18 14:31:21 +01:00
Jonathan Naylor c55002534e Rename the Goertzel class to CTCSSRX. 2020-04-18 13:55:34 +01:00
Jonathan Naylor 8ca756ec22 Simplify the FM arguments. 2020-04-18 13:47:41 +01:00
Jonathan Naylor d1c106b3b8 Add state machine debugging messages. 2020-04-17 18:53:28 +01:00
Jonathan Naylor 564260b2f1 Add the main audio filter. 2020-04-17 18:45:42 +01:00
Jonathan Naylor 4a85122483 CTCSS tones are added to the audio, not replacing it. 2020-04-17 14:11:42 +01:00
Jonathan Naylor bc889f3d26 Handle some extra edge cases. 2020-04-17 13:11:21 +01:00
Jonathan Naylor 95e76f387c Complete the CW keyer. 2020-04-16 21:15:15 +01:00
Jonathan Naylor 4a5f985d02 More efficient CTCSS tone generation. 2020-04-16 14:27:33 +01:00
Jonathan Naylor bbe56f5082 Return configuration errors. 2020-04-16 14:00:31 +01:00
Jonathan Naylor 4b0c3d88f3 More work on the keyer. 2020-04-15 22:41:30 +01:00
Jonathan Naylor c103ac91b3 Add the CTCSS tone generator. 2020-04-15 19:49:26 +01:00
Jonathan Naylor ebd87584da Add the timeout tones. 2020-04-15 18:38:39 +01:00
Jonathan Naylor a9a985182f Add the timer class functionality. 2020-04-15 17:18:01 +01:00
Jonathan Naylor db6fde90e0 Add the intial state machine. 2020-04-15 16:31:49 +01:00
Jonathan Naylor 74228c506e Add stubs for FM classes. 2020-04-15 15:24:01 +01:00
Geoffrey Merck bcd43006ac Merge branch 'FM' of https://github.com/F4FXL/MMDVM into FM 2020-04-14 13:33:59 +02:00
Geoffrey Merck cf616caef9 add CTCSS decoder 2020-04-14 13:33:35 +02:00
Geoffrey Merck 7ab6e51c2c Add Goertzel 2020-04-14 13:33:35 +02:00
Jonathan Naylor 7a549e96ba Handle the net ack parameter. 2020-04-14 12:23:26 +01:00
Geoffrey Merck 3e4d709225 Merge remote-tracking branch 'upstream/FM' into FM 2020-04-14 12:16:54 +02:00
Geoffrey Merck 031563e727 add CTCSS decoder 2020-04-14 12:16:07 +02:00
Geoffrey Merck 3f80248477 Add Goertzel 2020-04-14 12:15:25 +02:00
Jonathan Naylor c84d81d91c Add the minimum time for a 'K' parameter. 2020-04-13 15:54:37 +01:00
Jonathan Naylor ef65268b45 First version of initialisation. 2020-04-12 15:28:56 +01:00
Jonathan Naylor 9d725b9479 Beginnings of FM controller support. 2020-04-11 22:08:17 +01:00
Andy CA6JAU b4647d8d1b Merge pull request #214 from veraabad/master
Fixed deploy-pi-f7
2019-10-23 21:22:43 -03:00
Abad Vera f28a22802d Fixed deploy-pi-f7 2019-10-23 14:36:34 -07:00
Jonathan Naylor 8a60fc1ecb Fix id string for the rpt_hat_tgo. 2019-07-15 09:06:43 +01:00
Jonathan Naylor dfad6d8409 Revert "Merge pull request #204 from shawnchain/support_udid"
This reverts commit b94b8afb77, reversing
changes made to 7c863671c9.
2019-06-04 10:12:53 +01:00
Jonathan Naylor b94b8afb77 Merge pull request #204 from shawnchain/support_udid
Fix HW_TYPE string of RPT_HAT_TGO for MMDVMCal and add UDID support
2019-05-17 08:08:06 +01:00
Shawn Chain 0f37bfa20d arduino_due support 2019-05-16 23:29:28 +08:00
Shawn Chain d6d03158d0 Fix HWType string of RPT_HAT_TGO to work with MMDVMCal and add udid support to the firmware 2019-05-16 23:22:27 +08:00
Jonathan Naylor 7c863671c9 Merge pull request #203 from shawnchain/stm32f1
add STM32F10X_Lib for stm32f105 support
2019-05-14 13:24:48 +01:00
Shawn Chain 2a6db2ab52 Make STM32F1_POG as default type when Makefile.CMSIS is used 2019-05-14 11:53:21 +08:00
Shawn Chain c8a345a301 rollback changes on Config.h 2019-05-14 11:43:29 +08:00
Shawn Chain 37efcb3d4f add STM32F10X_Lib 2019-05-13 21:59:32 +08:00
Jonathan Naylor ff7a9fdd4e Simplify the state change. 2019-03-01 08:00:20 +00:00
Jonathan Naylor 9ccbb842bf Merge branch 'pocsagcal' 2019-01-31 07:56:41 +00:00
Jonathan Naylor 73d3bd5778 Do the POCSAG calibration in a different way. 2019-01-30 14:31:15 +00:00
Jonathan Naylor f785a5260a Merge branch 'master' of https://github.com/g4klx/MMDVM 2019-01-30 13:51:22 +00:00
Jonathan Naylor 03716daca0 Bump the version date. 2019-01-30 13:51:05 +00:00
phl0 9987140790 Fix damn typo 2019-01-30 14:49:21 +01:00
phl0 6b00f7d27a Change to square wave and align amplitude 2019-01-30 14:42:17 +01:00
phl0 98fffb9b77 Fix const compiler issue 2019-01-30 13:02:55 +01:00
Jonathan Naylor 000da1889f Simplify the POCSAG calibration code. 2019-01-30 11:18:16 +00:00
phl0 0a634b1223 Fix some minor bugs :) 2019-01-30 09:40:09 +01:00
phl0 5456f403a1 Add changes by G4KLX 2019-01-30 09:25:33 +01:00
phl0 461182bf60 1st attempt to send 600Hz sine wave 2019-01-23 16:23:45 +01:00
phl0 580ba0b536 Add synthetic 600Hz sine wave and some more POCSAGCal states 2019-01-23 14:58:01 +01:00
phl0 5e3c4c91bb Add basics for a POCSAG Cal mode 2019-01-22 22:21:40 +01:00
phl0 3875da80e7 Make MODE_PINS available on MMDVM_RPT_Hat 2018-11-02 15:02:34 +01:00
Jonathan Naylor 6af252f315 Ignore DVMEGA-Cast specific command. 2018-10-31 14:49:57 +00:00
Jonathan Naylor e46ef4f9ce Merge pull request #198 from gatekeep/master
fix proper PDU reception and processing;
2018-10-09 07:43:11 +01:00
Bryan Biedenkapp 3bae422a8e fix proper PDU reception and processing; 2018-10-08 10:19:31 -04:00
Andy CA6JAU d7526891c5 Restore ring buffer default size 2018-10-07 21:10:34 -03:00
Florian (DF2ET) 6563ee2fb2 Merge pull request #195 from shawnchain/master
Fixed the concat macro error if no GITVERSION is defined, which is in…
2018-09-18 15:23:36 +02:00
Shawn Chain c0952d73d1 Fixed the concat macro error if no GITVERSION is defined, which is introduced by my previous changes. 2018-09-18 21:19:50 +08:00
phl0 4d780389bf Add GitVersion target to Makefile.CMSIS 2018-09-18 10:46:24 +02:00
phl0 5c9abf2eeb Only need rawRSSI variable if SEND_RSSI is defined 2018-09-18 10:33:33 +02:00
phl0 11997ca017 Fix -Wmisleading-indentation compiler warning 2018-09-18 10:17:51 +02:00
Jonathan Naylor ed36d13c8f Merge pull request #194 from shawnchain/rpt_hat_tgo_board
Add support for RPT_HAT_TGO board by BG4TGO and BG5HHP
2018-09-18 09:11:42 +01:00
Shawn Chain 119eea161e Restore the DEFS_DVM for DVM board 2018-09-18 15:46:33 +08:00
Shawn Chain d67809eda6 Add support for RPT_HAT_TGO board by BG4TGO and BG5HHP 2018-09-15 12:06:41 +08:00
phl0 428d36da90 Rename F7Hat to (MMDVM_)RPT_Hat 2018-08-29 09:49:53 +02:00
phl0 328e88856a Add MODE_PINS for F7hat boards 2018-08-28 15:22:54 +02:00
Andy CA6JAU 99966e20ad Reduce buffer sizes for Teensy 3.2/3.1 2018-08-19 12:16:36 -03:00
phl0 1fef7772cb Add MODE pin for POCSAG 2018-08-08 11:16:16 +02:00
Andy CA6JAU f8ab4fe9bd Fix for STM32F105 startup hang 2018-08-06 14:53:47 -04:00
phl0 c2e785cdc4 Generalize MODE_PINS (not F4 specific any more) 2018-08-01 21:12:31 +02:00
phl0 5f19cfcb49 Rename MODE_PINS to MODE_LEDS 2018-08-01 21:09:57 +02:00
Florian (DF2ET) 5405395e1a Merge pull request #186 from N4IRS/master
Add POCSAG Pin for STM32-DVM
2018-07-24 12:05:24 +02:00
Steve N4IRS 3c95d1f604 Add POCSAG Pin for STM32-DVM 2018-07-24 05:58:58 -04:00
Jonathan Naylor da8023eabf Bump the version date. 2018-07-23 21:53:36 +01:00
phl0 0d55ba317d Correct POCSAG LED for F7Hat 2018-07-23 11:39:16 +02:00
Andy CA6JAU 404dc3d99d Additional check to transmit all POCSAG buffer 2018-07-20 20:31:38 -04:00
Andy CA6JAU 4821d0e959 Fix for missing POCSAG start tone 2018-07-20 14:17:33 -04:00
Jonathan Naylor db3649827f Merge pull request #184 from Hootie81/VK6MST_Shield
Add support VK6MST_Shield Serial pass-thru
2018-07-20 12:17:01 +01:00
Hootie81 5bec0d0780 Add support VK6MST_Shield Serial pass-thru 2018-07-20 21:00:09 +10:00
Andy CA6JAU 110062bf65 Reduce the size of serial ring buffer 2018-07-20 00:50:53 -04:00
Jonathan Naylor f3c621307a Restore the original configuration file. 2018-07-19 18:21:17 +01:00
Jonathan Naylor 03177a05e7 Merge pull request #183 from Hootie81/VK6MST_Shield
Add support for VK6MST_Shield
2018-07-19 18:15:57 +01:00
Hootie81 e93b08380d Add support for VK6MST_Shield 2018-07-19 13:01:20 +00:00
phl0 012b366143 Add POCSAG Pin for F7hat 2018-07-18 22:35:13 +02:00
phl0 fd8bc07b61 Merge branch 'master' into F7hat 2018-07-18 22:30:34 +02:00
phl0 68106058d6 Add missing ifdefines for F7Hat 2018-07-18 21:32:56 +02:00
phl0 d62c945887 Add POCSAG pin defs for f767 target 2018-07-12 07:36:44 +02:00
phl0 0aea9aef38 Correct typo in Makefile 2018-07-12 07:16:40 +02:00
Andy 88409dccd2 Add temporary POCSAG pin definitions for F446 and F722 2018-07-12 00:59:08 -04:00
Jonathan Naylor f705656178 Bump the version date. 2018-07-05 18:44:31 +01:00
Jonathan Naylor 5c61ee6be8 Add an mode output pin on the STM32-F7M board as suggested by Tom BG4TGO. 2018-07-05 18:29:18 +01:00
Jonathan Naylor a4af04fae2 Allow for alternative LEDs for NXDN and POCSAG. 2018-07-04 18:40:54 +01:00
phl0 6b28efc011 Flash F7Hat via GPIO 2018-07-01 01:45:42 +02:00
phl0 8c6289802f Add support for MMDVM-F7-Hat 2018-07-01 01:41:33 +02:00
Jonathan Naylor 78d79d4124 Update the README file. 2018-06-26 18:18:43 +01:00
Jonathan Naylor 76d2058075 Recalculate the TX delay for POCSAG. 2018-06-26 18:16:13 +01:00
Jonathan Naylor dcd8142c51 Add a smoothing filter to the POCSAG TX waveform. 2018-06-25 18:00:11 +01:00
Jonathan Naylor 88c530d9e6 Merge branch 'master' into pocsag 2018-06-25 17:47:24 +01:00
phl0 61d5dd6eb3 Add submodules for F4/F7 libs 2018-06-23 22:40:13 +02:00
Jonathan Naylor 9eb6bc1a60 Add the POCSAG mode pin for the Arduino Due, Teensy 3.2/3.6 and the
STM32F105.
2018-06-19 18:17:05 +01:00
Jonathan Naylor 2098146af8 Rename ARDUINO_MODE_PINS to MODE_PINS. 2018-06-19 18:01:24 +01:00
Jonathan Naylor ef32988827 More tweaking of the POCSAG deviation. 2018-06-18 22:12:13 +01:00
Jonathan Naylor ce05dec2e6 Fix crash caused by the larger version string. 2018-06-18 21:32:08 +01:00
Jonathan Naylor 895bed1f70 Fix getStatus length. 2018-06-18 19:18:47 +01:00
phl0 dbea23f171 Merge branch 'master' into pocsag 2018-06-14 19:34:16 +02:00
Florian (DF2ET) ead9747f95 Merge pull request #179 from EA3HKB/patch-1
Add description for non TCXO systems
2018-06-14 19:31:08 +02:00
Florian (DF2ET) 5fe665a6d3 Merge branch 'master' into patch-1 2018-06-14 19:30:52 +02:00
Florian (DF2ET) 3515b16222 Merge pull request #178 from EA3HKB/patch-2
Define new TCXO frequency names for add NO TCXO option
2018-06-14 19:29:39 +02:00
EA3HKB a5c162a75e Define new TCXO frequency names for add NO TCXO option 2018-06-14 19:05:48 +02:00
EA3HKB b5a56487b1 Add description for non TCXO systems
Fixes compiler error
2018-06-14 18:27:48 +02:00
Jonathan Naylor d151c100db Fix length of the getConfig reply. 2018-06-14 07:25:09 +01:00
Jonathan Naylor 56ced0d939 Decrease the deviation. 2018-06-12 21:42:15 +01:00
Jonathan Naylor b6cb23d876 Invert the transmit frequencies. 2018-06-12 20:59:39 +01:00
Jonathan Naylor 20a0a875f3 Add the POCSAG transmitter. 2018-06-06 20:27:46 +01:00
Jonathan Naylor d6c1bea80a Merge pull request #177 from phl0/tcxo
Add TCXO frequency to modem description
2018-06-06 13:34:38 +01:00
Jonathan Naylor 6d4ec5d8a1 Merge pull request #176 from phl0/gitignore
Add F7 lib to .gitignore
2018-06-06 13:33:59 +01:00
phl0 474dce0141 Add F7 lib to .gitignore 2018-06-06 14:06:42 +02:00
phl0 5adbe6d0d5 Add TCXO frequency to modem description 2018-06-06 14:05:36 +02:00
Jonathan Naylor 28adbef81b Add YSF TX hang. 2018-06-04 20:50:43 +01:00
Andy CA6JAU c86d53d9d4 Change 1.2 kHz fill tone by a pseudo random fill (DMR DMO) 2018-06-01 14:39:02 -04:00
Andy CA6JAU eb33bdde5a Merge pull request #171 from g0wfv/constant_srv_led
Constant Service LED
2018-05-23 12:26:30 -04:00
g0wfv 0a89469ffc Constant Service LED 2018-05-23 17:12:53 +01:00
Andy CA6JAU bdd4f395ad Merge pull request #170 from gatekeep/master
Correctly use the CORRELATION_COUNTDOWN constant vs magic number of 5U.
2018-05-15 12:34:23 -04:00
Bryan Biedenkapp 4ae2999e95 Correctly use the CORRELATION_COUNTDOWN constant vs magic number of 5U. 2018-05-15 12:30:15 -04:00
Andy CA6JAU 077bb3b366 Merge pull request #169 from N4IRS/master
Fix comments for STM32-DVM Rev 3
2018-05-15 08:09:14 -04:00
Steve N4IRS b0ca829cf6 Fix comments for STM32-DVM Rev 3 2018-05-15 07:54:39 -04:00
Andy CA6JAU c11ff6bf20 Increasing ring buffer lengths 2018-05-14 22:41:26 -04:00
Jonathan Naylor e1b99f6ee4 Merge pull request #168 from gatekeep/master
Add support to decode P25 DUIDs and non-LDU packets in during processHdr.
2018-05-14 18:45:26 +01:00
Bryan Biedenkapp 4c792ff668 Fix commit with bad line endings. 2018-05-14 10:11:58 -04:00
Bryan Biedenkapp 260dca9664 Add support to decode DUIDs in during processHdr; Add support to process non-LDU packets during processHdr. 2018-05-14 09:09:43 -04:00
Andy CA6JAU 91a15a5782 Merge pull request #167 from N4IRS/master
Add support for the STM32-DVM Rev 3
2018-05-13 08:42:44 -04:00
Steve N4IRS 03f15d8689 Add support for the STM32-DVM Rev 3 2018-05-13 07:39:12 -04:00
Jonathan Naylor 86bf20b06b Update the README. 2018-04-30 17:58:50 +01:00
Jonathan Naylor 41ffe6d2eb Fix Nucleo compiler issues. 2018-04-17 22:32:39 +01:00
Jonathan Naylor 41946ff0aa Bump the version date. 2018-03-27 21:35:38 +01:00
Jonathan Naylor 0ca06e2219 Add new transparent data bypass. 2018-03-21 22:01:35 +00:00
Jonathan Naylor 59ed3f07c8 Change the pin for the NXDN LED on the Teensy. 2018-03-07 20:04:23 +00:00
Andy CA6JAU e20630a425 Support for MMDVM-F7M Pi-Hat board (F0DEI) 2018-03-03 17:05:23 -03:00
Andy CA6JAU ec8a2bc9ff Change NXDN LED pin to PA3 in Arduino header (Nucleo64 F446) 2018-03-01 00:49:14 -03:00
Jonathan Naylor b21c1f21a4 Make the DC blocker optional to reduce CPU load. 2018-02-26 19:55:14 +00:00
Jonathan Naylor 01b3dcc689 Reduce CPU load on idle. 2018-02-26 19:37:15 +00:00
Andy CA6JAU 23f27cf496 Bump the version date 2018-02-23 16:14:26 -03:00
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
Jonathan Naylor 7b68017411 Finish reverting to the master branch P25 filtering. 2017-04-29 10:08:38 +01:00
Jonathan Naylor a2cf35629b Revert "Testing low pass filter for P25 RX"
This reverts commit 68dfdf0c21.
2017-04-28 16:56:18 +01:00
Jonathan Naylor 2506690e98 Revert "Fix comments"
This reverts commit 3760404af9.
2017-04-28 16:55:55 +01:00
Jonathan Naylor 7e15d1ac70 Fix the TX FIFO write level calculation. 2017-04-26 08:18:00 +01:00
Jonathan Naylor 0fb75f974e Fix typo USART5 -> UART5 2017-04-25 08:03:10 +01:00
Jonathan Naylor 99ac6146d9 Add a ring buffer to the serial repeater. Uncompiled on the STM32
platform.
2017-04-24 18:02:36 +01:00
Jonathan Naylor 6161d298f7 Merge branch 'master' into c4fmdemod 2017-04-20 20:49:42 +01:00
Jonathan Naylor 7f181133c7 Merge pull request #90 from phl0/fixWindooze
Make Makefile compatible with builds on Windows
2017-04-18 06:09:50 +01:00
phl0 1d6ca99df9 Make Makefile compatible with builds on Windows 2017-04-17 23:01:19 +02:00
Jonathan Naylor baed701a6c Merge branch 'master' into c4fmdemod 2017-04-17 09:26:14 +01:00
Jonathan Naylor 8b31a53e4e Revert the DMR DMO TX changes. 2017-04-17 09:25:38 +01:00
Jonathan Naylor f6f1198873 Merge pull request #89 from juribeparada/master
Adding Pi Hat F446 support for stm32flash utility in Makefile
2017-04-16 19:57:08 +01:00
Andy CA6JAU 4b17bcd991 Changing default Makefile target to “nucleo” and adding “GitVersion.h” rule for all targets 2017-04-16 15:40:34 -03:00
Andy CA6JAU 852785b616 Workaround for Pi Hat F446 and stm32flash 2017-04-16 15:36:10 -03:00
Jonathan Naylor 1034670ac4 Merge pull request #88 from juribeparada/c4fmdemod
Testing low pass filter for P25 RX
2017-04-16 16:32:37 +01:00
Andy CA6JAU ff8bf96abb Adding GPIO sequence to enter serial bootloader mode (F446) 2017-04-16 11:48:41 -03:00
Andy CA6JAU edc53fc347 Adding Pi Hat F446 support for stm32flash utility in Makefile 2017-04-16 10:55:43 -03:00
Andy CA6JAU 3760404af9 Fix comments 2017-04-16 10:28:30 -03:00
Andy CA6JAU 68dfdf0c21 Testing low pass filter for P25 RX 2017-04-16 10:25:34 -03:00
Jonathan Naylor 5bd01645fa Merge pull request #87 from juribeparada/c4fmdemod
Fixing TX inverse SINC filter for P25, and change TX filters for gain=1
2017-04-15 18:18:19 +01:00
Andy CA6JAU f31cceac18 Fixing TX inverse SINC filter for P25, and change TX filters for gain=1 2017-04-15 13:44:00 -03:00
Andy CA6JAU 1b48c4de1c Merge remote-tracking branch 'g4klx/c4fmdemod' into c4fmdemod 2017-04-15 11:27:17 -03:00
Jonathan Naylor a6ed1e9667 Finish committing the last change. 2017-04-15 10:22:56 +01:00
Jonathan Naylor c7eb072d2f Add an extra flter for P25 RX. 2017-04-14 14:47:37 +01:00
Jonathan Naylor caa73c6c4a Remove the optional wide filters for C4FSK modes. 2017-04-14 14:22:47 +01:00
Jonathan Naylor 9386fb2e11 Make modem debugging a run-time parameter, not compile-time. 2017-04-14 14:19:00 +01:00
Jonathan Naylor 9c9b759db5 Merge pull request #86 from phl0/fixArduinoWarning
Remove Arduino compiler warning
2017-04-13 09:19:18 +01:00
phl0 cfb6e31e2f Remove Arduino compiler warning 2017-04-13 09:35:21 +02:00
Jonathan Naylor 4f6f519dc7 Merge pull request #84 from phl0/ArduinoMakefile
Arduino makefile
2017-04-13 05:43:42 +01:00
Jonathan Naylor fe8e8329ad Merge pull request #85 from juribeparada/master
Update the copyright message
2017-04-13 05:41:28 +01:00
Andy CA6JAU 38bcf1f4c4 Update the copyright message 2017-04-12 23:28:43 -03:00
Andy CA6JAU 6a1c06576b Reverting new RX filter for D-Star 2017-04-12 23:26:48 -03:00
Andy CA6JAU 27b3773f00 Update the copyright message 2017-04-12 23:00:54 -03:00
phl0 871c328914 Cleanup Makefile.Arduino 2017-04-12 23:00:39 +02:00
phl0 fa251afdcb Add define for default Makefile 2017-04-12 22:58:35 +02:00
phl0 27618658a9 Force rebuild of GitVersion.h 2017-04-12 22:43:02 +02:00
phl0 bb42bdc422 Add build/ dir for Arduino Makefile to .gitignore 2017-04-12 22:31:59 +02:00
phl0 f15fcc17ec Update Arduino Makefile to latest SAM version 2017-04-12 22:18:25 +02:00
phl0 59a9b3018f Add a define to Makefile 2017-04-12 21:57:32 +02:00
phl0 07b7801821 A little less verbose and add verfiy 2017-04-12 17:39:15 +02:00
phl0 3d430cbe44 Add first working version of Arduino Due Makefile 2017-04-12 17:35:01 +02:00
Andy CA6JAU fd27ffa464 Merge remote-tracking branch 'g4klx/master' 2017-04-12 09:00:36 -03:00
Jonathan Naylor 42517d691e Merge pull request #83 from phl0/GitID
Include Git ID in Modem description
2017-04-12 12:43:01 +01:00
phl0 53f51820fa Include GitID of Modem firmware 2017-04-12 11:51:28 +02:00
phl0 61a86b7f06 Make GITVERSION a macro and make before nucleo 2017-04-12 11:12:50 +02:00
phl0 696964a3a4 Add GitVersion.h to .gitignore 2017-04-12 10:15:47 +02:00
phl0 23228a0027 Add GitVersion.h to clean command 2017-04-12 10:15:05 +02:00
phl0 b4bef6e7c3 Add GitVersion.h to Makefile 2017-04-12 10:13:44 +02:00
Andy CA6JAU d2548f9e84 Merge remote-tracking branch 'g4klx/master' 2017-04-12 00:16:48 -03:00
Andy CA6JAU 4a01e9b3a1 Testing new RX filter for D-Star 2017-04-12 00:15:43 -03:00
Jonathan Naylor 8a245e7313 Update the copyright message. 2017-04-11 14:40:14 +01:00
Andy CA6JAU c132a58d2e Merge remote-tracking branch 'g4klx/master' 2017-04-10 22:05:58 -03:00
Jonathan Naylor 9cf91ddc7f Add a couple of extra CW characters. 2017-04-10 17:52:12 +01:00
Jonathan Naylor 016ed333ec Remove the unused sample dumping code. 2017-04-10 17:51:44 +01:00
Jonathan Naylor 453fb33b76 Revert the DMO sync bytes from MS to BS sourced. 2017-04-10 09:17:06 +01:00
Jonathan Naylor 9c1410eaae Merge pull request #81 from juribeparada/master
Improving DC filter for D-Star
2017-04-10 05:48:27 +01:00
Andy CA6JAU 5d1a54eee5 Improving DC filter for D-Star 2017-04-10 00:30:45 -03:00
Andy CA6JAU 4f516a827f Merge remote-tracking branch 'g4klx/master' 2017-04-09 16:29:15 -03:00
Jonathan Naylor acb2004843 Convert the DMO idle frame to have an MS data sync. 2017-04-09 20:04:16 +01:00
Jonathan Naylor 0f43670066 Small reformatting. 2017-04-09 20:00:00 +01:00
Jonathan Naylor ab3cdbc277 Merge pull request #80 from juribeparada/master
Filter for DC level estimation for D-Star
2017-04-09 19:53:42 +01:00
Andy CA6JAU 9efe38d825 Merge remote-tracking branch 'g4klx/master' into c4fmdemod 2017-04-09 15:02:57 -03:00
Andy CA6JAU 132cde0864 Merge remote-tracking branch 'g4klx/master' 2017-04-09 14:58:35 -03:00
Andy CA6JAU bc969ff5e5 Merge branch 'c4fmdemod' 2017-04-09 14:55:03 -03:00
Andy CA6JAU ee3f2a0e6d Filter for DC level estimation for D-Star 2017-04-09 14:35:08 -03:00
Jonathan Naylor 421031323d Bump the version date. 2017-04-06 18:11:23 +01:00
Jonathan Naylor 6118653053 Revert "Reduce the YSF deviations(s) by 10%."
This reverts commit 06ef230ad5.
2017-04-06 18:08:47 +01:00
Andy CA6JAU 1a5bc9cf8c Merge remote-tracking branch 'g4klx/c4fmdemod' into c4fmdemod 2017-04-05 21:21:09 -03:00
Jonathan Naylor 06ef230ad5 Reduce the YSF deviations(s) by 10%. 2017-04-05 14:24:29 +01:00
Jonathan Naylor 9d4779e4c3 Put idle into the second DMO slot instead of the repeat of the data. MD380/390 bug workaround. 2017-04-05 14:19:25 +01:00
Jonathan Naylor d5531177f2 Merge pull request #76 from juribeparada/c4fmdemod
Adding conditional compilation for Arduino 1.6.7 fix
2017-04-03 05:02:51 +01:00
Andy CA6JAU f2c50083d8 Adding conditional compilation for Arduino 1.6.7 fix 2017-04-02 22:17:09 -03:00
Jonathan Naylor 838d813ab9 Merge pull request #75 from juribeparada/c4fmdemod
New filter for D-Star, BT=0.35
2017-04-02 22:48:06 +01:00
Andy CA6JAU dffc6f0a5a New filter for D-Star, BT=0.35 2017-04-02 18:03:36 -03:00
Andy CA6JAU 7a042c10ad Better fix for Arduino IDE compilation error, now including STM32F4 2017-04-02 18:02:33 -03:00
Jonathan Naylor 0c44b8ca25 Merge pull request #74 from juribeparada/c4fmdemod
Fix for Arduino 1.6 compilation error
2017-04-02 21:14:55 +01:00
Andy CA6JAU 6f29fe62b1 Fix for Arduino 1.6 compilation error 2017-04-02 16:48:50 -03:00
Andy CA6JAU 937c0b8b97 Merge remote-tracking branch 'g4klx/c4fmdemod' into c4fmdemod 2017-04-02 15:40:55 -03:00
Andy CA6JAU 941d77bd51 Merge remote-tracking branch 'g4klx/master' 2017-04-02 14:22:57 -03:00
Jonathan Naylor 6a0fa19c07 Merge pull request #73 from juribeparada/c4fmdemod
New deviation values for YSF and P25
2017-04-02 18:04:00 +01:00
Jonathan Naylor a14ebca9e0 Merge branch 'master' into c4fmdemod 2017-04-02 18:02:17 +01:00
Andy CA6JAU 61b4093aec Merge remote-tracking branch 'g4klx/c4fmdemod' into c4fmdemod 2017-04-02 13:58:15 -03:00
Andy CA6JAU 555197b0a2 New deviation value for YSF 2017-04-02 13:49:39 -03:00
Andy CA6JAU bb6a554919 New deviation values for P25 (not tested) 2017-04-02 13:49:39 -03:00
Jonathan Naylor c0941c4856 Add TX Delay buffer protection. 2017-04-02 13:48:40 +01:00
Jonathan Naylor e93b264d9c Merge pull request #72 from juribeparada/c4fmdemod
Compensate DMR deviation to match old adjustments
2017-04-02 06:20:26 +01:00
Andy CA6JAU fcdbb8cda0 Compensate DMR deviation to match old adjustments (K=0.904) 2017-04-01 21:52:02 -03:00
Jonathan Naylor a4ff8920e5 Merge pull request #71 from juribeparada/c4fmdemod
New serial port buffer size for STM32F4
2017-04-02 00:25:31 +01:00
Andy CA6JAU db1c01f4dc New serial port buffer size for STM32F4 2017-04-01 15:04:05 -03:00
Andy CA6JAU ab50521f74 Testing new serial port buffer size for STM32F4 2017-04-01 11:52:34 -03:00
Jonathan Naylor 5843ca0e3d Merge pull request #70 from juribeparada/c4fmdemod
Using CMSIS FIR interpolator for all modulators
2017-04-01 08:42:07 +01:00
Andy CA6JAU 6b0868b8f2 Merge branch 'c4fmdemod' of https://github.com/juribeparada/MMDVM into c4fmdemod 2017-04-01 01:44:23 -03:00
Andy CA6JAU a49871cd8b Using CMSIS FIR interpolator for all modulators 2017-04-01 01:29:35 -03:00
Andy CA6JAU 78f5d34373 Using CMSIS FIR interpolator for all modulators 2017-04-01 01:16:56 -03:00
Jonathan Naylor 9bcaba0419 Change the start sync sequence. 2017-03-31 08:33:01 +01:00
Jonathan Naylor a25b634366 Merge pull request #68 from wojciechk8/mmdvm_pog
Adding support for STM32F1 MCU and MMDVM_pog board
2017-03-31 08:20:33 +01:00
Jonathan Naylor 4039f576ae Use the DMR changes from Andy in the DMR DMO TX. 2017-03-31 08:16:13 +01:00
Jonathan Naylor 03aa405b41 Merge pull request #69 from juribeparada/c4fmdemod
Fixing symbol generation for all modes (zero padding for FIR interpolation)
2017-03-31 08:14:52 +01:00
Andy CA6JAU 546243eec6 Fixing symbol generation (zero padding for FIR interpolation) 2017-03-31 01:26:07 -03:00
Andy CA6JAU a033ee66fd Restoring original TX filter for YSF, fixing symbol generation (zero padding for FIR interpolation) 2017-03-31 01:25:45 -03:00
Wojciech Krutnik 70dfb0964e Corrected Makefile.CMSIS and IOSTM_CMSIS.cpp to enable compilation
without errors
2017-03-31 01:25:24 +02:00
Wojciech Krutnik ab09848afd Updated .gitignore 2017-03-31 00:52:24 +02:00
Wojciech Krutnik ed7b57d618 Added Makefile for STM32F1 with CMSIS 2017-03-31 00:52:24 +02:00
Wojciech Krutnik e8010137f7 Added STM32F1 startup code 2017-03-31 00:52:24 +02:00
Wojciech Krutnik c2d5c31db1 Added includes and definitions to support STM32F1 2017-03-31 00:52:24 +02:00
Wojciech Krutnik 5f2375e99e Added STM32F1 support to Serial module using CMSIS driver 2017-03-31 00:52:24 +02:00
Wojciech Krutnik fd56870d22 Added STM32F1 and mmdvm_pog board support to IO module using CMSIS driver 2017-03-31 00:51:50 +02:00
Wojciech Krutnik 5bc21fa192 Added mmdvm_pog board definition to Config.h 2017-03-31 00:19:01 +02:00
Jonathan Naylor 33293258f3 Merge pull request #67 from juribeparada/c4fmdemod
New YSF filter for TX
2017-03-30 07:54:46 +01:00
Andy CA6JAU aee9cac546 New YSF filter for TX 2017-03-30 01:09:03 -03:00
Jonathan Naylor c9b553bc2e Follow the ETSI standard for DMO operation. 2017-03-29 20:36:02 +01:00
Jonathan Naylor 12dc9183da Add YSF low deviation mode. 2017-03-23 20:27:23 +00:00
Jonathan Naylor 8c38341c17 Merge branch 'master' into c4fmdemod 2017-03-21 18:31:59 +00:00
Jonathan Naylor 418b63b9ca Update copyright date. 2017-03-20 07:57:25 +00:00
Jonathan Naylor e697a91710 Revert the DMR DMO transmitter changes. 2017-03-19 09:35:46 +00:00
Jonathan Naylor e04057a5b5 Update P25 raised cosine filter coefficients. 2017-03-18 11:35:31 +00:00
Jonathan Naylor e17d771d41 Reduce the number of diffs. 2017-03-18 09:22:55 +00:00
Jonathan Naylor 38516074dd Forgot to set the at variable within the CACH. 2017-03-13 08:24:35 +00:00
Jonathan Naylor 3814d4243c Add extra idle frames at the start of a DMR DMO transmission. 2017-03-12 18:36:41 +00:00
Jonathan Naylor bcbfb66131 Roll back the YSF changes and simplify the P25 code. 2017-03-10 18:18:36 +00:00
Jonathan Naylor 9560c77358 Merge branch 'master' into c4fmdemod 2017-03-10 17:47:50 +00:00
Jonathan Naylor 785cb5584b Merge pull request #66 from m1geo/master
Add compilation timestamp to hardware description varible sent in ::getVersion()
2017-03-10 17:17:31 +00:00
George Smart 917b303a0f Added compilation timestamp to hardware description varible sent in ::getVersion() 2017-03-09 23:32:46 +00:00
George Smart 80d659d7d0 Merge pull request #1 from g4klx/master
Merge with KLX Master Repo
2017-03-09 22:40:38 +00:00
Jonathan Naylor 90111dc43d Use the Raised Cosine filter on YSF TX. 2017-03-07 20:48:39 +00:00
Jonathan Naylor 9110f5404f Add the Raised Cosine filter to P25 RX and change YSF to use the Raised
Cosine filter on RX also.
2017-03-07 20:44:41 +00:00
Jonathan Naylor df1210eaea Remove the OscOffset parameter. 2017-03-07 20:41:54 +00:00
Jonathan Naylor a9b761d1dc Change the P25 TX and RX filters and add a DMR TX data holdoff counter. 2017-03-06 20:42:37 +00:00
Jonathan Naylor 8c970b26db Change size of space in transmit routines. 2017-03-06 20:36:44 +00:00
Jonathan Naylor d89b68ff76 Bump the version date. 2017-03-03 15:00:19 +00:00
Jonathan Naylor 7fafd762d2 Improve frame dumping capabilities. 2017-02-26 12:33:59 +00:00
Jonathan Naylor a6affb765e Remove the sync sample dumping. 2017-02-21 17:51:09 +00:00
Jonathan Naylor 2f9eb3523d Add full frame dumping. 2017-02-20 21:35:23 +00:00
Jonathan Naylor 3b5e1afb54 Merge branch 'master' into c4fmdemod 2017-02-18 11:19:52 +00:00
Jonathan Naylor 8b019d49fd Merge pull request #65 from juribeparada/master
Fixing RSSI raw value position in buffer (YSF and P25)
2017-02-18 06:21:12 +00:00
Andy CA6JAU d92a00ae6e Fixing RSSI raw value position in buffer (YSF and P25) 2017-02-17 20:09:23 -03:00
Andy CA6JAU b83d13fe3a Merge remote-tracking branch 'g4klx/master' 2017-02-16 10:44:39 -03:00
Jonathan Naylor bc6c650973 Improve YSF and P25 receive BER. 2017-02-12 18:44:45 +00:00
Jonathan Naylor 1bb474dfef Add new interpolation for most modes and start positioning for P25 and YSF. 2017-02-06 21:02:45 +00:00
Jonathan Naylor 18ec4bafb6 Merge branch 'master' into c4fmdemod 2017-02-06 20:52:33 +00:00
Jonathan Naylor b2c490e0bd Bump the version date. 2017-02-06 20:52:06 +00:00
Jonathan Naylor 4221ac45b1 Improve the P25 sync positioning. 2017-02-05 19:33:52 +00:00
Jonathan Naylor ec5100bf6f Alter the P25 HDR start pointer calculation. 2017-02-03 12:01:12 +00:00
Jonathan Naylor ac4249bbb1 Add working sync sample dumping for DMR, P25 and YSF. 2017-02-02 20:13:28 +00:00
Jonathan Naylor f3a3132a6c Add sync dumping and improve YSF and P25. 2017-01-31 20:36:31 +00:00
Jonathan Naylor 4bc0f36b49 Begin P25 Header detection. 2017-01-29 19:28:27 +00:00
Jonathan Naylor 9d1fbcfc73 Update P25 to match YSF demodulator, work in progress. 2017-01-29 19:08:44 +00:00
Jonathan Naylor 609c2ead53 Revert the DMR changes. 2017-01-29 18:51:33 +00:00
Jonathan Naylor 37daa04a6c Merge branch 'master' into c4fmdemod 2017-01-28 20:07:00 +00:00
Jonathan Naylor 20a4cf0378 Merge pull request #63 from juribeparada/master
Adding conditional compilation
2017-01-28 13:57:57 +00:00
Andy CA6JAU 693f517aec Adding conditional compilation 2017-01-28 10:18:10 -03:00
Andy CA6JAU 4549027e95 Merge remote-tracking branch 'g4klx/master' 2017-01-28 09:46:53 -03:00
Jonathan Naylor b3a1961279 Merge branch 'master' into c4fmdemod 2017-01-26 20:30:49 +00:00
Jonathan Naylor afae6e552c Merge pull request #62 from phl0/MODEpins
Mode pins
2017-01-22 12:24:24 +00:00
phl0 5ee6a0d6db Correct comments to align with changed pins 2017-01-22 12:22:40 +01:00
phl0 49e0d13967 Redefine Mode pins for D-Star and DMR 2017-01-22 00:46:12 +01:00
Jonathan Naylor 53067d36d0 More averaging of the centre and threshold. 2017-01-21 18:57:39 +00:00
Jonathan Naylor a5568efd51 Merge branch 'master' into c4fmdemod 2017-01-21 18:37:46 +00:00
Jonathan Naylor d4d1f8282b Tweaks to the new YSF demodulator. 2017-01-21 18:37:30 +00:00
phl0 79b0b141a2 Add support for external mode pins on F0DEI board 2017-01-20 17:34:32 +01:00
Jonathan Naylor 850978a954 Merge pull request #61 from phl0/gitignore
Add gitignore to irgnore object files and STM lib
2017-01-20 16:03:57 +00:00
phl0 f97e53f1eb Add gitignore to irgnore object files and STM lib 2017-01-20 16:34:25 +01:00
Jonathan Naylor dfd2a4db38 Merge pull request #60 from phl0/devel
Refactored STM code concerning whitespace
2017-01-20 06:13:59 +00:00
phl0 eab91cca3a Correct typo 2017-01-19 21:54:21 +01:00
phl0 1e7c06de45 Refactor SerialSTM.cpp 2017-01-19 21:50:06 +01:00
Jonathan Naylor b15933bf8a Cleanups but still untested. 2017-01-19 19:59:01 +00:00
phl0 df5ab3de60 Refactor IOSTM.cpp 2017-01-19 14:07:30 +01:00
Jonathan Naylor 9a7b07027a New demodulators for C4FM modes. 2017-01-17 20:05:20 +00:00
Jonathan Naylor 8b13a3c8a6 Merge pull request #59 from juribeparada/master
New pin definitions for STM32F446RE board, enabling Arduino header
2017-01-11 09:11:37 +00:00
Andy CA6JAU 1ce71bcd62 New pin definitions for serial port Nucleo-64 STM32F446RE board, Arduino header 2017-01-11 00:27:27 -03:00
Andy CA6JAU ed13addd3d Merge remote-tracking branch 'g4klx/master' 2017-01-10 23:56:31 -03:00
Jonathan Naylor 3e937a71d9 Average the RSSI value for all modes. 2017-01-10 19:20:16 +00:00
Andy CA6JAU a59da0ebd2 Adding more flexibility for STM32F4 pin definitions 2017-01-10 01:38:56 -03:00
Andy CA6JAU 33f4d35e2b Adding new pin definitions for Nucleo-64 STM32F446RE board 2017-01-10 00:47:45 -03:00
Andy CA6JAU 048888f45b Merge remote-tracking branch 'g4klx/master' 2017-01-08 19:18:26 -03:00
Jonathan Naylor 57fde3afcc Add RSSI reporting for all modes. 2017-01-05 18:59:15 +00:00
Jonathan Naylor 8777c2b29c Update README.md 2017-01-03 16:36:34 +00:00
Jonathan Naylor 8330ed7dcf Merge pull request #56 from g4eml/master
Fix crash in DMR DMO Mode on Teensy
2017-01-01 15:20:47 +00:00
g4eml 9f47e67630 Fix crash in DMR DMO Mode
Modem was crashing on Teensy when running in DMO mode. Crashed as soon as Tx started. Traced to exceeding the bounds of m_poBuffer during the txdelay phase.
 m_poBuffer was dimensioned to 80 but m_txdelay could be 600 to 1200 so a massive overwrite was happening.
Surprisingly this didn't crash on the Due only on the Teensy.
2017-01-01 14:22:49 +00:00
Andy CA6JAU d0f320a862 Merge remote-tracking branch 'g4klx/master' 2016-12-31 12:20:47 -03:00
Jonathan Naylor a05eaee855 Fix RSSI compile. 2016-12-30 13:48:55 +00:00
Jonathan Naylor 4b5f496a0c Bump the version date. 2016-12-30 11:35:39 +00:00
Jonathan Naylor fca53dc67e Small tweaks. 2016-12-30 11:34:31 +00:00
Jonathan Naylor 52fbd4f6ce Merge pull request #53 from juribeparada/master
Adding RSSI samples averaging
2016-12-29 09:32:06 +00:00
Andy CA6JAU d22c86e4d8 Fixing RSSI buffer length 2016-12-29 01:08:31 -03:00
Andy CA6JAU cc1b6d1367 Optimizing RSSI averaging 2016-12-29 00:51:14 -03:00
Andy CA6JAU 2ff955631f Adding #define constants in the RSSI average code 2016-12-29 00:36:45 -03:00
Andy CA6JAU f66e32fbb4 Merge remote-tracking branch 'g4klx/master' 2016-12-28 22:05:06 -03:00
Jonathan Naylor 33527dd3e9 Add the RSSI calibration mode. 2016-12-28 18:07:31 +00:00
Andy CA6JAU 442dbe0b6a Adding RSSI samples averaging 2016-12-27 00:40:14 -03:00
Andy CA6JAU fc200c4cd7 Merge remote-tracking branch 'g4klx/master' 2016-12-26 14:14:02 -03:00
Jonathan Naylor 7266f5c53b Merge pull request #52 from g4eml/master
Change ADC1 to reduce number of interrupts.
2016-12-22 22:58:01 +00:00
g4eml 957d0d8d34 Change ADC1 to reduce number of interrupts.
Disable interrupts for ADC1. 
Every time ADC0 interrupts (24Khz) read the current conversion from ADC1 and software trigger a new one. 
This way there will always be an ADC1 conversion available whenever ADC0 interrupts.
2016-12-22 22:27:10 +00:00
Jonathan Naylor c69c573000 Merge pull request #51 from g4eml/master
Adjust ADC pre-trigger setting for external TCXO
2016-12-22 18:22:16 +00:00
g4eml cb30a8d357 Adjust ADC pre-trigger setting for external TCXO
External TCXO was not working with Pre-Trigger set to B.
This change sets it to A which appears to work.
2016-12-22 16:35:35 +00:00
Jonathan Naylor 38f6d7d9d8 Update DAC reference comment. 2016-12-21 14:01:18 +00:00
Jonathan Naylor 461e7c942e Add RSSI input for the ZUM board also. 2016-12-21 08:46:17 +00:00
Jonathan Naylor 773cda818d Merge pull request #49 from sq6pog/nth_rssi
RSSI readout support for NTH board @Arduino Due
2016-12-21 08:43:00 +00:00
Jonathan Naylor 625a6c1a79 Merge pull request #50 from g4eml/master
Update IOTeensy.cpp
2016-12-21 08:41:13 +00:00
Paweł Gomułka 414f3eb193 typo :/ 2016-12-21 01:57:58 +01:00
Paweł Gomułka bef0d9cfd6 Added missing conditions for preprocessor 2016-12-21 01:55:35 +01:00
Andy CA6JAU 1a270642cd Merge remote-tracking branch 'g4klx/master' 2016-12-20 20:27:16 -03:00
g4eml 75eccb751e Update IOTeensy.cpp
Switch ADCs to External Reference. (3v3 on Teensy)
2016-12-20 20:48:15 +00:00
Paweł Gomułka 2c76d67098 RSSI readout support for NTH board @Arduino Due 2016-12-20 20:32:54 +01:00
Jonathan Naylor 0585d817cb Change Teensy RSSI input pins. 2016-12-20 14:21:36 +00:00
Jonathan Naylor 5d0d2d0bd9 Fix calibration setting. 2016-12-20 08:42:56 +00:00
186 changed files with 6898 additions and 119038 deletions
+5
View File
@@ -0,0 +1,5 @@
*.o
obj/
bin/
GitVersion.h
build/
+9
View File
@@ -0,0 +1,9 @@
[submodule "STM32F4XX_Lib"]
path = STM32F4XX_Lib
url = https://github.com/juribeparada/STM32F4XX_Lib.git
[submodule "STM32F7XX_Lib"]
path = STM32F7XX_Lib
url = https://github.com/juribeparada/STM32F7XX_Lib.git
[submodule "STM32F10X_Lib"]
path = STM32F10X_Lib
url = https://github.com/shawnchain/STM32F10X_Lib.git
+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2020 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(AX25DEFINES_H)
#define AX25DEFINES_H
const uint8_t AX25_RADIO_SYMBOL_LENGTH = 20U; // At 24 kHz sample rate
const uint8_t AX25_FRAME_START = 0x7EU;
const uint8_t AX25_FRAME_END = 0x7EU;
const uint8_t AX25_FRAME_ABORT = 0xFEU;
const uint8_t AX25_MAX_ONES = 5U;
const uint16_t AX25_MIN_FRAME_LENGTH = 17U; // Callsign (7) + Callsign (7) + Control (1) + Checksum (2)
const uint16_t AX25_MAX_FRAME_LENGTH = 330U; // Callsign (7) + Callsign (7) + 8 Digipeaters (56) +
// Control (1) + PID (1) + Data (256) + Checksum (2)
#endif
+266
View File
@@ -0,0 +1,266 @@
/*
* Copyright (C) 2020 by Jonathan Naylor G4KLX
* Copyright 2015-2019 Mobilinkd LLC <[email protected]>
*
* 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 "AX25Demodulator.h"
#include "AX25Defines.h"
const float32_t SAMPLE_RATE = 24000.0F;
const float32_t SYMBOL_RATE = 1200.0F;
const uint16_t DELAY_LEN = 11U;
const float32_t SAMPLES_PER_SYMBOL = SAMPLE_RATE / SYMBOL_RATE;
const float32_t PLL_LIMIT = SAMPLES_PER_SYMBOL / 2.0F;
const uint32_t LPF_FILTER_LEN = 96U;
q15_t LPF_FILTER_COEFFS[] = {
0, 0, 0, 1, 2, 5, 8, 12, 18, 23,
29, 33, 36, 36, 33, 25, 13, -5, -28, -57,
-89, -123, -159, -194, -225, -249, -264, -267, -254, -224,
-175, -104, -12, 102, 236, 389, 557, 738, 926, 1117,
1306, 1486, 1654, 1802, 1927, 2025, 2092, 2126, 2126, 2092,
2025, 1927, 1802, 1654, 1486, 1306, 1117, 926, 738, 557,
389, 236, 102, -12, -104, -175, -224, -254, -267, -264,
-249, -225, -194, -159, -123, -89, -57, -28, -5, 13,
25, 33, 36, 36, 33, 29, 23, 18, 12, 8,
5, 2, 1, 0, 0, 0
};
// 64 Hz loop filter.
// scipy.signal:
// loop_coeffs = firwin(9, [64.0/(1200/2)], width = None,
// pass_zero = True, scale = True, window='hann')
//
const uint32_t PLL_FILTER_LEN = 7U;
float32_t PLL_FILTER_COEFFS[] = {3.196252e-02F, 1.204223e-01F, 2.176819e-01F, 2.598666e-01F, 2.176819e-01F, 1.204223e-01F, 3.196252e-02F};
CAX25Demodulator::CAX25Demodulator(int8_t n) :
m_frame(),
m_twist(n),
m_lpfFilter(),
m_lpfState(),
m_delayLine(NULL),
m_delayPos(0U),
m_nrziState(false),
m_pllFilter(),
m_pllState(),
m_pllLast(false),
m_pllBits(1U),
m_pllCount(0.0F),
m_hdlcOnes(0U),
m_hdlcFlag(false),
m_hdlcBuffer(0U),
m_hdlcBits(0U),
m_hdlcState(AX25_IDLE)
{
m_delayLine = new bool[DELAY_LEN];
m_lpfFilter.numTaps = LPF_FILTER_LEN;
m_lpfFilter.pState = m_lpfState;
m_lpfFilter.pCoeffs = LPF_FILTER_COEFFS;
m_pllFilter.numTaps = PLL_FILTER_LEN;
m_pllFilter.pState = m_pllState;
m_pllFilter.pCoeffs = PLL_FILTER_COEFFS;
}
bool CAX25Demodulator::process(q15_t* samples, uint8_t length, CAX25Frame& frame)
{
bool result = false;
q15_t fa[RX_BLOCK_SIZE];
m_twist.process(samples, fa, RX_BLOCK_SIZE);
int16_t buffer[RX_BLOCK_SIZE];
for (uint8_t i = 0; i < length; i++) {
bool level = (fa[i] >= 0);
bool delayed = delay(level);
buffer[i] = (int16_t(level ^ delayed) << 1) - 1;
}
q15_t fc[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_lpfFilter, buffer, fc, RX_BLOCK_SIZE);
for (uint8_t i = 0; i < length; i++) {
bool bit = fc[i] >= 0;
bool sample = PLL(bit);
if (sample) {
// We will only ever get one frame because there are
// not enough bits in a block for more than one.
if (result) {
HDLC(NRZI(bit));
} else {
result = HDLC(NRZI(bit));
if (result) {
// Copy the frame data.
::memcpy(frame.m_data, m_frame.m_data, AX25_MAX_PACKET_LEN);
frame.m_length = m_frame.m_length;
frame.m_fcs = m_frame.m_fcs;
m_frame.m_length = 0U;
}
}
}
}
return result;
}
bool CAX25Demodulator::delay(bool b)
{
bool r = m_delayLine[m_delayPos];
m_delayLine[m_delayPos++] = b;
if (m_delayPos >= DELAY_LEN)
m_delayPos = 0U;
return r;
}
bool CAX25Demodulator::NRZI(bool b)
{
bool result = (b == m_nrziState);
m_nrziState = b;
return result;
}
bool CAX25Demodulator::PLL(bool input)
{
bool sample = false;
if (input != m_pllLast || m_pllBits > 16U) {
// Record transition.
m_pllLast = input;
if (m_pllCount > PLL_LIMIT)
m_pllCount -= SAMPLES_PER_SYMBOL;
float32_t offset = m_pllCount / float32_t(m_pllBits);
float32_t jitter;
::arm_fir_f32(&m_pllFilter, &offset, &jitter, 1U);
m_pllCount -= jitter / 2.0F;
m_pllBits = 1U;
} else {
if (m_pllCount > PLL_LIMIT) {
sample = true;
m_pllCount -= SAMPLES_PER_SYMBOL;
m_pllBits++;
}
}
m_pllCount += 1.0F;
return sample;
}
bool CAX25Demodulator::HDLC(bool b)
{
if (m_hdlcOnes == AX25_MAX_ONES) {
if (b) {
// flag byte
m_hdlcFlag = true;
} else {
// bit stuffing...
m_hdlcFlag = false;
m_hdlcOnes = 0U;
return false;
}
}
m_hdlcBuffer >>= 1;
m_hdlcBuffer |= b ? 128U : 0U;
m_hdlcBits++; // Free-running until Sync byte.
if (b)
m_hdlcOnes++;
else
m_hdlcOnes = 0U;
if (m_hdlcFlag) {
bool result = false;
switch (m_hdlcBuffer) {
case AX25_FRAME_END:
if (m_frame.m_length >= AX25_MIN_FRAME_LENGTH) {
result = m_frame.checkCRC();
if (!result)
m_frame.m_length = 0U;
} else {
m_frame.m_length = 0U;
}
m_hdlcState = AX25_SYNC;
m_hdlcFlag = false;
m_hdlcBits = 0U;
break;
case AX25_FRAME_ABORT:
// Frame aborted
m_frame.m_length = 0U;
m_hdlcState = AX25_IDLE;
m_hdlcFlag = false;
m_hdlcBits = 0U;
break;
default:
break;
}
return result;
}
switch (m_hdlcState) {
case AX25_IDLE:
break;
case AX25_SYNC:
if (m_hdlcBits == 8U) { // 8th bit.
// Start of frame data.
m_hdlcState = AX25_RECEIVE;
m_frame.append(m_hdlcBuffer);
m_hdlcBits = 0U;
}
break;
case AX25_RECEIVE:
if (m_hdlcBits == 8U) { // 8th bit.
m_frame.append(m_hdlcBuffer);
m_hdlcBits = 0U;
}
break;
default:
break;
}
return false;
}
void CAX25Demodulator::setTwist(int8_t n)
{
m_twist.setTwist(n);
}
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright (C) 2020 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(AX25Demodulator_H)
#define AX25Demodulator_H
#include "Config.h"
#include "AX25Frame.h"
#include "AX25Twist.h"
enum AX25_STATE {
AX25_IDLE,
AX25_SYNC,
AX25_RECEIVE
};
class CAX25Demodulator {
public:
CAX25Demodulator(int8_t n);
bool process(q15_t* samples, uint8_t length, CAX25Frame& frame);
void setTwist(int8_t n);
private:
CAX25Frame m_frame;
CAX25Twist m_twist;
arm_fir_instance_q15 m_lpfFilter;
q15_t m_lpfState[120U]; // NoTaps + BlockSize - 1, 96 + 20 - 1 plus some spare
bool* m_delayLine;
uint16_t m_delayPos;
bool m_nrziState;
arm_fir_instance_f32 m_pllFilter;
float32_t m_pllState[20U]; // NoTaps + BlockSize - 1, 7 + 1 - 1 plus some spare
bool m_pllLast;
uint8_t m_pllBits;
float32_t m_pllCount;
uint16_t m_hdlcOnes;
bool m_hdlcFlag;
uint16_t m_hdlcBuffer;
uint16_t m_hdlcBits;
AX25_STATE m_hdlcState;
bool delay(bool b);
bool NRZI(bool b);
bool PLL(bool b);
bool HDLC(bool b);
};
#endif
+122
View File
@@ -0,0 +1,122 @@
/*
* Copyright (C) 2020 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 "AX25Frame.h"
const uint16_t CCITT_TABLE[] = {
0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78 };
CAX25Frame::CAX25Frame(const uint8_t* data, uint16_t length) :
m_data(),
m_length(0U),
m_fcs(0U)
{
for (uint16_t i = 0U; i < length && i < (AX25_MAX_PACKET_LEN - 2U); i++)
m_data[m_length++] = data[i];
}
CAX25Frame::CAX25Frame() :
m_data(),
m_length(0U),
m_fcs(0U)
{
}
bool CAX25Frame::append(uint16_t c)
{
if (m_length == AX25_MAX_PACKET_LEN)
return false;
m_data[m_length++] = uint8_t(c);
return true;
}
bool CAX25Frame::checkCRC()
{
union {
uint16_t crc16;
uint8_t crc8[2U];
};
crc16 = 0xFFFFU;
for (uint16_t i = 0U; i < (m_length - 2U); i++)
crc16 = uint16_t(crc8[1U]) ^ CCITT_TABLE[crc8[0U] ^ m_data[i]];
crc16 = ~crc16;
if (crc8[0U] == m_data[m_length - 2U] && crc8[1U] == m_data[m_length - 1U]) {
m_fcs = crc16;
return true;
} else {
return false;
}
}
void CAX25Frame::addCRC()
{
union {
uint16_t crc16;
uint8_t crc8[2U];
};
crc16 = 0xFFFFU;
for (uint16_t i = 0U; i < m_length; i++)
crc16 = uint16_t(crc8[1U]) ^ CCITT_TABLE[crc8[0U] ^ m_data[i]];
crc16 = ~crc16;
m_fcs = crc16;
m_data[m_length++] = crc8[0U];
m_data[m_length++] = crc8[1U];
}
+43
View File
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2020 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(AX25Frame_H)
#define AX25Frame_H
#include "Config.h"
const uint16_t AX25_MAX_PACKET_LEN = 300U;
class CAX25Frame {
public:
CAX25Frame(const uint8_t* data, uint16_t length);
CAX25Frame();
bool append(uint16_t c);
bool checkCRC();
void addCRC();
uint8_t m_data[AX25_MAX_PACKET_LEN];
uint16_t m_length;
uint16_t m_fcs;
};
#endif
+120
View File
@@ -0,0 +1,120 @@
/*
* Copyright (C) 2020 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 "AX25RX.h"
/*
* Generated with Scipy Filter, 152 coefficients, 1100-2300Hz bandpass,
* Hann window, starting and ending 0 value coefficients removed.
*
* np.array(
* firwin2(152,
* [
* 0.0,
* 1000.0/(sample_rate/2),
* 1100.0/(sample_rate/2),
* 2350.0/(sample_rate/2),
* 2500.0/(sample_rate/2),
* 1.0
* ],
* [0,0,1,1,0,0],
* antisymmetric = False,
* window='hann') * 32768,
* dtype=int)[10:-10]
*/
const uint32_t FILTER_LEN = 132;
q15_t FILTER_COEFFS[] = {
0, 5, 12, 18, 21, 19, 11, -2, -15, -25,
-27, -21, -11, -3, -5, -19, -43, -69, -83, -73,
-35, 27, 98, 155, 180, 163, 109, 39, -20, -45,
-26, 23, 74, 89, 39, -81, -247, -407, -501, -480,
-334, -92, 175, 388, 479, 429, 275, 99, 5, 68,
298, 626, 913, 994, 740, 115, -791, -1770, -2544, -2847,
-2509, -1527, -76, 1518, 2875, 3653, 3653, 2875, 1518, -76,
-1527, -2509, -2847, -2544, -1770, -791, 115, 740, 994, 913,
626, 298, 68, 5, 99, 275, 429, 479, 388, 175,
-92, -334, -480, -501, -407, -247, -81, 39, 89, 74,
23, -26, -45, -20, 39, 109, 163, 180, 155, 98,
27, -35, -73, -83, -69, -43, -19, -5, -3, -11,
-21, -27, -25, -15, -2, 11, 19, 21, 18, 12,
5, 0
};
CAX25RX::CAX25RX() :
m_filter(),
m_state(),
m_demod1(3),
m_demod2(6),
m_demod3(9),
m_lastFCS(0U),
m_count(0U)
{
m_filter.numTaps = FILTER_LEN;
m_filter.pState = m_state;
m_filter.pCoeffs = FILTER_COEFFS;
}
void CAX25RX::samples(q15_t* samples, uint8_t length)
{
q15_t output[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_filter, samples, output, RX_BLOCK_SIZE);
m_count++;
CAX25Frame frame;
bool ret = m_demod1.process(output, length, frame);
if (ret) {
if (frame.m_fcs != m_lastFCS || m_count > 2U) {
m_lastFCS = frame.m_fcs;
m_count = 0U;
serial.writeAX25Data(frame.m_data, frame.m_length - 2U);
}
DEBUG1("Decoder 1 reported");
}
ret = m_demod2.process(output, length, frame);
if (ret) {
if (frame.m_fcs != m_lastFCS || m_count > 2U) {
m_lastFCS = frame.m_fcs;
m_count = 0U;
serial.writeAX25Data(frame.m_data, frame.m_length - 2U);
}
DEBUG1("Decoder 2 reported");
}
ret = m_demod3.process(output, length, frame);
if (ret) {
if (frame.m_fcs != m_lastFCS || m_count > 2U) {
m_lastFCS = frame.m_fcs;
m_count = 0U;
serial.writeAX25Data(frame.m_data, frame.m_length - 2U);
}
DEBUG1("Decoder 3 reported");
}
}
void CAX25RX::setParams(int8_t twist)
{
m_demod1.setTwist(twist - 3);
m_demod2.setTwist(twist);
m_demod3.setTwist(twist + 3);
}
+45
View File
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2020 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(AX25RX_H)
#define AX25RX_H
#include "Config.h"
#include "AX25Demodulator.h"
class CAX25RX {
public:
CAX25RX();
void samples(q15_t* samples, uint8_t length);
void setParams(int8_t twist);
private:
arm_fir_instance_q15 m_filter;
q15_t m_state[160U]; // NoTaps + BlockSize - 1, 132 + 20 - 1 plus some spare
CAX25Demodulator m_demod1;
CAX25Demodulator m_demod2;
CAX25Demodulator m_demod3;
uint16_t m_lastFCS;
uint32_t m_count;
};
#endif
+180
View File
@@ -0,0 +1,180 @@
/*
* Copyright (C) 2020 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 "AX25TX.h"
#include "AX25Defines.h"
#include "AX25Frame.h"
const uint8_t START_FLAG[] = { AX25_FRAME_START };
const uint8_t END_FLAG[] = { AX25_FRAME_END };
const uint8_t BIT_MASK_TABLE1[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE1[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE1[(i)&7])
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE1[(i)&7])
const uint8_t BIT_MASK_TABLE2[] = { 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U };
#define WRITE_BIT2(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE2[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE2[(i)&7])
#define READ_BIT2(p,i) (p[(i)>>3] & BIT_MASK_TABLE2[(i)&7])
const uint16_t AUDIO_TABLE_LEN = 120U;
const q15_t AUDIO_TABLE_DATA[] = {
0, 214, 428, 641, 851, 1060, 1265, 1468, 1666, 1859, 2048, 2230, 2407, 2577, 2740, 2896, 3043, 3182, 3313, 3434, 3546, 3649,
3741, 3823, 3895, 3955, 4006, 4045, 4073, 4089, 4095, 4089, 4073, 4045, 4006, 3955, 3895, 3823, 3741, 3649, 3546, 3434, 3313,
3182, 3043, 2896, 2740, 2577, 2407, 2230, 2048, 1859, 1666, 1468, 1265, 1060, 851, 641, 428, 214, 0, -214, -428, -641, -851,
-1060, -1265, -1468, -1666, -1859, -2047, -2230, -2407, -2577, -2740, -2896, -3043, -3182, -3313, -3434, -3546, -3649, -3741,
-3823, -3895, -3955, -4006, -4045, -4073, -4089, -4095, -4089, -4073, -4045, -4006, -3955, -3895, -3823, -3741, -3649, -3546,
-3434, -3313, -3182, -3043, -2896, -2740, -2577, -2407, -2230, -2047, -1859, -1666, -1468, -1265, -1060, -851, -641, -428, -214
};
CAX25TX::CAX25TX() :
m_twist(-6),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(120U),
m_tablePtr(0U),
m_nrzi(false)
{
}
void CAX25TX::process()
{
if (m_poLen == 0U)
return;
uint16_t space = io.getSpace();
while (space > AX25_RADIO_SYMBOL_LENGTH) {
bool b = READ_BIT1(m_poBuffer, m_poPtr) != 0U;
m_poPtr++;
writeBit(b);
space -= AX25_RADIO_SYMBOL_LENGTH;
if (m_poPtr >= m_poLen) {
m_poPtr = 0U;
m_poLen = 0U;
return;
}
}
}
uint8_t CAX25TX::writeData(const uint8_t* data, uint16_t length)
{
CAX25Frame frame(data, length);
frame.addCRC();
m_poLen = 0U;
m_poPtr = 0U;
m_nrzi = false;
m_tablePtr = 0U;
// Add TX delay (already NRZI)
for (uint16_t i = 0U; i < m_txDelay; i++, m_poLen++)
WRITE_BIT1(m_poBuffer, m_poLen, false);
// Add the Start Flag
for (uint16_t i = 0U; i < 8U; i++, m_poLen++) {
bool b1 = READ_BIT1(START_FLAG, i) != 0U;
bool b2 = NRZI(b1);
WRITE_BIT1(m_poBuffer, m_poLen, b2);
}
uint8_t ones = 0U;
for (uint16_t i = 0U; i < (frame.m_length * 8U); i++) {
bool b1 = READ_BIT2(frame.m_data, i) != 0U;
bool b2 = NRZI(b1);
WRITE_BIT1(m_poBuffer, m_poLen, b2);
m_poLen++;
if (b1) {
ones++;
if (ones == AX25_MAX_ONES) {
// Bit stuffing
bool b = NRZI(false);
WRITE_BIT1(m_poBuffer, m_poLen, b);
m_poLen++;
ones = 0U;
}
} else {
ones = 0U;
}
}
// Add the End Flag
for (uint16_t i = 0U; i < 8U; i++, m_poLen++) {
bool b1 = READ_BIT1(END_FLAG, i) != 0U;
bool b2 = NRZI(b1);
WRITE_BIT1(m_poBuffer, m_poLen, b2);
}
return 0U;
}
void CAX25TX::writeBit(bool b)
{
q15_t in[AX25_RADIO_SYMBOL_LENGTH];
for (uint8_t i = 0U; i < AX25_RADIO_SYMBOL_LENGTH; i++) {
in[i] = AUDIO_TABLE_DATA[m_tablePtr];
if (b)
m_tablePtr += 6U;
else
m_tablePtr += 11U;
if (m_tablePtr >= AUDIO_TABLE_LEN)
m_tablePtr -= AUDIO_TABLE_LEN;
}
q15_t out[AX25_RADIO_SYMBOL_LENGTH];
m_twist.process(in, out, AX25_RADIO_SYMBOL_LENGTH);
io.write(STATE_AX25, out, AX25_RADIO_SYMBOL_LENGTH);
}
void CAX25TX::setParams(int8_t twist)
{
m_twist.setTwist(twist);
}
void CAX25TX::setTXDelay(uint8_t delay)
{
m_txDelay = delay * 12U;
}
uint8_t CAX25TX::getSpace() const
{
return m_poLen == 0U ? 255U : 0U;
}
bool CAX25TX::NRZI(bool b)
{
bool result = (b == m_nrzi);
m_nrzi = b;
return result;
}
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2020 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(AX25TX_H)
#define AX25TX_H
#include "Config.h"
#include "AX25Twist.h"
class CAX25TX {
public:
CAX25TX();
uint8_t writeData(const uint8_t* data, uint16_t length);
void process();
void setParams(int8_t twist);
void setTXDelay(uint8_t delay);
uint8_t getSpace() const;
private:
CAX25Twist m_twist;
uint8_t m_poBuffer[600U];
uint16_t m_poLen;
uint16_t m_poPtr;
uint16_t m_txDelay;
uint16_t m_tablePtr;
bool m_nrzi;
void writeBit(bool b);
bool NRZI(bool b);
};
#endif
+311
View File
@@ -0,0 +1,311 @@
/*
* Copyright (C) 2020 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 "AX25Twist.h"
// 1200Hz = -12dB, 2200Hz = 0dB; 3381Hz cutoff; cosine.
q15_t dB12[] = {
176,
-812,
-3916,
-7586,
23536,
-7586,
-3916,
-812,
176
};
// 1200Hz = -11dB, 2200Hz = 0dB; 3258Hz cutoff; cosine.
q15_t dB11[] = {
121,
-957,
-3959,
-7383,
23871,
-7383,
-3959,
-957,
121
};
// 1200Hz = -10dB, 2200Hz = 0dB; 3118Hz cutoff; cosine.
q15_t dB10[] = {
56,
-1110,
-3987,
-7141,
24254,
-7141,
-3987,
-1110,
56
};
// 1200Hz = -9dB, 2200Hz = 0dB; 2959Hz cutoff; cosine.
q15_t dB9[] = {
-19,
-1268,
-3994,
-6856,
24688,
-6856,
-3994,
-1268,
-19
};
// 1200Hz = -8dB, 2200Hz = 0dB; 2778Hz cutoff; cosine.
q15_t dB8[] = {
-104,
-1424,
-3968,
-6516,
25182,
-6516,
-3968,
-1424,
-104
};
// 1200Hz = -7dB, 2200Hz = 0dB; 2573Hz cutoff; cosine.
q15_t dB7[] = {
-196,
-1565,
-3896,
-6114,
25742,
-6114,
-3896,
-1565,
-196
};
// 1200Hz = -6dB, 2200Hz = 0dB; 2343Hz cutoff; cosine.
q15_t dB6[] = {
-288,
-1676,
-3761,
-5642,
26370,
-5642,
-3761,
-1676,
-288
};
// 1200Hz = -5dB, 2200Hz = 0dB; 2085Hz cutoff; cosine.
q15_t dB5[] = {
-370,
-1735,
-3545,
-5088,
27075,
-5088,
-3545,
-1735,
-370
};
// 1200Hz = -4dB, 2200Hz = 0dB; 1790Hz cutoff; cosine.
q15_t dB4[] = {
-432,
-1715,
-3220,
-4427,
27880,
-4427,
-3220,
-1715,
-432
};
// 1200Hz = -3dB, 2200Hz = 0dB; 1456Hz cutoff; cosine.
q15_t dB3[] = {
-452,
-1582,
-2759,
-3646,
28792,
-3646,
-2759,
-1582,
-452
};
// 1200Hz = -2dB, 2200Hz = 0dB; 1070Hz cutoff; cosine.
q15_t dB2[] = {
-408,
-1295,
-2123,
-2710,
29846,
-2710,
-2123,
-1295,
-408
};
// 1200Hz = -1dB, 2200Hz = 0dB; 605Hz cutoff; cosine.
q15_t dB1[] = {
-268,
-795,
-1244,
-1546,
31116,
-1546,
-1244,
-795,
-268
};
q15_t dB0[] = {
0,
0,
0,
0,
32767,
0,
0,
0,
0,
};
// 1200Hz = 0dB, 2200Hz = -1dB; 4130Hz cutoff; cosine.
q15_t dB_1[] = {
-419,
-177,
3316,
8650,
11278,
8650,
3316,
-177,
-419
};
// 1200Hz = 0dB, 2200Hz = -2dB; 3190Hz cutoff; cosine.
q15_t dB_2[] = {
-90,
1033,
3975,
7267,
8711,
7267,
3975,
1033,
-90
};
// 1200Hz = 0dB, 2200Hz = -3dB; 2330Hz cutoff; cosine.
q15_t dB_3[] = {
292,
1680,
3752,
5615,
6362,
5615,
3752,
1680,
292
};
// 1200Hz = 0dB, 2200Hz = -4dB; 2657Hz cutoff; boxcar.
q15_t dB_4[] = {
917,
3024,
5131,
6684,
7255,
6684,
5131,
3024,
917
};
// 1200Hz = 0dB, 2200Hz = -5dB; 2360Hz cutoff; boxcar.
q15_t dB_5[] = {
1620,
3339,
4925,
6042,
6444,
6042,
4925,
3339,
1620
};
// 1200Hz = 0dB, 2200Hz = -6dB; 2067Hz cutoff; boxcar.
q15_t dB_6[] = {
2161,
3472,
4605,
5373,
5644,
5373,
4605,
3472,
2161
};
q15_t* coeffs[] = {
dB12,
dB11,
dB10,
dB9,
dB8,
dB7,
dB6,
dB5,
dB4,
dB3,
dB2,
dB1,
dB0,
dB_1,
dB_2,
dB_3,
dB_4,
dB_5,
dB_6
};
CAX25Twist::CAX25Twist(int8_t n) :
m_filter(),
m_state()
{
setTwist(n);
}
void CAX25Twist::process(q15_t* in, q15_t* out, uint8_t length)
{
::arm_fir_fast_q15(&m_filter, in, out, length);
}
void CAX25Twist::setTwist(int8_t n)
{
uint8_t twist = uint8_t(n + 6);
m_filter.numTaps = 9;
m_filter.pState = m_state;
m_filter.pCoeffs = coeffs[twist];
}
+39
View File
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2020 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(AX25Twist_H)
#define AX25Twist_H
#include "Config.h"
class CAX25Twist {
public:
CAX25Twist(int8_t n);
void process(q15_t* in, q15_t* out, uint8_t length);
void setTwist(int8_t n);
private:
arm_fir_instance_q15 m_filter;
q15_t m_state[40U]; // NoTaps + BlockSize - 1, 9 + 20 - 1 plus some spare
};
#endif
+8 -8
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2017,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
@@ -22,12 +22,12 @@
#include "CWIdTX.h"
q15_t TONE[] = {
0, 261, 518, 765, 1000, 1218, 1414, 1587, 1732, 1848, 1932, 1983, 2000, 1983, 1932, 1848, 1732, 1587, 1414, 1218, 1000, 765, 518, 261, 0, -261, -518, -765, -1000, -1218, -1414,
-1587, -1732, -1848, -1932, -1983, -2000, -1983, -1932, -1848, -1732, -1587, -1414, -1218, -1000, -765, -518, -261};
q15_t SILENCE[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0, 518, 1000, 1414, 1732, 1932, 2000, 1932, 1732, 1414, 1000, 518, 0, -518, -1000, -1414, -1732, -1932, -2000, -1932, -1732, -1414, -1000, -518};
const uint8_t CYCLE_LENGTH = 48U;
q15_t SILENCE[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const uint8_t CYCLE_LENGTH = 24U;
const uint8_t DOT_LENGTH = 50U;
@@ -77,6 +77,7 @@ const struct {
{',', 0xEEAEE000U, 22U},
{'-', 0xEAAE0000U, 18U},
{'=', 0xEAB80000U, 16U},
{'.', 0xBAEB8000U, 20U},
{' ', 0x00000000U, 4U},
{0U, 0x00000000U, 0U}
};
@@ -124,7 +125,7 @@ void CCWIdTX::process()
}
}
uint8_t CCWIdTX::write(const uint8_t* data, uint8_t length)
uint8_t CCWIdTX::write(const uint8_t* data, uint16_t length)
{
::memset(m_poBuffer, 0x00U, 1000U * sizeof(uint8_t));
@@ -170,4 +171,3 @@ void CCWIdTX::reset()
m_poPtr = 0U;
m_n = 0U;
}
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2009-2015 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
* Copyright (C) 2016,2020 by Colin Durbridge G4EML
*
* 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
@@ -28,7 +28,7 @@ public:
void process();
uint8_t write(const uint8_t* data, uint8_t length);
uint8_t write(const uint8_t* data, uint16_t length);
void reset();
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2015 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2015,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
@@ -208,7 +208,7 @@ void CCalDMR::dmrdmo1k()
}
}
uint8_t CCalDMR::write(const uint8_t* data, uint8_t length)
uint8_t CCalDMR::write(const uint8_t* data, uint16_t length)
{
if (length != 1U)
return 4U;
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2015 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2015,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
@@ -41,7 +41,7 @@ public:
void createData1k(uint8_t n);
void createDataDMO1k(uint8_t n);
uint8_t write(const uint8_t* data, uint8_t length);
uint8_t write(const uint8_t* data, uint16_t length);
private:
bool m_transmit;
+1 -1
View File
@@ -24,7 +24,7 @@
const unsigned int BUFFER_LENGTH = 200U;
const uint32_t PLLMAX = 0x10000U;
const uint32_t PLLINC = PLLMAX / DSTAR_RADIO_SYMBOL_LENGTH;
const uint32_t PLLINC = PLLMAX / DSTAR_RADIO_BIT_LENGTH;
const uint32_t INC = PLLINC / 32U;
// D-Star bit order version of 0x55 0x2D 0x16
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2016 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2016,2020 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
@@ -162,7 +162,7 @@ void CCalDStarTX::process()
m_count = (m_count + 1U) % (30U * 21U);
}
uint8_t CCalDStarTX::write(const uint8_t* data, uint8_t length)
uint8_t CCalDStarTX::write(const uint8_t* data, uint16_t length)
{
if (length != 1U)
return 4U;
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2020 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
@@ -26,7 +26,7 @@ class CCalDStarTX {
public:
CCalDStarTX();
uint8_t write(const uint8_t* data, uint8_t length);
uint8_t write(const uint8_t* data, uint16_t length);
void process();
+127
View File
@@ -0,0 +1,127 @@
/*
* Copyright (C) 2009-2015,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
* Copyright (C) 2020 by Phil Taylor M0VSE
*
* 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 "CalFM.h"
const struct TONE_TABLE {
uint16_t frequency;
uint16_t length;
q31_t increment;
} TONE_TABLE_DATA[] = {
{2495U, 10U, 223248821},
{2079U, 12U, 186025772},
{1633U, 15U, 146118367},
{1247U, 19U, 111579672},
{1039U, 23U, 93012886},
{956U, 25U, 85541432}};
const uint8_t TONE_TABLE_DATA_LEN = 6U;
CCalFM::CCalFM() :
m_frequency(0),
m_length(0),
m_tone(NULL),
m_level(128 * 12),
m_transmit(false),
m_audioSeq(0),
m_lastState(STATE_IDLE)
{
}
void CCalFM::process()
{
const TONE_TABLE* entry = NULL;
if (m_modemState!=m_lastState)
{
switch (m_modemState) {
case STATE_FMCAL10K:
m_frequency = 956U;
break;
case STATE_FMCAL12K:
m_frequency = 1039U;
break;
case STATE_FMCAL15K:
m_frequency = 1247U;
break;
case STATE_FMCAL20K:
m_frequency = 1633U;
break;
case STATE_FMCAL25K:
m_frequency = 2079U;
break;
case STATE_FMCAL30K:
m_frequency = 2495U;
break;
default:
m_frequency = 0U;
break;
}
for (uint8_t i = 0U; i < TONE_TABLE_DATA_LEN; i++) {
if (TONE_TABLE_DATA[i].frequency == m_frequency) {
entry = TONE_TABLE_DATA + i;
break;
}
}
if (entry == NULL)
return;
m_length = entry->length;
delete[] m_tone;
m_tone = new q15_t[m_length];
q31_t arg = 0;
for (uint16_t i = 0U; i < m_length; i++) {
q63_t value = ::arm_sin_q31(arg) * q63_t(m_level);
m_tone[i] = q15_t(__SSAT((value >> 31), 16));
arg += entry->increment;
}
m_lastState=m_modemState;
}
if (m_transmit)
{
uint16_t space = io.getSpace();
while (space > m_length)
{
io.write(m_modemState,m_tone,m_length);
space -= m_length;
}
}
}
uint8_t CCalFM::write(const uint8_t* data, uint16_t length)
{
if (length != 1U)
return 4U;
m_transmit = data[0U] == 1U;
return 0U;
}
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2009-2015,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
* Copyright (C) 2020 by Phil Taylor M0VSE
*
* 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(CALFM_H)
#define CALFM_H
#include "Config.h"
class CCalFM {
public:
CCalFM();
void process();
void fm10kcal();
void fm12k5cal();
void fm15kcal();
void fm20kcal();
void fm25kcal();
void fm30kcal();
uint8_t write(const uint8_t* data, uint16_t length);
private:
uint16_t m_frequency;
uint16_t m_length;
q15_t* m_tone;
q15_t m_level;
bool m_transmit;
uint8_t m_audioSeq;
uint8_t m_lastState;
};
#endif
+2 -1
View File
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 by Andy Uribe CA6JAU
* Copyright (C) 2020 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
@@ -79,7 +80,7 @@ void CCalNXDN::process()
}
}
uint8_t CCalNXDN::write(const uint8_t* data, uint8_t length)
uint8_t CCalNXDN::write(const uint8_t* data, uint16_t length)
{
if (length != 1U)
return 4U;
+2 -1
View File
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 by Andy Uribe CA6JAU
* Copyright (C) 2020 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
@@ -32,7 +33,7 @@ public:
void process();
uint8_t write(const uint8_t* data, uint8_t length);
uint8_t write(const uint8_t* data, uint16_t length);
private:
bool m_transmit;
+2 -1
View File
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 by Andy Uribe CA6JAU
* Copyright (C) 2020 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
@@ -82,7 +83,7 @@ void CCalP25::process()
}
}
uint8_t CCalP25::write(const uint8_t* data, uint8_t length)
uint8_t CCalP25::write(const uint8_t* data, uint16_t length)
{
if (length != 1U)
return 4U;
+2 -1
View File
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018 by Andy Uribe CA6JAU
* Copyright (C) 2020 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,7 +35,7 @@ public:
void process();
uint8_t write(const uint8_t* data, uint8_t length);
uint8_t write(const uint8_t* data, uint16_t length);
private:
bool m_transmit;
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2019 by Florian Wolters DF2ET
* Copyright (C) 2020 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 "CalPOCSAG.h"
CCalPOCSAG::CCalPOCSAG() :
m_state(POCSAGCAL_IDLE)
{
}
void CCalPOCSAG::process()
{
if (m_state == POCSAGCAL_IDLE)
return;
uint16_t space = io.getSpace();
if (space <= 165U)
return;
pocsagTX.writeByte(0xAAU);
}
uint8_t CCalPOCSAG::write(const uint8_t* data, uint16_t length)
{
if (length != 1U)
return 4U;
m_state = data[0U] == 1U ? POCSAGCAL_TX : POCSAGCAL_IDLE;
return 0U;
}
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2019 by Florian Wolters DF2ET
* Copyright (C) 2020 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(CALPOCSAG_H)
#define CALPOCSAG_H
#include "Config.h"
enum POCSAGCAL {
POCSAGCAL_IDLE,
POCSAGCAL_TX
};
class CCalPOCSAG {
public:
CCalPOCSAG();
void process();
uint8_t write(const uint8_t* data, uint16_t length);
private:
POCSAGCAL m_state;
};
#endif
+13 -14
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020 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
@@ -35,27 +35,26 @@
// For 19.2 MHz
// #define EXTERNAL_OSC 19200000
// Allow the use of the COS line to lockout the modem
// #define USE_COS_AS_LOCKOUT
// Use pins to output the current mode via LEDs
// #define MODE_LEDS
#define MODE_LEDS
// For the original Arduino Due pin layout
// #define ARDUINO_DUE_PAPA
// For the ZUM V1.0 and V1.0.1 boards pin layout
// #define ARDUINO_DUE_ZUM_V10
#if defined(STM32F1)
// For the SQ6POG board
// #define STM32F1_POG
#define STM32F1_POG
#else
// For the ZUM V1.0 and V1.0.1 boards pin layout
#define ARDUINO_DUE_ZUM_V10
#endif
// For the SP8NTH board
// #define ARDUINO_DUE_NTH
// For ST Nucleo-64 STM32F446RE board
// #define STM32F4_NUCLEO_MORPHO_HEADER
#define STM32F4_NUCLEO_ARDUINO_HEADER
// #define STM32F4_NUCLEO_ARDUINO_HEADER
// Use separate mode pins to switch external channel/filters/bandwidth for example
// #define MODE_PINS
@@ -64,13 +63,13 @@
// #define VK6MST_TEENSY_PI3_SHIELD_I2C
// Pass RSSI information to the host
#define SEND_RSSI_DATA
// #define SEND_RSSI_DATA
// Use the modem as a serial repeater for Nextion displays
// #define SERIAL_REPEATER
// To reduce CPU load, you can remove the DC blocker by commenting out the next line
// #define USE_DCBLOCKER
#define USE_DCBLOCKER
// Constant Service LED once repeater is running
// Do not use if employing an external hardware watchdog
@@ -82,7 +81,7 @@
// Use the D-Star and DMR LEDs for POCSAG
// #define USE_ALTERNATE_POCSAG_LEDS
// Select BOXCAR Filter into D-Star
// #define DSTARBOXCAR
// Use the D-Star and YSF LEDs for FM
#define USE_ALTERNATE_FM_LEDS
#endif
+1 -1
View File
@@ -22,7 +22,7 @@
#include "Config.h"
#include "DMRDefines.h"
const uint16_t DMO_BUFFER_LENGTH_SAMPLES = 2880U; // 60ms at 48 kHz
const uint16_t DMO_BUFFER_LENGTH_SAMPLES = 1440U; // 60ms at 24 kHz
enum DMORX_STATE {
DMORXS_NONE,
+7 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2017,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
* Copyright (C) 2017 by Andy Uribe CA6JAU
*
@@ -22,16 +22,10 @@
#include "Globals.h"
#include "DMRSlotType.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
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 850, 219, -720, -1548, -1795, -1172, 237, 1927, 3120, 3073, 1447, -1431, -4544, -6442,
-5735, -1633, 5651, 14822, 23810, 30367, 32767, 30367, 23810, 14822, 5651, -1633, -5735, -6442,
-4544, -1431, 1447, 3073, 3120, 1927, 237, -1172, -1795, -1548, -720, 219, 850}; // numTaps = 45, L = 5
const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
const q15_t DMR_LEVELA = 1362;
@@ -110,7 +104,7 @@ void CDMRDMOTX::process()
}
}
uint8_t CDMRDMOTX::writeData(const uint8_t* data, uint8_t length)
uint8_t CDMRDMOTX::writeData(const uint8_t* data, uint16_t length)
{
if (length != (DMR_FRAME_LENGTH_BYTES + 1U))
return 4U;
@@ -166,3 +160,4 @@ void CDMRDMOTX::setTXDelay(uint8_t delay)
if (m_txDelay > 1200U)
m_txDelay = 1200U;
}
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
@@ -29,7 +29,7 @@ class CDMRDMOTX {
public:
CDMRDMOTX();
uint8_t writeData(const uint8_t* data, uint8_t length);
uint8_t writeData(const uint8_t* data, uint16_t length);
void process();
+2 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2016 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,7 +19,7 @@
#if !defined(DMRDEFINES_H)
#define DMRDEFINES_H
const unsigned int DMR_RADIO_SYMBOL_LENGTH = 10U; // At 48 kHz sample rate
const unsigned int DMR_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
const unsigned int DMR_FRAME_LENGTH_BYTES = 33U;
const unsigned int DMR_FRAME_LENGTH_BITS = DMR_FRAME_LENGTH_BYTES * 8U;
+2 -2
View File
@@ -24,8 +24,8 @@
const q15_t SCALING_FACTOR = 19505; // Q15(0.60)
const uint8_t MAX_SYNC_SYMBOLS_ERRS = 4U;
const uint8_t MAX_SYNC_BYTES_ERRS = 6U;
const uint8_t MAX_SYNC_SYMBOLS_ERRS = 2U;
const uint8_t MAX_SYNC_BYTES_ERRS = 3U;
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
+6 -6
View File
@@ -22,15 +22,15 @@
#include "DMRSlotType.h"
#include "Utils.h"
const uint16_t SCAN_START = 790U;
const uint16_t SCAN_END = 920U;
const uint16_t SCAN_START = 400U;
const uint16_t SCAN_END = 490U;
const q15_t SCALING_FACTOR = 19505; // Q15(0.60)
const uint8_t MAX_SYNC_SYMBOLS_ERRS = 4U;
const uint8_t MAX_SYNC_BYTES_ERRS = 6U;
const uint8_t MAX_SYNC_SYMBOLS_ERRS = 2U;
const uint8_t MAX_SYNC_BYTES_ERRS = 3U;
const uint8_t MAX_SYNC_LOST_FRAMES = 26U;
const uint8_t MAX_SYNC_LOST_FRAMES = 13U;
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
@@ -97,7 +97,7 @@ bool CDMRSlotRX::processSample(q15_t sample, uint16_t rssi)
return m_state != DMRRXS_NONE;
// Ensure that the buffer doesn't overflow
if (m_dataPtr > m_endPtr || m_dataPtr >= 1900U)
if (m_dataPtr > m_endPtr || m_dataPtr >= 900U)
return m_state != DMRRXS_NONE;
m_buffer[m_dataPtr] = sample;
+2 -2
View File
@@ -44,7 +44,7 @@ public:
private:
bool m_slot;
uint32_t m_bitBuffer[DMR_RADIO_SYMBOL_LENGTH];
q15_t m_buffer[1900U];
q15_t m_buffer[900U];
uint16_t m_bitPtr;
uint16_t m_dataPtr;
uint16_t m_syncPtr;
@@ -62,7 +62,7 @@ private:
DMRRX_STATE m_state;
uint8_t m_n;
uint8_t m_type;
uint16_t m_rssi[1900U];
uint16_t m_rssi[900U];
void correlateSync(bool first);
void samplesToBits(uint16_t start, uint8_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold);
+9 -15
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2017,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
* Copyright (C) 2017 by Andy Uribe CA6JAU
*
@@ -22,16 +22,10 @@
#include "Globals.h"
#include "DMRSlotType.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
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 850, 219, -720, -1548, -1795, -1172, 237, 1927, 3120, 3073, 1447, -1431, -4544, -6442,
-5735, -1633, 5651, 14822, 23810, 30367, 32767, 30367, 23810, 14822, 5651, -1633, -5735, -6442,
-4544, -1431, 1447, 3073, 3120, 1927, 237, -1172, -1795, -1548, -720, 219, 850}; // numTaps = 45, L = 5
const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
const q15_t DMR_LEVELA = 1362;
@@ -150,7 +144,7 @@ void CDMRTX::process()
}
}
uint8_t CDMRTX::writeData1(const uint8_t* data, uint8_t length)
uint8_t CDMRTX::writeData1(const uint8_t* data, uint16_t length)
{
if (length != (DMR_FRAME_LENGTH_BYTES + 1U))
return 4U;
@@ -174,7 +168,7 @@ uint8_t CDMRTX::writeData1(const uint8_t* data, uint8_t length)
return 0U;
}
uint8_t CDMRTX::writeData2(const uint8_t* data, uint8_t length)
uint8_t CDMRTX::writeData2(const uint8_t* data, uint16_t length)
{
if (length != (DMR_FRAME_LENGTH_BYTES + 1U))
return 4U;
@@ -198,7 +192,7 @@ uint8_t CDMRTX::writeData2(const uint8_t* data, uint8_t length)
return 0U;
}
uint8_t CDMRTX::writeShortLC(const uint8_t* data, uint8_t length)
uint8_t CDMRTX::writeShortLC(const uint8_t* data, uint16_t length)
{
if (length != 9U)
return 4U;
@@ -214,7 +208,7 @@ uint8_t CDMRTX::writeShortLC(const uint8_t* data, uint8_t length)
return 0U;
}
uint8_t CDMRTX::writeAbort(const uint8_t* data, uint8_t length)
uint8_t CDMRTX::writeAbort(const uint8_t* data, uint16_t length)
{
if (length != 1U)
return 4U;
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
@@ -38,11 +38,11 @@ class CDMRTX {
public:
CDMRTX();
uint8_t writeData1(const uint8_t* data, uint8_t length);
uint8_t writeData2(const uint8_t* data, uint8_t length);
uint8_t writeData1(const uint8_t* data, uint16_t length);
uint8_t writeData2(const uint8_t* data, uint16_t length);
uint8_t writeShortLC(const uint8_t* data, uint8_t length);
uint8_t writeAbort(const uint8_t* data, uint8_t length);
uint8_t writeShortLC(const uint8_t* data, uint16_t length);
uint8_t writeAbort(const uint8_t* data, uint16_t length);
void setStart(bool start);
void setCal(bool start);
+17 -37
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2015,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2015 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,50 +19,30 @@
#if !defined(DSTARDEFINES_H)
#define DSTARDEFINES_H
const unsigned int DSTAR_RADIO_SYMBOL_LENGTH = 10U; // At 48 kHz sample rate
const unsigned int DSTAR_RADIO_BIT_LENGTH = 5U; // At 24 kHz sample rate
const unsigned int DSTAR_HEADER_LENGTH_BYTES = 41U;
const unsigned int DSTAR_HEADER_LENGTH_BYTES = 41U;
const unsigned int DSTAR_HEADER_LENGTH_BITS = DSTAR_HEADER_LENGTH_BYTES * 8U;
const unsigned int DSTAR_FEC_SECTION_LENGTH_BYTES = 83U;
const unsigned int DSTAR_FEC_SECTION_LENGTH_SYMBOLS = 660U;
const unsigned int DSTAR_FEC_SECTION_LENGTH_SAMPLES = DSTAR_FEC_SECTION_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
const unsigned int DSTAR_FEC_SECTION_LENGTH_BYTES = 83U;
const unsigned int DSTAR_FEC_SECTION_LENGTH_BITS = 660U;
const unsigned int DSTAR_DATA_LENGTH_BYTES = 12U;
const unsigned int DSTAR_DATA_LENGTH_SYMBOLS = DSTAR_DATA_LENGTH_BYTES * 8U;
const unsigned int DSTAR_DATA_LENGTH_SAMPLES = DSTAR_DATA_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
const unsigned int DSTAR_DATA_LENGTH_BYTES = 12U;
const unsigned int DSTAR_DATA_LENGTH_BITS = DSTAR_DATA_LENGTH_BYTES * 8U;
const unsigned int DSTAR_END_SYNC_LENGTH_BYTES = 6U;
const unsigned int DSTAR_END_SYNC_LENGTH_BITS = DSTAR_END_SYNC_LENGTH_BYTES * 8U;
const uint8_t DSTAR_EOT_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned int DSTAR_EOT_LENGTH_BYTES = 6U;
const unsigned int DSTAR_EOT_LENGTH_BITS = DSTAR_EOT_LENGTH_BYTES * 8U;
const unsigned int DSTAR_FRAME_SYNC_LENGTH_BYTES = 3U;
const unsigned int DSTAR_FRAME_SYNC_LENGTH_SYMBOLS = DSTAR_FRAME_SYNC_LENGTH_BYTES * 8U;
const unsigned int DSTAR_FRAME_SYNC_LENGTH_SAMPLES = DSTAR_FRAME_SYNC_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
const uint8_t DSTAR_DATA_SYNC_LENGTH_BYTES = 3U;
const uint8_t DSTAR_DATA_SYNC_LENGTH_BITS = DSTAR_DATA_SYNC_LENGTH_BYTES * 8U;
const unsigned int DSTAR_DATA_SYNC_LENGTH_BYTES = 3U;
const unsigned int DSTAR_DATA_SYNC_LENGTH_SYMBOLS = DSTAR_DATA_SYNC_LENGTH_BYTES * 8U;
const unsigned int DSTAR_DATA_SYNC_LENGTH_SAMPLES = DSTAR_DATA_SYNC_LENGTH_SYMBOLS * DSTAR_RADIO_SYMBOL_LENGTH;
const uint8_t DSTAR_DATA_SYNC_BYTES[] = {0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x55, 0x2D, 0x16};
const uint8_t DSTAR_DATA_SYNC_BYTES[] = {0x9E, 0x8D, 0x32, 0x88, 0x26, 0x1A, 0x3F, 0x61, 0xE8, 0x55, 0x2D, 0x16};
const uint8_t DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U;
const uint8_t DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U;
// D-Star bit order version of 0x55 0x6E 0x0A
const uint32_t DSTAR_FRAME_SYNC_DATA = 0x00557650U;
const uint32_t DSTAR_FRAME_SYNC_MASK = 0x00FFFFFFU;
const bool DSTAR_FRAME_SYNC_SYMBOLS[] = {false, true, false, true, false, true, false, true, false, true, true, true, false, true, true, false, false, true, false, true, false, false, false, false};
// D-Star bit order version of 0x55 0x2D 0x16
const uint32_t DSTAR_DATA_SYNC_DATA = 0x00AAB468U;
const uint32_t DSTAR_DATA_SYNC_MASK = 0x00FFFFFFU;
const bool DSTAR_DATA_SYNC_SYMBOLS[] = {true, false, true, false, true, false, true, false, true, false, true, true, false, true, false, false, false, true, true, false, true, false, false, false};
// D-Star bit order version of 0x55 0x55 0xC8 0x7A
const uint32_t DSTAR_END_SYNC_DATA = 0xAAAA135EU;
const uint32_t DSTAR_END_SYNC_MASK = 0xFFFFFFFFU;
const uint8_t DSTAR_END_SYNC_BYTES[] = {0x55, 0x55, 0x55, 0x55, 0xC8, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U;
const uint8_t DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U;
const uint8_t DSTAR_SCRAMBLER_BYTES[] = {0x70U, 0x4FU, 0x93U};
const uint8_t DSTAR_SCRAMBLER_BYTES[] = {0x70U, 0x4FU, 0x93U};
#endif
+136 -238
View File
@@ -1,4 +1,3 @@
/*
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
* Copyright (C) 2017 by Andy Uribe CA6JAU
@@ -23,12 +22,18 @@
#include "DStarRX.h"
#include "Utils.h"
const unsigned int MAX_FRAMES = 150U;
const unsigned int BUFFER_LENGTH = 200U;
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 = 100U * DSTAR_DATA_LENGTH_BITS;
// D-Star bit order version of 0x55 0x55 0x6E 0x0A
const uint32_t FRAME_SYNC_DATA = 0x00557650U;
const uint32_t FRAME_SYNC_MASK = 0x00FFFFFFU;
const uint8_t FRAME_SYNC_ERRS = 1U;
const uint8_t FRAME_SYNC_ERRS = 2U;
// D-Star bit order version of 0x55 0x2D 0x16
const uint32_t DATA_SYNC_DATA = 0x00AAB468U;
@@ -232,24 +237,14 @@ const uint16_t CCITT_TABLE[] = {
0xf78fU, 0xe606U, 0xd49dU, 0xc514U, 0xb1abU, 0xa022U, 0x92b9U, 0x8330U,
0x7bc7U, 0x6a4eU, 0x58d5U, 0x495cU, 0x3de3U, 0x2c6aU, 0x1ef1U, 0x0f78U};
const uint16_t NOENDPTR = 9999U;
CDStarRX::CDStarRX() :
m_pll(0U),
m_prev(false),
m_rxState(DSRXS_NONE),
m_bitBuffer(),
m_headerBuffer(),
m_dataBuffer(),
m_bitPtr(0U),
m_headerPtr(0U),
m_dataPtr(0U),
m_startPtr(NOENDPTR),
m_syncPtr(NOENDPTR),
m_minSyncPtr(NOENDPTR),
m_maxSyncPtr(NOENDPTR),
m_maxFrameCorr(0),
m_maxDataCorr(0),
m_frameCount(0U),
m_countdown(0U),
m_patternBuffer(0x00U),
m_rxBuffer(),
m_rxBufferBits(0U),
m_dataBits(0U),
m_mar(0U),
m_pathMetric(),
m_pathMemory0(),
@@ -264,20 +259,14 @@ m_rssiCount(0U)
void CDStarRX::reset()
{
m_rxState = DSRXS_NONE;
m_headerPtr = 0U;
m_dataPtr = 0U;
m_bitPtr = 0U;
m_maxFrameCorr = 0;
m_maxDataCorr = 0;
m_startPtr = NOENDPTR;
m_syncPtr = NOENDPTR;
m_minSyncPtr = NOENDPTR;
m_maxSyncPtr = NOENDPTR;
m_frameCount = 0U;
m_countdown = 0U;
m_rssiAccum = 0U;
m_rssiCount = 0U;
m_pll = 0U;
m_prev = false;
m_rxState = DSRXS_NONE;
m_patternBuffer = 0x00U;
m_rxBufferBits = 0U;
m_dataBits = 0U;
m_rssiAccum = 0U;
m_rssiCount = 0U;
}
void CDStarRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t length)
@@ -286,117 +275,125 @@ void CDStarRX::samples(const q15_t* samples, const uint16_t* rssi, uint8_t lengt
m_rssiAccum += rssi[i];
m_rssiCount++;
q15_t sample = samples[i];
bool bit = samples[i] < 0;
m_bitBuffer[m_bitPtr] <<= 1;
if (sample < 0)
m_bitBuffer[m_bitPtr] |= 0x01U;
m_dataBuffer[m_dataPtr] = sample;
switch (m_rxState) {
case DSRXS_HEADER:
processHeader(sample);
break;
case DSRXS_DATA:
processData();
break;
default:
processNone(sample);
break;
if (bit != m_prev) {
if (m_pll < (PLLMAX / 2U))
m_pll += INC;
else
m_pll -= INC;
}
m_dataPtr++;
if (m_dataPtr >= DSTAR_DATA_LENGTH_SAMPLES)
m_dataPtr = 0U;
m_prev = bit;
m_bitPtr++;
if (m_bitPtr >= DSTAR_RADIO_SYMBOL_LENGTH)
m_bitPtr = 0U;
m_pll += PLLINC;
if (m_pll >= PLLMAX) {
m_pll -= PLLMAX;
switch (m_rxState) {
case DSRXS_NONE:
processNone(bit);
break;
case DSRXS_HEADER:
processHeader(bit);
break;
case DSRXS_DATA:
processData(bit);
break;
default:
break;
}
}
}
}
void CDStarRX::processNone(q15_t sample)
void CDStarRX::processNone(bool bit)
{
m_patternBuffer <<= 1;
if (bit)
m_patternBuffer |= 0x01U;
// Fuzzy matching of the frame sync sequence
bool ret = correlateFrameSync();
if (ret) {
m_countdown = 5U;
m_headerBuffer[m_headerPtr] = sample;
m_headerPtr++;
if (countBits32((m_patternBuffer & FRAME_SYNC_MASK) ^ FRAME_SYNC_DATA) <= FRAME_SYNC_ERRS) {
DEBUG1("DStarRX: found frame sync in None");
::memset(m_rxBuffer, 0x00U, DSTAR_FEC_SECTION_LENGTH_BYTES);
m_rxBufferBits = 0U;
m_rssiAccum = 0U;
m_rssiCount = 0U;
m_rxState = DSRXS_HEADER;
return;
}
// Fuzzy matching of the data sync bit sequence
ret = correlateDataSync();
if (ret) {
// Exact matching of the data sync bit sequence
if (countBits32((m_patternBuffer & DATA_SYNC_MASK) ^ DATA_SYNC_DATA) == 0U) {
DEBUG1("DStarRX: found data sync in None");
io.setDecode(true);
io.setADCDetection(true);
m_rxState = DSRXS_DATA;
// Suppress RSSI on the dummy sync message
m_rssiAccum = 0U;
m_rssiCount = 0U;
::memcpy(m_rxBuffer, DSTAR_DATA_SYNC_BYTES, DSTAR_DATA_LENGTH_BYTES);
writeRSSIData(m_rxBuffer);
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
m_rxBufferBits = 0U;
m_dataBits = MAX_SYNC_BITS;
m_rxState = DSRXS_DATA;
return;
}
}
void CDStarRX::processHeader(q15_t sample)
void CDStarRX::processHeader(bool bit)
{
if (m_countdown > 0U) {
correlateFrameSync();
m_countdown--;
}
m_patternBuffer <<= 1;
if (bit)
m_patternBuffer |= 0x01U;
m_headerBuffer[m_headerPtr] = sample;
m_headerPtr++;
WRITE_BIT2(m_rxBuffer, m_rxBufferBits, bit);
m_rxBufferBits++;
// A full FEC header
if (m_headerPtr == (DSTAR_FEC_SECTION_LENGTH_SAMPLES + DSTAR_RADIO_SYMBOL_LENGTH)) {
uint8_t buffer[DSTAR_FEC_SECTION_LENGTH_BYTES];
samplesToBits(m_headerBuffer, DSTAR_RADIO_SYMBOL_LENGTH, DSTAR_FEC_SECTION_LENGTH_SYMBOLS, buffer, DSTAR_FEC_SECTION_LENGTH_SAMPLES);
// Process the scrambling, interleaving and FEC, then return true if the chcksum was correct
uint8_t header[DSTAR_HEADER_LENGTH_BYTES];
bool ok = rxHeader(buffer, header);
if (!ok) {
// The checksum failed, return to looking for syncs
m_rxState = DSRXS_NONE;
m_maxFrameCorr = 0;
m_maxDataCorr = 0;
} else {
if (m_rxBufferBits == DSTAR_FEC_SECTION_LENGTH_BITS) {
// Process the scrambling, interleaving and FEC, then return if the chcksum was correct
unsigned char header[DSTAR_HEADER_LENGTH_BYTES];
bool ok = rxHeader(m_rxBuffer, header);
if (ok) {
io.setDecode(true);
io.setADCDetection(true);
writeRSSIHeader(header);
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
m_rxBufferBits = 0U;
m_rxState = DSRXS_DATA;
m_dataBits = MAX_SYNC_BITS;
} else {
// The checksum failed, return to looking for syncs
m_rxState = DSRXS_NONE;
}
}
// Ready to start the first data section
if (m_headerPtr == (DSTAR_FEC_SECTION_LENGTH_SAMPLES + 2U * DSTAR_RADIO_SYMBOL_LENGTH)) {
m_frameCount = 0U;
m_dataPtr = 0U;
m_startPtr = 952U;
m_syncPtr = 942U;
m_maxSyncPtr = 944U;
m_minSyncPtr = 940U;
DEBUG5("DStarRX: calc start/sync/max/min", m_startPtr, m_syncPtr, m_maxSyncPtr, m_minSyncPtr);
m_rxState = DSRXS_DATA;
}
}
void CDStarRX::processData()
void CDStarRX::processData(bool bit)
{
m_patternBuffer <<= 1;
if (bit)
m_patternBuffer |= 0x01U;
WRITE_BIT2(m_rxBuffer, m_rxBufferBits, bit);
m_rxBufferBits++;
// Fuzzy matching of the end frame sequences
if (countBits32((m_bitBuffer[m_bitPtr] & DSTAR_END_SYNC_MASK) ^ DSTAR_END_SYNC_DATA) <= END_SYNC_ERRS) {
if (countBits32((m_patternBuffer & END_SYNC_MASK) ^ END_SYNC_DATA) <= END_SYNC_ERRS) {
DEBUG1("DStarRX: Found end sync in Data");
io.setDecode(false);
@@ -404,24 +401,35 @@ void CDStarRX::processData()
serial.writeDStarEOT();
m_maxFrameCorr = 0;
m_maxDataCorr = 0;
m_rxState = DSRXS_NONE;
return;
}
// Fuzzy matching of the data sync bit sequence
if (m_minSyncPtr < m_maxSyncPtr) {
if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr)
correlateDataSync();
} else {
if (m_dataPtr >= m_minSyncPtr || m_dataPtr <= m_maxSyncPtr)
correlateDataSync();
bool syncSeen = false;
if (m_rxBufferBits >= (DSTAR_DATA_LENGTH_BITS - 3U)) {
if (countBits32((m_patternBuffer & DATA_SYNC_MASK) ^ DATA_SYNC_DATA) <= DATA_SYNC_ERRS) {
m_rxBufferBits = DSTAR_DATA_LENGTH_BITS;
m_dataBits = MAX_SYNC_BITS;
syncSeen = true;
}
}
// We've not seen a data sync for too long, signal RXLOST and change to RX_NONE
if (m_frameCount >= MAX_FRAMES) {
// Check to see if the sync is arriving late
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) {
m_rxBufferBits -= i;
break;
}
}
}
m_dataBits--;
if (m_dataBits == 0U) {
DEBUG1("DStarRX: data sync timed out, lost lock");
io.setDecode(false);
@@ -429,35 +437,24 @@ void CDStarRX::processData()
serial.writeDStarLost();
m_maxFrameCorr = 0;
m_maxDataCorr = 0;
m_rxState = DSRXS_NONE;
return;
}
// Send a data frame to the host if the required number of bits have been received
if (m_dataPtr == m_maxSyncPtr) {
uint8_t buffer[DSTAR_DATA_LENGTH_BYTES + 2U];
samplesToBits(m_dataBuffer, m_startPtr, DSTAR_DATA_LENGTH_SYMBOLS, buffer, DSTAR_DATA_LENGTH_SAMPLES);
if ((m_frameCount % 21U) == 0U) {
if (m_frameCount == 0U) {
buffer[9U] = DSTAR_DATA_SYNC_BYTES[9U];
buffer[10U] = DSTAR_DATA_SYNC_BYTES[10U];
buffer[11U] = DSTAR_DATA_SYNC_BYTES[11U];
DEBUG5("DStarRX: found start/sync/max/min", m_startPtr, m_syncPtr, m_maxSyncPtr, m_minSyncPtr);
}
writeRSSIData(buffer);
// Send a data frame to the host if the required number of bits have been received, or if a data sync has been seen
if (m_rxBufferBits == DSTAR_DATA_LENGTH_BITS) {
if (syncSeen) {
m_rxBuffer[9U] = DSTAR_DATA_SYNC_BYTES[9U];
m_rxBuffer[10U] = DSTAR_DATA_SYNC_BYTES[10U];
m_rxBuffer[11U] = DSTAR_DATA_SYNC_BYTES[11U];
writeRSSIData(m_rxBuffer);
} else {
serial.writeDStarData(buffer, DSTAR_DATA_LENGTH_BYTES);
}
serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES);
}
m_frameCount++;
m_maxFrameCorr = 0;
m_maxDataCorr = 0;
// Start the next frame
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
m_rxBufferBits = 0U;
}
}
@@ -503,105 +500,6 @@ void CDStarRX::writeRSSIData(unsigned char* data)
m_rssiCount = 0U;
}
bool CDStarRX::correlateFrameSync()
{
if (countBits32((m_bitBuffer[m_bitPtr] & DSTAR_FRAME_SYNC_MASK) ^ DSTAR_FRAME_SYNC_DATA) <= FRAME_SYNC_ERRS) {
uint16_t ptr = m_dataPtr + DSTAR_DATA_LENGTH_SAMPLES - DSTAR_FRAME_SYNC_LENGTH_SAMPLES + DSTAR_RADIO_SYMBOL_LENGTH;
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
q31_t corr = 0;
for (uint8_t i = 0U; i < DSTAR_FRAME_SYNC_LENGTH_SYMBOLS; i++) {
q15_t val = m_dataBuffer[ptr];
if (DSTAR_FRAME_SYNC_SYMBOLS[i])
corr -= val;
else
corr += val;
ptr += DSTAR_RADIO_SYMBOL_LENGTH;
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
}
if (corr > m_maxFrameCorr) {
m_maxFrameCorr = corr;
m_headerPtr = 0U;
return true;
}
}
return false;
}
bool CDStarRX::correlateDataSync()
{
uint8_t maxErrs = 0U;
if (m_rxState == DSRXS_DATA)
maxErrs = DATA_SYNC_ERRS;
if (countBits32((m_bitBuffer[m_bitPtr] & DSTAR_DATA_SYNC_MASK) ^ DSTAR_DATA_SYNC_DATA) <= maxErrs) {
uint16_t ptr = m_dataPtr + DSTAR_DATA_LENGTH_SAMPLES - DSTAR_DATA_SYNC_LENGTH_SAMPLES + DSTAR_RADIO_SYMBOL_LENGTH;
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
q31_t corr = 0;
for (uint8_t i = 0U; i < DSTAR_DATA_SYNC_LENGTH_SYMBOLS; i++) {
q15_t val = m_dataBuffer[ptr];
if (DSTAR_DATA_SYNC_SYMBOLS[i])
corr -= val;
else
corr += val;
ptr += DSTAR_RADIO_SYMBOL_LENGTH;
if (ptr >= DSTAR_DATA_LENGTH_SAMPLES)
ptr -= DSTAR_DATA_LENGTH_SAMPLES;
}
if (corr > m_maxDataCorr) {
m_maxDataCorr = corr;
m_frameCount = 0U;
m_syncPtr = m_dataPtr;
m_startPtr = m_dataPtr + DSTAR_RADIO_SYMBOL_LENGTH;
if (m_startPtr >= DSTAR_DATA_LENGTH_SAMPLES)
m_startPtr -= DSTAR_DATA_LENGTH_SAMPLES;
m_maxSyncPtr = m_syncPtr + 1U;
if (m_maxSyncPtr >= DSTAR_DATA_LENGTH_SAMPLES)
m_maxSyncPtr -= DSTAR_DATA_LENGTH_SAMPLES;
m_minSyncPtr = m_syncPtr + DSTAR_DATA_LENGTH_SAMPLES - 1U;
if (m_minSyncPtr >= DSTAR_DATA_LENGTH_SAMPLES)
m_minSyncPtr -= DSTAR_DATA_LENGTH_SAMPLES;
return true;
}
}
return false;
}
void CDStarRX::samplesToBits(const q15_t* inBuffer, uint16_t start, uint16_t count, uint8_t* outBuffer, uint16_t limit)
{
for (uint16_t i = 0U; i < count; i++) {
q15_t sample = inBuffer[start];
if (sample < 0)
WRITE_BIT2(outBuffer, i, true);
else
WRITE_BIT2(outBuffer, i, false);
start += DSTAR_RADIO_SYMBOL_LENGTH;
if (start >= limit)
start -= limit;
}
}
bool CDStarRX::rxHeader(uint8_t* in, uint8_t* out)
{
int i;
+9 -20
View File
@@ -37,21 +37,13 @@ public:
void reset();
private:
uint32_t m_pll;
bool m_prev;
DSRX_STATE m_rxState;
uint32_t m_bitBuffer[DSTAR_RADIO_SYMBOL_LENGTH];
q15_t m_headerBuffer[DSTAR_FEC_SECTION_LENGTH_SAMPLES + 2U * DSTAR_RADIO_SYMBOL_LENGTH];
q15_t m_dataBuffer[DSTAR_DATA_LENGTH_SAMPLES];
uint16_t m_bitPtr;
uint16_t m_headerPtr;
uint16_t m_dataPtr;
uint16_t m_startPtr;
uint16_t m_syncPtr;
uint16_t m_minSyncPtr;
uint16_t m_maxSyncPtr;
q31_t m_maxFrameCorr;
q31_t m_maxDataCorr;
uint16_t m_frameCount;
uint8_t m_countdown;
uint32_t m_patternBuffer;
uint8_t m_rxBuffer[100U];
unsigned int m_rxBufferBits;
unsigned int m_dataBits;
unsigned int m_mar;
int m_pathMetric[4U];
unsigned int m_pathMemory0[42U];
@@ -62,12 +54,9 @@ private:
uint32_t m_rssiAccum;
uint16_t m_rssiCount;
void processNone(q15_t sample);
void processHeader(q15_t sample);
void processData();
bool correlateFrameSync();
bool correlateDataSync();
void samplesToBits(const q15_t* inBuffer, uint16_t start, uint16_t count, uint8_t* outBuffer, uint16_t limit);
void processNone(bool bit);
void processHeader(bool bit);
void processData(bool bit);
void writeRSSIHeader(unsigned char* header);
void writeRSSIData(unsigned char* data);
bool rxHeader(uint8_t* in, uint8_t* out);
+14 -16
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2017,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2017 by Andy Uribe CA6JAU
*
* This program is free software; you can redistribute it and/or modify
@@ -27,10 +27,8 @@ const uint8_t BIT_SYNC = 0xAAU;
const uint8_t FRAME_SYNC[] = {0xEAU, 0xA6U, 0x00U};
// Generated using gaussfir(0.35, 1, 10) in MATLAB
static q15_t GAUSSIAN_0_35_FILTER[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1001, 1942, 3514, 5930,
9333, 13699, 18751, 23938, 28499, 31644, 32767, 31644,
28499, 23938, 18751, 13699, 9333, 5930, 3514, 1942, 1001}; // numTaps = 30, L = 10
// Generated using gaussfir(0.35, 1, 5) in MATLAB
static q15_t GAUSSIAN_0_35_FILTER[] = {0, 0, 0, 0, 1001, 3514, 9333, 18751, 28499, 32767, 28499, 18751, 9333, 3514, 1001}; // numTaps = 15, L = 5
const uint16_t GAUSSIAN_0_35_FILTER_PHASE_LEN = 3U; // phaseLength = numTaps/L
const q15_t DSTAR_LEVEL0 = -841;
@@ -198,9 +196,9 @@ m_poLen(0U),
m_poPtr(0U),
m_txDelay(60U) // 100ms
{
::memset(m_modState, 0x00U, 15U * sizeof(q15_t));
::memset(m_modState, 0x00U, 20U * sizeof(q15_t));
m_modFilter.L = DSTAR_RADIO_SYMBOL_LENGTH;
m_modFilter.L = DSTAR_RADIO_BIT_LENGTH;
m_modFilter.phaseLength = GAUSSIAN_0_35_FILTER_PHASE_LEN;
m_modFilter.pCoeffs = GAUSSIAN_0_35_FILTER;
m_modFilter.pState = m_modState;
@@ -254,8 +252,8 @@ void CDStarTX::process()
m_buffer.get();
for (uint8_t j = 0U; j < 3U; j++) {
for (uint8_t i = 0U; i < DSTAR_END_SYNC_LENGTH_BYTES; i++)
m_poBuffer[m_poLen++] = DSTAR_END_SYNC_BYTES[i];
for (uint8_t i = 0U; i < DSTAR_EOT_LENGTH_BYTES; i++)
m_poBuffer[m_poLen++] = DSTAR_EOT_BYTES[i];
}
m_poPtr = 0U;
@@ -264,11 +262,11 @@ void CDStarTX::process()
if (m_poLen > 0U) {
uint16_t space = io.getSpace();
while (space > (8U * DSTAR_RADIO_SYMBOL_LENGTH)) {
while (space > (8U * DSTAR_RADIO_BIT_LENGTH)) {
uint8_t c = m_poBuffer[m_poPtr++];
writeByte(c);
space -= 8U * DSTAR_RADIO_SYMBOL_LENGTH;
space -= 8U * DSTAR_RADIO_BIT_LENGTH;
if (m_poPtr >= m_poLen) {
m_poPtr = 0U;
@@ -279,7 +277,7 @@ void CDStarTX::process()
}
}
uint8_t CDStarTX::writeHeader(const uint8_t* header, uint8_t length)
uint8_t CDStarTX::writeHeader(const uint8_t* header, uint16_t length)
{
if (length != DSTAR_HEADER_LENGTH_BYTES)
return 4U;
@@ -298,7 +296,7 @@ uint8_t CDStarTX::writeHeader(const uint8_t* header, uint8_t length)
return 0U;
}
uint8_t CDStarTX::writeData(const uint8_t* data, uint8_t length)
uint8_t CDStarTX::writeData(const uint8_t* data, uint16_t length)
{
if (length != DSTAR_DATA_LENGTH_BYTES)
return 4U;
@@ -390,7 +388,7 @@ void CDStarTX::txHeader(const uint8_t* in, uint8_t* out) const
if (i < 660U) {
if (d & 0x08U)
out[INTERLEAVE_TABLE_TX[i * 2U]] |= (0x01U << INTERLEAVE_TABLE_TX[i * 2U + 1U]);
i++;
i++;
if (d & 0x04U)
out[INTERLEAVE_TABLE_TX[i * 2U]] |= (0x01U << INTERLEAVE_TABLE_TX[i * 2U + 1U]);
@@ -414,7 +412,7 @@ void CDStarTX::txHeader(const uint8_t* in, uint8_t* out) const
void CDStarTX::writeByte(uint8_t c)
{
q15_t inBuffer[8U];
q15_t outBuffer[DSTAR_RADIO_SYMBOL_LENGTH * 8U];
q15_t outBuffer[DSTAR_RADIO_BIT_LENGTH * 8U];
uint8_t mask = 0x01U;
@@ -429,7 +427,7 @@ void CDStarTX::writeByte(uint8_t c)
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 8U);
io.write(STATE_DSTAR, outBuffer, DSTAR_RADIO_SYMBOL_LENGTH * 8U);
io.write(STATE_DSTAR, outBuffer, DSTAR_RADIO_BIT_LENGTH * 8U);
}
void CDStarTX::setTXDelay(uint8_t delay)
+4 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2020 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
@@ -27,8 +27,8 @@ class CDStarTX {
public:
CDStarTX();
uint8_t writeHeader(const uint8_t* header, uint8_t length);
uint8_t writeData(const uint8_t* data, uint8_t length);
uint8_t writeHeader(const uint8_t* header, uint16_t length);
uint8_t writeData(const uint8_t* data, uint16_t length);
uint8_t writeEOT();
void process();
@@ -40,7 +40,7 @@ public:
private:
CSerialRB m_buffer;
arm_fir_interpolate_instance_q15 m_modFilter;
q15_t m_modState[15U]; // blockSize + phaseLength - 1, 8 + 3 - 1 plus some spare
q15_t m_modState[20U]; // blockSize + phaseLength - 1, 8 + 9 - 1 plus some spare
uint8_t m_poBuffer[600U];
uint16_t m_poLen;
uint16_t m_poPtr;
+523
View File
@@ -0,0 +1,523 @@
/*
* Copyright (C) 2020 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 "FM.h"
/*
* Access Mode values are:
* 0 - Carrier access with COS
* 1 - CTCSS only access without COS
* 2 - CTCSS only access with COS
* 3 - CTCSS only access with COS to start, then carrier access with COS
*/
CFM::CFM() :
m_callsign(),
m_rfAck(),
m_ctcssRX(),
m_ctcssTX(),
m_timeoutTone(),
m_state(FS_LISTENING),
m_callsignAtStart(false),
m_callsignAtEnd(false),
m_callsignAtLatch(false),
m_callsignTimer(),
m_timeoutTimer(),
m_holdoffTimer(),
m_kerchunkTimer(),
m_ackMinTimer(),
m_ackDelayTimer(),
m_hangTimer(),
m_reverseTimer(),
m_filterStage1( 724, 1448, 724, 32768, -37895, 21352),//3rd order Cheby Filter 300 to 2700Hz, 0.2dB passband ripple, sampling rate 24kHz
m_filterStage2(32768, 0,-32768, 32768, -50339, 19052),
m_filterStage3(32768, -65536, 32768, 32768, -64075, 31460),
m_blanking(),
m_accessMode(1U),
m_cosInvert(false),
m_rfAudioBoost(1U),
m_downsampler(128U),//Size might need adjustement
m_rxLevel(1),
m_inputRB(4800U), // 200ms of audio
m_outputRB(2400U) // 100ms of audio
{
m_reverseTimer.setTimeout(0U, 150U);
insertDelay(100U);
}
void CFM::samples(bool cos, const q15_t* samples, uint8_t length)
{
if (m_cosInvert)
cos = !cos;
clock(length);
uint8_t i = 0U;
for (; i < length; i++) {
// ARMv7-M has hardware integer division
q15_t currentSample = q15_t((q31_t(samples[i]) << 8) / m_rxLevel);
switch (m_accessMode) {
case 0U:
stateMachine(cos);
break;
case 1U: {
uint8_t ctcssState = m_ctcssRX.process(currentSample);
// Delay the audio by 100ms to better match the CTCSS detector output
m_inputRB.put(currentSample);
m_inputRB.get(currentSample);
if (CTCSS_NOT_READY(ctcssState) && m_modemState != STATE_FM) {
// Not enough samples to determine if you have CTCSS, just carry on
} else {
bool validCTCSS = CTCSS_VALID(ctcssState);
stateMachine(validCTCSS);
}
}
break;
case 2U: {
uint8_t ctcssState = m_ctcssRX.process(currentSample);
if (CTCSS_NOT_READY(ctcssState) && m_modemState != STATE_FM) {
// Not enough samples to determine if you have CTCSS, just carry on
} else {
bool validCTCSS = CTCSS_VALID(ctcssState);
stateMachine(validCTCSS && cos);
}
}
break;
default: {
uint8_t ctcssState = m_ctcssRX.process(currentSample);
if (CTCSS_NOT_READY(ctcssState) && m_modemState != STATE_FM) {
// Not enough samples to determine if you have CTCSS, just carry on
} else if (CTCSS_READY(ctcssState) && m_modemState != STATE_FM) {
// We had enough samples for CTCSS and we are in some other mode than FM
bool validCTCSS = CTCSS_VALID(ctcssState);
stateMachine(validCTCSS && cos);
} else {
stateMachine(cos);
}
}
break;
}
if (m_modemState != STATE_FM)
continue;
// Only let audio through when relaying audio
if (m_state == FS_RELAYING || m_state == FS_KERCHUNK) {
// m_downsampler.addSample(currentSample);
currentSample = m_blanking.process(currentSample);
currentSample *= m_rfAudioBoost;
} else {
currentSample = 0;
}
if (!m_callsign.isRunning())
currentSample += m_rfAck.getHighAudio();
if (!m_rfAck.isRunning()) {
if (m_state == FS_LISTENING)
currentSample += m_callsign.getHighAudio();
else
currentSample += m_callsign.getLowAudio();
}
currentSample = m_filterStage3.filter(m_filterStage2.filter(m_filterStage1.filter(currentSample)));
if (!m_callsign.isRunning() && !m_rfAck.isRunning())
currentSample += m_timeoutTone.getAudio();
currentSample += m_ctcssTX.getAudio(m_reverseTimer.isRunning());
m_outputRB.put(currentSample);
}
}
void CFM::process()
{
q15_t sample;
while (io.getSpace() >= 3U && m_outputRB.get(sample))
io.write(STATE_FM, &sample, 1U);
}
void CFM::reset()
{
m_state = FS_LISTENING;
m_callsignTimer.stop();
m_timeoutTimer.stop();
m_kerchunkTimer.stop();
m_ackMinTimer.stop();
m_ackDelayTimer.stop();
m_hangTimer.stop();
m_reverseTimer.stop();
m_ctcssRX.reset();
m_rfAck.stop();
m_callsign.stop();
m_timeoutTone.stop();
m_outputRB.reset();
}
uint8_t CFM::setCallsign(const char* callsign, uint8_t speed, uint16_t frequency, uint8_t time, uint8_t holdoff, uint8_t highLevel, uint8_t lowLevel, bool callsignAtStart, bool callsignAtEnd, bool callsignAtLatch)
{
m_callsignAtStart = callsignAtStart;
m_callsignAtEnd = callsignAtEnd;
m_callsignAtLatch = callsignAtLatch;
uint16_t holdoffTime = holdoff * 60U;
uint16_t callsignTime = time * 60U;
m_holdoffTimer.setTimeout(holdoffTime, 0U);
m_callsignTimer.setTimeout(callsignTime, 0U);
if (holdoffTime > 0U)
m_holdoffTimer.start();
return m_callsign.setParams(callsign, speed, frequency, highLevel, lowLevel);
}
uint8_t CFM::setAck(const char* rfAck, uint8_t speed, uint16_t frequency, uint8_t minTime, uint16_t delay, uint8_t level)
{
m_ackDelayTimer.setTimeout(0U, delay);
if (minTime > 0U)
m_ackMinTimer.setTimeout(minTime, delay);
return m_rfAck.setParams(rfAck, speed, frequency, level, level);
}
uint8_t CFM::setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssHighThreshold, uint8_t ctcssLowThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, uint8_t hangTime, uint8_t accessMode, bool cosInvert, uint8_t rfAudioBoost, uint8_t maxDev, uint8_t rxLevel)
{
m_accessMode = accessMode;
m_cosInvert = cosInvert;
m_rfAudioBoost = q15_t(rfAudioBoost);
m_timeoutTimer.setTimeout(timeout, 0U);
m_kerchunkTimer.setTimeout(kerchunkTime, 0U);
m_hangTimer.setTimeout(hangTime, 0U);
m_timeoutTone.setParams(timeoutLevel);
m_blanking.setParams(maxDev, timeoutLevel);
m_rxLevel = rxLevel; //q15_t(255)/q15_t(rxLevel >> 1);
uint8_t ret = m_ctcssRX.setParams(ctcssFrequency, ctcssHighThreshold, ctcssLowThreshold);
if (ret != 0U)
return ret;
return m_ctcssTX.setParams(ctcssFrequency, ctcssLevel);
}
void CFM::stateMachine(bool validSignal)
{
switch (m_state) {
case FS_LISTENING:
listeningState(validSignal);
break;
case FS_KERCHUNK:
kerchunkState(validSignal);
break;
case FS_RELAYING:
relayingState(validSignal);
break;
case FS_RELAYING_WAIT:
relayingWaitState(validSignal);
break;
case FS_TIMEOUT:
timeoutState(validSignal);
break;
case FS_TIMEOUT_WAIT:
timeoutWaitState(validSignal);
break;
case FS_HANG:
hangState(validSignal);
break;
default:
break;
}
if (m_state == FS_LISTENING && m_modemState == STATE_FM) {
if (!m_callsign.isWanted() && !m_rfAck.isWanted() && !m_reverseTimer.isRunning())
m_reverseTimer.start();
if (!m_callsign.isWanted() && !m_rfAck.isWanted() && m_reverseTimer.isRunning() && m_reverseTimer.hasExpired()) {
DEBUG1("Change to STATE_IDLE");
m_modemState = STATE_IDLE;
m_callsignTimer.stop();
m_timeoutTimer.stop();
m_kerchunkTimer.stop();
m_ackMinTimer.stop();
m_ackDelayTimer.stop();
m_hangTimer.stop();
m_reverseTimer.stop();
}
}
}
void CFM::clock(uint8_t length)
{
m_callsignTimer.clock(length);
m_timeoutTimer.clock(length);
m_holdoffTimer.clock(length);
m_kerchunkTimer.clock(length);
m_ackMinTimer.clock(length);
m_ackDelayTimer.clock(length);
m_hangTimer.clock(length);
m_reverseTimer.clock(length);
}
void CFM::listeningState(bool validSignal)
{
if (validSignal) {
if (m_kerchunkTimer.getTimeout() > 0U) {
DEBUG1("State to KERCHUNK");
m_state = FS_KERCHUNK;
m_kerchunkTimer.start();
if (m_callsignAtStart && !m_callsignAtLatch)
sendCallsign();
} else {
DEBUG1("State to RELAYING");
m_state = FS_RELAYING;
if (m_callsignAtStart)
sendCallsign();
}
insertSilence(50U);
beginRelaying();
m_callsignTimer.start();
m_reverseTimer.stop();
io.setDecode(true);
io.setADCDetection(true);
DEBUG1("Change to STATE_FM");
m_modemState = STATE_FM;
}
}
void CFM::kerchunkState(bool validSignal)
{
if (validSignal) {
if (m_kerchunkTimer.hasExpired()) {
DEBUG1("State to RELAYING");
m_state = FS_RELAYING;
m_kerchunkTimer.stop();
if (m_callsignAtStart && m_callsignAtLatch) {
sendCallsign();
m_callsignTimer.start();
}
}
} else {
io.setDecode(false);
io.setADCDetection(false);
DEBUG1("State to LISTENING");
m_state = FS_LISTENING;
m_kerchunkTimer.stop();
m_timeoutTimer.stop();
m_ackMinTimer.stop();
m_callsignTimer.stop();
}
}
void CFM::relayingState(bool validSignal)
{
if (validSignal) {
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) {
DEBUG1("State to TIMEOUT");
m_state = FS_TIMEOUT;
m_ackMinTimer.stop();
m_timeoutTimer.stop();
m_timeoutTone.start();
}
} else {
io.setDecode(false);
io.setADCDetection(false);
DEBUG1("State to RELAYING_WAIT");
m_state = FS_RELAYING_WAIT;
m_ackDelayTimer.start();
}
if (m_callsignTimer.isRunning() && m_callsignTimer.hasExpired()) {
sendCallsign();
m_callsignTimer.start();
}
}
void CFM::relayingWaitState(bool validSignal)
{
if (validSignal) {
io.setDecode(true);
io.setADCDetection(true);
DEBUG1("State to RELAYING");
m_state = FS_RELAYING;
m_ackDelayTimer.stop();
} else {
if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) {
DEBUG1("State to HANG");
m_state = FS_HANG;
if (m_ackMinTimer.isRunning()) {
if (m_ackMinTimer.hasExpired()) {
DEBUG1("Send ack");
m_rfAck.start();
m_ackMinTimer.stop();
}
} else {
DEBUG1("Send ack");
m_rfAck.start();
m_ackMinTimer.stop();
}
m_ackDelayTimer.stop();
m_timeoutTimer.stop();
m_hangTimer.start();
}
}
if (m_callsignTimer.isRunning() && m_callsignTimer.hasExpired()) {
sendCallsign();
m_callsignTimer.start();
}
}
void CFM::hangState(bool validSignal)
{
if (validSignal) {
io.setDecode(true);
io.setADCDetection(true);
DEBUG1("State to RELAYING");
m_state = FS_RELAYING;
DEBUG1("Stop ack");
m_rfAck.stop();
beginRelaying();
} else {
if (m_hangTimer.isRunning() && m_hangTimer.hasExpired()) {
DEBUG1("State to LISTENING");
m_state = FS_LISTENING;
m_hangTimer.stop();
if (m_callsignAtEnd)
sendCallsign();
m_callsignTimer.stop();
}
}
if (m_callsignTimer.isRunning() && m_callsignTimer.hasExpired()) {
sendCallsign();
m_callsignTimer.start();
}
}
void CFM::timeoutState(bool validSignal)
{
if (!validSignal) {
io.setDecode(false);
io.setADCDetection(false);
DEBUG1("State to TIMEOUT_WAIT");
m_state = FS_TIMEOUT_WAIT;
m_ackDelayTimer.start();
}
if (m_callsignTimer.isRunning() && m_callsignTimer.hasExpired()) {
sendCallsign();
m_callsignTimer.start();
}
}
void CFM::timeoutWaitState(bool validSignal)
{
if (validSignal) {
io.setDecode(true);
io.setADCDetection(true);
DEBUG1("State to TIMEOUT");
m_state = FS_TIMEOUT;
m_ackDelayTimer.stop();
} else {
if (m_ackDelayTimer.isRunning() && m_ackDelayTimer.hasExpired()) {
DEBUG1("State to HANG");
m_state = FS_HANG;
m_timeoutTone.stop();
DEBUG1("Send ack");
m_rfAck.start();
m_ackDelayTimer.stop();
m_ackMinTimer.stop();
m_timeoutTimer.stop();
m_hangTimer.start();
}
}
if (m_callsignTimer.isRunning() && m_callsignTimer.hasExpired()) {
sendCallsign();
m_callsignTimer.start();
}
}
void CFM::sendCallsign()
{
if (m_holdoffTimer.isRunning()) {
if (m_holdoffTimer.hasExpired()) {
DEBUG1("Send callsign");
m_callsign.start();
m_holdoffTimer.start();
}
} else {
DEBUG1("Send callsign");
m_callsign.start();
}
}
void CFM::beginRelaying()
{
m_timeoutTimer.start();
m_ackMinTimer.start();
}
void CFM::insertDelay(uint16_t ms)
{
uint32_t nSamples = ms * 24U;
for (uint32_t i = 0U; i < nSamples; i++)
m_inputRB.put(0);
}
void CFM::insertSilence(uint16_t ms)
{
uint32_t nSamples = ms * 24U;
for (uint32_t i = 0U; i < nSamples; i++)
m_outputRB.put(0);
}
+109
View File
@@ -0,0 +1,109 @@
/*
* Copyright (C) 2020 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(FM_H)
#define FM_H
#include "Config.h"
#include "FMBlanking.h"
#include "FMCTCSSRX.h"
#include "FMCTCSSTX.h"
#include "FMTimeout.h"
#include "FMKeyer.h"
#include "FMTimer.h"
#include "FMRB.h"
#include "FMDirectForm1.h"
#include "FMDownsampler.h"
enum FM_STATE {
FS_LISTENING,
FS_KERCHUNK,
FS_RELAYING,
FS_RELAYING_WAIT,
FS_TIMEOUT,
FS_TIMEOUT_WAIT,
FS_HANG
};
class CFM {
public:
CFM();
void samples(bool cos, const q15_t* samples, uint8_t length);
void process();
void reset();
uint8_t setCallsign(const char* callsign, uint8_t speed, uint16_t frequency, uint8_t time, uint8_t holdoff, uint8_t highLevel, uint8_t lowLevel, bool callsignAtStart, bool callsignAtEnd, bool callsignAtLatch);
uint8_t setAck(const char* rfAck, uint8_t speed, uint16_t frequency, uint8_t minTime, uint16_t delay, uint8_t level);
uint8_t setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssHighThreshold, uint8_t ctcssLowThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, uint8_t hangTime, uint8_t accessMode, bool cosInvert, uint8_t rfAudioBoost, uint8_t maxDev, uint8_t rxLevel);
private:
CFMKeyer m_callsign;
CFMKeyer m_rfAck;
CFMCTCSSRX m_ctcssRX;
CFMCTCSSTX m_ctcssTX;
CFMTimeout m_timeoutTone;
FM_STATE m_state;
bool m_callsignAtStart;
bool m_callsignAtEnd;
bool m_callsignAtLatch;
CFMTimer m_callsignTimer;
CFMTimer m_timeoutTimer;
CFMTimer m_holdoffTimer;
CFMTimer m_kerchunkTimer;
CFMTimer m_ackMinTimer;
CFMTimer m_ackDelayTimer;
CFMTimer m_hangTimer;
CFMTimer m_reverseTimer;
CFMDirectFormI m_filterStage1;
CFMDirectFormI m_filterStage2;
CFMDirectFormI m_filterStage3;
CFMBlanking m_blanking;
uint8_t m_accessMode;
bool m_cosInvert;
q15_t m_rfAudioBoost;
CFMDownsampler m_downsampler;
q15_t m_rxLevel;
CFMRB m_inputRB;
CFMRB m_outputRB;
void stateMachine(bool validSignal);
void listeningState(bool validSignal);
void kerchunkState(bool validSignal);
void relayingState(bool validSignal);
void relayingWaitState(bool validSignal);
void timeoutState(bool validSignal);
void timeoutWaitState(bool validSignal);
void hangState(bool validSignal);
void clock(uint8_t length);
void sendCallsign();
void beginRelaying();
void insertDelay(uint16_t ms);
void insertSilence(uint16_t ms);
};
#endif
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2020 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 "FMBlanking.h"
// 2000 Hz sine wave at 24000 Hz sample rate
const q31_t TONE[] = {0, 16384, 28378, 32767, 28378, 16384, 0, -16383, -28377, -32767, -28377, -16383};
const uint8_t TONE_LEN = 12U;
const uint32_t BLEEP_LEN = 2400U; // 100ms
CFMBlanking::CFMBlanking() :
m_posValue(0),
m_negValue(0),
m_level(128 * 128),
m_running(false),
m_pos(0U),
m_n(0U)
{
}
void CFMBlanking::setParams(uint8_t value, uint8_t level)
{
m_posValue = q15_t(value * 128);
m_negValue = -m_posValue;
m_level = q15_t(level * 128);
}
q15_t CFMBlanking::process(q15_t sample)
{
if (m_posValue == 0)
return sample;
if (!m_running) {
if (sample >= m_posValue) {
m_running = true;
m_pos = 0U;
m_n = 0U;
} else if (sample <= m_negValue) {
m_running = true;
m_pos = 0U;
m_n = 0U;
}
}
if (!m_running)
return sample;
if (m_pos <= BLEEP_LEN) {
q31_t value = TONE[m_n++] * m_level;
sample = q15_t(__SSAT((value >> 15), 16));
if (m_n >= TONE_LEN)
m_n = 0U;
} else {
sample = 0;
}
m_pos++;
if (m_pos >= 12000U)
m_running = false;
return sample;
}
+41
View File
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2020 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(FMBlanking_H)
#define FMBlanking_H
#include "Config.h"
class CFMBlanking {
public:
CFMBlanking();
void setParams(uint8_t value, uint8_t level);
q15_t process(q15_t sample);
private:
q15_t m_posValue;
q15_t m_negValue;
q15_t m_level;
bool m_running;
uint32_t m_pos;
uint8_t m_n;
};
#endif
+181
View File
@@ -0,0 +1,181 @@
/*
* Copyright (C) 2020 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 "FMCTCSSRX.h"
const struct RX_CTCSS_TABLE {
uint8_t frequency;
q63_t coeffDivTwo;
} RX_CTCSS_TABLE_DATA[] = {
{ 67U, 2147153298},
{ 69U, 2147130228},
{ 71U, 2147103212},
{ 74U, 2147076297},
{ 77U, 2147047330},
{ 79U, 2147016195},
{ 82U, 2146982775},
{ 85U, 2146946945},
{ 88U, 2146907275},
{ 91U, 2146867538},
{ 94U, 2146822298},
{ 97U, 2146785526},
{100U, 2146747759},
{103U, 2146695349},
{107U, 2146637984},
{110U, 2146578604},
{114U, 2146513835},
{118U, 2146445080},
{123U, 2146370355},
{127U, 2146291161},
{131U, 2146205372},
{136U, 2146112589},
{141U, 2146014479},
{146U, 2145910829},
{151U, 2145796971},
{156U, 2145676831},
{159U, 2145604646},
{162U, 2145547790},
{165U, 2145468230},
{167U, 2145409363},
{171U, 2145324517},
{173U, 2145261046},
{177U, 2145170643},
{179U, 2145102321},
{183U, 2145006080},
{186U, 2144932648},
{189U, 2144830280},
{192U, 2144748638},
{196U, 2144639788},
{199U, 2144555290},
{203U, 2144436713},
{206U, 2144346237},
{210U, 2144217348},
{218U, 2143983951},
{225U, 2143735870},
{229U, 2143622139},
{233U, 2143469001},
{241U, 2143182299},
{250U, 2142874683},
{254U, 2142733729}};
const uint8_t CTCSS_TABLE_DATA_LEN = 50U;
// 4Hz bandwidth
const uint16_t N = 24000U / 4U;
CFMCTCSSRX::CFMCTCSSRX() :
m_coeffDivTwo(0),
m_highThreshold(0),
m_lowThreshold(0),
m_count(0U),
m_q0(0),
m_q1(0),
m_result(CTS_NONE)
{
}
uint8_t CFMCTCSSRX::setParams(uint8_t frequency, uint8_t highThreshold, uint8_t lowThreshold)
{
m_coeffDivTwo = 0;
for (uint8_t i = 0U; i < CTCSS_TABLE_DATA_LEN; i++) {
if (RX_CTCSS_TABLE_DATA[i].frequency == frequency) {
m_coeffDivTwo = RX_CTCSS_TABLE_DATA[i].coeffDivTwo;
break;
}
}
if (m_coeffDivTwo == 0)
return 4U;
m_highThreshold = q31_t(highThreshold);
m_lowThreshold = q31_t(lowThreshold);
return 0U;
}
uint8_t CFMCTCSSRX::process(q15_t sample)
{
//get more dynamic into the decoder by multiplying the sample by 1.5
q31_t sample31 = q31_t(sample) + (q31_t(sample) >> 1);
m_result &= ~CTS_READY;
q31_t q2 = m_q1;
m_q1 = m_q0;
// Q31 multiplication, t3 = m_coeffDivTwo * 2 * m_q1
q63_t t1 = m_coeffDivTwo * m_q1;
q31_t t2 = __SSAT((t1 >> 31), 31);
q31_t t3 = t2 * 2;
// m_q0 = m_coeffDivTwo * m_q1 * 2 - q2 + sample
m_q0 = t3 - q2 + sample31;
m_count++;
if (m_count == N) {
// Q31 multiplication, t2 = m_q0 * m_q0
q63_t t1 = q63_t(m_q0) * q63_t(m_q0);
q31_t t2 = __SSAT((t1 >> 31), 31);
// Q31 multiplication, t4 = m_q0 * m_q0
q63_t t3 = q63_t(m_q1) * q63_t(m_q1);
q31_t t4 = __SSAT((t3 >> 31), 31);
// Q31 multiplication, t9 = m_q0 * m_q1 * m_coeffDivTwo * 2
q63_t t5 = q63_t(m_q0) * q63_t(m_q1);
q31_t t6 = __SSAT((t5 >> 31), 31);
q63_t t7 = t6 * m_coeffDivTwo;
q31_t t8 = __SSAT((t7 >> 31), 31);
q31_t t9 = t8 * 2;
// value = m_q0 * m_q0 + m_q1 * m_q1 - m_q0 * m_q1 * m_coeffDivTwo * 2
q31_t value = t2 + t4 - t9;
bool previousCTCSSValid = CTCSS_VALID(m_result);
q31_t threshold = m_highThreshold;
if (previousCTCSSValid)
threshold = m_lowThreshold;
m_result |= CTS_READY;
if (value >= threshold)
m_result |= CTS_VALID;
else
m_result &= ~CTS_VALID;
if (previousCTCSSValid != CTCSS_VALID(m_result))
DEBUG4("CTCSS Value / Threshold / Valid", value, threshold, CTCSS_VALID(m_result));
m_count = 0U;
m_q0 = 0;
m_q1 = 0;
}
return m_result;
}
void CFMCTCSSRX::reset()
{
m_q0 = 0;
m_q1 = 0;
m_result = CTS_NONE;
m_count = 0U;
}
+53
View File
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2020 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(FMCTCSSRX_H)
#define FMCTCSSRX_H
#include "Config.h"
const uint8_t CTS_NONE = 0U;
const uint8_t CTS_READY = 1U;
const uint8_t CTS_VALID = 2U;
#define CTCSS_READY(a) ((a & CTS_READY) != 0)
#define CTCSS_NOT_READY(a) ((a & CTS_READY) == 0)
#define CTCSS_VALID(a) ((a & CTS_VALID) != 0)
#define CTCSS_NOT_VALID(a) ((a & CTS_VALID) == 0)
class CFMCTCSSRX {
public:
CFMCTCSSRX();
uint8_t setParams(uint8_t frequency, uint8_t highThreshold, uint8_t lowThreshold);
uint8_t process(q15_t sample);
void reset();
private:
q63_t m_coeffDivTwo;
q31_t m_highThreshold;
q31_t m_lowThreshold;
uint16_t m_count;
q31_t m_q0;
q31_t m_q1;
uint8_t m_result;
};
#endif
+128
View File
@@ -0,0 +1,128 @@
/*
* Copyright (C) 2020 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 "FMCTCSSTX.h"
const struct TX_CTCSS_TABLE {
uint8_t frequency;
uint16_t length;
q31_t increment;
} TX_CTCSS_TABLE_DATA[] = {
{ 67U, 358U, 5995059},
{ 69U, 346U, 6200860},
{ 71U, 334U, 6433504},
{ 74U, 323U, 6657200},
{ 77U, 312U, 6889844},
{ 79U, 301U, 7131436},
{ 82U, 291U, 7381976},
{ 85U, 281U, 7641463},
{ 88U, 271U, 7918846},
{ 91U, 262U, 8187282},
{ 94U, 253U, 8482561},
{ 97U, 246U, 8715205},
{100U, 240U, 8947849},
{103U, 232U, 9261024},
{107U, 224U, 9592094},
{110U, 216U, 9923165},
{114U, 209U, 10272131},
{118U, 202U, 10630045},
{123U, 195U, 11005854},
{127U, 189U, 11390612},
{131U, 182U, 11793265},
{136U, 176U, 12213814},
{141U, 170U, 12643310},
{146U, 164U, 13081755},
{151U, 159U, 13547043},
{156U, 153U, 14021279},
{159U, 150U, 14298662},
{162U, 148U, 14513411},
{165U, 145U, 14808690},
{167U, 143U, 15023438},
{171U, 140U, 15327665},
{173U, 138U, 15551361},
{177U, 135U, 15864536},
{179U, 133U, 16097180},
{183U, 131U, 16419303},
{186U, 129U, 16660894},
{189U, 126U, 16991965},
{192U, 124U, 17251452},
{196U, 122U, 17591471},
{199U, 120U, 17850958},
{203U, 118U, 18208872},
{206U, 116U, 18477308},
{210U, 114U, 18853117},
{218U, 110U, 19515258},
{225U, 106U, 20195295},
{229U, 105U, 20499521},
{233U, 103U, 20902175},
{241U, 99U, 21635898},
{250U, 96U, 22396465},
{254U, 94U, 22736484}};
const uint8_t CTCSS_TABLE_DATA_LEN = 50U;
CFMCTCSSTX::CFMCTCSSTX() :
m_values(NULL),
m_length(0U),
m_n(0U)
{
}
uint8_t CFMCTCSSTX::setParams(uint8_t frequency, uint8_t level)
{
const TX_CTCSS_TABLE* entry = NULL;
for (uint8_t i = 0U; i < CTCSS_TABLE_DATA_LEN; i++) {
if (TX_CTCSS_TABLE_DATA[i].frequency == frequency) {
entry = TX_CTCSS_TABLE_DATA + i;
break;
}
}
if (entry == NULL)
return 4U;
m_length = entry->length;
delete[] m_values;
m_values = new q15_t[m_length];
q31_t arg = 0;
for (uint16_t i = 0U; i < m_length; i++) {
q63_t value = ::arm_sin_q31(arg) * q63_t(level * 13);
m_values[i] = q15_t(__SSAT((value >> 31), 16));
arg += entry->increment;
}
return 0U;
}
q15_t CFMCTCSSTX::getAudio(bool reverse)
{
q15_t sample = m_values[m_n++];
if (m_n >= m_length)
m_n = 0U;
if (reverse)
return -sample;
else
return sample;
}
+38
View File
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2020 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(FMCTCSSTX_H)
#define FMCTCSSTX_H
#include "Config.h"
class CFMCTCSSTX {
public:
CFMCTCSSTX();
uint8_t setParams(uint8_t frequency, uint8_t level);
q15_t getAudio(bool reverse);
private:
q15_t* m_values;
uint16_t m_length;
uint16_t m_n;
};
#endif
+111
View File
@@ -0,0 +1,111 @@
/*******************************************************************************
This header file has been taken from:
"A Collection of Useful C++ Classes for Digital Signal Processing"
By Vinnie Falco
Bernd Porr adapted it for Linux and turned it into a filter using
fixed point arithmetic.
--------------------------------------------------------------------------------
License: MIT License (http://www.opensource.org/licenses/mit-license.php)
Copyright (c) 2009 by Vinnie Falco
Copyright (C) 2013-2017, Bernd Porr, [email protected]
Copyright (C) 2020 , Mario Molitor , [email protected]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*******************************************************************************/
// based on https://raw.githubusercontent.com/berndporr/iir_fixed_point/master/DirectFormI.h
#include "Globals.h"
#ifndef DIRECTFORMI_H_
#define DIRECTFORMI_H_
class CFMDirectFormI
{
public:
// convenience function which takes the a0 argument but ignores it!
CFMDirectFormI(const q31_t b0, const q31_t b1, const q31_t b2,
const q31_t, const q31_t a1, const q31_t a2)
{
// FIR coefficients
c_b0 = b0;
c_b1 = b1;
c_b2 = b2;
// IIR coefficients
c_a1 = a1;
c_a2 = a2;
reset();
}
CFMDirectFormI(const CFMDirectFormI &my)
{
// delay line
m_x2 = my.m_x2; // x[n-2]
m_y2 = my.m_y2; // y[n-2]
m_x1 = my.m_x1; // x[n-1]
m_y1 = my.m_y1; // y[n-1]
// coefficients
c_b0 = my.c_b0;
c_b1 = my.c_b1;
c_b2 = my.c_b2; // FIR
c_a1 = my.c_a1;
c_a2 = my.c_a2; // IIR
}
void reset ()
{
m_x1 = 0;
m_x2 = 0;
m_y1 = 0;
m_y2 = 0;
}
// filtering operation: one sample in and one out
inline q15_t filter(const q15_t in)
{
// calculate the output
register q31_t out_upscaled = c_b0 * in
+ c_b1 * m_x1
+ c_b2 * m_x2
- c_a1 * m_y1
- c_a2 * m_y2;
q15_t out = __SSAT(out_upscaled >> 15, 15);
// update the delay lines
m_x2 = m_x1;
m_y2 = m_y1;
m_x1 = in;
m_y1 = out;
return out;
}
private:
// delay line
q31_t m_x2; // x[n-2]
q31_t m_y2; // y[n-2]
q31_t m_x1; // x[n-1]
q31_t m_y1; // y[n-1]
// coefficients
q31_t c_b0,c_b1,c_b2; // FIR
q31_t c_a1,c_a2; // IIR
};
#endif /* DIRECTFORMI_H */
+101
View File
@@ -0,0 +1,101 @@
/*
* Copyright (C) 2020 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 "FMDownsampleRB.h"
CFMDownsampleRB::CFMDownsampleRB(uint16_t length) :
m_length(length),
m_head(0U),
m_tail(0U),
m_full(false),
m_overflow(false)
{
m_samples = new uint8_t[length];
}
uint16_t CFMDownsampleRB::getSpace() const
{
uint16_t n = 0U;
if (m_tail == m_head)
n = m_full ? 0U : m_length;
else if (m_tail < m_head)
n = m_length - m_head + m_tail;
else
n = m_tail - m_head;
if (n > m_length)
n = 0U;
return n;
}
uint16_t CFMDownsampleRB::getData() const
{
if (m_tail == m_head)
return m_full ? m_length : 0U;
else if (m_tail < m_head)
return m_head - m_tail;
else
return m_length - m_tail + m_head;
}
bool CFMDownsampleRB::put(uint8_t sample)
{
if (m_full) {
m_overflow = true;
return false;
}
m_samples[m_head] = sample;
m_head++;
if (m_head >= m_length)
m_head = 0U;
if (m_head == m_tail)
m_full = true;
return true;
}
bool CFMDownsampleRB::get(uint8_t& sample)
{
if (m_head == m_tail && !m_full)
return false;
sample = m_samples[m_tail];
m_full = false;
m_tail++;
if (m_tail >= m_length)
m_tail = 0U;
return true;
}
bool CFMDownsampleRB::hasOverflowed()
{
bool overflow = m_overflow;
m_overflow = false;
return overflow;
}
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright (C) 2020 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(FMDOWNSAMPLERB_H)
#define FMDOWNSAMPLERB_H
#if defined(STM32F4XX)
#include "stm32f4xx.h"
#elif defined(STM32F7XX)
#include "stm32f7xx.h"
#elif defined(STM32F105xC)
#include "stm32f1xx.h"
#include <cstddef>
#else
#include <Arduino.h>
#endif
#if defined(__SAM3X8E__) || defined(STM32F105xC)
#define ARM_MATH_CM3
#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"
#endif
#include <arm_math.h>
class CFMDownsampleRB {
public:
CFMDownsampleRB(uint16_t length);
uint16_t getSpace() const;
uint16_t getData() const;
bool put(uint8_t sample);
bool get(uint8_t& sample);
bool hasOverflowed();
private:
uint16_t m_length;
volatile uint8_t* m_samples;
volatile uint16_t m_head;
volatile uint16_t m_tail;
volatile bool m_full;
bool m_overflow;
};
#endif
+63
View File
@@ -0,0 +1,63 @@
/*
* Copyright (C) 2020 by Jonathan Naylor G4KLX
* Copyright (C) 2020 by Geoffrey Merck F4FXL - KC3FRA
*
* 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 "FMDownsampler.h"
CFMDownsampler::CFMDownsampler(uint16_t length) :
m_ringBuffer(length),//length might need tweaking
m_packIndex(0),
m_downSampleIndex(0)
{
m_samplePack = 0;
}
void CFMDownsampler::addSample(q15_t sample)
{
//only take one of three samples
if(m_downSampleIndex == 0) {
switch(m_packIndex){
case 0:
m_samplePack = int32_t(sample) << 12;
break;
case 1:{
m_samplePack |= int32_t(sample);
//we did not use MSB; skip it
m_ringBuffer.put(m_samplePackBytes[1]);
m_ringBuffer.put(m_samplePackBytes[2]);
m_ringBuffer.put(m_samplePackBytes[3]);
m_samplePack = 0;
}
break;
default:
//should never happen
break;
}
m_packIndex++;
if(m_packIndex >= 2)
m_packIndex = 0;
}
m_downSampleIndex++;
if(m_downSampleIndex >= 3)
m_downSampleIndex = 0;
}
+43
View File
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2020 by Jonathan Naylor G4KLX
* Copyright (C) 2020 by Geoffrey Merck F4FXL - KC3FRA
*
* 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(FMDOWNSAMPLER_H)
#define FMDOWNSAMPLER_H
#include "Config.h"
#include "FMDownsampleRB.h"
class CFMDownsampler {
public:
CFMDownsampler(uint16_t length);
void addSample(q15_t sample);
inline bool getPackedData(uint8_t& data){ return m_ringBuffer.get(data); };
inline bool hasOverflowed() { return m_ringBuffer.hasOverflowed(); };
private:
CFMDownsampleRB m_ringBuffer;
union {
int32_t m_samplePack;
int8_t m_samplePackBytes[4];
};
uint8_t m_packIndex;
uint8_t m_downSampleIndex;
};
#endif
+216
View File
@@ -0,0 +1,216 @@
/*
* Copyright (C) 2020 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 "FMKeyer.h"
const struct {
char c;
uint32_t pattern;
uint8_t length;
} SYMBOL_LIST[] = {
{'A', 0xB8000000U, 8U},
{'B', 0xEA800000U, 12U},
{'C', 0xEBA00000U, 14U},
{'D', 0xEA000000U, 10U},
{'E', 0x80000000U, 4U},
{'F', 0xAE800000U, 12U},
{'G', 0xEE800000U, 12U},
{'H', 0xAA000000U, 10U},
{'I', 0xA0000000U, 6U},
{'J', 0xBBB80000U, 16U},
{'K', 0xEB800000U, 12U},
{'L', 0xBA800000U, 12U},
{'M', 0xEE000000U, 10U},
{'N', 0xE8000000U, 8U},
{'O', 0xEEE00000U, 14U},
{'P', 0xBBA00000U, 14U},
{'Q', 0xEEB80000U, 16U},
{'R', 0xBA000000U, 10U},
{'S', 0xA8000000U, 8U},
{'T', 0xE0000000U, 6U},
{'U', 0xAE000000U, 10U},
{'V', 0xAB800000U, 12U},
{'W', 0xBB800000U, 12U},
{'X', 0xEAE00000U, 14U},
{'Y', 0xEBB80000U, 16U},
{'Z', 0xEEA00000U, 14U},
{'1', 0xBBBB8000U, 20U},
{'2', 0xAEEE0000U, 18U},
{'3', 0xABB80000U, 16U},
{'4', 0xAAE00000U, 14U},
{'5', 0xAA800000U, 12U},
{'6', 0xEAA00000U, 14U},
{'7', 0xEEA80000U, 16U},
{'8', 0xEEEA0000U, 18U},
{'9', 0xEEEE8000U, 20U},
{'0', 0xEEEEE000U, 22U},
{'/', 0xEAE80000U, 16U},
{'?', 0xAEEA0000U, 18U},
{',', 0xEEAEE000U, 22U},
{'-', 0xEAAE0000U, 18U},
{'=', 0xEAB80000U, 16U},
{'.', 0xBAEB8000U, 20U},
{' ', 0x00000000U, 4U},
{0U, 0x00000000U, 0U}
};
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
#define WRITE_BIT_FM(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
#define READ_BIT_FM(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
CFMKeyer::CFMKeyer() :
m_wanted(false),
m_poBuffer(),
m_poLen(0U),
m_poPos(0U),
m_dotLen(0U),
m_dotPos(0U),
m_audio(NULL),
m_audioLen(0U),
m_audioPos(0U),
m_highLevel(0U),
m_lowLevel(0)
{
}
uint8_t CFMKeyer::setParams(const char* text, uint8_t speed, uint16_t frequency, uint8_t highLevel, uint8_t lowLevel)
{
m_poLen = 0U;
for (uint8_t i = 0U; text[i] != '\0'; i++) {
for (uint8_t j = 0U; SYMBOL_LIST[j].c != 0U; j++) {
if (SYMBOL_LIST[j].c == text[i]) {
uint32_t MASK = 0x80000000U;
for (uint8_t k = 0U; k < SYMBOL_LIST[j].length; k++, m_poLen++, MASK >>= 1) {
bool b = (SYMBOL_LIST[j].pattern & MASK) == MASK;
WRITE_BIT_FM(m_poBuffer, m_poLen, b);
if (m_poLen >= 995U) {
m_poLen = 0U;
return 4U;
}
}
break;
}
}
}
m_highLevel = q15_t(highLevel);
m_lowLevel = q15_t(lowLevel);
m_dotLen = 24000U / speed; // In samples
m_audioLen = 24000U / frequency; // In samples
delete[] m_audio;
m_audio = new bool[m_audioLen];
for (uint16_t i = 0U; i < m_audioLen; i++) {
if (i < (m_audioLen / 2U))
m_audio[i] = true;
else
m_audio[i] = false;
}
return 0U;
}
q15_t CFMKeyer::getHighAudio()
{
q15_t output = 0U;
if (!m_wanted)
return 0U;
bool b = READ_BIT_FM(m_poBuffer, m_poPos);
if (b)
output = m_audio[m_audioPos] ? m_highLevel : -m_highLevel;
m_audioPos++;
if (m_audioPos >= m_audioLen)
m_audioPos = 0U;
m_dotPos++;
if (m_dotPos >= m_dotLen) {
m_dotPos = 0U;
m_poPos++;
if (m_poPos >= m_poLen) {
stop();
return output;
}
}
return output;
}
q15_t CFMKeyer::getLowAudio()
{
q15_t output = 0U;
if (!m_wanted)
return 0U;
bool b = READ_BIT_FM(m_poBuffer, m_poPos);
if (b)
output = m_audio[m_audioPos] ? m_lowLevel : -m_lowLevel;
m_audioPos++;
if (m_audioPos >= m_audioLen)
m_audioPos = 0U;
m_dotPos++;
if (m_dotPos >= m_dotLen) {
m_dotPos = 0U;
m_poPos++;
if (m_poPos >= m_poLen) {
stop();
return output;
}
}
return output;
}
void CFMKeyer::start()
{
if (isRunning())
return;
m_wanted = true;
m_poPos = 0U;
m_dotPos = 0U;
m_audioPos = 0U;
}
void CFMKeyer::stop()
{
m_wanted = false;
m_poPos = 0U;
m_dotPos = 0U;
m_audioPos = 0U;
}
bool CFMKeyer::isWanted() const
{
return m_wanted;
}
bool CFMKeyer::isRunning() const
{
return m_poPos > 0U || m_dotPos > 0U || m_audioPos > 0U;
}
+54
View File
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2020 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(FMKeyer_H)
#define FMKeyer_H
#include "Config.h"
class CFMKeyer {
public:
CFMKeyer();
uint8_t setParams(const char* text, uint8_t speed, uint16_t frequency, uint8_t highLevel, uint8_t lowLevel);
q15_t getHighAudio();
q15_t getLowAudio();
void start();
void stop();
bool isRunning() const;
bool isWanted() const;
private:
bool m_wanted;
uint8_t m_poBuffer[1000U];
uint16_t m_poLen;
uint16_t m_poPos;
uint16_t m_dotLen;
uint16_t m_dotPos;
bool* m_audio;
uint16_t m_audioLen;
uint16_t m_audioPos;
q15_t m_highLevel;
q15_t m_lowLevel;
};
#endif
+110
View File
@@ -0,0 +1,110 @@
/*
TX fifo control - Copyright (C) KI6ZUM 2015
Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "FMRB.h"
CFMRB::CFMRB(uint16_t length) :
m_length(length),
m_head(0U),
m_tail(0U),
m_full(false),
m_overflow(false)
{
m_samples = new q15_t[length];
}
uint16_t CFMRB::getSpace() const
{
uint16_t n = 0U;
if (m_tail == m_head)
n = m_full ? 0U : m_length;
else if (m_tail < m_head)
n = m_length - m_head + m_tail;
else
n = m_tail - m_head;
if (n > m_length)
n = 0U;
return n;
}
uint16_t CFMRB::getData() const
{
if (m_tail == m_head)
return m_full ? m_length : 0U;
else if (m_tail < m_head)
return m_head - m_tail;
else
return m_length - m_tail + m_head;
}
bool CFMRB::put(q15_t sample)
{
if (m_full) {
m_overflow = true;
return false;
}
m_samples[m_head] = sample;
m_head++;
if (m_head >= m_length)
m_head = 0U;
if (m_head == m_tail)
m_full = true;
return true;
}
bool CFMRB::get(q15_t& sample)
{
if (m_head == m_tail && !m_full)
return false;
sample = m_samples[m_tail];
m_full = false;
m_tail++;
if (m_tail >= m_length)
m_tail = 0U;
return true;
}
bool CFMRB::hasOverflowed()
{
bool overflow = m_overflow;
m_overflow = false;
return overflow;
}
void CFMRB::reset()
{
m_head = 0U;
m_tail = 0U;
m_full = false;
m_overflow = false;
}
+72
View File
@@ -0,0 +1,72 @@
/*
Serial fifo control - Copyright (C) KI6ZUM 2015
Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#if !defined(FMRB_H)
#define FMRB_H
#if defined(STM32F4XX)
#include "stm32f4xx.h"
#elif defined(STM32F7XX)
#include "stm32f7xx.h"
#elif defined(STM32F105xC)
#include "stm32f1xx.h"
#include <cstddef>
#else
#include <Arduino.h>
#endif
#if defined(__SAM3X8E__) || defined(STM32F105xC)
#define ARM_MATH_CM3
#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"
#endif
#include <arm_math.h>
class CFMRB {
public:
CFMRB(uint16_t length);
uint16_t getSpace() const;
uint16_t getData() const;
bool put(q15_t sample);
bool get(q15_t& sample);
bool hasOverflowed();
void reset();
private:
uint16_t m_length;
volatile q15_t* m_samples;
volatile uint16_t m_head;
volatile uint16_t m_tail;
volatile bool m_full;
bool m_overflow;
};
#endif
+74
View File
@@ -0,0 +1,74 @@
/*
* Copyright (C) 2020 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 "FMTimeout.h"
// 400 Hz sine wave at 24000 Hz sample rate
const q15_t BUSY_AUDIO[] = {0, 3426, 6813, 10126, 13328, 16384, 19261, 21926, 24351, 26510, 28378, 29935, 31164, 32052, 32588, 32767, 32588, 32052, 31164, 29935, 28378, 26510, 24351,
21926, 19261, 16384, 13328, 10126, 6813, 3425, 0, -3425, -6813, -10126, -13328, -16384, -19261, -21926, -24351, -26510, -28378, -29935, -31164, -32052,
-32588, -32768, -32588, -32052, -31164, -29935, -28378, -26510, -24351, -21926, -19261, -16384, -13328, -10126, -6813, -3425};
const uint8_t BUSY_AUDIO_LEN = 60U;
CFMTimeout::CFMTimeout() :
m_level(128 * 128),
m_running(false),
m_pos(0U),
m_n(0U)
{
}
void CFMTimeout::setParams(uint8_t level)
{
m_level = q15_t(level * 5);
}
q15_t CFMTimeout::getAudio()
{
q15_t sample = 0;
if (!m_running)
return sample;
if (m_pos >= 12000U) {
q31_t sample31 = BUSY_AUDIO[m_n] * m_level;
sample = q15_t(__SSAT((sample31 >> 15), 16));
m_n++;
if (m_n >= BUSY_AUDIO_LEN)
m_n = 0U;
}
m_pos++;
if (m_pos >= 24000U)
m_pos = 0U;
return sample;
}
void CFMTimeout::start()
{
m_running = true;
m_pos = 0U;
m_n = 0U;
}
void CFMTimeout::stop()
{
m_running = false;
}
+42
View File
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2020 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(FMTimeout_H)
#define FMTimeout_H
#include "Config.h"
class CFMTimeout {
public:
CFMTimeout();
void setParams(uint8_t level);
void start();
void stop();
q15_t getAudio();
private:
q15_t m_level;
bool m_running;
uint32_t m_pos;
uint8_t m_n;
};
#endif
+70
View File
@@ -0,0 +1,70 @@
/*
* Copyright (C) 2009,2010,2015,2020 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 "FMTimer.h"
CFMTimer::CFMTimer() :
m_timeout(0U),
m_timer(0U)
{
}
void CFMTimer::setTimeout(uint16_t secs, uint32_t msecs)
{
m_timeout = (secs * 24000U) + (msecs * 24U);
}
uint32_t CFMTimer::getTimeout() const
{
return m_timeout / 24U;
}
void CFMTimer::start()
{
if (m_timeout > 0U)
m_timer = 1U;
}
void CFMTimer::stop()
{
m_timer = 0U;
}
void CFMTimer::clock(uint8_t length)
{
if (m_timer > 0U && m_timeout > 0U)
m_timer += length;
}
bool CFMTimer::isRunning() const
{
return m_timer > 0U;
}
bool CFMTimer::hasExpired() const
{
if (m_timeout == 0U || m_timer == 0U)
return false;
if (m_timer > m_timeout)
return true;
return false;
}
+47
View File
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2009,2010,2015,2020 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(FMTimer_H)
#define FMTimer_H
#include "Config.h"
class CFMTimer {
public:
CFMTimer();
void setTimeout(uint16_t secs, uint32_t msecs);
uint32_t getTimeout() const;
void start();
void stop();
void clock(uint8_t length);
bool isRunning() const;
bool hasExpired() const;
private:
uint32_t m_timeout;
uint32_t m_timer;
};
#endif
-1
View File
@@ -1 +0,0 @@
#define GITVERSION "0000000"
+27 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020 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
@@ -50,6 +50,8 @@ enum MMDVM_STATE {
STATE_P25 = 4,
STATE_NXDN = 5,
STATE_POCSAG = 6,
STATE_FM = 10,
STATE_AX25 = 11,
// Dummy states start at 90
STATE_NXDNCAL1K = 91,
@@ -60,7 +62,15 @@ enum MMDVM_STATE {
STATE_RSSICAL = 96,
STATE_CWID = 97,
STATE_DMRCAL = 98,
STATE_DSTARCAL = 99
STATE_DSTARCAL = 99,
STATE_INTCAL = 100,
STATE_POCSAGCAL = 101,
STATE_FMCAL10K = 102,
STATE_FMCAL12K = 103,
STATE_FMCAL15K = 104,
STATE_FMCAL20K = 105,
STATE_FMCAL25K = 106,
STATE_FMCAL30K = 107
};
#include "SerialPort.h"
@@ -80,13 +90,18 @@ enum MMDVM_STATE {
#include "POCSAGTX.h"
#include "CalDStarRX.h"
#include "CalDStarTX.h"
#include "CalFM.h"
#include "CalDMR.h"
#include "CalP25.h"
#include "CalNXDN.h"
#include "CalPOCSAG.h"
#include "CalRSSI.h"
#include "CWIdTX.h"
#include "AX25RX.h"
#include "AX25TX.h"
#include "Debug.h"
#include "IO.h"
#include "FM.h"
const uint8_t MARK_SLOT1 = 0x08U;
const uint8_t MARK_SLOT2 = 0x04U;
@@ -94,8 +109,8 @@ const uint8_t MARK_NONE = 0x00U;
const uint16_t RX_BLOCK_SIZE = 2U;
const uint16_t TX_RINGBUFFER_SIZE = 1000U;
const uint16_t RX_RINGBUFFER_SIZE = 1200U;
const uint16_t TX_RINGBUFFER_SIZE = 500U;
const uint16_t RX_RINGBUFFER_SIZE = 600U;
#if defined(STM32F105xC) || defined(__MK20DX256__)
const uint16_t TX_BUFFER_LEN = 2000U;
@@ -111,6 +126,8 @@ extern bool m_ysfEnable;
extern bool m_p25Enable;
extern bool m_nxdnEnable;
extern bool m_pocsagEnable;
extern bool m_fmEnable;
extern bool m_ax25Enable;
extern bool m_duplex;
@@ -141,11 +158,17 @@ extern CNXDNTX nxdnTX;
extern CPOCSAGTX pocsagTX;
extern CFM fm;
extern CAX25RX ax25RX;
extern CAX25TX ax25TX;
extern CCalDStarRX calDStarRX;
extern CCalDStarTX calDStarTX;
extern CCalDMR calDMR;
extern CCalFM calFM;
extern CCalP25 calP25;
extern CCalNXDN calNXDN;
extern CCalPOCSAG calPOCSAG;
extern CCalRSSI calRSSI;
extern CCWIdTX cwIdTX;
+106 -145
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2015 by Jim Mclaughlin KI6ZUM
* Copyright (C) 2016 by Colin Durbridge G4EML
*
@@ -22,41 +22,35 @@
#include "Globals.h"
#include "IO.h"
// Generated using [b, a] = butter(1, 0.0005) in MATLAB
static q31_t DC_FILTER[] = {1685306, 0, 1685306, 0, 2144113034, 0}; // {b0, 0, b1, b2, -a1, -a2}
// 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};
const uint16_t RRC_0_2_FILTER_LEN = 42U;
// Generated using rcosdesign(0.2, 8, 10, 'sqrt') in MATLAB
static q15_t RRC_0_2_FILTER[] = {284, 198, 73, -78, -240, -393, -517, -590, -599, -533, -391, -181, 79, 364, 643, 880, 1041, 1097, 1026, 819,
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 RRC_0_2_FILTER_LEN = 82U;
const uint16_t NXDN_0_2_FILTER_LEN = 82U;
// Generated using rcosdesign(0.2, 8, 20, 'sqrt') in MATLAB
static q15_t NXDN_0_2_FILTER[] = {201, 174, 140, 99, 52, 0, -55, -112, -170, -226, -278, -325, -365, -397, -417, -427, -424, -407, -377, -333, -277, -208,
-128, -40, 56, 156, 258, 358, 455, 544, 622, 687, 736, 766, 775, 762, 725, 664, 579, 471, 342, 193, 27, -151, -338, -528,
-718, -901, -1072, -1225, -1354, -1454, -1520, -1547, -1530, -1466, -1353, -1189, -972, -704, -385, -18, 394, 846, 1333,
1850, 2388, 2940, 3498, 4053, 4598, 5122, 5619, 6079, 6494, 6859, 7166, 7410, 7588, 7696, 7732, 7696, 7588, 7410, 7166,
6859, 6494, 6079, 5619, 5122, 4598, 4053, 3498, 2940, 2388, 1850, 1333, 846, 394, -18, -385, -704, -972, -1189, -1353,
-1466, -1530, -1547, -1520, -1454, -1354, -1225, -1072, -901, -718, -528, -338, -151, 27, 193, 342, 471, 579, 664, 725,
762, 775, 766, 736, 687, 622, 544, 455, 358, 258, 156, 56, -40, -128, -208, -277, -333, -377, -407, -424, -427, -417, -397,
-365, -325, -278, -226, -170, -112, -55, 0, 52, 99, 140, 174, 201, 0};
const uint16_t NXDN_0_2_FILTER_LEN = 162U;
static q15_t NXDN_ISINC_FILTER[] = {7616, -1333, -1856, -2611, -3399, -4006, -4230, -3918, -2988, -1458, 561, 2867, 5200, 7276, 8832, 9665,
9665, 8832, 7276, 5200, 2867, 561, -1458, -2988, -3918, -4230, -4006, -3399, -2611, -1856, -1333, 7616};
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;
#if !defined (DSTARBOXCAR)
// Generated using gaussfir(0.5, 4, 10) in MATLAB
static q15_t GAUSSIAN_0_5_FILTER[] = {1, 4, 15, 52, 151, 380, 832, 1579, 2599, 3710, 4594, 4933, 4594, 3710, 2599, 1579, 832, 380, 151, 52, 15, 4, 1, 0};
const uint16_t GAUSSIAN_0_5_FILTER_LEN = 24U;
#endif
// 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[] = {6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 0, 0};
const uint16_t BOXCAR_FILTER_LEN = 12U;
static q15_t BOXCAR_FILTER[] = {12000, 12000, 12000, 12000, 12000, 0};
const uint16_t BOXCAR_FILTER_LEN = 6U;
const uint16_t DC_OFFSET = 2048U;
@@ -68,16 +62,12 @@ m_rssiBuffer(RX_RINGBUFFER_SIZE),
m_dcFilter(),
m_dcState(),
m_rrcFilter(),
#if !defined (DSTARBOXCAR)
m_gaussianFilter(),
#endif
m_boxcarFilter(),
m_nxdnFilter(),
m_nxdnISincFilter(),
m_rrcState(),
#if !defined (DSTARBOXCAR)
m_gaussianState(),
#endif
m_boxcarState(),
m_nxdnState(),
m_nxdnISincState(),
@@ -90,8 +80,11 @@ m_ysfTXLevel(128 * 128),
m_p25TXLevel(128 * 128),
m_nxdnTXLevel(128 * 128),
m_pocsagTXLevel(128 * 128),
m_fmTXLevel(128 * 128),
m_ax25TXLevel(128 * 128),
m_rxDCOffset(DC_OFFSET),
m_txDCOffset(DC_OFFSET),
m_useCOSAsLockout(false),
m_ledCount(0U),
m_ledValue(true),
m_detect(false),
@@ -100,14 +93,12 @@ m_dacOverflow(0U),
m_watchdog(0U),
m_lockout(false)
{
::memset(m_rrcState, 0x00U, 140U * sizeof(q15_t));
#if !defined (DSTARBOXCAR)
::memset(m_gaussianState, 0x00U, 80U * sizeof(q15_t));
#endif
::memset(m_boxcarState, 0x00U, 60U * sizeof(q15_t));
::memset(m_nxdnState, 0x00U, 220U * sizeof(q15_t));
::memset(m_nxdnISincState, 0x00U, 60U * sizeof(q15_t));
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
::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_nxdnState, 0x00U, 110U * sizeof(q15_t));
::memset(m_nxdnISincState, 0x00U, 60U * sizeof(q15_t));
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
m_dcFilter.numStages = DC_FILTER_STAGES;
m_dcFilter.pState = m_dcState;
@@ -117,11 +108,11 @@ m_lockout(false)
m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN;
m_rrcFilter.pState = m_rrcState;
m_rrcFilter.pCoeffs = RRC_0_2_FILTER;
#if !defined (DSTARBOXCAR)
m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN;
m_gaussianFilter.pState = m_gaussianState;
m_gaussianFilter.pCoeffs = GAUSSIAN_0_5_FILTER;
#endif
m_boxcarFilter.numTaps = BOXCAR_FILTER_LEN;
m_boxcarFilter.pState = m_boxcarState;
m_boxcarFilter.pCoeffs = BOXCAR_FILTER;
@@ -149,123 +140,75 @@ void CIO::selfTest()
// We exclude PTT to avoid trigger the transmitter
setLEDInt(ledValue);
setCOSInt(ledValue);
#if defined(MODE_PINS)
#if defined(MODE_LEDS)
setDStarInt(ledValue);
setDMRInt(ledValue);
setYSFInt(ledValue);
setP25Int(ledValue);
setNXDNInt(ledValue);
setPOCSAGInt(ledValue);
setFMInt(ledValue);
#endif
delayInt(250);
}
#if defined(MODE_PINS)
#if defined(MODE_LEDS)
setDStarInt(true);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
setFMInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
delayInt(250);
setP25Int(true);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
#if !defined(USE_ALTERNATE_NXDN_LEDS)
delayInt(250);
setNXDNInt(true);
setPOCSAGInt(false);
delayInt(250);
#endif
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(true);
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
delayInt(250);
setPOCSAGInt(true);
delayInt(250);
#endif
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(true);
#if !defined(USE_ALTERNATE_FM_LEDS)
delayInt(250);
setFMInt(true);
delayInt(250);
setFMInt(false);
#endif
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
delayInt(250);
setPOCSAGInt(false);
delayInt(250);
#endif
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
#if !defined(USE_ALTERNATE_NXDN_LEDS)
delayInt(250);
setNXDNInt(false);
setPOCSAGInt(false);
#endif
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(false);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
#endif
}
@@ -286,8 +229,8 @@ void CIO::process()
m_ledCount++;
if (m_started) {
// Two seconds timeout
if (m_watchdog >= 96000U) {
if (m_modemState == STATE_DSTAR || m_modemState == STATE_DMR || m_modemState == STATE_YSF || m_modemState == STATE_P25 || m_modemState == STATE_NXDN) {
if (m_watchdog >= 48000U) {
if (m_modemState == STATE_DSTAR || m_modemState == STATE_DMR || m_modemState == STATE_YSF || m_modemState == STATE_P25 || m_modemState == STATE_NXDN || m_modemState == STATE_POCSAG) {
if (m_modemState == STATE_DMR && m_tx)
dmrTX.setStart(false);
m_modemState = STATE_IDLE;
@@ -300,14 +243,14 @@ void CIO::process()
#if defined(CONSTANT_SRV_LED)
setLEDInt(true);
#else
if (m_ledCount >= 48000U) {
if (m_ledCount >= 24000U) {
m_ledCount = 0U;
m_ledValue = !m_ledValue;
setLEDInt(m_ledValue);
}
#endif
} else {
if (m_ledCount >= 480000U) {
if (m_ledCount >= 240000U) {
m_ledCount = 0U;
m_ledValue = !m_ledValue;
setLEDInt(m_ledValue);
@@ -315,9 +258,8 @@ void CIO::process()
return;
}
#if defined(USE_COS_AS_LOCKOUT)
m_lockout = getCOSInt();
#endif
if (m_useCOSAsLockout)
m_lockout = getCOSInt();
// Switch off the transmitter if needed
if (m_txBuffer.getData() == 0U && m_tx) {
@@ -370,17 +312,9 @@ void CIO::process()
if (m_dstarEnable) {
q15_t GMSKVals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#endif
#else
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
@@ -422,21 +356,30 @@ void CIO::process()
dmrDMORX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
}
}
if (m_fmEnable) {
bool cos = getCOSInt();
#if defined(USE_DCBLOCKER)
fm.samples(cos, dcSamples, RX_BLOCK_SIZE);
#else
fm.samples(cos, samples, RX_BLOCK_SIZE);
#endif
}
if (m_ax25Enable) {
#if defined(USE_DCBLOCKER)
ax25RX.samples(dcSamples, RX_BLOCK_SIZE);
#else
ax25RX.samples(samples, RX_BLOCK_SIZE);
#endif
}
} else if (m_modemState == STATE_DSTAR) {
if (m_dstarEnable) {
q15_t GMSKVals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#endif
#else
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
@@ -488,13 +431,21 @@ void CIO::process()
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_FM) {
bool cos = getCOSInt();
#if defined(USE_DCBLOCKER)
fm.samples(cos, dcSamples, RX_BLOCK_SIZE);
if (m_ax25Enable)
ax25RX.samples(dcSamples, RX_BLOCK_SIZE);
#else
fm.samples(cos, samples, RX_BLOCK_SIZE);
if (m_ax25Enable)
ax25RX.samples(samples, RX_BLOCK_SIZE);
#endif
} else if (m_modemState == STATE_DSTARCAL) {
q15_t GMSKVals[RX_BLOCK_SIZE];
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
calDStarRX.samples(GMSKVals, RX_BLOCK_SIZE);
} else if (m_modemState == STATE_RSSICAL) {
calRSSI.samples(rssi, RX_BLOCK_SIZE);
@@ -536,6 +487,12 @@ void CIO::write(MMDVM_STATE mode, q15_t* samples, uint16_t length, const uint8_t
case STATE_POCSAG:
txLevel = m_pocsagTXLevel;
break;
case STATE_FM:
txLevel = m_fmTXLevel;
break;
case STATE_AX25:
txLevel = m_ax25TXLevel;
break;
default:
txLevel = m_cwIdTXLevel;
break;
@@ -577,17 +534,18 @@ void CIO::setADCDetection(bool detect)
void CIO::setMode()
{
#if defined(MODE_PINS)
#if defined(MODE_LEDS)
setDStarInt(m_modemState == STATE_DSTAR);
setDMRInt(m_modemState == STATE_DMR);
setYSFInt(m_modemState == STATE_YSF);
setP25Int(m_modemState == STATE_P25);
setNXDNInt(m_modemState == STATE_NXDN);
setPOCSAGInt(m_modemState == STATE_POCSAG);
setFMInt(m_modemState == STATE_FM);
#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, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, int16_t txDCOffset, int16_t rxDCOffset)
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, uint8_t pocsagTXLevel, uint8_t fmTXLevel, uint8_t ax25TXLevel, int16_t txDCOffset, int16_t rxDCOffset, bool useCOSAsLockout)
{
m_pttInvert = pttInvert;
@@ -599,9 +557,13 @@ void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rx
m_p25TXLevel = q15_t(p25TXLevel * 128);
m_nxdnTXLevel = q15_t(nxdnTXLevel * 128);
m_pocsagTXLevel = q15_t(pocsagTXLevel * 128);
m_fmTXLevel = q15_t(fmTXLevel * 128);
m_ax25TXLevel = q15_t(ax25TXLevel * 128);
m_rxDCOffset = DC_OFFSET + rxDCOffset;
m_txDCOffset = DC_OFFSET + txDCOffset;
m_useCOSAsLockout = useCOSAsLockout;
if (rxInvert)
m_rxLevel = -m_rxLevel;
@@ -649,4 +611,3 @@ bool CIO::hasLockout() const
{
return m_lockout;
}
+11 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020 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, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, int16_t txDCOffset, int16_t rxDCOffset);
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 nxdnTXLevel, uint8_t pocsagTXLevel, uint8_t fmTXLevel, uint8_t ax25TXLevel, int16_t txDCOffset, int16_t rxDCOffset, bool useCOSAsLockout);
void getOverflow(bool& adcOverflow, bool& dacOverflow);
@@ -67,18 +67,14 @@ private:
q31_t m_dcState[4];
arm_fir_instance_q15 m_rrcFilter;
#if !defined (DSTARBOXCAR)
arm_fir_instance_q15 m_gaussianFilter;
#endif
arm_fir_instance_q15 m_boxcarFilter;
arm_fir_instance_q15 m_nxdnFilter;
arm_fir_instance_q15 m_nxdnISincFilter;
q15_t m_rrcState[140U]; // NoTaps + BlockSize - 1, 82 + 20 - 1 plus some spare
#if !defined (DSTARBOXCAR)
q15_t m_gaussianState[80U]; // NoTaps + BlockSize - 1, 24 + 20 - 1 plus some spare
#endif
q15_t m_boxcarState[60U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare
q15_t m_nxdnState[220U]; // NoTaps + BlockSize - 1, 162 + 20 - 1 plus some spare
q15_t m_rrcState[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
bool m_pttInvert;
@@ -90,10 +86,14 @@ private:
q15_t m_p25TXLevel;
q15_t m_nxdnTXLevel;
q15_t m_pocsagTXLevel;
q15_t m_fmTXLevel;
q15_t m_ax25TXLevel;
uint16_t m_rxDCOffset;
uint16_t m_txDCOffset;
bool m_useCOSAsLockout;
uint32_t m_ledCount;
bool m_ledValue;
@@ -122,9 +122,9 @@ private:
void setP25Int(bool on);
void setNXDNInt(bool on);
void setPOCSAGInt(bool on);
void setFMInt(bool on);
void delayInt(unsigned int dly);
};
#endif
+21 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2015 by Jim Mclaughlin KI6ZUM
* Copyright (C) 2016 by Colin Durbridge G4EML
*
@@ -35,6 +35,7 @@
#define PIN_P25 19
#define PIN_NXDN 20
#define PIN_POCSAG 4
#define PIN_FM 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
@@ -50,6 +51,7 @@
#define PIN_P25 6
#define PIN_NXDN 5
#define PIN_POCSAG 4
#define PIN_FM 3
#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
@@ -67,6 +69,7 @@
#define PIN_P25 6
#define PIN_NXDN 5
#define PIN_POCSAG 4
#define PIN_FM 3
#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
@@ -107,6 +110,9 @@ void CIO::initInt()
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
pinMode(PIN_POCSAG, OUTPUT);
#endif
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
pinMode(PIN_FM, OUTPUT);
#endif
#endif
}
@@ -152,11 +158,11 @@ void CIO::startInt()
TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |
TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR;
#if defined(EXTERNAL_OSC)
t->TC_RC = EXTERNAL_OSC / 48000; // Counter resets on RC, so sets period in terms of the external clock
t->TC_RA = EXTERNAL_OSC / 96000; // Roughly square wave
t->TC_RC = EXTERNAL_OSC / 24000; // Counter resets on RC, so sets period in terms of the external clock
t->TC_RA = EXTERNAL_OSC / 48000; // Roughly square wave
#else
t->TC_RC = 875; // Counter resets on RC, so sets period in terms of 42MHz internal clock
t->TC_RA = 438; // Roughly square wave
t->TC_RC = 1750; // Counter resets on RC, so sets period in terms of 42MHz internal clock
t->TC_RA = 880; // Roughly square wave
#endif
t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET; // Set clear and set from RA and RC compares
t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG; // re-enable local clocking and switch to hardware trigger source.
@@ -258,10 +264,19 @@ void CIO::setPOCSAGInt(bool on)
#endif
}
void CIO::setFMInt(bool on)
{
#if defined(USE_ALTERNATE_FM_LEDS)
digitalWrite(PIN_DSTAR, on ? HIGH : LOW);
digitalWrite(PIN_YSF, on ? HIGH : LOW);
#else
digitalWrite(PIN_FM, on ? HIGH : LOW);
#endif
}
void CIO::delayInt(unsigned int dly)
{
delay(dly);
}
#endif
+73
View File
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2019,2020 by BG5HHP
*
* 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.
*/
#ifndef _IO_PINS_H
#define _IO_PINS_H
#if !defined(CONFIG_H)
#error "Requires Config.h to be included first!"
#endif
#if defined(STM32F4_RPT_HAT_TGO)
#include "pins/pins_f4_rpt_tgo.h"
#elif defined(STM32F4_DISCOVERY)
#include "pins/pins_f4_discovery.h"
#elif defined(STM32F4_PI)
#include "pins/pins_f4_pi.h"
#elif defined(STM32F722_PI)
#include "pins/pins_f7_pi.h"
#elif defined(STM32F4_F4M)
#include "pins/pins_f4_f4m.h"
#elif defined(STM32F722_F7M)
#include "pins/pins_f7_f7m.h"
#elif defined(STM32F722_RPT_HAT)
#include "pins/pins_f7_rpt_hat.h"
#elif defined(STM32F4_NUCLEO)
#if defined(STM32F4_NUCLEO_MORPHO_HEADER)
#include "pins/pins_f4_nucleo_morpho.h"
#elif defined(STM32F4_NUCLEO_ARDUINO_HEADER)
#include "pins/pins_f4_nucleo_arduino.h"
#else
#error "Either STM32F4_NUCLEO_MORPHO_HEADER or STM32F4_NUCLEO_ARDUINO_HEADER need to be defined"
#endif
#elif defined(STM32F7_NUCLEO)
#include "pins/pins_f7_nucleo.h"
#elif defined(STM32F4_DVM)
#include "pins/pins_f4_stm32dvm_v3.h"
#elif defined(DRCC_DVM_NQF)
#include "pins/pins_f4_drcc_nqf.h"
#elif defined(STM32F4_EDA_405) || defined(STM32F4_EDA_446)
#include "pins/pins_f4_stm32eda.h"
#else
#error "A valid board type macro need to be defined."
#endif
#endif //#ifndef _IO_PINS_H
+74 -883
View File
File diff suppressed because it is too large Load Diff
+12 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
* Copyright (C) 2016, 2017 by Andy Uribe CA6JAU
* Copyright (C) 2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2017,2018,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2017 by Wojciech Krutnik N0CALL
*
* This program is free software; you can redistribute it and/or modify
@@ -111,7 +111,7 @@ USART1_RXD PA10 input (AF)
const uint16_t DC_OFFSET = 2048U;
// Sampling frequency
#define SAMP_FREQ 48000
#define SAMP_FREQ 24000
extern "C" {
void TIM2_IRQHandler() {
@@ -369,7 +369,9 @@ void CIO::interrupt()
{
uint8_t control = MARK_NONE;
uint16_t sample = DC_OFFSET;
#if defined(SEND_RSSI_DATA)
uint16_t rawRSSI = 0U;
#endif
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)
@@ -458,6 +460,14 @@ void CIO::setPOCSAGInt(bool on)
#endif
}
void CIO::setFMInt(bool on)
{
#if defined(USE_ALTERNATE_FM_LEDS)
BB_DSTAR = !!on;
BB_YSF = !!on;
#endif
}
void CIO::delayInt(unsigned int dly)
{
delay(dly);
+20 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2016,2017,2018,2020 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
@@ -37,9 +37,11 @@
#if defined(__MK20DX256__)
#define PIN_NXDN 2
#define PIN_POCSAG 3
#define PIN_FM 4
#else
#define PIN_NXDN 24
#define PIN_POCSAG 25
#define PIN_FM 26
#endif
#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
@@ -76,6 +78,9 @@ void CIO::initInt()
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
pinMode(PIN_POCSAG, OUTPUT);
#endif
#if !defined(USE_ALTERNATE_FM_LEDS)
pinMode(PIN_FM, OUTPUT);
#endif
#endif
}
@@ -125,7 +130,7 @@ void CIO::startInt()
#endif
#if defined(EXTERNAL_OSC)
// Set ADC0 to trigger from the LPTMR at 48 kHz
// Set ADC0 to trigger from the LPTMR at 24 kHz
SIM_SOPT7 = SIM_SOPT7_ADC0ALTTRGEN | // Enable ADC0 alternate trigger
SIM_SOPT7_ADC0TRGSEL(14); // Trigger ADC0 by LPTMR0
@@ -134,14 +139,14 @@ void CIO::startInt()
SIM_SCGC5 |= SIM_SCGC5_LPTIMER; // Enable Low Power Timer Access
LPTMR0_CSR = 0; // Disable
LPTMR0_PSR = LPTMR_PSR_PBYP; // Bypass prescaler/filter
LPTMR0_CMR = (EXTERNAL_OSC / 48000) - 1; // Frequency divided by CMR + 1
LPTMR0_CMR = (EXTERNAL_OSC / 24000) - 1; // Frequency divided by CMR + 1
LPTMR0_CSR = LPTMR_CSR_TPS(2) | // Pin: 0=CMP0, 1=xtal, 2=pin13
LPTMR_CSR_TMS; // Mode Select, 0=timer, 1=counter
LPTMR0_CSR |= LPTMR_CSR_TEN; // Enable
#else
// Setup PDB for ADC0 at 48 kHz
// Setup PDB for ADC0 at 24 kHz
SIM_SCGC6 |= SIM_SCGC6_PDB; // Enable PDB clock
PDB0_MOD = (F_BUS / 48000) - 1; // Timer period - 1
PDB0_MOD = (F_BUS / 24000) - 1; // Timer period - 1
PDB0_IDLY = 0; // Interrupt delay
PDB0_CH0C1 = PDB_CHnC1_TOS | PDB_CHnC1_EN; // Enable pre-trigger for ADC0
PDB0_SC = PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | // SW trigger, enable interrupts, continuous mode
@@ -243,6 +248,16 @@ void CIO::setPOCSAGInt(bool on)
#endif
}
void CIO::setFMInt(bool on)
{
#if defined(USE_ALTERNATE_FM_LEDS)
digitalWrite(PIN_DSTAR, on ? HIGH : LOW);
digitalWrite(PIN_YSF, on ? HIGH : LOW);
#else
digitalWrite(PIN_FM, on ? HIGH : LOW);
#endif
}
void CIO::delayInt(unsigned int dly)
{
delay(dly);
+21 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Mathis Schmieder DB9MAT
* Copyright (C) 2016 by Colin Durbridge G4EML
*
@@ -32,6 +32,8 @@ bool m_ysfEnable = true;
bool m_p25Enable = true;
bool m_nxdnEnable = true;
bool m_pocsagEnable = true;
bool m_fmEnable = true;
bool m_ax25Enable = true;
bool m_duplex = true;
@@ -59,11 +61,17 @@ CNXDNTX nxdnTX;
CPOCSAGTX pocsagTX;
CFM fm;
CAX25RX ax25RX;
CAX25TX ax25TX;
CCalDStarRX calDStarRX;
CCalDStarTX calDStarTX;
CCalDMR calDMR;
CCalP25 calP25;
CCalNXDN calNXDN;
CCalFM calFM;
CCalPOCSAG calPOCSAG;
CCalRSSI calRSSI;
CCWIdTX cwIdTX;
@@ -105,6 +113,12 @@ void loop()
if (m_pocsagEnable && (m_modemState == STATE_POCSAG || pocsagTX.busy()))
pocsagTX.process();
if (m_ax25Enable && (m_modemState == STATE_IDLE || m_modemState == STATE_FM))
ax25TX.process();
if (m_fmEnable && m_modemState == STATE_FM)
fm.process();
if (m_modemState == STATE_DSTARCAL)
calDStarTX.process();
@@ -117,6 +131,12 @@ void loop()
if (m_modemState == STATE_NXDNCAL1K)
calNXDN.process();
if (m_modemState == STATE_POCSAGCAL)
calPOCSAG.process();
if (m_modemState == STATE_FMCAL10K || m_modemState == STATE_FMCAL12K || m_modemState == STATE_FMCAL15K || m_modemState == STATE_FMCAL20K || m_modemState == STATE_FMCAL25K ||m_modemState == STATE_FMCAL30K)
calFM.process();
if (m_modemState == STATE_IDLE)
cwIdTX.process();
}
+21 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
@@ -29,6 +29,8 @@ bool m_ysfEnable = true;
bool m_p25Enable = true;
bool m_nxdnEnable = true;
bool m_pocsagEnable = true;
bool m_fmEnable = true;
bool m_ax25Enable = true;
bool m_duplex = true;
@@ -56,11 +58,17 @@ CNXDNTX nxdnTX;
CPOCSAGTX pocsagTX;
CFM fm;
CAX25RX ax25RX;
CAX25 ax25TX;
CCalDStarRX calDStarRX;
CCalDStarTX calDStarTX;
CCalDMR calDMR;
CCalFM calFM;
CCalP25 calP25;
CCalNXDN calNXDN;
CCalPOCSAG calPOCSAG;
CCalRSSI calRSSI;
CCWIdTX cwIdTX;
@@ -102,19 +110,30 @@ void loop()
if (m_pocsagEnable && (m_modemState == STATE_POCSAG || pocsagTX.busy()))
pocsagTX.process();
if (m_ax25Enable && (m_modemState == STATE_IDLE || m_modemState == STATE_FM))
ax25TX.process();
if (m_fmEnable && m_modemState == STATE_FM)
fm.process();
if (m_modemState == STATE_DSTARCAL)
calDStarTX.process();
if (m_modemState == STATE_DMRCAL || m_modemState == STATE_LFCAL || m_modemState == STATE_DMRCAL1K || m_modemState == STATE_DMRDMO1K)
calDMR.process();
if (m_modemState == STATE_FMCAL10K || m_modemState == STATE_FMCAL12K || m_modemState == STATE_FMCAL15K || m_modemState == STATE_FMCAL20K || m_modemState == STATE_FMCAL25K || m_modemState == STATE_FMCAL30K)
calFM.process();
if (m_modemState == STATE_P25CAL1K)
calP25.process();
if (m_modemState == STATE_NXDNCAL1K)
calNXDN.process();
if (m_modemState == STATE_POCSAGCAL)
calPOCSAG.process();
if (m_modemState == STATE_IDLE)
cwIdTX.process();
}
-360
View File
@@ -1,360 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Project version="2G - 2.0.5" name="MMDVM_STM32F4xx">
<Target name="MMDVM_Discovery_407" isCurrent="0">
<Device manufacturerId="9" manufacturerName="ST" chipId="261" chipName="STM32F407VG" boardId="" boardName="" boardUrl="" coreId="" coreName=""/>
<BuildOption>
<Compile>
<Option name="OptimizationLevel" value="4"/>
<Option name="UseFPU" value="0"/>
<Option name="UserEditCompiler" value=""/>
<Option name="SupportCPlusplus" value="1"/>
<Option name="FPU" value="2"/>
<Option name="DEBUG" value="2"/>
<Option name="WARNING" value="1"/>
<Includepaths>
<Includepath path="."/>
</Includepaths>
<DefinedSymbols>
<Define name="STM32F4XX"/>
<Define name="USE_STDPERIPH_DRIVER"/>
<Define name="__ASSEMBLY__"/>
<Define name="SUPPORT_CPLUSPLUS"/>
<Define name="STM32F40_41xxx"/>
<Define name="HSE_VALUE=8000000"/>
<Define name="STM32F4_DISCOVERY"/>
<Define name="__FPU_USED"/>
</DefinedSymbols>
</Compile>
<Link useDefault="0">
<Option name="DiscardUnusedSection" value="0"/>
<Option name="UserEditLinkder" value=""/>
<Option name="UseMemoryLayout" value="0"/>
<Option name="nostartfiles" value="1"/>
<Option name="LTO" value="0"/>
<Option name="IsNewStartupCode" value="1"/>
<Option name="Library" value="Semihosting"/>
<Option name="UserEditLinker" value="-lstdc++; --specs=nano.specs;"/>
<LinkedLibraries>
<Libset dir="stm32f4xx_lib\cmsis\lib\gcc\" libs="arm_cortexm4lf_math"/>
</LinkedLibraries>
<MemoryAreas debugInFlashNotRAM="1">
<Memory name="IROM1" type="ReadOnly" size="0x00100000" startValue="0x08000000"/>
<Memory name="IRAM1" type="ReadWrite" size="0x00020000" startValue="0x20000000"/>
<Memory name="IROM2" type="ReadOnly" size="" startValue=""/>
<Memory name="IRAM2" type="ReadWrite" size="0x00010000" startValue="0x10000000"/>
</MemoryAreas>
<LocateLinkFile path="./stm32f4xx_link.ld" type="0"/>
</Link>
<Output>
<Option name="OutputFileType" value="0"/>
<Option name="Path" value="./"/>
<Option name="Name" value="MMDVM_DIS"/>
<Option name="HEX" value="1"/>
<Option name="BIN" value="1"/>
</Output>
<User>
<UserRun name="Run#1" type="Before" checked="0" value=""/>
<UserRun name="Run#1" type="After" checked="0" value=""/>
</User>
</BuildOption>
<DebugOption>
<Option name="org.coocox.codebugger.gdbjtag.core.adapter" value="ST-Link"/>
<Option name="org.coocox.codebugger.gdbjtag.core.debugMode" value="SWD"/>
<Option name="org.coocox.codebugger.gdbjtag.core.clockDiv" value="1M"/>
<Option name="org.coocox.codebugger.gdbjtag.corerunToMain" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkgdbserver" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.userDefineGDBScript" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.targetEndianess" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkResetMode" value="Type 0: Normal"/>
<Option name="org.coocox.codebugger.gdbjtag.core.resetMode" value="SYSRESETREQ"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifSemihost" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifCacheRom" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ipAddress" value="127.0.0.1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.portNumber" value="2009"/>
<Option name="org.coocox.codebugger.gdbjtag.core.autoDownload" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.verify" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.downloadFuction" value="Erase Effected"/>
<Option name="org.coocox.codebugger.gdbjtag.core.defaultAlgorithm" value="STM32F4xx_1024.elf"/>
</DebugOption>
<ExcludeFile/>
</Target>
<Target name="MMDVM_Pi_446" isCurrent="0">
<Device manufacturerId="9" manufacturerName="ST" chipId="344" chipName="STM32F407VG" boardId="" boardName="" boardUrl="" coreId="" coreName=""/>
<BuildOption>
<Compile>
<Option name="OptimizationLevel" value="4"/>
<Option name="UseFPU" value="0"/>
<Option name="UserEditCompiler" value=""/>
<Option name="SupportCPlusplus" value="1"/>
<Option name="FPU" value="2"/>
<Includepaths>
<Includepath path="."/>
</Includepaths>
<DefinedSymbols>
<Define name="STM32F4XX"/>
<Define name="USE_STDPERIPH_DRIVER"/>
<Define name="__ASSEMBLY__"/>
<Define name="SUPPORT_CPLUSPLUS"/>
<Define name="__FPU_USED"/>
<Define name="STM32F446xx"/>
<Define name="HSE_VALUE=12000000"/>
<Define name="STM32F4_PI"/>
<Define name="ARDUINO_MODE_PINS"/>
</DefinedSymbols>
</Compile>
<Link useDefault="0">
<Option name="DiscardUnusedSection" value="0"/>
<Option name="UserEditLinkder" value=""/>
<Option name="UseMemoryLayout" value="0"/>
<Option name="nostartfiles" value="1"/>
<Option name="LTO" value="0"/>
<Option name="IsNewStartupCode" value="1"/>
<Option name="Library" value="Semihosting"/>
<Option name="UserEditLinker" value="-lstdc++; --specs=nano.specs;"/>
<LinkedLibraries>
<Libset dir="stm32f4xx_lib\cmsis\lib\gcc\" libs="arm_cortexm4lf_math"/>
</LinkedLibraries>
<MemoryAreas debugInFlashNotRAM="1">
<Memory name="IROM1" type="ReadOnly" size="0x00100000" startValue="0x08000000"/>
<Memory name="IRAM1" type="ReadWrite" size="0x00020000" startValue="0x20000000"/>
<Memory name="IROM2" type="ReadOnly" size="" startValue=""/>
<Memory name="IRAM2" type="ReadWrite" size="0x00010000" startValue="0x10000000"/>
</MemoryAreas>
<LocateLinkFile path="./stm32f4xx_link.ld" type="0"/>
</Link>
<Output>
<Option name="OutputFileType" value="0"/>
<Option name="Path" value="./"/>
<Option name="Name" value="MMDVM_PI"/>
<Option name="HEX" value="1"/>
<Option name="BIN" value="1"/>
</Output>
<User>
<UserRun name="Run#1" type="Before" checked="0" value=""/>
<UserRun name="Run#1" type="After" checked="0" value=""/>
</User>
</BuildOption>
<DebugOption>
<Option name="org.coocox.codebugger.gdbjtag.core.adapter" value="ST-Link"/>
<Option name="org.coocox.codebugger.gdbjtag.core.debugMode" value="SWD"/>
<Option name="org.coocox.codebugger.gdbjtag.core.clockDiv" value="1M"/>
<Option name="org.coocox.codebugger.gdbjtag.corerunToMain" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkgdbserver" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.userDefineGDBScript" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.targetEndianess" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkResetMode" value="Type 0: Normal"/>
<Option name="org.coocox.codebugger.gdbjtag.core.resetMode" value="SYSRESETREQ"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifSemihost" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifCacheRom" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ipAddress" value="127.0.0.1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.portNumber" value="2009"/>
<Option name="org.coocox.codebugger.gdbjtag.core.autoDownload" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.verify" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.downloadFuction" value="Erase Effected"/>
<Option name="org.coocox.codebugger.gdbjtag.core.defaultAlgorithm" value="STM32F4xx_1024.elf"/>
</DebugOption>
<ExcludeFile/>
</Target>
<Target name="MMDVM_Nucleo_446" isCurrent="1">
<Device manufacturerId="9" manufacturerName="ST" chipId="261" chipName="STM32F407VG" boardId="" boardName="" boardUrl="" coreId="" coreName=""/>
<BuildOption>
<Compile>
<Option name="OptimizationLevel" value="4"/>
<Option name="UseFPU" value="0"/>
<Option name="UserEditCompiler" value=""/>
<Option name="SupportCPlusplus" value="1"/>
<Option name="FPU" value="2"/>
<Option name="DEBUG" value="2"/>
<Option name="WARNING" value="0"/>
<Includepaths>
<Includepath path="."/>
</Includepaths>
<DefinedSymbols>
<Define name="STM32F4XX"/>
<Define name="USE_STDPERIPH_DRIVER"/>
<Define name="__ASSEMBLY__"/>
<Define name="SUPPORT_CPLUSPLUS"/>
<Define name="HSE_VALUE=8000000"/>
<Define name="__FPU_USED"/>
<Define name="STM32F4_NUCLEO"/>
<Define name="STM32F446xx"/>
</DefinedSymbols>
</Compile>
<Link useDefault="0">
<Option name="DiscardUnusedSection" value="0"/>
<Option name="UserEditLinkder" value=""/>
<Option name="UseMemoryLayout" value="0"/>
<Option name="nostartfiles" value="1"/>
<Option name="LTO" value="0"/>
<Option name="IsNewStartupCode" value="1"/>
<Option name="Library" value="Semihosting"/>
<Option name="UserEditLinker" value="-lstdc++; --specs=nano.specs;"/>
<LinkedLibraries>
<Libset dir="stm32f4xx_lib\cmsis\lib\gcc\" libs="arm_cortexm4lf_math"/>
</LinkedLibraries>
<MemoryAreas debugInFlashNotRAM="1">
<Memory name="IROM1" type="ReadOnly" size="0x00100000" startValue="0x08000000"/>
<Memory name="IRAM1" type="ReadWrite" size="0x00020000" startValue="0x20000000"/>
<Memory name="IROM2" type="ReadOnly" size="" startValue=""/>
<Memory name="IRAM2" type="ReadWrite" size="0x00010000" startValue="0x10000000"/>
</MemoryAreas>
<LocateLinkFile path="./stm32f4xx_link.ld" type="0"/>
</Link>
<Output>
<Option name="OutputFileType" value="0"/>
<Option name="Path" value="./"/>
<Option name="Name" value="MMDVM_NUCLEO"/>
<Option name="HEX" value="1"/>
<Option name="BIN" value="1"/>
</Output>
<User>
<UserRun name="Run#1" type="Before" checked="0" value=""/>
<UserRun name="Run#1" type="After" checked="0" value=""/>
</User>
</BuildOption>
<DebugOption>
<Option name="org.coocox.codebugger.gdbjtag.core.adapter" value="ST-Link"/>
<Option name="org.coocox.codebugger.gdbjtag.core.debugMode" value="SWD"/>
<Option name="org.coocox.codebugger.gdbjtag.core.clockDiv" value="1M"/>
<Option name="org.coocox.codebugger.gdbjtag.corerunToMain" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkgdbserver" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.userDefineGDBScript" value=""/>
<Option name="org.coocox.codebugger.gdbjtag.core.targetEndianess" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.jlinkResetMode" value="Type 0: Normal"/>
<Option name="org.coocox.codebugger.gdbjtag.core.resetMode" value="SYSRESETREQ"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifSemihost" value="0"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ifCacheRom" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.ipAddress" value="127.0.0.1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.portNumber" value="2009"/>
<Option name="org.coocox.codebugger.gdbjtag.core.autoDownload" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.verify" value="1"/>
<Option name="org.coocox.codebugger.gdbjtag.core.downloadFuction" value="Erase Effected"/>
<Option name="org.coocox.codebugger.gdbjtag.core.defaultAlgorithm" value="STM32F4xx_1024.elf"/>
</DebugOption>
<ExcludeFile/>
</Target>
<Components path="./"/>
<LocalComponents/>
<Files>
<File name="DMRIdleRX.h" path="DMRIdleRX.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_dac.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_dac.c" type="1"/>
<File name="DMRDMOTX.cpp" path="DMRDMOTX.cpp" type="1"/>
<File name="DMRRX.cpp" path="DMRRX.cpp" type="1"/>
<File name="YSFRX.cpp" path="YSFRX.cpp" type="1"/>
<File name="STM32F4XX_Lib/Device/stm32f4xx.h" path="STM32F4XX_Lib/Device/stm32f4xx.h" type="1"/>
<File name="SampleRB.cpp" path="SampleRB.cpp" type="1"/>
<File name="CalDStarTX.h" path="CalDStarTX.h" type="1"/>
<File name="CalNXDN.cpp" path="CalNXDN.cpp" type="1"/>
<File name="NXDNTX.cpp" path="NXDNTX.cpp" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include/core_cm4.h" path="STM32F4XX_Lib/CMSIS/Include/core_cm4.h" type="1"/>
<File name="I2CTeensy.cpp" path="I2CTeensy.cpp" type="1"/>
<File name="DMRSlotRX.h" path="DMRSlotRX.h" type="1"/>
<File name="YSFRX.h" path="YSFRX.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include" path="" type="2"/>
<File name="NXDNRX.cpp" path="NXDNRX.cpp" type="1"/>
<File name="IO.cpp" path="IO.cpp" type="1"/>
<File name="DMRDMORX.cpp" path="DMRDMORX.cpp" type="1"/>
<File name="P25RX.h" path="P25RX.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/misc.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/misc.c" type="1"/>
<File name="STM32F4XX_Lib/CMSIS" path="" type="2"/>
<File name="SerialArduino.cpp" path="SerialArduino.cpp" type="1"/>
<File name="SerialPort.cpp" path="SerialPort.cpp" type="1"/>
<File name="CalP25.cpp" path="CalP25.cpp" type="1"/>
<File name="STM32F4XX_Lib/Device/stm32f4xx_conf.h" path="STM32F4XX_Lib/Device/stm32f4xx_conf.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_adc.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_adc.c" type="1"/>
<File name="IOSTM_CMSIS.cpp" path="IOSTM_CMSIS.cpp" type="1"/>
<File name="DStarTX.cpp" path="DStarTX.cpp" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_usart.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_usart.c" type="1"/>
<File name="YSFTX.h" path="YSFTX.h" type="1"/>
<File name="SampleRB.h" path="SampleRB.h" type="1"/>
<File name="SerialSTM_CMSIS.cpp" path="SerialSTM_CMSIS.cpp" type="1"/>
<File name="DMRRX.h" path="DMRRX.h" type="1"/>
<File name="IOTeensy.cpp" path="IOTeensy.cpp" type="1"/>
<File name="MMDVM.cpp" path="MMDVM.cpp" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmSimd.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmSimd.h" type="1"/>
<File name="POCSAGTX.cpp" path="POCSAGTX.cpp" type="1"/>
<File name="DMRDMORX.h" path="DMRDMORX.h" type="1"/>
<File name="GitVersion.h" path="GitVersion.h" type="1"/>
<File name="SerialPort.h" path="SerialPort.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_dac.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_dac.h" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" type="1"/>
<File name="STM32F4XX_Lib/Device/system_stm32f4xx.h" path="STM32F4XX_Lib/Device/system_stm32f4xx.h" type="1"/>
<File name="CWIdTX.h" path="CWIdTX.h" type="1"/>
<File name="CalDStarTX.cpp" path="CalDStarTX.cpp" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source" path="" type="2"/>
<File name="POCSAGTX.h" path="POCSAGTX.h" type="1"/>
<File name="DMRDMOTX.h" path="DMRDMOTX.h" type="1"/>
<File name="CalDMR.h" path="CalDMR.h" type="1"/>
<File name="IODue.cpp" path="IODue.cpp" type="1"/>
<File name="DMRTX.cpp" path="DMRTX.cpp" type="1"/>
<File name="CalRSSI.h" path="CalRSSI.h" type="1"/>
<File name="P25RX.cpp" path="P25RX.cpp" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Lib/GCC" path="" type="2"/>
<File name="STM32F4XX_Lib" path="" type="2"/>
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmInstr.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmInstr.h" type="1"/>
<File name="DMRTX.h" path="DMRTX.h" type="1"/>
<File name="STM32F4XX_Lib/Device/system_stm32f4xx.c" path="STM32F4XX_Lib/Device/system_stm32f4xx.c" type="1"/>
<File name="RSSIRB.h" path="RSSIRB.h" type="1"/>
<File name="STM32F4XX_Lib/Device/startup/startup_stm32f4xx.c" path="STM32F4XX_Lib/Device/startup/startup_stm32f4xx.c" type="1"/>
<File name="STM32F4XX_Lib/Device/startup" path="" type="2"/>
<File name="SerialRB.h" path="SerialRB.h" type="1"/>
<File name="NXDNDefines.h" path="NXDNDefines.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_gpio.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_gpio.h" type="1"/>
<File name="NXDNTX.h" path="NXDNTX.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver" path="" type="2"/>
<File name="DMRDefines.h" path="DMRDefines.h" type="1"/>
<File name="CalDMR.cpp" path="CalDMR.cpp" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_adc.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_adc.h" type="1"/>
<File name="SerialSTM.cpp" path="SerialSTM.cpp" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a" path="STM32F4XX_Lib/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a" type="1"/>
<File name="DStarDefines.h" path="DStarDefines.h" type="1"/>
<File name="DStarRX.h" path="DStarRX.h" type="1"/>
<File name="NXDNRX.h" path="NXDNRX.h" type="1"/>
<File name="Config.h" path="Config.h" type="1"/>
<File name="RingBuff.h" path="RingBuff.h" type="1"/>
<File name="DMRSlotType.cpp" path="DMRSlotType.cpp" type="1"/>
<File name="Globals.h" path="Globals.h" type="1"/>
<File name="STM32F4XX_Lib/Device" path="" type="2"/>
<File name="CalDStarRX.cpp" path="CalDStarRX.cpp" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_tim.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_tim.h" type="1"/>
<File name="CalNXDN.h" path="CalNXDN.h" type="1"/>
<File name="CalDStarRX.h" path="CalDStarRX.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include" path="" type="2"/>
<File name="CalRSSI.cpp" path="CalRSSI.cpp" type="1"/>
<File name="IO.h" path="IO.h" type="1"/>
<File name="Utils.cpp" path="Utils.cpp" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Lib/.DS_Store" path="STM32F4XX_Lib/CMSIS/Lib/.DS_Store" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/.DS_Store" path="STM32F4XX_Lib/CMSIS/.DS_Store" type="1"/>
<File name="Utils.h" path="Utils.h" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Lib" path="" type="2"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/.DS_Store" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/.DS_Store" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include/.DS_Store" path="STM32F4XX_Lib/CMSIS/Include/.DS_Store" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include/arm_math.h" path="STM32F4XX_Lib/CMSIS/Include/arm_math.h" type="1"/>
<File name="YSFDefines.h" path="YSFDefines.h" type="1"/>
<File name="DStarTX.h" path="DStarTX.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_rcc.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_rcc.c" type="1"/>
<File name="CalP25.h" path="CalP25.h" type="1"/>
<File name="STM32F4XX_Lib/Device/.DS_Store" path="STM32F4XX_Lib/Device/.DS_Store" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_rcc.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_rcc.h" type="1"/>
<File name="P25Defines.h" path="P25Defines.h" type="1"/>
<File name="DMRSlotType.h" path="DMRSlotType.h" type="1"/>
<File name="Debug.h" path="Debug.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/misc.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/misc.h" type="1"/>
<File name="P25TX.h" path="P25TX.h" type="1"/>
<File name="RSSIRB.cpp" path="RSSIRB.cpp" type="1"/>
<File name="DStarRX.cpp" path="DStarRX.cpp" type="1"/>
<File name="IOSTM.cpp" path="IOSTM.cpp" type="1"/>
<File name="DMRSlotRX.cpp" path="DMRSlotRX.cpp" type="1"/>
<File name="P25TX.cpp" path="P25TX.cpp" type="1"/>
<File name="SerialRB.cpp" path="SerialRB.cpp" type="1"/>
<File name="CWIdTX.cpp" path="CWIdTX.cpp" type="1"/>
<File name="DMRIdleRX.cpp" path="DMRIdleRX.cpp" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_usart.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_usart.h" type="1"/>
<File name="STM32Utils.h" path="STM32Utils.h" type="1"/>
<File name="STM32F4XX_Lib/.DS_Store" path="STM32F4XX_Lib/.DS_Store" type="1"/>
<File name="YSFTX.cpp" path="YSFTX.cpp" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_gpio.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_gpio.c" type="1"/>
</Files>
<Bookmarks/>
</Project>
+55 -16
View File
@@ -25,6 +25,7 @@ F7_LIB_PATH=./STM32F7XX_Lib
# MCU external clock frequency (Hz)
CLK_MMDVM_PI=12000000
CLK_NUCLEO=8000000
CLK_12MHZ=12000000
# Directory Structure
BINDIR=bin
@@ -93,6 +94,8 @@ ifndef $(OSC)
OSC=$(CLK_MMDVM_PI)
else ifeq ($(MAKECMDGOALS),pi-f722)
OSC=$(CLK_MMDVM_PI)
else ifeq ($(MAKECMDGOALS),drcc_nqf)
OSC=$(CLK_12MHZ)
else
OSC=$(CLK_NUCLEO)
endif
@@ -128,10 +131,19 @@ DEFS_NUCLEO_F767=-DUSE_HAL_DRIVER -DSTM32F767xx -DSTM32F7XX -DSTM32F7_NUCLEO -DH
DEFS_PI_F722=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_PI -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# MMDVM-F7M F0DEI board:
DEFS_F7M=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_F7M -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# MMDVM-F7-Hat F0DEI, DB9MAT, DF2ET board:
DEFS_F7HAT=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_F7HAT -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# MMDVM_RPT_Hat F0DEI, DB9MAT, DF2ET board:
DEFS_RPT_HAT=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_RPT_HAT -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# STM32F4 DVM board:
DEFS_DVM=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_DVM -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# MMDVM_RPT_Hat BG4TGO, BG5HHP board:
DEFS_RPT_HAT_TGO=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40_41xxx -DSTM32F4_RPT_HAT_TGO -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# DRCC_DVM BG7NQF board:
DEFS_DRCC_DVM=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DDRCC_DVM -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# WA0EDA F405 MTR2K, MASTR3 board:
DEFS_EDA_405=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40_41xxx -DSTM32F4_EDA_405 -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# WA0EDA F446 MTR2K, MASTR3 board:
DEFS_EDA_446=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_EDA_446 -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# Build compiler flags
CFLAGS_F4=-c $(MCFLAGS_F4) $(INCLUDES_F4)
@@ -147,10 +159,10 @@ LDFLAGS_F722 =-T stm32f722_link.ld $(MCFLAGS_F7) --specs=nosys.specs $(INCLUDES_
# 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
LDFLAGS=-Os --specs=nano.specs -Wl,-Map=bin/mmdvm.map
# Build Rules
.PHONY: all release dis pi pi-f722 f4m nucleo f767 dvm clean
.PHONY: all release dis pi pi-f722 f4m nucleo f767 dvm drcc_nqf clean
# Default target: Nucleo-64 F446RE board
all: nucleo
@@ -179,11 +191,17 @@ f7m: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_F7M)
f7m: LDFLAGS+=$(LDFLAGS_F722)
f7m: release_f7
f7hat: GitVersion.h
f7hat: CFLAGS+=$(CFLAGS_F7) $(DEFS_F7HAT)
f7hat: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_F7HAT)
f7hat: LDFLAGS+=$(LDFLAGS_F722)
f7hat: release_f7
rpt_hat: GitVersion.h
rpt_hat: CFLAGS+=$(CFLAGS_F7) $(DEFS_RPT_HAT)
rpt_hat: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_RPT_HAT)
rpt_hat: LDFLAGS+=$(LDFLAGS_F722)
rpt_hat: release_f7
rpt_hat_tgo: GitVersion.h
rpt_hat_tgo: CFLAGS+=$(CFLAGS_F4) $(DEFS_RPT_HAT_TGO)
rpt_hat_tgo: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_RPT_HAT_TGO)
rpt_hat_tgo: LDFLAGS+=$(LDFLAGS_F4)
rpt_hat_tgo: release_f4
nucleo: GitVersion.h
nucleo: CFLAGS+=$(CFLAGS_F4) $(DEFS_NUCLEO)
@@ -209,6 +227,24 @@ dvm: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_DVM)
dvm: LDFLAGS+=$(LDFLAGS_F4)
dvm: release_f4
drcc_nqf: GitVersion.h
drcc_nqf: CFLAGS+=$(CFLAGS_F4) $(DEFS_DRCC_DVM) -DDRCC_DVM_NQF
drcc_nqf: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_DRCC_DVM) -DDRCC_DVM_NQF
drcc_nqf: LDFLAGS+=$(LDFLAGS_F4)
drcc_nqf: release_f4
eda405: GitVersion.h
eda405: CFLAGS+=$(CFLAGS_F4) $(DEFS_EDA_405)
eda405: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_EDA_405)
eda405: LDFLAGS+=$(LDFLAGS_F4)
eda405: release_f4
eda446: GitVersion.h
eda446: CFLAGS+=$(CFLAGS_F4) $(DEFS_EDA_446)
eda446: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_EDA_446)
eda446: LDFLAGS+=$(LDFLAGS_F4)
eda446: release_f4
release_f4: $(BINDIR)
release_f4: $(OBJDIR_F4)
release_f4: $(BINDIR)/$(BINHEX_F4)
@@ -231,7 +267,7 @@ $(OBJDIR_F7):
$(BINDIR)/$(BINHEX_F4): $(BINDIR)/$(BINELF_F4)
$(CP) -O ihex $< $@
@echo "Objcopy from ELF to IHEX complete!\n"
$(BINDIR)/$(BINBIN_F4): $(BINDIR)/$(BINELF_F4)
$(CP) -O binary $< $@
@echo "Objcopy from ELF to BINARY complete!\n"
@@ -244,7 +280,7 @@ $(BINDIR)/$(BINELF_F4): $(OBJ_F4)
$(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"
@@ -330,22 +366,21 @@ endif
deploy-f4m: deploy-pi
deploy-dvm: deploy-pi
deploy-eda405: deploy-pi
deploy-eda446: 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),)
else 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
deploy-f7m: deploy-pi-f7
deploy-f7hat: deploy-pi-f7
deploy-rpt_hat: deploy-pi-f7
# Export the current git version if the index file exists, else 000...
GitVersion.h:
@@ -360,3 +395,7 @@ else
echo "#define GITVERSION \"0000000\"" > $@
endif
endif
flash_f4:
@echo "flashing firmware..."
st-flash write bin/$(BINBIN_F4) 0x8000000
+18 -4
View File
@@ -25,7 +25,7 @@ STARTUP:=$(SYSDIR)/startup_stm32f105xc.S
STARTUP_DEFS=
# Include directory for CMSIS
CMSISDIR:=/opt/STM32Cube_FW_F1_V1.4.0/Drivers/CMSIS
CMSISDIR:=STM32F10X_Lib/CMSIS
# Libraries
LIBDIR:=
@@ -65,7 +65,7 @@ COMMON_FLAGS =-mthumb -mlittle-endian -mcpu=$(MCPU)
COMMON_FLAGS+= -Wall
COMMON_FLAGS+= -I. -I$(CMSISDIR)/Include -I$(CMSISDIR)/Device/ST/STM32F1xx/Include -I$(SYSDIR)
COMMON_FLAGS+= $(addprefix -I,$(INCDIR))
COMMON_FLAGS+= -D$(MCU)
COMMON_FLAGS+= -D$(MCU) -DMADEBYMAKEFILE -DSTM32F1
COMMON_FLAGS+= -Os -flto -ffunction-sections -fdata-sections
COMMON_FLAGS+= -g
# Assembler flags
@@ -91,7 +91,7 @@ DEPENDS:=$(CSRC:%.c=$(OBJDIR)/%.d) $(CXXSRC:%.cpp=$(OBJDIR)/%.d)
# Targets
.PHONY: all
all: $(DIS) $(HEX)
all: GitVersion.h $(DIS) $(HEX)
$(SIZE) $(ELF)
.PHONY: program
@@ -116,7 +116,7 @@ debug: $(ELF)
.PHONY: clean
clean:
$(RM) $(OBJ) $(HEX) $(ELF) $(DIS) $(MAP) $(DEPENDS)
$(RM) $(OBJ) $(HEX) $(ELF) $(DIS) $(MAP) $(DEPENDS) GitVersion.h
# implicit rules
.elf.hex:
@@ -149,3 +149,17 @@ $(DIS): $(ELF)
# include dependecies
-include $(DEPENDS)
# Export the current git version if the index file exists, else 000...
GitVersion.h:
ifdef SYSTEMROOT
echo #define GITVERSION "0000000" > $@
else ifdef SystemRoot
echo #define GITVERSION "0000000" > $@
else
ifneq ("$(wildcard .git/index)","")
echo "#define GITVERSION \"$(shell git rev-parse --short HEAD)\"" > $@
else
echo "#define GITVERSION \"0000000\"" > $@
endif
endif
+1 -1
View File
@@ -19,7 +19,7 @@
#if !defined(NXDNDEFINES_H)
#define NXDNDEFINES_H
const unsigned int NXDN_RADIO_SYMBOL_LENGTH = 20U; // At 48 kHz sample rate
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;
+60 -21
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2018 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2018,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2017 by Andy Uribe CA6JAU
*
* This program is free software; you can redistribute it and/or modify
@@ -23,21 +23,19 @@
#include "NXDNDefines.h"
// NXDN RRC filter + SINC filter
static q15_t RRC_0_2_FILTER[] = {51, 71, 92, 112, 129, 141, 144, 138, 120, 87, 39, -26, -107, -204, -314, -437, -567, -702, -835,
-932,-1066, -1176, -1257, -1304, -1314, -1284, -1213, -1099, -944, -749, -519, -257, 30, 335, 651,
968, 1277, 1569, 1832, 2058, 2237, 2360, 2420, 2412, 2329, 2170, 1935, 1623, 1239, 790, 283, -271,
-858, -1466, -2076, -2671, -3233, -3742, -4178, -4521, -4754, -4857, -4815, -4614, -4242, -3690,
-2952, -2025, -912, 385, 1855, 3488, 5266, 7172, 9183, 11274, 13418, 15585, 17746, 19869, 21923,
23876, 25700, 27364, 28844, 30116, 31159, 31956, 32495, 32767, 32767, 32495, 31956, 31159, 30116,
28844, 27364, 25700, 23876, 21923, 19869, 17746, 15585, 13418, 11274, 9183, 7172, 5266, 3488, 1855,
385, -912, -2025, -2952, -3690, -4242, -4614, -4815, -4857, -4754, -4521, -4178, -3742, -3233, -2671,
-2076, -1466, -858, -271, 283, 790, 1239, 1623, 1935, 2170, 2329, 2412, 2420, 2360, 2237, 2058, 1832,
1569, 1277, 968, 651, 335, 30, -257, -519, -749, -944, -1099, -1213, -1284, -1314, -1304, -1257,
-1176, -1066, -932, -835, -702, -567, -437, -314, -204, -107, -26, 39, 87, 120, 138, 144, 141, 129,
112, 92, 71, 51}; // numTaps = 180, L = 20
// 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;
@@ -49,26 +47,32 @@ const uint8_t NXDN_SYNC = 0x5FU;
CNXDNTX::CNXDNTX() :
m_buffer(TX_BUFFER_LEN),
m_modFilter(),
m_sincFilter(),
m_modState(),
m_sincState(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(240U) // 200ms
m_txDelay(240U), // 200ms
m_txHang(3000U), // 5s
m_txCount(0U)
{
::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_poLen == 0U && m_buffer.getData() > 0U) {
if (!m_tx) {
for (uint16_t i = 0U; i < m_txDelay; i++)
m_poBuffer[m_poLen++] = NXDN_SYNC;
@@ -93,6 +97,8 @@ void CNXDNTX::process()
writeByte(c);
space -= 4U * NXDN_RADIO_SYMBOL_LENGTH;
if (m_duplex)
m_txCount = m_txHang;
if (m_poPtr >= m_poLen) {
m_poPtr = 0U;
@@ -100,10 +106,23 @@ void CNXDNTX::process()
return;
}
}
} else if (m_txCount > 0U) {
// Transmit silence until the hang timer has expired.
uint16_t space = io.getSpace();
while (space > (4U * NXDN_RADIO_SYMBOL_LENGTH)) {
writeSilence();
space -= 4U * NXDN_RADIO_SYMBOL_LENGTH;
m_txCount--;
if (m_txCount == 0U)
return;
}
}
}
uint8_t CNXDNTX::writeData(const uint8_t* data, uint8_t length)
uint8_t CNXDNTX::writeData(const uint8_t* data, uint16_t length)
{
if (length != (NXDN_FRAME_LENGTH_BYTES + 1U))
return 4U;
@@ -121,6 +140,7 @@ uint8_t CNXDNTX::writeData(const uint8_t* data, uint8_t length)
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;
@@ -142,7 +162,22 @@ void CNXDNTX::writeByte(uint8_t c)
}
}
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 4U);
::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::writeSilence()
{
q15_t inBuffer[4U] = {0x00U, 0x00U, 0x00U, 0x00U};
q15_t intBuffer[NXDN_RADIO_SYMBOL_LENGTH * 4U];
q15_t outBuffer[NXDN_RADIO_SYMBOL_LENGTH * 4U];
::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);
}
@@ -160,3 +195,7 @@ uint8_t CNXDNTX::getSpace() const
return m_buffer.getSpace() / NXDN_FRAME_LENGTH_BYTES;
}
void CNXDNTX::setParams(uint8_t txHang)
{
m_txHang = txHang * 600U;
}
+9 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018,2020 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
@@ -27,7 +27,7 @@ class CNXDNTX {
public:
CNXDNTX();
uint8_t writeData(const uint8_t* data, uint8_t length);
uint8_t writeData(const uint8_t* data, uint16_t length);
void process();
@@ -35,17 +35,23 @@ public:
uint8_t getSpace() const;
void setParams(uint8_t txHang);
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;
uint32_t m_txHang;
uint32_t m_txCount;
void writeByte(uint8_t c);
void writeSilence();
};
#endif
+6 -1
View File
@@ -20,7 +20,7 @@
#if !defined(P25DEFINES_H)
#define P25DEFINES_H
const unsigned int P25_RADIO_SYMBOL_LENGTH = 10U; // At 48 kHz sample rate
const unsigned int P25_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
const unsigned int P25_HDR_FRAME_LENGTH_BYTES = 99U;
const unsigned int P25_HDR_FRAME_LENGTH_BITS = P25_HDR_FRAME_LENGTH_BYTES * 8U;
@@ -47,6 +47,11 @@ const unsigned int P25_TSDU_FRAME_LENGTH_BITS = P25_TSDU_FRAME_LENGTH_BYTES
const unsigned int P25_TSDU_FRAME_LENGTH_SYMBOLS = P25_TSDU_FRAME_LENGTH_BYTES * 4U;
const unsigned int P25_TSDU_FRAME_LENGTH_SAMPLES = P25_TSDU_FRAME_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
const unsigned int P25_PDU_HDR_FRAME_LENGTH_BYTES = 45U;
const unsigned int P25_PDU_HDR_FRAME_LENGTH_BITS = P25_PDU_HDR_FRAME_LENGTH_BYTES * 8U;
const unsigned int P25_PDU_HDR_FRAME_LENGTH_SYMBOLS = P25_PDU_HDR_FRAME_LENGTH_BYTES * 4U;
const unsigned int P25_PDU_HDR_FRAME_LENGTH_SAMPLES = P25_PDU_HDR_FRAME_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
const unsigned int P25_SYNC_LENGTH_BYTES = 6U;
const unsigned int P25_SYNC_LENGTH_BITS = P25_SYNC_LENGTH_BYTES * 8U;
const unsigned int P25_SYNC_LENGTH_SYMBOLS = P25_SYNC_LENGTH_BYTES * 4U;
+13 -1
View File
@@ -199,7 +199,19 @@ void CP25RX::processHdr(q15_t sample)
serial.writeP25Hdr(frame, P25_HDR_FRAME_LENGTH_BYTES + 1U);
}
break;
case P25_DUID_TSDU: {
case P25_DUID_PDU: {
calculateLevels(m_hdrSyncPtr, P25_PDU_HDR_FRAME_LENGTH_SYMBOLS);
DEBUG4("P25RX: sync found in PDU pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
uint8_t frame[P25_PDU_HDR_FRAME_LENGTH_BYTES + 1U];
samplesToBits(m_hdrSyncPtr, P25_PDU_HDR_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
frame[0U] = 0x01U;
serial.writeP25Hdr(frame, P25_PDU_HDR_FRAME_LENGTH_BYTES + 1U);
}
break;
case P25_DUID_TSDU: {
calculateLevels(m_hdrStartPtr, P25_TSDU_FRAME_LENGTH_SYMBOLS);
DEBUG4("P25RX: sync found in TSDU pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
+49 -23
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2016,2017,2020 by Jonathan Naylor G4KLX
* Copyright (C) 2017 by Andy Uribe CA6JAU
*
* This program is free software; you can redistribute it and/or modify
@@ -23,23 +23,17 @@
#include "P25Defines.h"
// Generated using rcosdesign(0.2, 8, 10, 'normal') in MATLAB
static q15_t RC_0_2_FILTER[] = {-444, -897, -1311, -1636, -1825, -1840, -1659, -1278, -712, 0,
800, 1613, 2354, 2936, 3277, 3310, 2994, 2315, 1296, 0, -1478,
-3011, -4448, -5627, -6386, -6580, -6090, -4839, -2800, 0, 3474,
7482, 11835, 16311, 20666, 24651, 28032, 30607, 32219, 32767,
32219, 30607, 28032, 24651, 20666, 16311, 11835, 7482, 3474, 0,
-2800, -4839, -6090, -6580, -6386, -5627, -4448, -3011, -1478,
0, 1296, 2315, 2994, 3310, 3277, 2936, 2354, 1613, 800, 0, -712,
-1278, -1659, -1840, -1825, -1636, -1311, -897, -444, 0}; // numTaps = 80, L = 10
// Generated using rcosdesign(0.2, 8, 5, 'normal') in MATLAB
// numTaps = 40, L = 5
static q15_t RC_0_2_FILTER[] = {-897, -1636, -1840, -1278, 0, 1613, 2936, 3310, 2315, 0, -3011, -5627, -6580, -4839,
0, 7482, 16311, 24651, 30607, 32767, 30607, 24651, 16311, 7482, 0, -4839, -6580, -5627,
-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[] = {1294, -2251, 4312, -8402, 20999, 20999, -8402, 4312, -2251, 1294};
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;
@@ -57,7 +51,9 @@ m_lpState(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(240U) // 200ms
m_txDelay(240U), // 200ms
m_txHang(6000U), // 5s
m_txCount(0U)
{
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
::memset(m_lpState, 0x00U, 60U * sizeof(q15_t));
@@ -74,10 +70,7 @@ m_txDelay(240U) // 200ms
void CP25TX::process()
{
if (m_buffer.getData() == 0U && m_poLen == 0U)
return;
if (m_poLen == 0U) {
if (m_poLen == 0U && m_buffer.getData() > 0U) {
if (!m_tx) {
for (uint16_t i = 0U; i < m_txDelay; i++)
m_poBuffer[m_poLen++] = P25_START_SYNC;
@@ -100,17 +93,32 @@ void CP25TX::process()
writeByte(c);
space -= 4U * P25_RADIO_SYMBOL_LENGTH;
if (m_duplex)
m_txCount = m_txHang;
if (m_poPtr >= m_poLen) {
m_poPtr = 0U;
m_poLen = 0U;
return;
}
}
} else if (m_txCount > 0U) {
// Transmit silence until the hang timer has expired.
uint16_t space = io.getSpace();
while (space > (4U * P25_RADIO_SYMBOL_LENGTH)) {
writeSilence();
space -= 4U * P25_RADIO_SYMBOL_LENGTH;
m_txCount--;
if (m_txCount == 0U)
return;
}
}
}
uint8_t CP25TX::writeData(const uint8_t* data, uint8_t length)
uint8_t CP25TX::writeData(const uint8_t* data, uint16_t length)
{
if (length < (P25_TERM_FRAME_LENGTH_BYTES + 1U))
return 4U;
@@ -158,6 +166,19 @@ void CP25TX::writeByte(uint8_t c)
io.write(STATE_P25, outBuffer, P25_RADIO_SYMBOL_LENGTH * 4U);
}
void CP25TX::writeSilence()
{
q15_t inBuffer[4U] = {0x00U, 0x00U, 0x00U, 0x00U};
q15_t intBuffer[P25_RADIO_SYMBOL_LENGTH * 4U];
q15_t outBuffer[P25_RADIO_SYMBOL_LENGTH * 4U];
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, intBuffer, 4U);
::arm_fir_fast_q15(&m_lpFilter, intBuffer, outBuffer, P25_RADIO_SYMBOL_LENGTH * 4U);
io.write(STATE_P25, outBuffer, P25_RADIO_SYMBOL_LENGTH * 4U);
}
void CP25TX::setTXDelay(uint8_t delay)
{
m_txDelay = 600U + uint16_t(delay) * 12U; // 500ms + tx delay
@@ -170,3 +191,8 @@ uint8_t CP25TX::getSpace() const
{
return m_buffer.getSpace() / P25_LDU_FRAME_LENGTH_BYTES;
}
void CP25TX::setParams(uint8_t txHang)
{
m_txHang = txHang * 1200U;
}
+7 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2016,2017,2020 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
@@ -27,7 +27,7 @@ class CP25TX {
public:
CP25TX();
uint8_t writeData(const uint8_t* data, uint8_t length);
uint8_t writeData(const uint8_t* data, uint16_t length);
void process();
@@ -35,6 +35,8 @@ public:
uint8_t getSpace() const;
void setParams(uint8_t txHang);
private:
CSerialRB m_buffer;
arm_fir_interpolate_instance_q15 m_modFilter;
@@ -45,9 +47,11 @@ private:
uint16_t m_poLen;
uint16_t m_poPtr;
uint16_t m_txDelay;
uint32_t m_txHang;
uint32_t m_txCount;
void writeByte(uint8_t c);
void writeSilence();
};
#endif
+9 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2018 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2018,2020 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
@@ -24,18 +24,18 @@ const uint16_t POCSAG_FRAME_LENGTH_BYTES = 17U * sizeof(uint32_t);
const uint16_t POCSAG_PREAMBLE_LENGTH_BYTES = 18U * sizeof(uint32_t);
const uint16_t POCSAG_RADIO_SYMBOL_LENGTH = 40U; // at 48Khz
const uint16_t POCSAG_RADIO_SYMBOL_LENGTH = 20U;
const q15_t POCSAG_LEVEL1[] = { 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700};
const q15_t POCSAG_LEVEL0[] = {-1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700};
const q15_t POCSAG_LEVEL1[] = { 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700};
const q15_t POCSAG_LEVEL0[] = {-1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700};
static q15_t SHAPING_FILTER[] = {2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730};
const uint16_t SHAPING_FILTER_LEN = 12U;
static q15_t SHAPING_FILTER[] = {5461, 5461, 5461, 5461, 5461, 5461};
const uint16_t SHAPING_FILTER_LEN = 6U;
const uint8_t POCSAG_SYNC = 0xAAU;
CPOCSAGTX::CPOCSAGTX() :
m_buffer(TX_BUFFER_LEN),
m_buffer(4000U),
m_modFilter(),
m_modState(),
m_poBuffer(),
@@ -43,7 +43,7 @@ m_poLen(0U),
m_poPtr(0U),
m_txDelay(POCSAG_PREAMBLE_LENGTH_BYTES)
{
::memset(m_modState, 0x00U, 180U * sizeof(q15_t));
::memset(m_modState, 0x00U, 170U * sizeof(q15_t));
m_modFilter.numTaps = SHAPING_FILTER_LEN;
m_modFilter.pState = m_modState;
@@ -95,7 +95,7 @@ bool CPOCSAGTX::busy()
return false;
}
uint8_t CPOCSAGTX::writeData(const uint8_t* data, uint8_t length)
uint8_t CPOCSAGTX::writeData(const uint8_t* data, uint16_t length)
{
if (length != POCSAG_FRAME_LENGTH_BYTES)
return 4U;
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015-2020 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
@@ -27,7 +27,9 @@ class CPOCSAGTX {
public:
CPOCSAGTX();
uint8_t writeData(const uint8_t* data, uint8_t length);
uint8_t writeData(const uint8_t* data, uint16_t length);
void writeByte(uint8_t c);
void process();
@@ -40,13 +42,11 @@ public:
private:
CSerialRB m_buffer;
arm_fir_instance_q15 m_modFilter;
q15_t m_modState[180U]; // NoTaps + BlockSize - 1, 12 + 160 - 1 plus some spare
q15_t m_modState[170U]; // NoTaps + BlockSize - 1, 6 + 160 - 1 plus some spare
uint8_t m_poBuffer[200U];
uint16_t m_poLen;
uint16_t m_poPtr;
uint16_t m_txDelay;
void writeByte(uint8_t c);
};
#endif
+14 -4
View File
@@ -1,7 +1,17 @@
This is the source code of the MMDVM firmware that supports D-Star, DMR, System Fusion, P25, NXDN, and POCSAG modes.
This is the source code of the MMDVM firmware that supports D-Star, DMR,
System Fusion, P25, NXDN, POCSAG, and FM modes.
It runs on the Arduino Due, the ST-Micro STM32F1xxx, STM32F4xxx and STM32F7xxx processors, as well as the Teensy 3.1/3.2/3.5/3.6. What these platforms have in common is the use of an ARM Cortex-M3 or M4 processor with a clock speed greater than 70 MHz, and access to at least one analogue to digital converter and one digital to analogue converter.
It runs on the Arduino Due, the ST-Micro STM32F1xxx, STM32F4xxx and STM32F7xxx
processors, as well as the Teensy 3.1/3.2/3.5/3.6. What these platforms have in
common is the use of an ARM Cortex-M3, M4, or M7 processors with a clock speed
greater than 70 MHz, and access to at least one analogue to digital converter
and one digital to analogue converter.
In order to build this software for the Arduino Due, you will need to edit a file within the Arduino GUI and that is detailed in the BUILD.txt file. The STM32 support is being supplied via the Coocox IDE with ARM GCC. The Teensy support uses Teensyduino.
In order to build this software for the Arduino Due, you will need to edit a
file within the Arduino GUI and that is detailed in the BUILD.txt file. The
STM32 support is being supplied via the ARM GCC compiler. The Teensy support
uses Teensyduino.
This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden.
This software is licenced under the GPL v2 and is intended for amateur and
educational use only. Use of this software for commercial purposes is strictly
forbidden.
Submodule
+1
Submodule STM32F10X_Lib added at 417e0c2f4a
Submodule
+1
Submodule STM32F4XX_Lib added at bcd346f530
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-664
View File
@@ -1,664 +0,0 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V4.10
* @date 18. March 2015
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2015 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Set Base Priority with condition
This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
{
register uint32_t __regBasePriMax __ASM("basepri_max");
__regBasePriMax = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f" : : : "memory");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f" : : : "memory");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
}
/** \brief Set Base Priority with condition
This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
or the new value increases the BASEPRI priority level.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
{
__ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
__ASM volatile ("");
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
__ASM volatile ("");
#endif
}
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */
-916
View File
@@ -1,916 +0,0 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V4.10
* @date 18. March 2015
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() do {\
__schedule_barrier();\
__isb(0xF);\
__schedule_barrier();\
} while (0)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() do {\
__schedule_barrier();\
__dsb(0xF);\
__schedule_barrier();\
} while (0)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() do {\
__schedule_barrier();\
__dmb(0xF);\
__schedule_barrier();\
} while (0)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
#define __RBIT __rbit
#else
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
result = value; // r will be reversed bits of v; first get LSB of v
for (value >>= 1; value; value >>= 1)
{
result <<= 1;
result |= value & 1;
s--;
}
result <<= s; // shift when v's highest bits are zero
return(result);
}
#endif
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
/** \brief LDR Exclusive (8 bit)
This function executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Rotate Right with Extend (32 bit)
This function moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
{
rrx r0, r0
bx lr
}
#endif
/** \brief LDRT Unprivileged (8 bit)
This function executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
/** \brief LDRT Unprivileged (16 bit)
This function executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
/** \brief LDRT Unprivileged (32 bit)
This function executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
/** \brief STRT Unprivileged (8 bit)
This function executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRBT(value, ptr) __strt(value, ptr)
/** \brief STRT Unprivileged (16 bit)
This function executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRHT(value, ptr) __strt(value, ptr)
/** \brief STRT Unprivileged (32 bit)
This function executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
#define __STRT(value, ptr) __strt(value, ptr)
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/* Define macros for porting to both thumb1 and thumb2.
* For thumb1, use low register (r0-r7), specified by constrant "l"
* Otherwise, use general registers, specified by constrant "r" */
#if defined (__thumb__) && !defined (__thumb2__)
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
#define __CMSIS_GCC_USE_REG(r) "l" (r)
#else
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
#define __CMSIS_GCC_USE_REG(r) "r" (r)
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb 0xF":::"memory");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb 0xF":::"memory");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb 0xF":::"memory");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
return __builtin_bswap32(value);
#else
uint32_t result;
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
return (short)__builtin_bswap16(value);
#else
uint32_t result;
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << (32 - op2));
}
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
#else
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
result = value; // r will be reversed bits of v; first get LSB of v
for (value >>= 1; value; value >>= 1)
{
result <<= 1;
result |= value & 1;
s--;
}
result <<= s; // shift when v's highest bits are zero
#endif
return(result);
}
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __builtin_clz
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
/** \brief LDR Exclusive (8 bit)
This function executes a exclusive LDR instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (16 bit)
This function executes a exclusive LDR instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint16_t) result); /* Add explicit type cast here */
}
/** \brief LDR Exclusive (32 bit)
This function executes a exclusive LDR instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function executes a exclusive STR instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function executes a exclusive STR instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function executes a exclusive STR instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex" ::: "memory");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Rotate Right with Extend (32 bit)
This function moves each bit of a bitstring right by one bit.
The carry input is shifted in at the left end of the bitstring.
\param [in] value Value to rotate
\return Rotated value
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
{
uint32_t result;
__ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
}
/** \brief LDRT Unprivileged (8 bit)
This function executes a Unprivileged LDRT instruction for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint8_t) result); /* Add explicit type cast here */
}
/** \brief LDRT Unprivileged (16 bit)
This function executes a Unprivileged LDRT instruction for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return ((uint16_t) result); /* Add explicit type cast here */
}
/** \brief LDRT Unprivileged (32 bit)
This function executes a Unprivileged LDRT instruction for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/** \brief STRT Unprivileged (8 bit)
This function executes a Unprivileged STRT instruction for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
{
__ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
}
/** \brief STRT Unprivileged (16 bit)
This function executes a Unprivileged STRT instruction for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
{
__ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
}
/** \brief STRT Unprivileged (32 bit)
This function executes a Unprivileged STRT instruction for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
*/
__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
{
__ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
}
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */
-697
View File
@@ -1,697 +0,0 @@
/**************************************************************************//**
* @file core_cmSimd.h
* @brief CMSIS Cortex-M SIMD Header File
* @version V4.10
* @date 18. March 2015
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009 - 2014 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#if defined ( __ICCARM__ )
#pragma system_include /* treat file as system include file for MISRA check */
#endif
#ifndef __CORE_CMSIMD_H
#define __CORE_CMSIMD_H
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Hardware Abstraction Layer
******************************************************************************/
/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#define __SADD8 __sadd8
#define __QADD8 __qadd8
#define __SHADD8 __shadd8
#define __UADD8 __uadd8
#define __UQADD8 __uqadd8
#define __UHADD8 __uhadd8
#define __SSUB8 __ssub8
#define __QSUB8 __qsub8
#define __SHSUB8 __shsub8
#define __USUB8 __usub8
#define __UQSUB8 __uqsub8
#define __UHSUB8 __uhsub8
#define __SADD16 __sadd16
#define __QADD16 __qadd16
#define __SHADD16 __shadd16
#define __UADD16 __uadd16
#define __UQADD16 __uqadd16
#define __UHADD16 __uhadd16
#define __SSUB16 __ssub16
#define __QSUB16 __qsub16
#define __SHSUB16 __shsub16
#define __USUB16 __usub16
#define __UQSUB16 __uqsub16
#define __UHSUB16 __uhsub16
#define __SASX __sasx
#define __QASX __qasx
#define __SHASX __shasx
#define __UASX __uasx
#define __UQASX __uqasx
#define __UHASX __uhasx
#define __SSAX __ssax
#define __QSAX __qsax
#define __SHSAX __shsax
#define __USAX __usax
#define __UQSAX __uqsax
#define __UHSAX __uhsax
#define __USAD8 __usad8
#define __USADA8 __usada8
#define __SSAT16 __ssat16
#define __USAT16 __usat16
#define __UXTB16 __uxtb16
#define __UXTAB16 __uxtab16
#define __SXTB16 __sxtb16
#define __SXTAB16 __sxtab16
#define __SMUAD __smuad
#define __SMUADX __smuadx
#define __SMLAD __smlad
#define __SMLADX __smladx
#define __SMLALD __smlald
#define __SMLALDX __smlaldx
#define __SMUSD __smusd
#define __SMUSDX __smusdx
#define __SMLSD __smlsd
#define __SMLSDX __smlsdx
#define __SMLSLD __smlsld
#define __SMLSLDX __smlsldx
#define __SEL __sel
#define __QADD __qadd
#define __QSUB __qsub
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
((int64_t)(ARG3) << 32) ) >> 32))
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#define __SSAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
#define __USAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
{
uint32_t result;
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
#ifndef __ARMEB__ // Little endian
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
#else // Big endian
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
#endif
return(llr.w64);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
{
uint32_t result;
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}
#define __PKHBT(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
#define __PKHTB(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
if (ARG3 == 0) \
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
else \
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
{
int32_t result;
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
return(result);
}
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/* not yet supported */
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
/* Cosmic specific functions */
#include <cmsis_csm.h>
#endif
/*@} end of group CMSIS_SIMD_intrinsics */
#ifdef __cplusplus
}
#endif
#endif /* __CORE_CMSIMD_H */
Binary file not shown.
@@ -1,436 +0,0 @@
/**
******************************************************************************
* @file startup_stm32f4xx.s
* @author Coocox
* @version V1.0
* @date 03/05/2012
* @brief STM32F4xx Devices vector table for RIDE7 toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Configure the clock system and the external SRAM mounted on
* STM324xG-EVAL board to be used as data memory (optional,
* to be enabled by user)
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M4 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
*/
/* Some modifications by Andy Uribe CA6JAU :
- Added C++ global constructors support
- Changed initial stack pointer
*/
/*----------Macro definition--------------------------------------------------*/
#define WEAK __attribute__ ((weak))
/*----------Declaration of the default fault handlers-------------------------*/
/* System exception vector handler */
__attribute__ ((used))
void WEAK Reset_Handler(void);
void WEAK NMI_Handler(void);
void WEAK HardFault_Handler(void);
void WEAK MemManage_Handler(void);
void WEAK BusFault_Handler(void);
void WEAK UsageFault_Handler(void);
void WEAK SVC_Handler(void);
void WEAK DebugMon_Handler(void);
void WEAK PendSV_Handler(void);
void WEAK SysTick_Handler(void);
void WEAK WWDG_IRQHandler(void);
void WEAK PVD_IRQHandler(void);
void WEAK TAMP_STAMP_IRQHandler(void);
void WEAK RTC_WKUP_IRQHandler(void);
void WEAK FLASH_IRQHandler(void);
void WEAK RCC_IRQHandler(void);
void WEAK EXTI0_IRQHandler(void);
void WEAK EXTI1_IRQHandler(void);
void WEAK EXTI2_IRQHandler(void);
void WEAK EXTI3_IRQHandler(void);
void WEAK EXTI4_IRQHandler(void);
void WEAK DMA1_Stream0_IRQHandler(void);
void WEAK DMA1_Stream1_IRQHandler(void);
void WEAK DMA1_Stream2_IRQHandler(void);
void WEAK DMA1_Stream3_IRQHandler(void);
void WEAK DMA1_Stream4_IRQHandler(void);
void WEAK DMA1_Stream5_IRQHandler(void);
void WEAK DMA1_Stream6_IRQHandler(void);
void WEAK ADC_IRQHandler(void);
void WEAK CAN1_TX_IRQHandler(void);
void WEAK CAN1_RX0_IRQHandler(void);
void WEAK CAN1_RX1_IRQHandler(void);
void WEAK CAN1_SCE_IRQHandler(void);
void WEAK EXTI9_5_IRQHandler(void);
void WEAK TIM1_BRK_TIM9_IRQHandler(void);
void WEAK TIM1_UP_TIM10_IRQHandler(void);
void WEAK TIM1_TRG_COM_TIM11_IRQHandler(void);
void WEAK TIM1_CC_IRQHandler(void);
void WEAK TIM2_IRQHandler(void);
void WEAK TIM3_IRQHandler(void);
void WEAK TIM4_IRQHandler(void);
void WEAK I2C1_EV_IRQHandler(void);
void WEAK I2C1_ER_IRQHandler(void);
void WEAK I2C2_EV_IRQHandler(void);
void WEAK I2C2_ER_IRQHandler(void);
void WEAK SPI1_IRQHandler(void);
void WEAK SPI2_IRQHandler(void);
void WEAK USART1_IRQHandler(void);
void WEAK USART2_IRQHandler(void);
void WEAK USART3_IRQHandler(void);
void WEAK EXTI15_10_IRQHandler(void);
void WEAK RTC_Alarm_IRQHandler(void);
void WEAK OTG_FS_WKUP_IRQHandler(void);
void WEAK TIM8_BRK_TIM12_IRQHandler(void);
void WEAK TIM8_UP_TIM13_IRQHandler(void);
void WEAK TIM8_TRG_COM_TIM14_IRQHandler(void);
void WEAK TIM8_CC_IRQHandler(void);
void WEAK DMA1_Stream7_IRQHandler(void);
void WEAK FSMC_IRQHandler(void);
void WEAK SDIO_IRQHandler(void);
void WEAK TIM5_IRQHandler(void);
void WEAK SPI3_IRQHandler(void);
void WEAK UART4_IRQHandler(void);
void WEAK UART5_IRQHandler(void);
void WEAK TIM6_DAC_IRQHandler(void);
void WEAK TIM7_IRQHandler(void);
void WEAK DMA2_Stream0_IRQHandler(void);
void WEAK DMA2_Stream1_IRQHandler(void);
void WEAK DMA2_Stream2_IRQHandler(void);
void WEAK DMA2_Stream3_IRQHandler(void);
void WEAK DMA2_Stream4_IRQHandler(void);
void WEAK ETH_IRQHandler(void);
void WEAK ETH_WKUP_IRQHandler(void);
void WEAK CAN2_TX_IRQHandler(void);
void WEAK CAN2_RX0_IRQHandler(void);
void WEAK CAN2_RX1_IRQHandler(void);
void WEAK CAN2_SCE_IRQHandler(void);
void WEAK OTG_FS_IRQHandler(void);
void WEAK DMA2_Stream5_IRQHandler(void);
void WEAK DMA2_Stream6_IRQHandler(void);
void WEAK DMA2_Stream7_IRQHandler(void);
void WEAK USART6_IRQHandler(void);
void WEAK I2C3_EV_IRQHandler(void);
void WEAK I2C3_ER_IRQHandler(void);
void WEAK OTG_HS_EP1_OUT_IRQHandler(void);
void WEAK OTG_HS_EP1_IN_IRQHandler(void);
void WEAK OTG_HS_WKUP_IRQHandler(void);
void WEAK OTG_HS_IRQHandler(void);
void WEAK DCMI_IRQHandler(void);
void WEAK CRYP_IRQHandler(void);
void WEAK HASH_RNG_IRQHandler(void);
void WEAK FPU_IRQHandler(void);
/*----------Symbols defined in linker script----------------------------------*/
extern unsigned long _estack; /*!< The initial stack pointer */
extern unsigned long _sidata; /*!< Start address for the initialization
values of the .data section. */
extern unsigned long _sdata; /*!< Start address for the .data section */
extern unsigned long _edata; /*!< End address for the .data section */
extern unsigned long _sbss; /*!< Start address for the .bss section */
extern unsigned long _ebss; /*!< End address for the .bss section */
/* C++ global constructors support */
extern unsigned long __preinit_array_start;
extern unsigned long __preinit_array_end;
extern unsigned long __init_array_start;
extern unsigned long __init_array_end;
/*----------Function prototypes-----------------------------------------------*/
extern int main(void); /*!< The entry point for the application. */
//extern void SystemInit(void); /*!< Setup the microcontroller system(CMSIS) */
void Default_Reset_Handler(void); /*!< Default reset handler */
static void Default_Handler(void); /*!< Default exception handler */
static void call_constructors(unsigned long *start, unsigned long *end) __attribute((noinline));
/**
*@brief The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x00000000.
*/
__attribute__ ((used,section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{
/*----------Core Exceptions------------------------------------------------ */
(void *) &_estack, /*!< The initial stack pointer */
Reset_Handler, /*!< Reset Handler */
NMI_Handler, /*!< NMI Handler */
HardFault_Handler, /*!< Hard Fault Handler */
MemManage_Handler, /*!< MPU Fault Handler */
BusFault_Handler, /*!< Bus Fault Handler */
UsageFault_Handler, /*!< Usage Fault Handler */
0,0,0,0, /*!< Reserved */
SVC_Handler, /*!< SVCall Handler */
DebugMon_Handler, /*!< Debug Monitor Handler */
0, /*!< Reserved */
PendSV_Handler, /*!< PendSV Handler */
SysTick_Handler, /*!< SysTick Handler */
/*----------External Exceptions---------------------------------------------*/
WWDG_IRQHandler, /*!< 0: Window WatchDog */
PVD_IRQHandler, /*!< 1: PVD through EXTI Line detection */
TAMP_STAMP_IRQHandler, /*!< 2: Tamper and TimeStamps through the EXTI line*/
RTC_WKUP_IRQHandler, /*!< 3: RTC Wakeup through the EXTI line */
FLASH_IRQHandler, /*!< 4: FLASH */
RCC_IRQHandler , /*!< 5: RCC */
EXTI0_IRQHandler, /*!< 6: EXTI Line0 */
EXTI1_IRQHandler, /*!< 7: EXTI Line1 */
EXTI2_IRQHandler, /*!< 8: EXTI Line2 */
EXTI3_IRQHandler, /*!< 9: EXTI Line3 */
EXTI4_IRQHandler, /*!< 10: EXTI Line4 */
DMA1_Stream0_IRQHandler, /*!< 11: DMA1 Stream 0 */
DMA1_Stream1_IRQHandler, /*!< 12: DMA1 Stream 1 */
DMA1_Stream2_IRQHandler, /*!< 13: DMA1 Stream 2 */
DMA1_Stream3_IRQHandler, /*!< 14: DMA1 Stream 3 */
DMA1_Stream4_IRQHandler, /*!< 15: DMA1 Stream 4 */
DMA1_Stream5_IRQHandler, /*!< 16: DMA1 Stream 5 */
DMA1_Stream6_IRQHandler, /*!< 17: DMA1 Stream 6 */
ADC_IRQHandler, /*!< 18: ADC1, ADC2 and ADC3s */
CAN1_TX_IRQHandler, /*!< 19: CAN1 TX */
CAN1_RX0_IRQHandler, /*!< 20: CAN1 RX0 */
CAN1_RX1_IRQHandler, /*!< 21: CAN1 RX1 */
CAN1_SCE_IRQHandler, /*!< 22: CAN1 SCE */
EXTI9_5_IRQHandler, /*!< 23: External Line[9:5]s */
TIM1_BRK_TIM9_IRQHandler, /*!< 24: TIM1 Break and TIM9 */
TIM1_UP_TIM10_IRQHandler, /*!< 25: TIM1 Update and TIM10 */
TIM1_TRG_COM_TIM11_IRQHandler,/*!< 26: TIM1 Trigger and Commutation and TIM11*/
TIM1_CC_IRQHandler, /*!< 27: TIM1 Capture Compare */
TIM2_IRQHandler, /*!< 28: TIM2 */
TIM3_IRQHandler, /*!< 29: TIM3 */
TIM4_IRQHandler, /*!< 30: TIM4 */
I2C1_EV_IRQHandler, /*!< 31: I2C1 Event */
I2C1_ER_IRQHandler, /*!< 32: I2C1 Error */
I2C2_EV_IRQHandler, /*!< 33: I2C2 Event */
I2C2_ER_IRQHandler, /*!< 34: I2C2 Error */
SPI1_IRQHandler, /*!< 35: SPI1 */
SPI2_IRQHandler, /*!< 36: SPI2 */
USART1_IRQHandler, /*!< 37: USART1 */
USART2_IRQHandler, /*!< 38: USART2 */
USART3_IRQHandler, /*!< 39: USART3 */
EXTI15_10_IRQHandler, /*!< 40: External Line[15:10]s */
RTC_Alarm_IRQHandler, /*!< 41: RTC Alarm (A and B) through EXTI Line */
OTG_FS_WKUP_IRQHandler, /*!< 42: USB OTG FS Wakeup through EXTI line */
TIM8_BRK_TIM12_IRQHandler, /*!< 43: TIM8 Break and TIM12 */
TIM8_UP_TIM13_IRQHandler, /*!< 44: TIM8 Update and TIM13 */
TIM8_TRG_COM_TIM14_IRQHandler,/*!< 45:TIM8 Trigger and Commutation and TIM14*/
TIM8_CC_IRQHandler, /*!< 46: TIM8 Capture Compare */
DMA1_Stream7_IRQHandler, /*!< 47: DMA1 Stream7 */
FSMC_IRQHandler, /*!< 48: FSMC */
SDIO_IRQHandler, /*!< 49: SDIO */
TIM5_IRQHandler, /*!< 50: TIM5 */
SPI3_IRQHandler, /*!< 51: SPI3 */
UART4_IRQHandler, /*!< 52: UART4 */
UART5_IRQHandler, /*!< 53: UART5 */
TIM6_DAC_IRQHandler, /*!< 54: TIM6 and DAC1&2 underrun errors */
TIM7_IRQHandler, /*!< 55: TIM7 */
DMA2_Stream0_IRQHandler, /*!< 56: DMA2 Stream 0 */
DMA2_Stream1_IRQHandler, /*!< 57: DMA2 Stream 1 */
DMA2_Stream2_IRQHandler, /*!< 58: DMA2 Stream 2 */
DMA2_Stream3_IRQHandler, /*!< 59: DMA2 Stream 3 */
DMA2_Stream4_IRQHandler, /*!< 60: DMA2 Stream 4 */
ETH_IRQHandler, /*!< 61: Ethernet */
ETH_WKUP_IRQHandler, /*!< 62: Ethernet Wakeup through EXTI line */
CAN2_TX_IRQHandler, /*!< 63: CAN2 TX */
CAN2_RX0_IRQHandler, /*!< 64: CAN2 RX0 */
CAN2_RX1_IRQHandler, /*!< 65: CAN2 RX1 */
CAN2_SCE_IRQHandler, /*!< 66: CAN2 SCE */
OTG_FS_IRQHandler, /*!< 67: USB OTG FS */
DMA2_Stream5_IRQHandler, /*!< 68: DMA2 Stream 5 */
DMA2_Stream6_IRQHandler, /*!< 69: DMA2 Stream 6 */
DMA2_Stream7_IRQHandler, /*!< 70: DMA2 Stream 7 */
USART6_IRQHandler, /*!< 71: USART6 */
I2C3_EV_IRQHandler, /*!< 72: I2C3 event */
I2C3_ER_IRQHandler, /*!< 73: I2C3 error */
OTG_HS_EP1_OUT_IRQHandler, /*!< 74: USB OTG HS End Point 1 Out */
OTG_HS_EP1_IN_IRQHandler, /*!< 75: USB OTG HS End Point 1 In */
OTG_HS_WKUP_IRQHandler, /*!< 76: USB OTG HS Wakeup through EXTI */
OTG_HS_IRQHandler, /*!< 77: USB OTG HS */
DCMI_IRQHandler, /*!< 53: DCMI */
CRYP_IRQHandler, /*!< 53: CRYP crypto */
HASH_RNG_IRQHandler, /*!< 53: Hash and Rng */
FPU_IRQHandler /*!< 53: FPU */
};
/* C++ global constructors support */
static void call_constructors(unsigned long *start, unsigned long *end)
{
unsigned long *i;
void (*funcptr)();
for ( i = start; i < end; i++)
{
funcptr=(void (*)())(*i);
funcptr();
}
}
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval None
*/
void Default_Reset_Handler(void)
{
/* Initialize data and bss */
unsigned long *pulSrc, *pulDest;
/* Copy the data segment initializers from flash to SRAM */
pulSrc = &_sidata;
for(pulDest = &_sdata; pulDest < &_edata; )
{
*(pulDest++) = *(pulSrc++);
}
/* Zero fill the bss segment. This is done with inline assembly since this
will clear the value of pulDest if it is not kept in a register. */
__asm(" ldr r0, =_sbss\n"
" ldr r1, =_ebss\n"
" mov r2, #0\n"
" .thumb_func\n"
"zero_loop:\n"
" cmp r0, r1\n"
" it lt\n"
" strlt r2, [r0], #4\n"
" blt zero_loop");
#ifdef __FPU_USED
/* Enable FPU.*/
__asm(" LDR.W R0, =0xE000ED88\n"
" LDR R1, [R0]\n"
" ORR R1, R1, #(0xF << 20)\n"
" STR R1, [R0]");
#endif
SystemInit();
//Call C++ global constructors
call_constructors(&__preinit_array_start, &__preinit_array_end);
call_constructors(&__init_array_start, &__init_array_end);
/* Call the application's entry point.*/
main();
}
/**
*@brief Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*/
#pragma weak Reset_Handler = Default_Reset_Handler
#pragma weak NMI_Handler = Default_Handler
#pragma weak HardFault_Handler = Default_Handler
#pragma weak MemManage_Handler = Default_Handler
#pragma weak BusFault_Handler = Default_Handler
#pragma weak UsageFault_Handler = Default_Handler
#pragma weak SVC_Handler = Default_Handler
#pragma weak DebugMon_Handler = Default_Handler
#pragma weak PendSV_Handler = Default_Handler
#pragma weak SysTick_Handler = Default_Handler
#pragma weak WWDG_IRQHandler = Default_Handler
#pragma weak PVD_IRQHandler = Default_Handler
#pragma weak TAMP_STAMP_IRQHandler = Default_Handler
#pragma weak RTC_WKUP_IRQHandler = Default_Handler
#pragma weak FLASH_IRQHandler = Default_Handler
#pragma weak RCC_IRQHandler = Default_Handler
#pragma weak EXTI0_IRQHandler = Default_Handler
#pragma weak EXTI1_IRQHandler = Default_Handler
#pragma weak EXTI2_IRQHandler = Default_Handler
#pragma weak EXTI3_IRQHandler = Default_Handler
#pragma weak EXTI4_IRQHandler = Default_Handler
#pragma weak DMA1_Stream0_IRQHandler = Default_Handler
#pragma weak DMA1_Stream1_IRQHandler = Default_Handler
#pragma weak DMA1_Stream2_IRQHandler = Default_Handler
#pragma weak DMA1_Stream3_IRQHandler = Default_Handler
#pragma weak DMA1_Stream4_IRQHandler = Default_Handler
#pragma weak DMA1_Stream5_IRQHandler = Default_Handler
#pragma weak DMA1_Stream6_IRQHandler = Default_Handler
#pragma weak ADC_IRQHandler = Default_Handler
#pragma weak CAN1_TX_IRQHandler = Default_Handler
#pragma weak CAN1_RX0_IRQHandler = Default_Handler
#pragma weak CAN1_RX1_IRQHandler = Default_Handler
#pragma weak CAN1_SCE_IRQHandler = Default_Handler
#pragma weak EXTI9_5_IRQHandler = Default_Handler
#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler
#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler
#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler
#pragma weak TIM1_CC_IRQHandler = Default_Handler
#pragma weak TIM2_IRQHandler = Default_Handler
#pragma weak TIM3_IRQHandler = Default_Handler
#pragma weak TIM4_IRQHandler = Default_Handler
#pragma weak I2C1_EV_IRQHandler = Default_Handler
#pragma weak I2C1_ER_IRQHandler = Default_Handler
#pragma weak I2C2_EV_IRQHandler = Default_Handler
#pragma weak I2C2_ER_IRQHandler = Default_Handler
#pragma weak SPI1_IRQHandler = Default_Handler
#pragma weak SPI2_IRQHandler = Default_Handler
#pragma weak USART1_IRQHandler = Default_Handler
#pragma weak USART2_IRQHandler = Default_Handler
#pragma weak USART3_IRQHandler = Default_Handler
#pragma weak EXTI15_10_IRQHandler = Default_Handler
#pragma weak RTC_Alarm_IRQHandler = Default_Handler
#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler
#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler
#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler
#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler
#pragma weak TIM8_CC_IRQHandler = Default_Handler
#pragma weak DMA1_Stream7_IRQHandler = Default_Handler
#pragma weak FSMC_IRQHandler = Default_Handler
#pragma weak SDIO_IRQHandler = Default_Handler
#pragma weak TIM5_IRQHandler = Default_Handler
#pragma weak SPI3_IRQHandler = Default_Handler
#pragma weak UART4_IRQHandler = Default_Handler
#pragma weak UART5_IRQHandler = Default_Handler
#pragma weak TIM6_DAC_IRQHandler = Default_Handler
#pragma weak TIM7_IRQHandler = Default_Handler
#pragma weak DMA2_Stream0_IRQHandler = Default_Handler
#pragma weak DMA2_Stream1_IRQHandler = Default_Handler
#pragma weak DMA2_Stream2_IRQHandler = Default_Handler
#pragma weak DMA2_Stream3_IRQHandler = Default_Handler
#pragma weak DMA2_Stream4_IRQHandler = Default_Handler
#pragma weak ETH_IRQHandler = Default_Handler
#pragma weak ETH_WKUP_IRQHandler = Default_Handler
#pragma weak CAN2_TX_IRQHandler = Default_Handler
#pragma weak CAN2_RX0_IRQHandler = Default_Handler
#pragma weak CAN2_RX1_IRQHandler = Default_Handler
#pragma weak CAN2_SCE_IRQHandler = Default_Handler
#pragma weak OTG_FS_IRQHandler = Default_Handler
#pragma weak DMA2_Stream5_IRQHandler = Default_Handler
#pragma weak DMA2_Stream6_IRQHandler = Default_Handler
#pragma weak DMA2_Stream7_IRQHandler = Default_Handler
#pragma weak USART6_IRQHandler = Default_Handler
#pragma weak I2C3_EV_IRQHandler = Default_Handler
#pragma weak I2C3_ER_IRQHandler = Default_Handler
#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler
#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler
#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler
#pragma weak OTG_HS_IRQHandler = Default_Handler
#pragma weak DCMI_IRQHandler = Default_Handler
#pragma weak CRYP_IRQHandler = Default_Handler
#pragma weak HASH_RNG_IRQHandler = Default_Handler
#pragma weak FPU_IRQHandler = Default_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop,
* preserving the system state for examination by a debugger.
* @param None
* @retval None
*/
static void Default_Handler(void)
{
/* Go into an infinite loop. */
while (1)
{
}
}
/*********************** (C) COPYRIGHT 2009 Coocox ************END OF FILE*****/
File diff suppressed because it is too large Load Diff
-78
View File
@@ -1,78 +0,0 @@
/**
******************************************************************************
* @file Project/STM32F4xx_StdPeriph_Templates/stm32f4xx_conf.h
* @author MCD Application Team
* @version V1.7.1
* @date 20-May-2016
* @brief Library configuration file.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_CONF_H
#define __STM32F4xx_CONF_H
/* Includes ------------------------------------------------------------------*/
/* Uncomment the line below to enable peripheral header file inclusion */
#include "stm32f4xx_adc.h"
#include "stm32f4xx_dac.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_usart.h"
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#ifndef NULL
#define NULL 0
#endif
/* If an external clock source is used, then the value of the following define
should be set to the value of the external clock source, else, if no external
clock is used, keep this define commented */
/*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */
/* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */
/* #define USE_FULL_ASSERT 1 */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
#endif /* __STM32F4xx_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Some files were not shown because too many files have changed in this diff Show More