aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common/includes/Audio/audio.h (renamed from src/fsm/audio.h)36
-rw-r--r--src/common/includes/Audio/cw.h (renamed from src/fsm/cw.h)0
-rw-r--r--src/common/includes/GPIO/i2c.h (renamed from src/fsm/i2c.h)0
-rw-r--r--src/common/src/Audio/audio.c32
-rw-r--r--src/common/src/Audio/cw.c (renamed from src/fsm/cw.c)23
-rw-r--r--src/common/src/Core/common.c9
-rw-r--r--src/common/src/Core/main.c106
-rw-r--r--src/fsm/common.c231
-rw-r--r--src/simulator/Makefile2
-rw-r--r--src/simulator/src/Audio/audio.c140
-rw-r--r--src/simulator/src/Audio/cw.c32
-rw-r--r--src/simulator/src/Core/main.c2
-rw-r--r--src/simulator/src/Gui/gui.c69
-rw-r--r--src/stm32f/src/Audio/audio.c (renamed from src/fsm/audio.c)132
-rw-r--r--src/stm32f/src/Audio/cw.c4
-rw-r--r--src/stm32f/src/GPIO/i2c.c (renamed from src/fsm/i2c.c)7
16 files changed, 430 insertions, 395 deletions
diff --git a/src/fsm/audio.h b/src/common/includes/Audio/audio.h
index 35f3f65..006f82e 100644
--- a/src/fsm/audio.h
+++ b/src/common/includes/Audio/audio.h
@@ -6,37 +6,37 @@
typedef void AudioCallbackFunction(void *context,int buffer);
-#define Audio8000HzSettings 256,5,12,1
-#define Audio16000HzSettings 213,2,13,0
-#define Audio32000HzSettings 213,2,6,1
-#define Audio48000HzSettings 258,3,3,1
-#define Audio96000HzSettings 344,2,3,1
-#define Audio22050HzSettings 429,4,9,1
-#define Audio44100HzSettings 271,2,6,0
-#define AudioVGAHSyncSettings 419,2,13,0 // 31475.3606. Actual VGA timer is 31472.4616.
+#define Audio8000HzSettings 256,5,12,1,8000
+#define Audio16000HzSettings 213,2,13,0,16000
+#define Audio32000HzSettings 213,2,6,1,32000
+#define Audio48000HzSettings 258,3,3,1,48000
+#define Audio96000HzSettings 344,2,3,1,96000
+#define Audio22050HzSettings 429,4,9,1,22050
+#define Audio44100HzSettings 271,2,6,0,44100
+#define AudioVGAHSyncSettings 419,2,13,0,31475 // 31475.3606. Actual VGA timer is 31472.4616.
#define AUDIO_BUF_LEN 4096
// Initialize and power up audio hardware. Use the above defines for the parameters.
// Can probably only be called once.
-void InitializeAudio(int plln,int pllr,int i2sdiv,int i2sodd);
+void audio_initialize(int plln,int pllr,int i2sdiv,int i2sodd, int rate);
// Power up and down the audio hardware.
-void AudioOn();
-void AudioOff();
+void audio_on();
+void audio_off();
// Set audio volume in steps of 0.5 dB. 0xff is +12 dB.
-void SetAudioVolume(int volume);
+void audio_set_volume(int volume);
// Output one audio sample directly to the hardware without using DMA.
-void OutputAudioSample(int16_t sample);
-void OutputAudioSampleWithoutBlocking(int16_t sample);
+void audio_output_sample(int16_t sample);
+void audio_output_sample_without_blocking(int16_t sample);
// Start and stop audio playback using DMA.
// Callback is optional, and called whenever a new buffer is needed.
-void PlayAudioWithCallback(AudioCallbackFunction *callback,void *context);
-void StopAudio();
+void audio_play_with_callback(AudioCallbackFunction *callback,void *context);
+void audio_stop();
// Provide a new buffer to the audio DMA. Output is double buffered, so
// at least two buffers must be maintained by the program. It is not allowed
@@ -44,7 +44,7 @@ void StopAudio();
// invocation.
// Buffers must reside in DMA1-accessible memory, that is, the 128k RAM bank,
// or flash.
-void ProvideAudioBuffer(void *samples,int numsamples);
-bool ProvideAudioBufferWithoutBlocking(void *samples,int numsamples);
+void audio_provide_buffer(void *samples,int numsamples);
+bool audio_provide_buffer_without_blocking(void *samples,int numsamples);
#endif
diff --git a/src/fsm/cw.h b/src/common/includes/Audio/cw.h
index 384918d..384918d 100644
--- a/src/fsm/cw.h
+++ b/src/common/includes/Audio/cw.h
diff --git a/src/fsm/i2c.h b/src/common/includes/GPIO/i2c.h
index 109213b..109213b 100644
--- a/src/fsm/i2c.h
+++ b/src/common/includes/GPIO/i2c.h
diff --git a/src/common/src/Audio/audio.c b/src/common/src/Audio/audio.c
new file mode 100644
index 0000000..3d3dbf4
--- /dev/null
+++ b/src/common/src/Audio/audio.c
@@ -0,0 +1,32 @@
+#include "Audio/audio.h"
+
+#include <stdlib.h>
+
+static void audio_write_register(uint8_t address, uint8_t value);
+static void audio_start_dma_and_request_buffers();
+static void audio_stop_dma();
+
+static AudioCallbackFunction *callback_function;
+static void *callback_context;
+static int16_t * volatile next_buffer_samples;
+static volatile int next_buffer_length;
+static volatile int buffer_number;
+static volatile bool dma_running;
+
+void audio_initialize_platform(int plln, int pllr, int i2sdiv, int i2sodd, int rate);
+
+void audio_initialize(int plln, int pllr, int i2sdiv, int i2sodd, int rate) {
+
+ // Intitialize state.
+ callback_function = NULL;
+ callback_context = NULL;
+ next_buffer_samples = NULL;
+ next_buffer_length = 0;
+ buffer_number = 0;
+ dma_running = false;
+
+ audio_initialize_platform(plln, pllr, i2sdiv, i2sodd, rate);
+
+ audio_set_volume(0xff);
+
+}
diff --git a/src/fsm/cw.c b/src/common/src/Audio/cw.c
index 6d54778..3f3b97d 100644
--- a/src/fsm/cw.c
+++ b/src/common/src/Audio/cw.c
@@ -34,11 +34,16 @@
* audio_queue
*/
-#include "cw.h"
-#include "common.h"
+#include "Audio/cw.h"
+#include "Core/common.h"
+#include "Audio/audio.h"
+
+#ifdef SIMULATOR
+#define arm_cos_f32 cosf
+#define arm_sin_f32 sinf
+#else
#include "arm_math.h"
-#include "audio.h"
-#include "debug.h"
+#endif
/* Kernel includes. */
#include "FreeRTOS.h"
@@ -367,6 +372,8 @@ int cw_psk31_push_message(const char* text, int dit_duration, int frequency)
xQueueSendToBack(cw_msg_queue, &msg, portMAX_DELAY); /* Send Message */
+ cw_message_sent(msg.message);
+
return 1;
}
@@ -461,6 +468,10 @@ static int16_t cw_generate_audio(float omega, int i, int t)
}
else {
cw_generate_audio_ampl -= cw_generate_audio_ampl / 64.0f;
+
+ if (cw_generate_audio_ampl < 0) {
+ cw_generate_audio_ampl = 0;
+ }
}
cw_generate_audio_nco += omega;
@@ -515,7 +526,7 @@ static void cw_psk31_task(void *pvParameters)
cw_transmit_ongoing = 1;
// Audio should be off, turn it on
- AudioOn();
+ audio_on();
if (cw_fill_msg_current.dit_duration) {
cw_psk31_buffer_len = cw_text_to_on_buffer(
@@ -582,7 +593,7 @@ static void cw_psk31_task(void *pvParameters)
cw_transmit_ongoing = 0;
// Turn off audio to save power
- AudioOff();
+ audio_off();
}
}
}
diff --git a/src/common/src/Core/common.c b/src/common/src/Core/common.c
index c31bbf8..476d1b4 100644
--- a/src/common/src/Core/common.c
+++ b/src/common/src/Core/common.c
@@ -38,8 +38,7 @@ static uint16_t lfsr;
static void common_increase_timestamp(TimerHandle_t t);
-int find_last_sunday(const struct tm* time)
-{
+int find_last_sunday(const struct tm* time) {
struct tm t = *time;
// the last sunday can never be before the 20th
@@ -68,8 +67,7 @@ int find_last_sunday(const struct tm* time)
* 1 if true
* -1 in case of error
*/
-static int is_dst(const struct tm *time)
-{
+static int is_dst(const struct tm *time) {
/* DST from 01:00 UTC on last Sunday in March
* to 01:00 UTC on last Sunday in October
*/
@@ -114,8 +112,7 @@ static int is_dst(const struct tm *time)
}
}
-int local_time(struct tm *time)
-{
+int local_time(struct tm *time) {
const int local_time_offset=1; // hours
int valid = gps_utctime(time);
diff --git a/src/common/src/Core/main.c b/src/common/src/Core/main.c
index 1a72e32..7760d6c 100644
--- a/src/common/src/Core/main.c
+++ b/src/common/src/Core/main.c
@@ -34,8 +34,8 @@
#include "semphr.h"
/* Includes */
-/* #include "audio.h" */
-/* #include "cw.h" */
+#include "Audio/audio.h"
+#include "Audio/cw.h"
/* #include "pio.h" */
/* #include "i2c.h" */
#include "GPS/gps.h"
@@ -119,11 +119,11 @@ static void test_task(void *pvParameters) {
if (i == 0) {
i = 1;
- leds_turn_on(LED_RED);
+ leds_turn_on(LED_GREEN);
} else {
i = 0;
- leds_turn_off(LED_RED);
+ leds_turn_off(LED_GREEN);
}
}
@@ -134,8 +134,8 @@ static void test_task(void *pvParameters) {
// already running when calling the init functions.
static void launcher_task(void *pvParameters)
{
- /* usart_debug_puts("CW init\r\n"); */
- /* cw_psk31_init(16000); */
+ usart_debug_puts("CW init\r\n");
+ cw_psk31_init(16000);
/* */
/* usart_debug_puts("PIO init\r\n"); */
/* pio_init(); */
@@ -143,17 +143,17 @@ static void launcher_task(void *pvParameters)
/* usart_debug_puts("I2C init\r\n"); */
/* i2c_init(); */
/* */
- /* usart_debug_puts("common init\r\n"); */
- /* common_init(); */
- /* */
+ usart_debug_puts("common init\r\n");
+ common_init();
+
usart_debug_puts("GPS init\r\n");
gps_init();
- /* */
+
/* usart_debug_puts("DS18B20 init\r\n"); */
/* temperature_init(); */
/* */
/* usart_debug_puts("TaskButton init\r\n"); */
- /* */
+
TaskHandle_t task_handle;
/* xTaskCreate( */
/* detect_button_press, */
@@ -195,24 +195,24 @@ static void launcher_task(void *pvParameters)
trigger_fault(FAULT_SOURCE_MAIN);
}
- /* usart_debug_puts("Audio init\r\n"); */
- /* */
- /* InitializeAudio(Audio16000HzSettings); */
- /* */
- /* usart_debug_puts("Audio set volume\r\n"); */
- /* SetAudioVolume(210); */
- /* */
- /* usart_debug_puts("Audio set callback\r\n"); */
- /* PlayAudioWithCallback(audio_callback, NULL); */
- /* */
- /* // By default, let's the audio off to save power */
- /* AudioOff(); */
+ usart_debug_puts("Audio init\r\n");
+
+ audio_initialize(Audio16000HzSettings);
+
+ usart_debug_puts("Audio set volume\r\n");
+ audio_set_volume(210);
+
+ usart_debug_puts("Audio set callback\r\n");
+ audio_play_with_callback(audio_callback, NULL);
+
+ // By default, let's the audio off to save power
+ audio_off();
usart_debug_puts("Init done.\r\n");
xTaskCreate(
test_task,
- "TaskFSM",
+ "Test task",
4*configMINIMAL_STACK_SIZE,
(void*) NULL,
tskIDLE_PRIORITY + 2UL,
@@ -224,6 +224,10 @@ static void launcher_task(void *pvParameters)
* for more info.
*/
+ cw_psk31_push_message("HB9G HI - TESTING", 50, 440);
+ cw_psk31_push_message("HB9G HI AGAIN", 50, 440);
+ cw_psk31_push_message("HB9G 73", 50, 440);
+
while (1) {
vTaskSuspend(NULL);
}
@@ -273,33 +277,33 @@ static void detect_button_press(void *pvParameters)
/* } */
}
-static void audio_callback(void* context, int select_buffer)
-{
- /* static int16_t audio_buffer0[AUDIO_BUF_LEN]; */
- /* static int16_t audio_buffer1[AUDIO_BUF_LEN]; */
- /* int16_t *samples; */
- /* */
- /* if (select_buffer == 0) { */
- /* samples = audio_buffer0; */
- /* GPIO_ResetBits(GPIOD, GPIOD_BOARD_LED_RED); */
- /* select_buffer = 1; */
- /* } else { */
- /* samples = audio_buffer1; */
- /* GPIO_SetBits(GPIOD, GPIOD_BOARD_LED_RED); */
- /* select_buffer = 0; */
- /* } */
- /* */
- /* size_t samples_len = cw_psk31_fill_buffer(samples, AUDIO_BUF_LEN); */
- /* */
- /* if (samples_len == 0) { */
- /* for (int i = 0; i < AUDIO_BUF_LEN; i++) { */
- /* samples[i] = 0; */
- /* } */
- /* */
- /* samples_len = AUDIO_BUF_LEN; */
- /* } */
- /* */
- /* ProvideAudioBufferWithoutBlocking(samples, samples_len); */
+static void audio_callback(void* context, int select_buffer) {
+ static int16_t audio_buffer0[AUDIO_BUF_LEN];
+ static int16_t audio_buffer1[AUDIO_BUF_LEN];
+ int16_t *samples;
+
+ if (select_buffer == 0) {
+ samples = audio_buffer0;
+ leds_turn_off(LED_RED);
+ select_buffer = 1;
+ } else {
+ samples = audio_buffer1;
+ leds_turn_on(LED_RED);
+ select_buffer = 0;
+ }
+
+ size_t samples_len = cw_psk31_fill_buffer(samples, AUDIO_BUF_LEN);
+
+ if (samples_len == 0) {
+ for (int i = 0; i < AUDIO_BUF_LEN; i++) {
+ samples[i] = 0;
+ }
+
+ samples_len = AUDIO_BUF_LEN;
+ }
+
+ audio_provide_buffer_without_blocking(samples, samples_len);
+
}
static struct tm gps_time;
diff --git a/src/fsm/common.c b/src/fsm/common.c
deleted file mode 100644
index 27c792f..0000000
--- a/src/fsm/common.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Matthias P. Braendli
- *
- * 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.
-*/
-
-#include "common.h"
-#include "usart.h"
-#include "FreeRTOS.h"
-#include "timers.h"
-#include "gps.h"
-#include <stm32f4xx.h>
-#include <time.h>
-
-static uint64_t common_timestamp = 0; // milliseconds since startup
-static TimerHandle_t common_timer;
-
-// The LFSR is used as random number generator
-static const uint16_t lfsr_start_state = 0x12ABu;
-static uint16_t lfsr;
-
-static void common_increase_timestamp(TimerHandle_t t);
-
-int find_last_sunday(const struct tm* time)
-{
- struct tm t = *time;
-
- // the last sunday can never be before the 20th
- t.tm_mday = 20;
-
- int last_sunday = 1;
-
- while (t.tm_mon == time->tm_mon) {
- t.tm_mday++;
- if (mktime(&t) == (time_t)-1) {
- // TODO error
- return -1;
- }
-
- const int sunday = 0;
- if (t.tm_wday == sunday) {
- last_sunday = t.tm_mday;
- }
- }
-
- return last_sunday;
-}
-
-/* Calculate if we are in daylight saving time.
- * return 0 if false
- * 1 if true
- * -1 in case of error
- */
-static int is_dst(const struct tm *time)
-{
- /* DST from 01:00 UTC on last Sunday in March
- * to 01:00 UTC on last Sunday in October
- */
- const int march = 2;
- const int october = 9;
- if (time->tm_mon < march) {
- return 0;
- }
- else if (time->tm_mon == march) {
- int last_sunday = find_last_sunday(time);
- if (last_sunday == -1) return -1;
-
- if (time->tm_mday < last_sunday) {
- return 0;
- }
- else if (time->tm_mday == last_sunday) {
- return (time->tm_hour < 1) ? 0 : 1;
- }
- else {
- return 1;
- }
- }
- else if (time->tm_mon > march && time->tm_mon < october) {
- return 1;
- }
- else if (time->tm_mon == october) {
- int last_sunday = find_last_sunday(time);
- if (last_sunday == -1) return -1;
-
- if (time->tm_mday < last_sunday) {
- return 1;
- }
- else if (time->tm_mday == last_sunday) {
- return (time->tm_hour < 1) ? 1 : 0;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
- }
-}
-
-int local_time(struct tm *time)
-{
- const int local_time_offset=1; // hours
-
- int valid = gps_utctime(time);
-
- if (valid) {
- time->tm_hour += local_time_offset;
-
- if (is_dst(time)) {
- time->tm_hour++;
- time->tm_isdst = 1;
- }
-
- // Let mktime fix the struct tm *time
- if (mktime(time) == (time_t)-1) {
- // TODO inform about failure
- valid = 0;
- }
- }
-
- return valid;
-}
-
-
-void common_init(void)
-{
- common_timer = xTimerCreate("Timer",
- portTICK_PERIOD_MS,
- pdTRUE, // Auto-reload
- NULL, // No unique id
- common_increase_timestamp
- );
-
- xTimerStart(common_timer, 0);
-
- lfsr = lfsr_start_state;
-}
-
-static void common_increase_timestamp(TimerHandle_t t)
-{
- common_timestamp++;
-}
-
-uint64_t timestamp_now(void)
-{
- return common_timestamp;
-}
-
-
-// Return either 0 or 1, somewhat randomly
-int random_bool(void)
-{
- uint16_t bit;
-
- /* taps: 16 14 13 11; feedback polynomial: x^16 + x^14 + x^13 + x^11 + 1 */
- bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
- lfsr = (lfsr >> 1) | (bit << 15);
-
- return bit;
-}
-
-// For the debugger
-static int faultsource = 0;
-void trigger_fault(int source)
-{
- usart_debug("Fatal: %d", source);
-
- __disable_irq();
-
- faultsource = source;
-
- while (1) {}
-}
-
-void hard_fault_handler_c(uint32_t *hardfault_args)
-{
- uint32_t stacked_r0;
- uint32_t stacked_r1;
- uint32_t stacked_r2;
- uint32_t stacked_r3;
- uint32_t stacked_r12;
- uint32_t stacked_lr;
- uint32_t stacked_pc;
- uint32_t stacked_psr;
-
- stacked_r0 = hardfault_args[0];
- stacked_r1 = hardfault_args[1];
- stacked_r2 = hardfault_args[2];
- stacked_r3 = hardfault_args[3];
-
- stacked_r12 = hardfault_args[4];
- stacked_lr = hardfault_args[5];
- stacked_pc = hardfault_args[6];
- stacked_psr = hardfault_args[7];
-
- usart_debug_puts("\n\n[Hard fault handler - all numbers in hex]\n");
- usart_debug("R0 = %x\n", stacked_r0);
- usart_debug("R1 = %x\n", stacked_r1);
- usart_debug("R2 = %x\n", stacked_r2);
- usart_debug("R3 = %x\n", stacked_r3);
- usart_debug("R12 = %x\n", stacked_r12);
- usart_debug("LR [R14] = %x subroutine call return address\n", stacked_lr);
- usart_debug("PC [R15] = %x program counter\n", stacked_pc);
- usart_debug("PSR = %x\n", stacked_psr);
- usart_debug("BFAR = %x\n", (*((volatile unsigned long *)(0xE000ED38))));
- usart_debug("CFSR = %x\n", (*((volatile unsigned long *)(0xE000ED28))));
- usart_debug("HFSR = %x\n", (*((volatile unsigned long *)(0xE000ED2C))));
- usart_debug("DFSR = %x\n", (*((volatile unsigned long *)(0xE000ED30))));
- usart_debug("AFSR = %x\n", (*((volatile unsigned long *)(0xE000ED3C))));
- usart_debug("SCB_SHCSR = %x\n", SCB->SHCSR);
-
- while (1);
-}
diff --git a/src/simulator/Makefile b/src/simulator/Makefile
index 511b6e6..663570e 100644
--- a/src/simulator/Makefile
+++ b/src/simulator/Makefile
@@ -70,7 +70,7 @@ CWARNS += -Wmissing-prototypes
CFLAGS += -m32
CFLAGS += -DDEBUG=1
-CFLAGS += -g -DUSE_STDIO=1 -D__GCC_POSIX__=1 -lX11 -lm -lGL -lm -lGLU
+CFLAGS += -g -DUSE_STDIO=1 -D__GCC_POSIX__=1 -lX11 -lm -lGL -lm -lGLU -lpulse-simple -lpulse
ifneq ($(shell uname), Darwin)
CFLAGS += -pthread
endif
diff --git a/src/simulator/src/Audio/audio.c b/src/simulator/src/Audio/audio.c
new file mode 100644
index 0000000..0d21305
--- /dev/null
+++ b/src/simulator/src/Audio/audio.c
@@ -0,0 +1,140 @@
+#include "../../../common/src/Audio/audio.c"
+
+#include <pulse/simple.h>
+#include "FreeRTOS.h"
+#include "task.h"
+
+
+pa_simple *s = NULL;
+
+int current_buffer_length = 0;
+int16_t * current_buffer_samples;
+
+static void audio_buffer_sender(void *args);
+
+extern char gui_audio_on;
+
+void audio_initialize_platform(int plln, int pllr, int i2sdiv, int i2sodd, int rate) {
+
+ int error;
+
+ static pa_sample_spec ss = {
+ .format = PA_SAMPLE_S16LE,
+ .rate = 0,
+ .channels = 1
+ };
+
+ ss.rate = rate;
+
+ if (s = pa_simple_new(NULL, "Glutte", PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error)) {
+
+ } else {
+ printf("Pulseaudio playback init error\n");
+ while(1);
+ }
+
+
+ TaskHandle_t task_handle;
+ xTaskCreate(
+ audio_buffer_sender,
+ "Audio buffer sender",
+ configMINIMAL_STACK_SIZE,
+ (void*) NULL,
+ tskIDLE_PRIORITY + 2UL,
+ &task_handle);
+
+}
+
+static void audio_buffer_sender(void *args) {
+
+ while(1) {
+
+ if (current_buffer_length != 0) {
+ pa_simple_write(s, current_buffer_samples, current_buffer_length * 2, NULL);
+ current_buffer_length = 0;
+ audio_buffer_sent();
+ }
+
+ taskYIELD();
+ }
+
+}
+
+void audio_buffer_sent() {
+
+ if (next_buffer_samples) {
+ audio_start_dma_and_request_buffers();
+ } else {
+ dma_running = false;
+ }
+
+}
+
+void audio_on() {
+ gui_audio_on = 1;
+}
+
+void audio_off() {
+ gui_audio_on = 0;
+}
+
+void audio_set_volume(int volume) {
+}
+
+
+void audio_output_sample_without_blocking(int16_t sample) {
+}
+
+void audio_play_with_callback(AudioCallbackFunction *callback, void *context) {
+ audio_stop_dma();
+
+ callback_function = callback;
+ callback_context = context;
+ buffer_number = 0;
+
+ if (callback_function)
+ callback_function(callback_context, buffer_number);
+}
+
+void audio_stop() {
+ audio_stop_dma();
+ callback_function = NULL;
+}
+
+void audio_provide_buffer(void *samples, int numsamples) {
+ while (!audio_provide_buffer_without_blocking(samples, numsamples))
+ __asm__ volatile ("nop");
+}
+
+bool audio_provide_buffer_without_blocking(void *samples, int numsamples) {
+ if (next_buffer_samples)
+ return false;
+
+ next_buffer_samples = samples;
+ next_buffer_length = numsamples;
+
+ if (!dma_running)
+ audio_start_dma_and_request_buffers();
+
+ return true;
+}
+
+static void audio_start_dma_and_request_buffers() {
+
+ current_buffer_length = next_buffer_length;
+ current_buffer_samples = next_buffer_samples;
+
+ // Update state.
+ next_buffer_samples = NULL;
+ buffer_number ^= 1;
+ dma_running = true;
+
+ // Invoke callback if it exists to queue up another buffer.
+ if (callback_function)
+ callback_function(callback_context, buffer_number);
+}
+
+static void audio_stop_dma() {
+ dma_running = false;
+}
+
diff --git a/src/simulator/src/Audio/cw.c b/src/simulator/src/Audio/cw.c
new file mode 100644
index 0000000..0f37be4
--- /dev/null
+++ b/src/simulator/src/Audio/cw.c
@@ -0,0 +1,32 @@
+#include "../../../common/src/Audio/cw.c"
+
+extern char gui_cw_text[4096];
+int gui_cw_text_pointer = 0;
+
+void cw_move_buffer_up() {
+
+ for (int i = 0; i <= 4010; i++) {
+ gui_cw_text[i] = gui_cw_text[i + 10];
+ gui_cw_text[i + 1] = '\0';
+ }
+
+ gui_cw_text_pointer -= 10;
+
+}
+void cw_message_sent(const char* str) {
+
+ while(*str) {
+ gui_cw_text[gui_cw_text_pointer+1] = '\0';
+ gui_cw_text[gui_cw_text_pointer] = *str;
+ gui_cw_text_pointer++;
+
+ if (gui_cw_text_pointer >= 4000) {
+ cw_move_buffer_up();
+ }
+ str++;
+ }
+
+ gui_cw_text[gui_cw_text_pointer+1] = '\0';
+ gui_cw_text[gui_cw_text_pointer] = '\n';
+ gui_cw_text_pointer++;
+}
diff --git a/src/simulator/src/Core/main.c b/src/simulator/src/Core/main.c
index 853ee83..088e344 100644
--- a/src/simulator/src/Core/main.c
+++ b/src/simulator/src/Core/main.c
@@ -58,7 +58,7 @@ char gui_gps_custom_day[4];
int gui_gps_custom_day_len;
char gui_gps_custom_month[4];
int gui_gps_custom_month_len;
-char gui_gps_custom_year[6];
+char gui_gps_custom_year[4];
int gui_gps_custom_year_len;
static void thread_gui_gps(void *arg) {
diff --git a/src/simulator/src/Gui/gui.c b/src/simulator/src/Gui/gui.c
index 58bbb78..cd7e004 100644
--- a/src/simulator/src/Gui/gui.c
+++ b/src/simulator/src/Gui/gui.c
@@ -86,6 +86,14 @@ int gui_gps_custom_month_len = 2;
char gui_gps_custom_year[4] = "16";
int gui_gps_custom_year_len = 2;
+
+/**
+ * Audio
+ **/
+char gui_audio_on = 0;
+char gui_cw_text[4096];
+
+
struct XWindow {
Display *dpy;
Window win;
@@ -314,12 +322,12 @@ int main_gui() {
uart_send_txt_len = 0;
}
- nk_menubar_end(ctx);
nk_layout_row_dynamic(ctx, 25, 1);
-
nk_label(ctx, "UART Output:", NK_TEXT_LEFT);
+ nk_menubar_end(ctx);
+
nk_layout_row_dynamic(ctx, 16, 1);
char * current_pointer = uart_recv_txt;
@@ -400,6 +408,63 @@ int main_gui() {
}
nk_end(ctx);
+ if (nk_begin(ctx, &layout, "Audio", nk_rect(160, 360, 100, 155), NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) {
+
+ nk_layout_row_static(ctx, 20, 20, 3);
+
+ struct nk_color color;
+
+ nk_text(ctx, "", 0, NK_TEXT_LEFT);
+ nk_text(ctx, "", 0, NK_TEXT_LEFT);
+ nk_text(ctx, "", 0, NK_TEXT_LEFT);
+
+ nk_text(ctx, "", 0, NK_TEXT_LEFT);
+
+ color.r = 255; color.g = 255; color.b = 0; color.a = 255;
+
+ if (gui_audio_on == 1) {
+ color.r = 0;
+ } else {
+ color.g = 0;
+ }
+ nk_button_color(ctx, color, NK_BUTTON_DEFAULT);
+ }
+ nk_end(ctx);
+
+
+ if (nk_begin(ctx, &layout, "CW", nk_rect(270, 360, 180, 155), NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_SCALABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) {
+
+ nk_menubar_begin(ctx);
+ nk_layout_row_dynamic(ctx, 25, 1);
+
+ nk_label(ctx, "CW Buffer:", NK_TEXT_LEFT);
+
+ nk_menubar_end(ctx);
+
+ nk_layout_row_dynamic(ctx, 16, 1);
+
+ char * current_pointer = gui_cw_text;
+ int l = 0;
+
+ while (*current_pointer != 0) {
+
+ if (*current_pointer == '\n') {
+ if (l > 1) {
+ nk_text(ctx, current_pointer - l, l, NK_TEXT_LEFT);
+ }
+ current_pointer++;
+ l = 0;
+ }
+ current_pointer++;
+ l++;
+ }
+
+ if (l > 1) {
+ nk_text(ctx, current_pointer - l, l, NK_TEXT_LEFT);
+ }
+ }
+ nk_end(ctx);
+
if (nk_begin(ctx, &layout, "GPS", nk_rect(460, 50, 200, 465), NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_MINIMIZABLE|NK_WINDOW_TITLE)) {
nk_layout_row_dynamic(ctx, 30, 1);
diff --git a/src/fsm/audio.c b/src/stm32f/src/Audio/audio.c
index 6ecea62..bdb2961 100644
--- a/src/fsm/audio.c
+++ b/src/stm32f/src/Audio/audio.c
@@ -1,32 +1,13 @@
-#include "audio.h"
-#include "i2c.h"
+#include "GPIO/i2c.h"
#include "stm32f4xx_conf.h"
#include "stm32f4xx.h"
-#include <stdlib.h>
+#include "../../../common/src/Audio/audio.c"
-static void WriteRegister(uint8_t address, uint8_t value);
-static void StartAudioDMAAndRequestBuffers();
-static void StopAudioDMA();
+void audio_initialize_platform(int plln, int pllr, int i2sdiv, int i2sodd, int rate) {
-static AudioCallbackFunction *CallbackFunction;
-static void *CallbackContext;
-static int16_t * volatile NextBufferSamples;
-static volatile int NextBufferLength;
-static volatile int BufferNumber;
-static volatile bool DMARunning;
-
-void InitializeAudio(int plln, int pllr, int i2sdiv, int i2sodd) {
GPIO_InitTypeDef GPIO_InitStructure;
- // Intitialize state.
- CallbackFunction = NULL;
- CallbackContext = NULL;
- NextBufferSamples = NULL;
- NextBufferLength = 0;
- BufferNumber = 0;
- DMARunning = false;
-
// Turn on peripherals.
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
@@ -74,26 +55,24 @@ void InitializeAudio(int plln, int pllr, int i2sdiv, int i2sodd) {
GPIO_SetBits(GPIOD, GPIO_Pin_4);
// Configure codec.
- WriteRegister(0x02, 0x01); // Keep codec powered off.
- WriteRegister(0x04, 0xaf); // SPK always off and HP always on.
+ audio_write_register(0x02, 0x01); // Keep codec powered off.
+ audio_write_register(0x04, 0xaf); // SPK always off and HP always on.
- WriteRegister(0x05, 0x81); // Clock configuration: Auto detection.
- WriteRegister(0x06, 0x04); // Set slave mode and Philips audio standard.
-
- SetAudioVolume(0xff);
+ audio_write_register(0x05, 0x81); // Clock configuration: Auto detection.
+ audio_write_register(0x06, 0x04); // Set slave mode and Philips audio standard.
// Power on the codec.
- WriteRegister(0x02, 0x9e);
+ audio_write_register(0x02, 0x9e);
// Configure codec for fast shutdown.
- WriteRegister(0x0a, 0x00); // Disable the analog soft ramp.
- WriteRegister(0x0e, 0x04); // Disable the digital soft ramp.
+ audio_write_register(0x0a, 0x00); // Disable the analog soft ramp.
+ audio_write_register(0x0e, 0x04); // Disable the digital soft ramp.
- WriteRegister(0x27, 0x00); // Disable the limiter attack level.
- WriteRegister(0x1f, 0x0f); // Adjust bass and treble levels.
+ audio_write_register(0x27, 0x00); // Disable the limiter attack level.
+ audio_write_register(0x1f, 0x0f); // Adjust bass and treble levels.
- WriteRegister(0x1a, 0x0a); // Adjust PCM volume level.
- WriteRegister(0x1b, 0x0a);
+ audio_write_register(0x1a, 0x0a); // Adjust PCM volume level.
+ audio_write_register(0x1b, 0x0a);
// Disable I2S.
SPI3 ->I2SCFGR = 0;
@@ -114,78 +93,79 @@ void InitializeAudio(int plln, int pllr, int i2sdiv, int i2sodd) {
}
-void AudioOn() {
- WriteRegister(0x02, 0x9e);
+void audio_on() {
+ audio_write_register(0x02, 0x9e);
SPI3 ->I2SCFGR = SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1
| SPI_I2SCFGR_I2SE; // Master transmitter, Phillips mode, 16 bit values, clock polarity low, enable.
}
-void AudioOff() {
- WriteRegister(0x02, 0x9f);
+void audio_off() {
+ audio_write_register(0x02, 0x9f);
SPI3 ->I2SCFGR = 0;
}
-void SetAudioVolume(int volume) {
- WriteRegister(0x20, (volume + 0x19) & 0xff);
- WriteRegister(0x21, (volume + 0x19) & 0xff);
+void audio_set_volume(int volume) {
+ audio_write_register(0x20, (volume + 0x19) & 0xff);
+ audio_write_register(0x21, (volume + 0x19) & 0xff);
}
-void OutputAudioSample(int16_t sample) {
+void audio_output_sample(int16_t sample) {
while (!(SPI3 ->SR & SPI_SR_TXE ))
;
SPI3 ->DR = sample;
}
-void OutputAudioSampleWithoutBlocking(int16_t sample) {
+
+void audio_output_sample_without_blocking(int16_t sample) {
SPI3 ->DR = sample;
}
-void PlayAudioWithCallback(AudioCallbackFunction *callback, void *context) {
- StopAudioDMA();
+void audio_play_with_callback(AudioCallbackFunction *callback, void *context) {
+ audio_stop_dma();
NVIC_EnableIRQ(DMA1_Stream7_IRQn);
NVIC_SetPriority(DMA1_Stream7_IRQn, 5);
SPI3 ->CR2 |= SPI_CR2_TXDMAEN; // Enable I2S TX DMA request.
- CallbackFunction = callback;
- CallbackContext = context;
- BufferNumber = 0;
+ callback_function = callback;
+ callback_context = context;
+ buffer_number = 0;
- if (CallbackFunction)
- CallbackFunction(CallbackContext, BufferNumber);
+ if (callback_function)
+ callback_function(callback_context, buffer_number);
}
-void StopAudio() {
- StopAudioDMA();
+void audio_stop() {
+ audio_stop_dma();
SPI3 ->CR2 &= ~SPI_CR2_TXDMAEN; // Disable I2S TX DMA request.
NVIC_DisableIRQ(DMA1_Stream7_IRQn);
- CallbackFunction = NULL;
+ callback_function = NULL;
}
-void ProvideAudioBuffer(void *samples, int numsamples) {
- while (!ProvideAudioBufferWithoutBlocking(samples, numsamples))
+void audio_provide_buffer(void *samples, int numsamples) {
+ while (!audio_provide_buffer_without_blocking(samples, numsamples))
__asm__ volatile ("wfi");
}
-bool ProvideAudioBufferWithoutBlocking(void *samples, int numsamples) {
- if (NextBufferSamples)
+bool audio_provide_buffer_without_blocking(void *samples, int numsamples) {
+ if (next_buffer_samples)
return false;
NVIC_DisableIRQ(DMA1_Stream7_IRQn);
- NextBufferSamples = samples;
- NextBufferLength = numsamples;
+ next_buffer_samples = samples;
+ next_buffer_length = numsamples;
- if (!DMARunning)
- StartAudioDMAAndRequestBuffers();
+ if (!dma_running)
+ audio_start_dma_and_request_buffers();
NVIC_EnableIRQ(DMA1_Stream7_IRQn);
return true;
}
-static void StartAudioDMAAndRequestBuffers() {
+static void audio_start_dma_and_request_buffers() {
// Configure DMA stream.
DMA1_Stream7 ->CR = (0 * DMA_SxCR_CHSEL_0 ) | // Channel 0
(1 * DMA_SxCR_PL_0 ) | // Priority 1
@@ -194,42 +174,42 @@ static void StartAudioDMAAndRequestBuffers() {
DMA_SxCR_MINC | // Increase memory address
(1 * DMA_SxCR_DIR_0 ) | // Memory to peripheral
DMA_SxCR_TCIE; // Transfer complete interrupt
- DMA1_Stream7 ->NDTR = NextBufferLength;
+ DMA1_Stream7 ->NDTR = next_buffer_length;
DMA1_Stream7 ->PAR = (uint32_t) &SPI3 ->DR;
- DMA1_Stream7 ->M0AR = (uint32_t) NextBufferSamples;
+ DMA1_Stream7 ->M0AR = (uint32_t) next_buffer_samples;
DMA1_Stream7 ->FCR = DMA_SxFCR_DMDIS;
DMA1_Stream7 ->CR |= DMA_SxCR_EN;
// Update state.
- NextBufferSamples = NULL;
- BufferNumber ^= 1;
- DMARunning = true;
+ next_buffer_samples = NULL;
+ buffer_number ^= 1;
+ dma_running = true;
// Invoke callback if it exists to queue up another buffer.
- if (CallbackFunction)
- CallbackFunction(CallbackContext, BufferNumber);
+ if (callback_function)
+ callback_function(callback_context, buffer_number);
}
-static void StopAudioDMA() {
+static void audio_stop_dma() {
DMA1_Stream7 ->CR &= ~DMA_SxCR_EN; // Disable DMA stream.
while (DMA1_Stream7 ->CR & DMA_SxCR_EN )
; // Wait for DMA stream to stop.
- DMARunning = false;
+ dma_running = false;
}
void DMA1_Stream7_IRQHandler() {
DMA1 ->HIFCR |= DMA_HIFCR_CTCIF7; // Clear interrupt flag.
- if (NextBufferSamples) {
- StartAudioDMAAndRequestBuffers();
+ if (next_buffer_samples) {
+ audio_start_dma_and_request_buffers();
} else {
- DMARunning = false;
+ dma_running = false;
}
}
// Warning: don't i2c_write call from IRQ handler !
-static void WriteRegister(uint8_t address, uint8_t value)
+static void audio_write_register(uint8_t address, uint8_t value)
{
const uint8_t device = 0x4a;
const uint8_t data[2] = {address, value};
diff --git a/src/stm32f/src/Audio/cw.c b/src/stm32f/src/Audio/cw.c
new file mode 100644
index 0000000..028ae82
--- /dev/null
+++ b/src/stm32f/src/Audio/cw.c
@@ -0,0 +1,4 @@
+#include "../../../common/src/Audio/cw.c"
+
+void cw_message_sent(const char* str) {
+}
diff --git a/src/fsm/i2c.c b/src/stm32f/src/GPIO/i2c.c
index 6f7e193..750f5de 100644
--- a/src/fsm/i2c.c
+++ b/src/stm32f/src/GPIO/i2c.c
@@ -22,8 +22,9 @@
* SOFTWARE.
*/
-#include "i2c.h"
-#include "common.h"
+#include "GPIO/i2c.h"
+#include "Core/common.h"
+
#include "stm32f4xx_conf.h"
#include "stm32f4xx_i2c.h"
#include "stm32f4xx.h"
@@ -31,7 +32,7 @@
#include "FreeRTOSConfig.h"
#include "task.h"
#include "semphr.h"
-#include "usart.h"
+#include "GPIO/usart.h"
/* I2C 1 on PB9 and PB6
* See pio.txt for PIO allocation details */