diff options
-rw-r--r-- | apps/misc.c | 21 | ||||
-rw-r--r-- | firmware/pcm_record.c | 61 | ||||
-rw-r--r-- | firmware/powermgmt.c | 19 |
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) | |||
578 | if(!charger_inserted()) | 578 | if(!charger_inserted()) |
579 | #endif | 579 | #endif |
580 | { | 580 | { |
581 | bool batt_crit = battery_level_critical(); | ||
582 | int audio_stat = audio_status(); | ||
583 | |||
581 | FOR_NB_SCREENS(i) | 584 | FOR_NB_SCREENS(i) |
582 | screens[i].clear_display(); | 585 | screens[i].clear_display(); |
583 | #ifdef X5_BACKLIGHT_SHUTDOWN | 586 | #ifdef X5_BACKLIGHT_SHUTDOWN |
@@ -604,11 +607,23 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) | |||
604 | } | 607 | } |
605 | 608 | ||
606 | if (global_settings.fade_on_stop | 609 | if (global_settings.fade_on_stop |
607 | && (audio_status() & AUDIO_STATUS_PLAY)) | 610 | && (audio_stat & AUDIO_STATUS_PLAY)) |
608 | { | 611 | { |
609 | fade(0); | 612 | fade(0); |
610 | } | 613 | } |
611 | 614 | ||
615 | #if defined(HAVE_RECORDING) && CONFIG_CODEC == SWCODEC | ||
616 | if (!batt_crit && (audio_stat & AUDIO_STATUS_RECORD)) | ||
617 | { | ||
618 | audio_stop_recording(); | ||
619 | while(audio_status() & AUDIO_STATUS_RECORD) | ||
620 | sleep(1); | ||
621 | } | ||
622 | |||
623 | audio_close_recording(); | ||
624 | #endif | ||
625 | /* audio_stop_recording == audio_stop for HWCODEC */ | ||
626 | |||
612 | audio_stop(); | 627 | audio_stop(); |
613 | while (audio_status()) | 628 | while (audio_status()) |
614 | sleep(1); | 629 | sleep(1); |
@@ -616,7 +631,7 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter) | |||
616 | if (callback != NULL) | 631 | if (callback != NULL) |
617 | callback(parameter); | 632 | callback(parameter); |
618 | 633 | ||
619 | if (!battery_level_critical()) /* do not save on critical battery */ | 634 | if (!batt_crit) /* do not save on critical battery */ |
620 | system_flush(); | 635 | system_flush(); |
621 | #ifdef HAVE_EEPROM_SETTINGS | 636 | #ifdef HAVE_EEPROM_SETTINGS |
622 | if (firmware_settings.initialized) | 637 | 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) | |||
244 | return 0; | 244 | return 0; |
245 | } /* pcm_rec_have_more */ | 245 | } /* pcm_rec_have_more */ |
246 | 246 | ||
247 | static void reset_hardware(void) | ||
248 | { | ||
249 | /* reset pcm to defaults (playback only) */ | ||
250 | pcm_set_frequency(HW_SAMPR_DEFAULT); | ||
251 | audio_set_output_source(AUDIO_SRC_PLAYBACK); | ||
252 | pcm_apply_settings(true); | ||
253 | } | ||
254 | |||
247 | /** pcm_rec_* group **/ | 255 | /** pcm_rec_* group **/ |
248 | void pcm_rec_error_clear(void) | 256 | void pcm_rec_error_clear(void) |
249 | { | 257 | { |
@@ -328,10 +336,7 @@ void audio_close_recording(void) | |||
328 | { | 336 | { |
329 | pcm_thread_wait_for_stop(); | 337 | pcm_thread_wait_for_stop(); |
330 | pcm_thread_sync_post(PCMREC_CLOSE, NULL); | 338 | pcm_thread_sync_post(PCMREC_CLOSE, NULL); |
331 | /* reset pcm to defaults (playback only) */ | 339 | reset_hardware(); |
332 | pcm_set_frequency(HW_SAMPR_DEFAULT); | ||
333 | audio_set_output_source(AUDIO_SRC_PLAYBACK); | ||
334 | pcm_apply_settings(true); | ||
335 | audio_remove_encoder(); | 340 | audio_remove_encoder(); |
336 | } /* audio_close_recording */ | 341 | } /* audio_close_recording */ |
337 | 342 | ||
@@ -460,10 +465,6 @@ void audio_stop_recording(void) | |||
460 | logf("audio_stop_recording"); | 465 | logf("audio_stop_recording"); |
461 | 466 | ||
462 | pcm_thread_wait_for_stop(); | 467 | pcm_thread_wait_for_stop(); |
463 | |||
464 | if (is_recording) | ||
465 | dma_lock = true; /* fix DMA write ptr at current position */ | ||
466 | |||
467 | pcm_thread_sync_post(PCMREC_STOP, NULL); | 468 | pcm_thread_sync_post(PCMREC_STOP, NULL); |
468 | 469 | ||
469 | logf("audio_stop_recording done"); | 470 | logf("audio_stop_recording done"); |
@@ -474,11 +475,8 @@ void audio_pause_recording(void) | |||
474 | logf("audio_pause_recording"); | 475 | logf("audio_pause_recording"); |
475 | 476 | ||
476 | pcm_thread_wait_for_stop(); | 477 | pcm_thread_wait_for_stop(); |
477 | |||
478 | if (is_recording) | ||
479 | dma_lock = true; /* fix DMA write ptr at current position */ | ||
480 | |||
481 | pcm_thread_sync_post(PCMREC_PAUSE, NULL); | 478 | pcm_thread_sync_post(PCMREC_PAUSE, NULL); |
479 | |||
482 | logf("audio_pause_recording done"); | 480 | logf("audio_pause_recording done"); |
483 | } /* audio_pause_recording */ | 481 | } /* audio_pause_recording */ |
484 | 482 | ||
@@ -1006,6 +1004,8 @@ static void pcmrec_new_stream(const char *filename, /* next file name */ | |||
1006 | /* PCMREC_INIT */ | 1004 | /* PCMREC_INIT */ |
1007 | static void pcmrec_init(void) | 1005 | static void pcmrec_init(void) |
1008 | { | 1006 | { |
1007 | unsigned char *buffer; | ||
1008 | |||
1009 | rec_fdata.rec_file = -1; | 1009 | rec_fdata.rec_file = -1; |
1010 | 1010 | ||
1011 | /* pcm FIFO */ | 1011 | /* pcm FIFO */ |
@@ -1035,11 +1035,13 @@ static void pcmrec_init(void) | |||
1035 | is_stopping = false; | 1035 | is_stopping = false; |
1036 | is_error = false; | 1036 | is_error = false; |
1037 | 1037 | ||
1038 | pcm_buffer = audio_get_recording_buffer(&rec_buffer_size); | 1038 | buffer = audio_get_recording_buffer(&rec_buffer_size); |
1039 | /* Line align pcm_buffer 2^4=16 bytes */ | 1039 | /* Line align pcm_buffer 2^4=16 bytes */ |
1040 | pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned)pcm_buffer, 4); | 1040 | pcm_buffer = (unsigned char *)ALIGN_UP_P2((unsigned long)buffer, 4); |
1041 | enc_buffer = pcm_buffer + ALIGN_UP_P2(PCM_NUM_CHUNKS*PCM_CHUNK_SIZE + | 1041 | enc_buffer = pcm_buffer + ALIGN_UP_P2(PCM_NUM_CHUNKS*PCM_CHUNK_SIZE + |
1042 | PCM_MAX_FEED_SIZE, 2); | 1042 | PCM_MAX_FEED_SIZE, 2); |
1043 | /* Adjust available buffer for possible align advancement */ | ||
1044 | rec_buffer_size -= pcm_buffer - buffer; | ||
1043 | 1045 | ||
1044 | pcm_init_recording(); | 1046 | pcm_init_recording(); |
1045 | pcm_thread_signal_event(PCMREC_INIT); | 1047 | pcm_thread_signal_event(PCMREC_INIT); |
@@ -1132,8 +1134,8 @@ static void pcmrec_start(const char *filename) | |||
1132 | pcmrec_fnq_set_empty(); | 1134 | pcmrec_fnq_set_empty(); |
1133 | } | 1135 | } |
1134 | 1136 | ||
1135 | dma_lock = false; | 1137 | dma_lock = false; |
1136 | is_paused = false; | 1138 | is_paused = false; |
1137 | is_recording = true; | 1139 | is_recording = true; |
1138 | 1140 | ||
1139 | pcmrec_new_stream(filename, | 1141 | pcmrec_new_stream(filename, |
@@ -1187,11 +1189,8 @@ static void pcmrec_finish_stop(void) | |||
1187 | pcmrec_flush(-1); | 1189 | pcmrec_flush(-1); |
1188 | 1190 | ||
1189 | /* wait for encoder to finish remaining data */ | 1191 | /* wait for encoder to finish remaining data */ |
1190 | if (!is_error) | 1192 | while (!is_error && !wav_queue_empty) |
1191 | { | 1193 | yield(); |
1192 | while (!wav_queue_empty) | ||
1193 | yield(); | ||
1194 | } | ||
1195 | 1194 | ||
1196 | /* end stream at last data */ | 1195 | /* end stream at last data */ |
1197 | pcmrec_new_stream(NULL, CHUNKF_END_FILE, 0); | 1196 | pcmrec_new_stream(NULL, CHUNKF_END_FILE, 0); |
@@ -1307,7 +1306,7 @@ static void pcmrec_thread(void) | |||
1307 | 1306 | ||
1308 | while(1) | 1307 | while(1) |
1309 | { | 1308 | { |
1310 | if (is_recording) | 1309 | if (is_recording && !is_stopping) |
1311 | { | 1310 | { |
1312 | /* Poll periodically to flush data */ | 1311 | /* Poll periodically to flush data */ |
1313 | queue_wait_w_tmo(&pcmrec_queue, &ev, HZ/5); | 1312 | queue_wait_w_tmo(&pcmrec_queue, &ev, HZ/5); |
@@ -1363,12 +1362,12 @@ static void pcmrec_thread(void) | |||
1363 | break; | 1362 | break; |
1364 | 1363 | ||
1365 | case SYS_USB_CONNECTED: | 1364 | case SYS_USB_CONNECTED: |
1366 | if (!is_recording) | 1365 | if (is_recording) |
1367 | { | 1366 | break; |
1368 | pcmrec_close(); | 1367 | pcmrec_close(); |
1369 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 1368 | reset_hardware(); |
1370 | usb_wait_for_disconnect(&pcmrec_queue); | 1369 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
1371 | } | 1370 | usb_wait_for_disconnect(&pcmrec_queue); |
1372 | break; | 1371 | break; |
1373 | } /* end switch */ | 1372 | } /* end switch */ |
1374 | } /* end while */ | 1373 | } /* end while */ |
@@ -1554,7 +1553,8 @@ void enc_finish_chunk(void) | |||
1554 | int enc_pcm_buf_near_empty(void) | 1553 | int enc_pcm_buf_near_empty(void) |
1555 | { | 1554 | { |
1556 | /* less than 1sec raw data? => unboost encoder */ | 1555 | /* less than 1sec raw data? => unboost encoder */ |
1557 | size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK; | 1556 | int wp = dma_wr_pos; |
1557 | size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK; | ||
1558 | return avail < (sample_rate << 2) ? 1 : 0; | 1558 | return avail < (sample_rate << 2) ? 1 : 0; |
1559 | } /* enc_pcm_buf_near_empty */ | 1559 | } /* enc_pcm_buf_near_empty */ |
1560 | 1560 | ||
@@ -1562,7 +1562,8 @@ int enc_pcm_buf_near_empty(void) | |||
1562 | /* TODO: this really should give the actual size returned */ | 1562 | /* TODO: this really should give the actual size returned */ |
1563 | unsigned char * enc_get_pcm_data(size_t size) | 1563 | unsigned char * enc_get_pcm_data(size_t size) |
1564 | { | 1564 | { |
1565 | size_t avail = (dma_wr_pos - pcm_rd_pos) & PCM_CHUNK_MASK; | 1565 | int wp = dma_wr_pos; |
1566 | size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK; | ||
1566 | 1567 | ||
1567 | /* limit the requested pcm data size */ | 1568 | /* limit the requested pcm data size */ |
1568 | if (size > PCM_MAX_FEED_SIZE) | 1569 | 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) | |||
1266 | { | 1266 | { |
1267 | logf("sys_poweroff()"); | 1267 | logf("sys_poweroff()"); |
1268 | /* If the main thread fails to shut down the system, we will force a | 1268 | /* If the main thread fails to shut down the system, we will force a |
1269 | power off after an 20 second timeout */ | 1269 | power off after an 20 second timeout - 28 seconds if recording */ |
1270 | shutdown_timeout = HZ*20; | 1270 | #if defined(IAUDIO_X5) && !defined (SIMULATOR) |
1271 | #if defined(HAVE_RECORDING) | 1271 | if (shutdown_timeout == 0) |
1272 | int audio_stat = audio_status(); | 1272 | pcf50606_reset_timeout(); /* Reset timer on first attempt only */ |
1273 | if (audio_stat & AUDIO_STATUS_RECORD) { | ||
1274 | audio_stop_recording(); | ||
1275 | shutdown_timeout += 8*HZ; | ||
1276 | } | ||
1277 | #endif | 1273 | #endif |
1278 | 1274 | #ifdef HAVE_RECORDING | |
1275 | if (audio_status() & AUDIO_STATUS_RECORD) | ||
1276 | shutdown_timeout += HZ*8; | ||
1277 | #endif | ||
1278 | |||
1279 | shutdown_timeout = HZ*20; | ||
1279 | queue_post(&button_queue, SYS_POWEROFF, NULL); | 1280 | queue_post(&button_queue, SYS_POWEROFF, NULL); |
1280 | } | 1281 | } |
1281 | 1282 | ||