summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/misc.c21
-rw-r--r--firmware/pcm_record.c61
-rw-r--r--firmware/powermgmt.c19
3 files changed, 59 insertions, 42 deletions
diff --git a/apps/misc.c b/apps/misc.c
index 2f3251431b..4ea8568018 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -578,6 +578,9 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
if(!charger_inserted())
#endif
{
+ bool batt_crit = battery_level_critical();
+ int audio_stat = audio_status();
+
FOR_NB_SCREENS(i)
screens[i].clear_display();
#ifdef X5_BACKLIGHT_SHUTDOWN
@@ -604,11 +607,23 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
}
if (global_settings.fade_on_stop
- && (audio_status() & AUDIO_STATUS_PLAY))
+ && (audio_stat & AUDIO_STATUS_PLAY))
{
fade(0);
}
-
+
+#if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
+ if (!batt_crit && (audio_stat & AUDIO_STATUS_RECORD))
+ {
+ audio_stop_recording();
+ while(audio_status() & AUDIO_STATUS_RECORD)
+ sleep(1);
+ }
+
+ audio_close_recording();
+#endif
+ /* audio_stop_recording == audio_stop for HWCODEC */
+
audio_stop();
while (audio_status())
sleep(1);
@@ -616,7 +631,7 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
if (callback != NULL)
callback(parameter);
- if (!battery_level_critical()) /* do not save on critical battery */
+ if (!batt_crit) /* do not save on critical battery */
system_flush();
#ifdef HAVE_EEPROM_SETTINGS
if (firmware_settings.initialized)
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c
index a72641baa6..93a6e067b1 100644
--- a/firmware/pcm_record.c
+++ b/firmware/pcm_record.c
@@ -244,6 +244,14 @@ static int pcm_rec_have_more(int status)
return 0;
} /* pcm_rec_have_more */
+static void reset_hardware(void)
+{
+ /* reset pcm to defaults (playback only) */
+ pcm_set_frequency(HW_SAMPR_DEFAULT);
+ audio_set_output_source(AUDIO_SRC_PLAYBACK);
+ pcm_apply_settings(true);
+}
+
/** pcm_rec_* group **/
void pcm_rec_error_clear(void)
{
@@ -328,10 +336,7 @@ void audio_close_recording(void)
{
pcm_thread_wait_for_stop();
pcm_thread_sync_post(PCMREC_CLOSE, NULL);
- /* reset pcm to defaults (playback only) */
- pcm_set_frequency(HW_SAMPR_DEFAULT);
- audio_set_output_source(AUDIO_SRC_PLAYBACK);
- pcm_apply_settings(true);
+ reset_hardware();
audio_remove_encoder();
} /* audio_close_recording */
@@ -460,10 +465,6 @@ void audio_stop_recording(void)
logf("audio_stop_recording");
pcm_thread_wait_for_stop();
-
- if (is_recording)
- dma_lock = true; /* fix DMA write ptr at current position */
-
pcm_thread_sync_post(PCMREC_STOP, NULL);
logf("audio_stop_recording done");
@@ -474,11 +475,8 @@ void audio_pause_recording(void)
logf("audio_pause_recording");
pcm_thread_wait_for_stop();
-
- if (is_recording)
- dma_lock = true; /* fix DMA write ptr at current position */
-
pcm_thread_sync_post(PCMREC_PAUSE, NULL);
+
logf("audio_pause_recording done");
} /* audio_pause_recording */
@@ -1006,6 +1004,8 @@ static void pcmrec_new_stream(const char *filename, /* next file name */
/* PCMREC_INIT */
static void pcmrec_init(void)
{
+ unsigned char *buffer;
+
rec_fdata.rec_file = -1;
/* pcm FIFO */
@@ -1035,11 +1035,13 @@ static void pcmrec_init(void)
is_stopping = false;
is_error = false;
- pcm_buffer = audio_get_recording_buffer(&rec_buffer_size);
+ buffer = audio_get_recording_buffer(&rec_buffer_size);
/* Line align pcm_buffer 2^4=16 bytes */
- pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned)pcm_buffer, 4);
+ pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned long)buffer, 4);
enc_buffer = pcm_buffer + ALIGN_UP_P2(PCM_NUM_CHUNKS*PCM_CHUNK_SIZE +
PCM_MAX_FEED_SIZE, 2);
+ /* Adjust available buffer for possible align advancement */
+ rec_buffer_size -= pcm_buffer - buffer;
pcm_init_recording();
pcm_thread_signal_event(PCMREC_INIT);
@@ -1132,8 +1134,8 @@ static void pcmrec_start(const char *filename)
pcmrec_fnq_set_empty();
}
- dma_lock = false;
- is_paused = false;
+ dma_lock = false;
+ is_paused = false;
is_recording = true;
pcmrec_new_stream(filename,
@@ -1187,11 +1189,8 @@ static void pcmrec_finish_stop(void)
pcmrec_flush(-1);
/* wait for encoder to finish remaining data */
- if (!is_error)
- {
- while (!wav_queue_empty)
- yield();
- }
+ while (!is_error && !wav_queue_empty)
+ yield();
/* end stream at last data */
pcmrec_new_stream(NULL, CHUNKF_END_FILE, 0);
@@ -1307,7 +1306,7 @@ static void pcmrec_thread(void)
while(1)
{
- if (is_recording)
+ if (is_recording && !is_stopping)
{
/* Poll periodically to flush data */
queue_wait_w_tmo(&pcmrec_queue, &ev, HZ/5);
@@ -1363,12 +1362,12 @@ static void pcmrec_thread(void)
break;
case SYS_USB_CONNECTED:
- if (!is_recording)
- {
- pcmrec_close();
- usb_acknowledge(SYS_USB_CONNECTED_ACK);
- usb_wait_for_disconnect(&pcmrec_queue);
- }
+ if (is_recording)
+ break;
+ pcmrec_close();
+ reset_hardware();
+ usb_acknowledge(SYS_USB_CONNECTED_ACK);
+ usb_wait_for_disconnect(&pcmrec_queue);
break;
} /* end switch */
} /* end while */
@@ -1554,7 +1553,8 @@ void enc_finish_chunk(void)
int enc_pcm_buf_near_empty(void)
{
/* less than 1sec raw data? => unboost encoder */
- size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK;
+ int wp = dma_wr_pos;
+ size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK;
return avail < (sample_rate << 2) ? 1 : 0;
} /* enc_pcm_buf_near_empty */
@@ -1562,7 +1562,8 @@ int enc_pcm_buf_near_empty(void)
/* TODO: this really should give the actual size returned */
unsigned char * enc_get_pcm_data(size_t size)
{
- size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK;
+ int wp = dma_wr_pos;
+ size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK;
/* limit the requested pcm data size */
if (size > PCM_MAX_FEED_SIZE)
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index e59e2d50b9..458745f0d9 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -1266,16 +1266,17 @@ void sys_poweroff(void)
{
logf("sys_poweroff()");
/* If the main thread fails to shut down the system, we will force a
- power off after an 20 second timeout */
- shutdown_timeout = HZ*20;
-#if defined(HAVE_RECORDING)
- int audio_stat = audio_status();
- if (audio_stat & AUDIO_STATUS_RECORD) {
- audio_stop_recording();
- shutdown_timeout += 8*HZ;
- }
+ power off after an 20 second timeout - 28 seconds if recording */
+#if defined(IAUDIO_X5) && !defined (SIMULATOR)
+ if (shutdown_timeout == 0)
+ pcf50606_reset_timeout(); /* Reset timer on first attempt only */
#endif
-
+#ifdef HAVE_RECORDING
+ if (audio_status() & AUDIO_STATUS_RECORD)
+ shutdown_timeout += HZ*8;
+#endif
+
+ shutdown_timeout = HZ*20;
queue_post(&button_queue, SYS_POWEROFF, NULL);
}