Porównaj commity

...

2 Commity

Autor SHA1 Wiadomość Data
eleccoder abab1692b0 Extra program for testing added, separate from demo/example 2022-12-22 21:42:56 +01:00
eleccoder 9fcdbd51c2 Code maintenance 2022-12-22 21:41:30 +01:00
6 zmienionych plików z 123 dodań i 69 usunięć

Wyświetl plik

@ -23,6 +23,12 @@ FetchContent_MakeAvailable(ax25_aprs_lib)
add_library(ax25_aprs_lib::ax25beacon ALIAS ax25beacon) add_library(ax25_aprs_lib::ax25beacon ALIAS ax25beacon)
# Compiler options
# Enable on demand only, since warnings from 3rd-party code will flood the console
# set(APRS_PICO_COMPILE_WARN_OPTIONS -Wundef -Wswitch-enum -Wall -Wextra -pedantic)
# ##### Configure the build of the 'aprs_pico' library ##### # ##### Configure the build of the 'aprs_pico' library #####
set(TARGET_LIB_NAME aprs_pico) set(TARGET_LIB_NAME aprs_pico)
@ -30,17 +36,18 @@ set(TARGET_LIB_NAME aprs_pico)
add_library(${TARGET_LIB_NAME} add_library(${TARGET_LIB_NAME}
src/aprs_pico.c) src/aprs_pico.c)
set_target_properties(${TARGET_LIB_NAME} target_compile_options(${TARGET_LIB_NAME}
PROPERTIES PRIVATE "${APRS_PICO_COMPILE_WARN_OPTIONS}"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
) )
target_include_directories(${TARGET_LIB_NAME} PUBLIC target_include_directories(${TARGET_LIB_NAME} PUBLIC
include include
) )
# Enable on demand set_target_properties(${TARGET_LIB_NAME}
#target_compile_options(${TARGET_LIB_NAME} PRIVATE "-Wundef;-Wall") PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
)
target_link_libraries(${TARGET_LIB_NAME} target_link_libraries(${TARGET_LIB_NAME}
ax25_aprs_lib::ax25beacon ax25_aprs_lib::ax25beacon
@ -49,29 +56,54 @@ target_link_libraries(${TARGET_LIB_NAME}
) )
# ##### Configure the build of the example application ##### # ##### Configure the build of the DEMO applications #####
set(TARGET_EXAMPLE_EXE_NAME aprs_pico_example) set(TARGET_DEMO_EXE_NAME aprs_pico_beacon_demo)
add_executable(${TARGET_EXAMPLE_EXE_NAME} add_executable(${TARGET_DEMO_EXE_NAME}
src/aprs_pico_example.c src/aprs_pico_beacon_demo.c
) )
target_include_directories(${TARGET_EXAMPLE_EXE_NAME} PRIVATE target_compile_options(${TARGET_DEMO_EXE_NAME}
PRIVATE "${APRS_PICO_COMPILE_WARN_OPTIONS}"
)
target_include_directories(${TARGET_DEMO_EXE_NAME} PRIVATE
include include
) )
# Configure the console interface
pico_enable_stdio_usb(${TARGET_EXAMPLE_EXE_NAME} 1) # USB
#pico_enable_stdio_uart(${TARGET_EXAMPLE_EXE_NAME} 1) # UART
# Create map/bin/hex file etc. # Create map/bin/hex file etc.
pico_add_extra_outputs(${TARGET_EXAMPLE_EXE_NAME}) pico_add_extra_outputs(${TARGET_DEMO_EXE_NAME})
target_link_libraries(${TARGET_EXAMPLE_EXE_NAME} target_link_libraries(${TARGET_DEMO_EXE_NAME}
${TARGET_LIB_NAME} ${TARGET_LIB_NAME}
ax25_aprs_lib::ax25beacon ax25_aprs_lib::ax25beacon
pico_audio_pwm pico_audio_pwm
pico_stdlib pico_stdlib
) )
# ##### Configure the build of the TEST application #####
set(TARGET_TEST_EXE_NAME aprs_pico_tone_test)
add_executable(${TARGET_TEST_EXE_NAME}
src/aprs_pico_tone_test.c
)
target_compile_options(${TARGET_TEST_EXE_NAME}
PRIVATE "${APRS_PICO_COMPILE_WARN_OPTIONS}"
)
target_include_directories(${TARGET_TEST_EXE_NAME} PRIVATE
include
)
# Create map/bin/hex file etc.
pico_add_extra_outputs(${TARGET_TEST_EXE_NAME})
target_link_libraries(${TARGET_TEST_EXE_NAME}
${TARGET_LIB_NAME}
pico_audio_pwm
pico_stdlib
)

Wyświetl plik

@ -13,7 +13,7 @@ An analog line-out audio signal will be generated by a band-pass filter connecte
Image: Line-out signal (see [below](#Hardware)) probed by a DSO. We clearly see the 1200 Hz and 2200 Hz tones of the 1200 Bd 2-AFSK. Image: Line-out signal (see [below](#Hardware)) probed by a DSO. We clearly see the 1200 Hz and 2200 Hz tones of the 1200 Bd 2-AFSK.
Both a static library `libaprs_pico.a` and an example application will be generated by the build. Both a static library `libaprs_pico.a` and a demo application will be generated by the build.
## Prerequisites ## Prerequisites
@ -39,7 +39,7 @@ We just need a simple band-pass filter to extract the analog AFSK-signal from th
The line-out voltage can be as high as 2.7 V<sub>pp</sub> (~1 V<sub>rms</sub>) (at full-scale volume setting in the software and high-impedance load). The line-out voltage can be as high as 2.7 V<sub>pp</sub> (~1 V<sub>rms</sub>) (at full-scale volume setting in the software and high-impedance load).
## Build the library and the example application ## Build the library and the 'beacon' demo application
``` ```
git clone https://github.com/eleccoder/raspi-pico-aprs-tnc.git git clone https://github.com/eleccoder/raspi-pico-aprs-tnc.git
@ -48,18 +48,18 @@ cmake -S . -B build
cmake --build build cmake --build build
``` ```
`build/lib/libaprs_pico.a` and `build/aprs_pico_example[.uf2|.elf|.bin]` will be generated. `build/lib/libaprs_pico.a` and `build/aprs_pico_beacon_demo[.uf2|.elf|.bin|.hex]` will be generated, as well as the testing application `build/aprs_pico_tone_test[.uf2|.elf|.bin|.hex]`.
## Run the example application ## Run the 'beacon' demo application
``` ```
cd build cd build
Flash 'aprs_pico_example[.uf2|.elf|.bin]' to the Pico board as usual Flash 'aprs_pico_beacon_demo[.uf2|.elf|.bin|.hex]' to the Pico board as usual.
``` ```
The analog AFSK audio signal will be available at the filter's line-out. You can probe it by a scope, listen to it by using an audio amp, or connect it to any RF transceiver to send it on the air (ham radio license required). The analog AFSK audio signal will be available at the filter's line-out. You can probe it by a scope, listen to it by using an audio amp, or connect it to any RF transceiver to send it on the air (ham radio license required).
## Test the example application using *Dire Wolf* (on LINUX) ## Test the 'beacon' demo application using *Dire Wolf* (on LINUX)
We can use the famous [Dire Wolf](https://github.com/wb2osz/direwolf) CLI software to decode the APRS data after sampling our APRS audio signal by means of a soundcard. We can use the famous [Dire Wolf](https://github.com/wb2osz/direwolf) CLI software to decode the APRS data after sampling our APRS audio signal by means of a soundcard.
@ -94,5 +94,6 @@ arecord -f cd -c 1 -t raw - | direwolf
## Ingredients / Acknowledgements ## Ingredients / Acknowledgements
- For APRS => AX.25 => PCM conversion I'm using [my modified version](https://github.com/eleccoder/ax25-aprs-lib) of [fsphil's ax25beacon](https://github.com/fsphil/ax25beacon) - For `APRS => AX.25 => PCM` conversion I'm using [my modified version](https://github.com/eleccoder/ax25-aprs-lib) of [fsphil's ax25beacon](https://github.com/fsphil/ax25beacon) project.
- For PCM => PWM conversion I'm using the `pico_audio_pwm` library from [pico-extras](https://github.com/raspberrypi/pico-extras) (NOTE: ATTOW, maturity seems to be rather alpha/beta) - For `PCM => PWM` conversion I'm using the `pico_audio_pwm` library from [pico-extras](https://github.com/raspberrypi/pico-extras) (NOTE: ATTOW, maturity seems to be rather alpha/beta).
- Basic PWM audio rendering with the Pi Pico has been spotted in the [pico-playground](https://github.com/raspberrypi/pico-playground/tree/master/audio).

Wyświetl plik

@ -16,13 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef APRS_PICO_H #pragma once
#define APRS_PICO_H
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <pico/audio_pwm.h> // For 'audio_buffer_pool_t' #include "pico/audio_pwm.h" // For 'audio_buffer_pool_t'
/** \brief Initializes the APRS Pico library /** \brief Initializes the APRS Pico library
@ -69,5 +68,3 @@ bool aprs_pico_sendAPRS(audio_buffer_pool_t* audio_buffer_pool,
* \param[in] volume The volume level of the generated signal (0 ... 256) * \param[in] volume The volume level of the generated signal (0 ... 256)
*/ */
void aprs_pico_send_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz, unsigned int sample_freq_in_hz, uint16_t volume); void aprs_pico_send_sine_wave(audio_buffer_pool_t* audio_buffer_pool, unsigned int freq_in_hz, unsigned int sample_freq_in_hz, uint16_t volume);
#endif // APRS_PICO_H

Wyświetl plik

@ -16,19 +16,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <aprs_pico.h> #include "aprs_pico.h"
#include "ax25beacon.h"
#include "pico/stdlib.h"
#include <stdio.h>
#include <math.h> #include <math.h>
#include <pico/stdlib.h>
#include <ax25beacon.h>
// NOTE: ATTOW, the pico-extra audio PWM lib worked only at a fixed 22050 Hz sampling frequency, while the
// WARNING: ATTOW, the pico audio PWM lib worked only @ 22050 Hz sampling frequency and 48 MHz system clock // system clock runs at 48 MHz. This is documented here: https://github.com/raspberrypi/pico-extras
// This is documented here: https://github.com/raspberrypi/pico-extras #define APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB__FIXED_SAMPLE_FREQ_IN_HZ (22050)
#define APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB_FIXED_SAMPLE_FREQ_IN_HZ (22050) #define APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB__SYS_CLOCK_FREQ_OF_IN_MHZ (48)
#define APRS_PICO__SYS_CLOCK_FREQ_OF_PICO_EXTRA_AUDIO_PWM_LIB_IN_MHZ (48)
typedef struct AudioCallBackUserData typedef struct AudioCallBackUserData
@ -81,14 +80,14 @@ static audio_buffer_pool_t* aprs_pico_initAudio(unsigned int sample_freq_in_hz,
*/ */
static void aprs_pico_initClock(unsigned int sample_freq_in_hz) static void aprs_pico_initClock(unsigned int sample_freq_in_hz)
{ {
// WARNING: ATTOW, the pico audio PWM lib worked only @ 22050 Hz sampling frequency and 48 MHz system clock // NOTE: ATTOW, the pico-extra audio PWM lib worked only at a fixed 22050 Hz sampling frequency, while the
// This is documented here: https://github.com/raspberrypi/pico-extras // system clock runs at 48 MHz. This is documented here: https://github.com/raspberrypi/pico-extras
// Compensate a non-'PICO_EXTRA_AUDIO_PWM_LIB_FIXED_SAMPLE_FREQ_IN_HZ' sampling frequency // Compensate a non-'APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB__FIXED_SAMPLE_FREQ_IN_HZ' sampling frequency
// by adapting the system clock accordingly // by adapting the system clock frequency accordingly.
float sys_clock_in_mhz = (float)APRS_PICO__SYS_CLOCK_FREQ_OF_PICO_EXTRA_AUDIO_PWM_LIB_IN_MHZ * float sys_clock_in_mhz = (float)APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB__SYS_CLOCK_FREQ_OF_IN_MHZ *
((float)sample_freq_in_hz / (float)APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB_FIXED_SAMPLE_FREQ_IN_HZ); ((float)sample_freq_in_hz / (float)APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB__FIXED_SAMPLE_FREQ_IN_HZ);
if (!set_sys_clock_khz((uint32_t)(1000.0f * sys_clock_in_mhz), false)) if (!set_sys_clock_khz((uint32_t)(1000.0f * sys_clock_in_mhz), false))
{ {
@ -177,7 +176,7 @@ static void aprs_pico_sendAPRSAudioCallback(const void* callback_user_data, cons
// See the header file for documentation // See the header file for documentation
audio_buffer_pool_t* aprs_pico_init() audio_buffer_pool_t* aprs_pico_init()
{ {
audio_buffer_pool_t* audio_buffer_pool = aprs_pico_initAudio(APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB_FIXED_SAMPLE_FREQ_IN_HZ, audio_buffer_pool_t* audio_buffer_pool = aprs_pico_initAudio(APRS_PICO__PICO_EXTRA_AUDIO_PWM_LIB__FIXED_SAMPLE_FREQ_IN_HZ,
AUDIO_BUFFER_FORMAT_PCM_S16); AUDIO_BUFFER_FORMAT_PCM_S16);
return audio_buffer_pool; return audio_buffer_pool;
} }

Wyświetl plik

@ -16,11 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <aprs_pico.h> #include "aprs_pico.h"
#include <pico/stdlib.h> #include "pico/stdlib.h"
#define SINE_WAVE_TEST (0) // For testing & debugging
int main() int main()
@ -29,17 +26,8 @@ int main()
audio_buffer_pool_t* audio_buffer_pool = aprs_pico_init(); audio_buffer_pool_t* audio_buffer_pool = aprs_pico_init();
#if (SINE_WAVE_TEST == 1) // Let the altitude run over time
double alt_in_m = 0.0;
const unsigned int FREQ_IN_HZ = 1000u;
const unsigned int SAMPLE_FREQ_IN_HZ = 48000u;
const uint16_t VOLUME = 128u;
aprs_pico_send_sine_wave(audio_buffer_pool, FREQ_IN_HZ, SAMPLE_FREQ_IN_HZ, VOLUME);
#else // !SINE_WAVE_TEST
double alt_in_m = 0.0f;
while (true) // Loop forever while (true) // Loop forever
{ {
@ -49,16 +37,15 @@ int main()
"DL3TG", // Destination call sign "DL3TG", // Destination call sign
"PATH1", // APRS path #1 "PATH1", // APRS path #1
"PATH2", // APRS path #2 "PATH2", // APRS path #2
"APRS by RPi-Pico - https://github.com/eleccoder/raspi-pico-aprs-tnc", // APRS message "APRS by RPi-Pico - https://github.com/eleccoder/raspi-pico-aprs-tnc", // Text message
10.0, // Latitude (in deg) 10.0, // Latitude (in deg)
20.0, // Longitude (in deg) 20.0, // Longitude (in deg)
alt_in_m, // Altitude (in m) alt_in_m, // Altitude (in m)
128u); // Volume (0 ... 256) 128u); // Volume (0 ... 256)
// Don't raise too high ...
alt_in_m = (alt_in_m < 1000.0) ? alt_in_m + 100.0 : 0.0; alt_in_m = (alt_in_m < 1000.0) ? alt_in_m + 100.0 : 0.0;
} }
#endif // SINE_WAVE_TEST, !SINE_WAVE_TEST
return 0; return 0;
} }

Wyświetl plik

@ -0,0 +1,38 @@
/*
* Project 'raspi-pico-aprs-tnc'
* Copyright (C) 2021-2023 Thomas Glau, DL3TG
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "aprs_pico.h"
#include "pico/stdlib.h"
int main()
{
// 48 kHz is used as a default by the underlying https://github.com/eleccoder/ax25-aprs-lib library
// The PWM base frequency is expected to be 16 * SAMPLE_FREQ_IN_HZ
const unsigned int SAMPLE_FREQ_IN_HZ = 48000u;
const unsigned int TONE_FREQ_IN_HZ = 1000u;
const uint16_t VOLUME = 128u; // 0 ... 256
stdio_init_all();
audio_buffer_pool_t* audio_buffer_pool = aprs_pico_init();
aprs_pico_send_sine_wave(audio_buffer_pool, TONE_FREQ_IN_HZ, SAMPLE_FREQ_IN_HZ, VOLUME);
return 0;
}