The "GR-PEACH_Audio_Playback_7InchLCD_Sample" is a sample code that can provides high-resolution audio playback of FLAC format files. It also allows the user to audio-playback control functions such as play, pause, and stop by manipulating key switches.
Dependencies: GR-PEACH_video R_BSP TLV320_RBSP USBHost_custom
Fork of GR-PEACH_Audio_Playback_Sample by
system.cpp
00001 /******************************************************************************* 00002 * DISCLAIMER 00003 * This software is supplied by Renesas Electronics Corporation and is only 00004 * intended for use with Renesas products. No other uses are authorized. This 00005 * software is owned by Renesas Electronics Corporation and is protected under 00006 * all applicable laws, including copyright laws. 00007 * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING 00008 * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT 00009 * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 00010 * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. 00011 * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS 00012 * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE 00013 * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR 00014 * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE 00015 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 00016 * Renesas reserves the right, without notice, to make changes to this software 00017 * and to discontinue the availability of this software. By using this software, 00018 * you agree to the additional terms and conditions found by accessing the 00019 * following link: 00020 * http://www.renesas.com/disclaimer* 00021 * Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved. 00022 *******************************************************************************/ 00023 00024 #include "mbed.h" 00025 #include "rtos.h" 00026 #include "FATFileSystem.h" 00027 #include "USBHostMSD.h" 00028 00029 #include "system.h" 00030 #include "sys_scan_folder.h" 00031 #include "decode.h" 00032 #include "display.h" 00033 00034 #if defined(TARGET_RZ_A1H) 00035 #include "usb_host_setting.h" 00036 #else 00037 #define USB_HOST_CH (0) 00038 #endif 00039 00040 /*--- Macro definition of mbed-rtos mail ---*/ 00041 #define MAIL_QUEUE_SIZE (12) /* Queue size */ 00042 #define MAIL_PARAM_NUM (3) /* Elements number of mail parameter array */ 00043 00044 /* sys_mail_t */ 00045 #define MAIL_PARAM0 (0) /* Index number of mail parameter array */ 00046 #define MAIL_PARAM1 (1) /* Index number of mail parameter array */ 00047 #define MAIL_PARAM2 (2) /* Index number of mail parameter array */ 00048 00049 #define MAIL_PARAM_NON (0u) /* Value of unused element of mail parameter array */ 00050 00051 /* mail_id = SYS_MAILID_KEYCODE */ 00052 #define MAIL_KEYCODE_CODE (MAIL_PARAM0) /* Key code */ 00053 00054 /* mail_id = SYS_MAILID_PLAY_TIME */ 00055 #define MAIL_PLAYTIME_STAT (MAIL_PARAM0) /* Playback status */ 00056 #define MAIL_PLAYTIME_TIME (MAIL_PARAM1) /* Playback time */ 00057 #define MAIL_PLAYTIME_TOTAL (MAIL_PARAM2) /* Total playback time */ 00058 00059 /* mail_id = SYS_MAILID_DEC_OPEN_FIN */ 00060 #define MAIL_DECOPEN_RESULT (MAIL_PARAM0) /* Result of the process */ 00061 #define MAIL_DECOPEN_FREQ (MAIL_PARAM1) /* Sampling rate in Hz of FLAC file */ 00062 #define MAIL_DECOPEN_CH (MAIL_PARAM2) /* Number of channel */ 00063 00064 #define RECV_MAIL_TIMEOUT_MS (10) 00065 00066 #define USB1_WAIT_TIME_MS (5) 00067 #define TRACK_ID_MIN (0u) 00068 #define TRACK_ID_ERR (0xFFFFFFFFu) 00069 00070 #define PRINT_MSG_USB_CONNECT "USB connection was detected." 00071 #define PRINT_MSG_OPEN_ERR "Could not play this file." 00072 #define PRINT_MSG_DECODE_ERR "This file format is not supported." 00073 00074 /*--- User defined types of mbed-rtos mail ---*/ 00075 typedef enum { 00076 SYS_MAILID_DUMMY = 0, 00077 SYS_MAILID_KEYCODE, /* Notifies main thread of key code. */ 00078 SYS_MAILID_PLAY_TIME, /* Notifies main thread of playback time. */ 00079 SYS_MAILID_DEC_OPEN_FIN, /* Finished the opening process of Decode Thread. */ 00080 SYS_MAILID_DEC_CLOSE_FIN, /* Finished the closing process of Decode Thread. */ 00081 SYS_MAILID_NUM 00082 } SYS_MAIL_ID; 00083 00084 typedef struct { 00085 SYS_MAIL_ID mail_id; 00086 uint32_t param[MAIL_PARAM_NUM]; 00087 } sys_mail_t; 00088 00089 /*--- User defined types of main thread ---*/ 00090 /* Status of main thread */ 00091 typedef enum { 00092 SYS_ST_WAIT_USB_CONNECT = 0,/* Wait the USB connection */ 00093 SYS_ST_STOP, /* Stop the playback */ 00094 SYS_ST_PLAY_PREPARE, /* Preparation of the playback */ 00095 SYS_ST_PLAY_PREPARE_REQ, /* Holds the stop request until completion */ 00096 /* of the playback preparation */ 00097 SYS_ST_PLAY, /* Play */ 00098 SYS_ST_PAUSE, /* Pause */ 00099 SYS_ST_STOP_PREPARE, /* Preparation of the stop */ 00100 SYS_ST_STOP_PREPARE_REQ, /* Holds the playback request until completion */ 00101 /* of the stop preparation */ 00102 SYS_ST_NUM 00103 } SYS_STATE; 00104 00105 /* Event of the state transition */ 00106 typedef enum { 00107 SYS_EV_NON = 0, 00108 /* Notification of pushed key. */ 00109 SYS_EV_KEY_STOP, /* "STOP" key */ 00110 SYS_EV_KEY_PLAY_PAUSE, /* "PLAY/PAUSE" key */ 00111 SYS_EV_KEY_NEXT, /* "NEXT" key */ 00112 SYS_EV_KEY_PREV, /* "PREV" key */ 00113 SYS_EV_KEY_PLAYINFO, /* "PLAYINFO" key */ 00114 SYS_EV_KEY_REPEAT, /* "REPEAT" key */ 00115 SYS_EV_KEY_HELP, /* "HELP" key */ 00116 SYS_EV_KEY_MODE, /* "MODE" key */ 00117 /* Notification of decoder process */ 00118 SYS_EV_DEC_OPEN_COMP, /* Finished the opening process */ 00119 SYS_EV_DEC_OPEN_COMP_ERR, /* Finished the opening process (An error occured)*/ 00120 SYS_EV_DEC_CLOSE_COMP, /* Finished the closing process */ 00121 /* Notification of the playback status */ 00122 SYS_EV_STAT_STOP, /* Stop */ 00123 SYS_EV_STAT_PLAY, /* Play */ 00124 SYS_EV_STAT_PAUSE, /* Pause */ 00125 /* Notification of USB connection */ 00126 SYS_EV_USB_CONNECT, /* Connect */ 00127 SYS_EV_USB_DISCONNECT, /* Disconnect */ 00128 SYS_EV_NUM 00129 } SYS_EVENT; 00130 00131 /* Control data of USB memory */ 00132 typedef struct { 00133 bool usb_flag_detach;/* Detected the disconnection of USB memory */ 00134 } usb_ctrl_t; 00135 00136 /* The playback information of the playback file */ 00137 typedef struct { 00138 SYS_PlayStat play_stat; /* Playback status */ 00139 bool repeat_mode; /* Repeat mode */ 00140 uint32_t track_id; /* Number of the selected track */ 00141 uint32_t open_track_id; /* Number of the track during the open processing */ 00142 FILE *p_file_handle; /* Handle of the track */ 00143 uint32_t play_time; /* Playback start time */ 00144 uint32_t total_time; /* Total playback time */ 00145 uint32_t sample_rate; /* Sampling rate in Hz of FLAC file */ 00146 uint32_t channel_num; /* Number of channel */ 00147 uint32_t disp_mode; /* Display mode */ 00148 } play_info_t; 00149 00150 /* Control data of main thread */ 00151 typedef struct { 00152 usb_ctrl_t usb_ctrl; 00153 fid_scan_folder_t scan_data; 00154 play_info_t play_info; 00155 } sys_ctrl_t; 00156 00157 static Mail<sys_mail_t, MAIL_QUEUE_SIZE> mail_box; 00158 00159 static void open_callback(const bool result, const uint32_t sample_freq, 00160 const uint32_t channel_num); 00161 static void close_callback(void); 00162 static void init_ctrl_data(sys_ctrl_t * const p_ctrl); 00163 static SYS_EVENT decode_mail(play_info_t * const p_info, 00164 const fid_scan_folder_t * const p_data, const SYS_MAIL_ID mail_id, 00165 const uint32_t * const p_param); 00166 static SYS_EVENT check_usb_event(const SYS_STATE stat, 00167 const usb_ctrl_t * const p_ctrl, USBHostMSD * const p_msd, 00168 FATFileSystem * const p_fs); 00169 static SYS_STATE state_trans_proc(const SYS_STATE stat, 00170 const SYS_EVENT event, sys_ctrl_t * const p_ctrl); 00171 static SYS_STATE state_trans_proc(const SYS_STATE stat, 00172 const SYS_EVENT event, sys_ctrl_t * const p_ctrl); 00173 static SYS_STATE state_proc_wait_usb_connect(const SYS_STATE stat, 00174 const SYS_EVENT event, sys_ctrl_t * const p_ctrl); 00175 static SYS_STATE state_proc_stop(const SYS_STATE stat, 00176 const SYS_EVENT event, sys_ctrl_t * const p_ctrl); 00177 static SYS_STATE state_proc_play_prepare(const SYS_STATE stat, 00178 const SYS_EVENT event, sys_ctrl_t * const p_ctrl); 00179 static SYS_STATE state_proc_play_prepare_req(const SYS_STATE stat, 00180 const SYS_EVENT event, sys_ctrl_t * const p_ctrl); 00181 static SYS_STATE state_proc_play_pause(const SYS_STATE stat, 00182 const SYS_EVENT event, sys_ctrl_t * const p_ctrl); 00183 static SYS_STATE state_proc_stop_prepare(const SYS_STATE stat, 00184 const SYS_EVENT event, sys_ctrl_t * const p_ctrl); 00185 static SYS_STATE state_proc_stop_prepare_req(const SYS_STATE stat, 00186 const SYS_EVENT event, sys_ctrl_t * const p_ctrl); 00187 static bool exe_scan_folder_proc(play_info_t * const p_info, 00188 fid_scan_folder_t * const p_data); 00189 static bool exe_open_proc(play_info_t * const p_info, 00190 fid_scan_folder_t * const p_data); 00191 static bool exe_play_proc(play_info_t * const p_info, 00192 const fid_scan_folder_t * const p_data); 00193 static bool exe_pause_on_proc(void); 00194 static bool exe_pause_off_proc(void); 00195 static bool exe_stop_proc(void); 00196 static bool exe_close_proc(void); 00197 static void exe_end_proc(play_info_t * const p_info); 00198 static bool is_track_changed(const play_info_t * const p_info); 00199 static void change_repeat_mode(play_info_t * const p_info); 00200 static bool change_next_track(play_info_t * const p_info, 00201 const fid_scan_folder_t * const p_data); 00202 static bool change_prev_track(play_info_t * const p_info, 00203 const fid_scan_folder_t * const p_data); 00204 static void print_play_time(const play_info_t * const p_info); 00205 static void print_play_info(const play_info_t * const p_info); 00206 static void print_file_name(const play_info_t * const p_info, 00207 const fid_scan_folder_t * const p_data); 00208 static void print_help_info(void); 00209 static void print_play_status(const play_info_t * const p_info); 00210 static void change_display_mode(play_info_t * const p_info); 00211 static uint32_t convert_track_id(const uint32_t trk_id); 00212 static bool send_mail(const SYS_MAIL_ID mail_id, const uint32_t param0, 00213 const uint32_t param1, const uint32_t param2); 00214 static bool recv_mail(SYS_MAIL_ID * const p_mail_id, uint32_t * const p_param0, 00215 uint32_t * const p_param1, uint32_t * const p_param2); 00216 00217 void system_main(void) 00218 { 00219 SYS_STATE sys_stat; 00220 SYS_EVENT sys_ev; 00221 bool result; 00222 SYS_MAIL_ID mail_type; 00223 uint32_t mail_param[MAIL_PARAM_NUM]; 00224 static sys_ctrl_t sys_ctrl; 00225 static FATFileSystem fs(SYS_USB_MOUNT_NAME); 00226 static USBHostMSD msd; 00227 #if (USB_HOST_CH == 1) /* Audio Shield USB1 */ 00228 static DigitalOut usb1en(P3_8); 00229 00230 /* Audio Shield USB1 enable */ 00231 usb1en.write(1); /* Outputs high level */ 00232 Thread::wait(USB1_WAIT_TIME_MS); 00233 usb1en.write(0); /* Outputs low level */ 00234 #endif /* USB_HOST_CH */ 00235 00236 /* Initializes the control data of main thread. */ 00237 init_ctrl_data(&sys_ctrl); 00238 /* Notifies the default display mode. */ 00239 (void) dsp_notify_disp_mode(sys_ctrl.play_info.disp_mode); 00240 sys_stat = SYS_ST_WAIT_USB_CONNECT; 00241 while (1) { 00242 sys_ev = check_usb_event(sys_stat, &sys_ctrl.usb_ctrl, &msd, &fs); 00243 if (sys_ev == SYS_EV_NON) { 00244 result = recv_mail(&mail_type, &mail_param[MAIL_PARAM0], 00245 &mail_param[MAIL_PARAM1], &mail_param[MAIL_PARAM2]); 00246 if (result == true) { 00247 sys_ev = decode_mail(&sys_ctrl.play_info, 00248 &sys_ctrl.scan_data, mail_type, mail_param); 00249 } 00250 } 00251 if (sys_ev != SYS_EV_NON) { 00252 sys_stat = state_trans_proc(sys_stat, sys_ev, &sys_ctrl); 00253 } 00254 } 00255 } 00256 00257 bool sys_notify_key_input(const SYS_KeyCode key_code) 00258 { 00259 bool ret = false; 00260 00261 ret = send_mail(SYS_MAILID_KEYCODE, (uint32_t)key_code, MAIL_PARAM_NON, MAIL_PARAM_NON); 00262 00263 return ret; 00264 } 00265 00266 bool sys_notify_play_time(const SYS_PlayStat play_stat, 00267 const uint32_t play_time, const uint32_t total_time) 00268 { 00269 bool ret = false; 00270 00271 ret = send_mail(SYS_MAILID_PLAY_TIME, (uint32_t)play_stat, play_time, total_time); 00272 00273 return ret; 00274 } 00275 00276 /** Callback function of Decode Thread 00277 * 00278 * @param result Result of the process. 00279 * @param sample_freq Sampling rate in Hz of FLAC file. 00280 * @param channel_num Number of channel. 00281 */ 00282 static void open_callback(const bool result, const uint32_t sample_freq, 00283 const uint32_t channel_num) 00284 { 00285 (void) send_mail(SYS_MAILID_DEC_OPEN_FIN, (uint32_t)result, sample_freq, channel_num); 00286 } 00287 00288 /** Callback function of Decode Thread 00289 * 00290 */ 00291 static void close_callback(void) 00292 { 00293 (void) send_mail(SYS_MAILID_DEC_CLOSE_FIN, MAIL_PARAM_NON, MAIL_PARAM_NON, MAIL_PARAM_NON); 00294 } 00295 00296 /** Initialises the control data of main thread 00297 * 00298 * @param p_ctrl Pointer to the control data of main thread 00299 */ 00300 static void init_ctrl_data(sys_ctrl_t * const p_ctrl) 00301 { 00302 if (p_ctrl != NULL) { 00303 /* Initialises the control data of USB memory. */ 00304 p_ctrl->usb_ctrl.usb_flag_detach = false; 00305 /* Initialises the information of folder scan. */ 00306 fid_init(&p_ctrl->scan_data); 00307 /* Initialises the playback information of the playback file */ 00308 p_ctrl->play_info.play_stat = SYS_PLAYSTAT_STOP; 00309 p_ctrl->play_info.repeat_mode = true; 00310 p_ctrl->play_info.track_id = TRACK_ID_MIN; 00311 p_ctrl->play_info.open_track_id = TRACK_ID_ERR; 00312 p_ctrl->play_info.p_file_handle = NULL; 00313 p_ctrl->play_info.play_time = 0u; 00314 p_ctrl->play_info.total_time = 0u; 00315 p_ctrl->play_info.sample_rate = 0u; 00316 p_ctrl->play_info.channel_num = 0u; 00317 p_ctrl->play_info.disp_mode = DSP_DISPMODE_1; 00318 } 00319 } 00320 00321 /** Converts the code of SYS_MAIL_ID into the code of SYS_EVENT 00322 * 00323 * @param p_info Pointer to the playback information of the playback file 00324 * @param p_data Pointer to the control data of folder scan 00325 * @param mail_id The event code of SYS_MAIL_ID 00326 * @param p_param Pointer to the parameter of the mail 00327 * 00328 * @returns 00329 * The event code of SYS_EVENT 00330 */ 00331 static SYS_EVENT decode_mail(play_info_t * const p_info, 00332 const fid_scan_folder_t * const p_data, const SYS_MAIL_ID mail_id, 00333 const uint32_t * const p_param) 00334 { 00335 SYS_EVENT ret = SYS_EV_NON; 00336 00337 if ((p_info != NULL) && (p_data != NULL) && (p_param != NULL)) { 00338 switch (mail_id) { 00339 case SYS_MAILID_KEYCODE: 00340 switch (p_param[MAIL_KEYCODE_CODE]) { 00341 case SYS_KEYCODE_STOP: 00342 ret = SYS_EV_KEY_STOP; 00343 break; 00344 case SYS_KEYCODE_PLAYPAUSE: 00345 ret = SYS_EV_KEY_PLAY_PAUSE; 00346 break; 00347 case SYS_KEYCODE_NEXT: 00348 ret = SYS_EV_KEY_NEXT; 00349 break; 00350 case SYS_KEYCODE_PREV: 00351 ret = SYS_EV_KEY_PREV; 00352 break; 00353 case SYS_KEYCODE_PLAYINFO: 00354 ret = SYS_EV_KEY_PLAYINFO; 00355 break; 00356 case SYS_KEYCODE_REPEAT: 00357 ret = SYS_EV_KEY_REPEAT; 00358 break; 00359 case SYS_KEYCODE_HELP: 00360 ret = SYS_EV_KEY_HELP; 00361 break; 00362 case SYS_KEYCODE_MODE: 00363 ret = SYS_EV_KEY_MODE; 00364 break; 00365 default: 00366 /* Unexpected cases : This is fail-safe processing. */ 00367 ret = SYS_EV_NON; 00368 break; 00369 } 00370 break; 00371 case SYS_MAILID_PLAY_TIME: 00372 switch (p_param[MAIL_PLAYTIME_STAT]) { 00373 case SYS_PLAYSTAT_STOP: 00374 ret = SYS_EV_STAT_STOP; 00375 break; 00376 case SYS_PLAYSTAT_PLAY: 00377 ret = SYS_EV_STAT_PLAY; 00378 break; 00379 case SYS_PLAYSTAT_PAUSE: 00380 ret = SYS_EV_STAT_PAUSE; 00381 break; 00382 default: 00383 ret = SYS_EV_NON; 00384 break; 00385 } 00386 /* Is the playback status correct? */ 00387 if (ret != SYS_EV_NON) { 00388 p_info->play_stat = (SYS_PlayStat)p_param[MAIL_PLAYTIME_STAT]; 00389 p_info->play_time = p_param[MAIL_PLAYTIME_TIME]; 00390 p_info->total_time = p_param[MAIL_PLAYTIME_TOTAL]; 00391 } else { 00392 /* Unexpected cases : This is fail-safe processing. */ 00393 p_info->play_stat = SYS_PLAYSTAT_STOP; 00394 p_info->play_time = 0u; 00395 p_info->total_time = 0u; 00396 } 00397 break; 00398 case SYS_MAILID_DEC_OPEN_FIN: 00399 if ((int32_t)p_param[MAIL_DECOPEN_RESULT] == true) { 00400 ret = SYS_EV_DEC_OPEN_COMP; 00401 p_info->sample_rate = p_param[MAIL_DECOPEN_FREQ]; 00402 p_info->channel_num = p_param[MAIL_DECOPEN_CH]; 00403 } else { 00404 /* The opening of the decoder was failure. */ 00405 ret = SYS_EV_DEC_OPEN_COMP_ERR; 00406 p_info->sample_rate = 0u; 00407 p_info->channel_num = 0u; 00408 /* Tries to open the next file. */ 00409 print_play_time(p_info); 00410 p_info->open_track_id = TRACK_ID_ERR; 00411 (void) change_next_track(p_info, p_data); 00412 } 00413 break; 00414 case SYS_MAILID_DEC_CLOSE_FIN: 00415 ret = SYS_EV_DEC_CLOSE_COMP; 00416 p_info->play_time = 0u; 00417 p_info->total_time = 0u; 00418 break; 00419 default: 00420 /* Unexpected cases : This is fail-safe processing. */ 00421 ret = SYS_EV_NON; 00422 break; 00423 } 00424 } 00425 return ret; 00426 } 00427 00428 /** Checks the event of USB connection 00429 * 00430 * @param stat Status of main thread 00431 * @param p_ctrl Pointer to the control data of USB memory 00432 * @param p_msd Pointer to the class object of USBHostMSD 00433 * @param P_fs Pointer to the class oblect of FATFileSystem 00434 * 00435 * @returns 00436 * The event code of SYS_EVENT 00437 */ 00438 static SYS_EVENT check_usb_event(const SYS_STATE stat, 00439 const usb_ctrl_t * const p_ctrl, 00440 USBHostMSD * const p_msd, FATFileSystem * const p_fs) 00441 { 00442 SYS_EVENT ret = SYS_EV_NON; 00443 int iRet; 00444 bool result; 00445 00446 if ((p_ctrl != NULL) && (p_msd != NULL)) { 00447 if (stat == SYS_ST_WAIT_USB_CONNECT) { 00448 /* Mounts the FAT filesystem again. */ 00449 /* Because the connecting USB memory is changed. */ 00450 result = p_msd->connect(); 00451 if (result == true) { 00452 iRet = p_fs->unmount(); 00453 iRet = p_fs->mount(p_msd); 00454 ret = SYS_EV_USB_CONNECT; 00455 } 00456 } else if (p_ctrl->usb_flag_detach != true) { 00457 result = p_msd->connected(); 00458 if (result != true) { 00459 ret = SYS_EV_USB_DISCONNECT; 00460 } 00461 } else { 00462 /* DO NOTHING */ 00463 } 00464 } 00465 return ret; 00466 } 00467 00468 /** Executes the state transition processing 00469 * 00470 * @param stat Status of main thread 00471 * @param event Event code of main thread 00472 * @param p_ctrl Pointer to the control data of main thread 00473 * 00474 * @returns 00475 * Next status of main thread 00476 */ 00477 static SYS_STATE state_trans_proc(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl) 00478 { 00479 SYS_STATE next_stat = stat; 00480 00481 if (p_ctrl != NULL) { 00482 /* State transition processing */ 00483 switch (stat) { 00484 case SYS_ST_WAIT_USB_CONNECT: /* Wait the USB connection */ 00485 next_stat = state_proc_wait_usb_connect(stat, event, p_ctrl); 00486 break; 00487 case SYS_ST_STOP: /* Stop the playback */ 00488 next_stat = state_proc_stop(stat, event, p_ctrl); 00489 break; 00490 case SYS_ST_PLAY_PREPARE: /* Preparation of the playback */ 00491 next_stat = state_proc_play_prepare(stat, event, p_ctrl); 00492 break; 00493 case SYS_ST_PLAY_PREPARE_REQ: /* Holds the stop request until completion */ 00494 /* of the playback preparation */ 00495 next_stat = state_proc_play_prepare_req(stat, event, p_ctrl); 00496 break; 00497 case SYS_ST_PLAY: /* Play */ 00498 case SYS_ST_PAUSE: /* Pause */ 00499 next_stat = state_proc_play_pause(stat, event, p_ctrl); 00500 break; 00501 case SYS_ST_STOP_PREPARE: /* Preparation of the stop */ 00502 next_stat = state_proc_stop_prepare(stat, event, p_ctrl); 00503 break; 00504 case SYS_ST_STOP_PREPARE_REQ: /* Holds the playback request until completion */ 00505 /* of the stop preparation */ 00506 next_stat = state_proc_stop_prepare_req(stat, event, p_ctrl); 00507 break; 00508 default: 00509 /* Unexpected cases : This is fail-safe processing. */ 00510 next_stat = SYS_ST_WAIT_USB_CONNECT; 00511 break; 00512 } 00513 } 00514 return next_stat; 00515 } 00516 00517 /** Executes the state transition processing in the state of SYS_ST_WAIT_USB_CONNECT. 00518 * 00519 * @param stat Status of main thread 00520 * @param event Event code of main thread 00521 * @param p_ctrl Pointer to the control data of main thread 00522 * 00523 * @returns 00524 * Next status of main thread 00525 */ 00526 static SYS_STATE state_proc_wait_usb_connect(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl) 00527 { 00528 SYS_STATE next_stat = stat; 00529 00530 if (p_ctrl != NULL) { 00531 if (event == SYS_EV_USB_CONNECT) { 00532 p_ctrl->usb_ctrl.usb_flag_detach = false; 00533 (void) exe_scan_folder_proc(&p_ctrl->play_info, &p_ctrl->scan_data); 00534 (void) dsp_notify_print_string(PRINT_MSG_USB_CONNECT); 00535 next_stat = SYS_ST_STOP; 00536 } else if (event == SYS_EV_KEY_HELP) { 00537 print_help_info(); 00538 } else if (event == SYS_EV_KEY_MODE) { 00539 change_display_mode(&p_ctrl->play_info); 00540 } else { 00541 /* DO NOTHING */ 00542 } 00543 } 00544 return next_stat; 00545 } 00546 00547 /** Executes the state transition processing in the state of SYS_ST_STOP. 00548 * 00549 * @param stat Status of main thread 00550 * @param event Event code of main thread 00551 * @param p_ctrl Pointer to the control data of main thread 00552 * 00553 * @returns 00554 * Next status of main thread 00555 */ 00556 static SYS_STATE state_proc_stop(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl) 00557 { 00558 SYS_STATE next_stat = stat; 00559 bool result; 00560 00561 if (p_ctrl != NULL) { 00562 switch (event) { 00563 case SYS_EV_KEY_PLAY_PAUSE: 00564 print_file_name(&p_ctrl->play_info, &p_ctrl->scan_data); 00565 result = exe_open_proc(&p_ctrl->play_info, &p_ctrl->scan_data); 00566 if (result == true) { 00567 next_stat = SYS_ST_PLAY_PREPARE; 00568 } 00569 break; 00570 case SYS_EV_KEY_REPEAT: 00571 change_repeat_mode(&p_ctrl->play_info); 00572 break; 00573 case SYS_EV_KEY_HELP: 00574 print_help_info(); 00575 break; 00576 case SYS_EV_KEY_MODE: 00577 change_display_mode(&p_ctrl->play_info); 00578 break; 00579 case SYS_EV_USB_DISCONNECT: 00580 p_ctrl->usb_ctrl.usb_flag_detach = true; 00581 next_stat = SYS_ST_WAIT_USB_CONNECT; 00582 break; 00583 default: 00584 /* Does not change the state. There is not the action. */ 00585 next_stat = stat; 00586 break; 00587 } 00588 } 00589 return next_stat; 00590 } 00591 00592 /** Executes the state transition processing in the state of SYS_ST_PLAY_PREPARE. 00593 * 00594 * @param stat Status of main thread 00595 * @param event Event code of main thread 00596 * @param p_ctrl Pointer to the control data of main thread 00597 * 00598 * @returns 00599 * Next status of main thread 00600 */ 00601 static SYS_STATE state_proc_play_prepare(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl) 00602 { 00603 SYS_STATE next_stat = stat; 00604 bool result; 00605 00606 if (p_ctrl != NULL) { 00607 switch (event) { 00608 case SYS_EV_KEY_STOP: 00609 next_stat = SYS_ST_PLAY_PREPARE_REQ; 00610 break; 00611 case SYS_EV_KEY_NEXT: 00612 result = change_next_track(&p_ctrl->play_info, &p_ctrl->scan_data); 00613 if (result != true) { 00614 /* Selected track was out of the playback range. */ 00615 next_stat = SYS_ST_PLAY_PREPARE_REQ; 00616 } 00617 break; 00618 case SYS_EV_KEY_PREV: 00619 result = change_prev_track(&p_ctrl->play_info, &p_ctrl->scan_data); 00620 if (result != true) { 00621 next_stat = SYS_ST_PLAY_PREPARE_REQ; 00622 } 00623 break; 00624 case SYS_EV_KEY_REPEAT: 00625 change_repeat_mode(&p_ctrl->play_info); 00626 break; 00627 case SYS_EV_KEY_HELP: 00628 print_help_info(); 00629 break; 00630 case SYS_EV_KEY_MODE: 00631 change_display_mode(&p_ctrl->play_info); 00632 break; 00633 case SYS_EV_DEC_OPEN_COMP: 00634 result = is_track_changed(&p_ctrl->play_info); 00635 if (result == true) { 00636 /* Track was changed during the waiting of callback. */ 00637 print_play_time(&p_ctrl->play_info); 00638 result = exe_close_proc(); 00639 if (result == true) { 00640 next_stat = SYS_ST_STOP_PREPARE_REQ; 00641 } else { 00642 /* Unexpected cases : This is fail-safe processing. */ 00643 print_play_status(&p_ctrl->play_info); 00644 exe_end_proc(&p_ctrl->play_info); 00645 next_stat = SYS_ST_STOP; 00646 } 00647 } else { 00648 print_play_info(&p_ctrl->play_info); 00649 result = exe_play_proc(&p_ctrl->play_info, &p_ctrl->scan_data); 00650 if (result == true) { 00651 next_stat = SYS_ST_PLAY; 00652 } else { 00653 result = exe_close_proc(); 00654 if (result == true) { 00655 next_stat = SYS_ST_STOP_PREPARE; 00656 } else { 00657 /* Unexpected cases : This is fail-safe processing. */ 00658 print_play_status(&p_ctrl->play_info); 00659 exe_end_proc(&p_ctrl->play_info); 00660 next_stat = SYS_ST_STOP; 00661 } 00662 } 00663 } 00664 break; 00665 case SYS_EV_DEC_OPEN_COMP_ERR: 00666 /* Output error message to PC */ 00667 print_play_status(&p_ctrl->play_info); 00668 (void) dsp_notify_print_string(PRINT_MSG_DECODE_ERR); 00669 exe_end_proc(&p_ctrl->play_info); 00670 next_stat = SYS_ST_STOP; 00671 break; 00672 case SYS_EV_USB_DISCONNECT: 00673 p_ctrl->usb_ctrl.usb_flag_detach = true; 00674 next_stat = SYS_ST_PLAY_PREPARE_REQ; 00675 break; 00676 default: 00677 /* Does not change the state. There is not the action. */ 00678 next_stat = stat; 00679 break; 00680 } 00681 } 00682 return next_stat; 00683 } 00684 00685 /** Executes the state transition processing in the state of SYS_ST_PLAY_PREPARE_REQ. 00686 * 00687 * @param stat Status of main thread 00688 * @param event Event code of main thread 00689 * @param p_ctrl Pointer to the control data of main thread 00690 * 00691 * @returns 00692 * Next status of main thread 00693 */ 00694 static SYS_STATE state_proc_play_prepare_req(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl) 00695 { 00696 SYS_STATE next_stat = stat; 00697 bool result; 00698 00699 if (p_ctrl != NULL) { 00700 switch (event) { 00701 case SYS_EV_KEY_REPEAT: 00702 change_repeat_mode(&p_ctrl->play_info); 00703 break; 00704 case SYS_EV_KEY_HELP: 00705 print_help_info(); 00706 break; 00707 case SYS_EV_KEY_MODE: 00708 change_display_mode(&p_ctrl->play_info); 00709 break; 00710 case SYS_EV_DEC_OPEN_COMP: 00711 print_play_time(&p_ctrl->play_info); 00712 result = exe_close_proc(); 00713 if (result == true) { 00714 next_stat = SYS_ST_STOP_PREPARE; 00715 } else { 00716 /* Unexpected cases : This is fail-safe processing. */ 00717 print_play_status(&p_ctrl->play_info); 00718 exe_end_proc(&p_ctrl->play_info); 00719 if (p_ctrl->usb_ctrl.usb_flag_detach == true) { 00720 next_stat = SYS_ST_WAIT_USB_CONNECT; 00721 } else { 00722 next_stat = SYS_ST_STOP; 00723 } 00724 } 00725 break; 00726 case SYS_EV_DEC_OPEN_COMP_ERR: 00727 /* Output error message to PC */ 00728 print_play_status(&p_ctrl->play_info); 00729 (void) dsp_notify_print_string(PRINT_MSG_DECODE_ERR); 00730 exe_end_proc(&p_ctrl->play_info); 00731 if (p_ctrl->usb_ctrl.usb_flag_detach == true) { 00732 next_stat = SYS_ST_WAIT_USB_CONNECT; 00733 } else { 00734 next_stat = SYS_ST_STOP; 00735 } 00736 break; 00737 case SYS_EV_USB_DISCONNECT: 00738 p_ctrl->usb_ctrl.usb_flag_detach = true; 00739 break; 00740 default: 00741 /* Does not change the state. There is not the action. */ 00742 next_stat = stat; 00743 break; 00744 } 00745 } 00746 return next_stat; 00747 } 00748 00749 /** Executes the state transition processing in the state of SYS_ST_PLAY / SYS_ST_PAUSE. 00750 * 00751 * @param stat Status of main thread 00752 * @param event Event code of main thread 00753 * @param p_ctrl Pointer to the control data of main thread 00754 * 00755 * @returns 00756 * Next status of main thread 00757 */ 00758 static SYS_STATE state_proc_play_pause(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl) 00759 { 00760 SYS_STATE next_stat = stat; 00761 bool result; 00762 00763 if (p_ctrl != NULL) { 00764 switch (event) { 00765 case SYS_EV_KEY_STOP: 00766 result = exe_stop_proc(); 00767 if (result == true) { 00768 next_stat = SYS_ST_STOP_PREPARE; 00769 } 00770 break; 00771 case SYS_EV_KEY_PLAY_PAUSE: 00772 if (stat == SYS_ST_PLAY) { 00773 (void) exe_pause_on_proc(); 00774 } else { 00775 (void) exe_pause_off_proc(); 00776 } 00777 break; 00778 case SYS_EV_KEY_NEXT: 00779 case SYS_EV_KEY_PREV: 00780 result = exe_stop_proc(); 00781 if (result == true) { 00782 if (event == SYS_EV_KEY_PREV) { 00783 result = change_prev_track(&p_ctrl->play_info, &p_ctrl->scan_data); 00784 } else { 00785 result = change_next_track(&p_ctrl->play_info, &p_ctrl->scan_data); 00786 } 00787 if (result == true) { 00788 next_stat = SYS_ST_STOP_PREPARE_REQ; 00789 } else { 00790 next_stat = SYS_ST_STOP_PREPARE; 00791 } 00792 } 00793 break; 00794 case SYS_EV_KEY_PLAYINFO: 00795 print_play_info(&p_ctrl->play_info); 00796 break; 00797 case SYS_EV_KEY_REPEAT: 00798 change_repeat_mode(&p_ctrl->play_info); 00799 break; 00800 case SYS_EV_KEY_HELP: 00801 print_help_info(); 00802 break; 00803 case SYS_EV_KEY_MODE: 00804 change_display_mode(&p_ctrl->play_info); 00805 break; 00806 case SYS_EV_STAT_STOP: 00807 print_play_time(&p_ctrl->play_info); 00808 result = exe_close_proc(); 00809 if (result == true) { 00810 result = change_next_track(&p_ctrl->play_info, &p_ctrl->scan_data); 00811 if (result == true) { 00812 next_stat = SYS_ST_STOP_PREPARE_REQ; 00813 } else { 00814 next_stat = SYS_ST_STOP_PREPARE; 00815 } 00816 } else { 00817 /* Unexpected cases : This is fail-safe processing. */ 00818 exe_end_proc(&p_ctrl->play_info); 00819 if (p_ctrl->usb_ctrl.usb_flag_detach == true) { 00820 next_stat = SYS_ST_WAIT_USB_CONNECT; 00821 } else { 00822 next_stat = SYS_ST_STOP; 00823 } 00824 } 00825 break; 00826 case SYS_EV_STAT_PLAY: 00827 print_play_time(&p_ctrl->play_info); 00828 next_stat = SYS_ST_PLAY; 00829 break; 00830 case SYS_EV_STAT_PAUSE: 00831 print_play_time(&p_ctrl->play_info); 00832 next_stat = SYS_ST_PAUSE; 00833 break; 00834 case SYS_EV_USB_DISCONNECT: 00835 p_ctrl->usb_ctrl.usb_flag_detach = true; 00836 result = exe_stop_proc(); 00837 if (result == true) { 00838 next_stat = SYS_ST_STOP_PREPARE; 00839 } else { 00840 /* Unexpected cases : This is fail-safe processing. */ 00841 /* In this case, main thread wait the notification of the stop status. */ 00842 /* An error will occur by the disconnection of USB memory. */ 00843 } 00844 break; 00845 default: 00846 /* Does not change the state. There is not the action. */ 00847 next_stat = stat; 00848 break; 00849 } 00850 } 00851 return next_stat; 00852 } 00853 00854 /** Executes the state transition processing in the state of SYS_ST_STOP_PREPARE. 00855 * 00856 * @param stat Status of main thread 00857 * @param event Event code of main thread 00858 * @param p_ctrl Pointer to the control data of main thread 00859 * 00860 * @returns 00861 * Next status of main thread 00862 */ 00863 static SYS_STATE state_proc_stop_prepare(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl) 00864 { 00865 SYS_STATE next_stat = stat; 00866 bool result; 00867 00868 if (p_ctrl != NULL) { 00869 switch (event) { 00870 case SYS_EV_KEY_REPEAT: 00871 change_repeat_mode(&p_ctrl->play_info); 00872 break; 00873 case SYS_EV_KEY_HELP: 00874 print_help_info(); 00875 break; 00876 case SYS_EV_KEY_MODE: 00877 change_display_mode(&p_ctrl->play_info); 00878 break; 00879 case SYS_EV_DEC_CLOSE_COMP: 00880 print_play_status(&p_ctrl->play_info); 00881 exe_end_proc(&p_ctrl->play_info); 00882 if (p_ctrl->usb_ctrl.usb_flag_detach == true) { 00883 next_stat = SYS_ST_WAIT_USB_CONNECT; 00884 } else { 00885 next_stat = SYS_ST_STOP; 00886 } 00887 break; 00888 case SYS_EV_STAT_STOP: 00889 result = exe_close_proc(); 00890 if (result != true) { 00891 /* Unexpected cases : This is fail-safe processing. */ 00892 print_play_status(&p_ctrl->play_info); 00893 exe_end_proc(&p_ctrl->play_info); 00894 if (p_ctrl->usb_ctrl.usb_flag_detach == true) { 00895 next_stat = SYS_ST_WAIT_USB_CONNECT; 00896 } else { 00897 next_stat = SYS_ST_STOP; 00898 } 00899 } 00900 break; 00901 case SYS_EV_STAT_PLAY: 00902 case SYS_EV_STAT_PAUSE: 00903 break; 00904 case SYS_EV_USB_DISCONNECT: 00905 p_ctrl->usb_ctrl.usb_flag_detach = true; 00906 break; 00907 default: 00908 /* Does not change the state. There is not the action. */ 00909 next_stat = stat; 00910 break; 00911 } 00912 } 00913 return next_stat; 00914 } 00915 00916 /** Executes the state transition processing in the state of SYS_ST_STOP_PREPARE_REQ. 00917 * 00918 * @param stat Status of main thread 00919 * @param event Event code of main thread 00920 * @param p_ctrl Pointer to the control data of main thread 00921 * 00922 * @returns 00923 * Next status of main thread 00924 */ 00925 static SYS_STATE state_proc_stop_prepare_req(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl) 00926 { 00927 SYS_STATE next_stat = stat; 00928 bool result; 00929 00930 if (p_ctrl != NULL) { 00931 switch (event) { 00932 case SYS_EV_KEY_STOP: 00933 next_stat = SYS_ST_STOP_PREPARE; 00934 break; 00935 case SYS_EV_KEY_NEXT: 00936 result = change_next_track(&p_ctrl->play_info, &p_ctrl->scan_data); 00937 if (result != true) { 00938 /* Selected track was out of the playback range. */ 00939 next_stat = SYS_ST_STOP_PREPARE; 00940 } 00941 break; 00942 case SYS_EV_KEY_PREV: 00943 result = change_prev_track(&p_ctrl->play_info, &p_ctrl->scan_data); 00944 if (result != true) { 00945 next_stat = SYS_ST_STOP_PREPARE; 00946 } 00947 break; 00948 case SYS_EV_KEY_REPEAT: 00949 change_repeat_mode(&p_ctrl->play_info); 00950 break; 00951 case SYS_EV_KEY_HELP: 00952 print_help_info(); 00953 break; 00954 case SYS_EV_KEY_MODE: 00955 change_display_mode(&p_ctrl->play_info); 00956 break; 00957 case SYS_EV_DEC_CLOSE_COMP: 00958 exe_end_proc(&p_ctrl->play_info); 00959 print_file_name(&p_ctrl->play_info, &p_ctrl->scan_data); 00960 result = exe_open_proc(&p_ctrl->play_info, &p_ctrl->scan_data); 00961 if (result == true) { 00962 next_stat = SYS_ST_PLAY_PREPARE; 00963 } else { 00964 print_play_status(&p_ctrl->play_info); 00965 next_stat = SYS_ST_STOP; 00966 } 00967 break; 00968 case SYS_EV_STAT_STOP: 00969 result = exe_close_proc(); 00970 if (result != true) { 00971 /* Unexpected cases : This is fail-safe processing. */ 00972 print_play_status(&p_ctrl->play_info); 00973 exe_end_proc(&p_ctrl->play_info); 00974 next_stat = SYS_ST_STOP; 00975 } 00976 break; 00977 case SYS_EV_STAT_PLAY: 00978 case SYS_EV_STAT_PAUSE: 00979 break; 00980 case SYS_EV_USB_DISCONNECT: 00981 p_ctrl->usb_ctrl.usb_flag_detach = true; 00982 next_stat = SYS_ST_STOP_PREPARE; 00983 break; 00984 default: 00985 /* Does not change the state. There is not the action. */ 00986 next_stat = stat; 00987 break; 00988 } 00989 } 00990 return next_stat; 00991 } 00992 00993 /** Executes the scan of the folder structure 00994 * 00995 * @param p_info Pointer to the playback information of the playback file 00996 * @param p_data Pointer to the control data of folder scan 00997 * 00998 * @returns 00999 * Results of process. true is success. false is failure. 01000 */ 01001 static bool exe_scan_folder_proc(play_info_t * const p_info, fid_scan_folder_t * const p_data) 01002 { 01003 bool ret = false; 01004 01005 if ((p_info != NULL) && (p_data != NULL)) { 01006 (void) fid_scan_folder_struct(p_data); 01007 p_info->track_id = TRACK_ID_MIN; 01008 ret = true; 01009 } 01010 return ret; 01011 } 01012 01013 /** Executes the opening process 01014 * 01015 * @param p_info Pointer to the playback information of the playback file 01016 * @param p_data Pointer to the control data of folder scan 01017 * 01018 * @returns 01019 * Results of process. true is success. false is failure. 01020 */ 01021 static bool exe_open_proc(play_info_t * const p_info, fid_scan_folder_t * const p_data) 01022 { 01023 bool ret = false; 01024 bool result; 01025 FILE *fp; 01026 uint32_t total_trk; 01027 01028 if ((p_info != NULL) && (p_data != NULL)) { 01029 total_trk = fid_get_total_track(p_data); 01030 if (p_info->track_id < total_trk) { 01031 fp = fid_open_track(p_data, p_info->track_id); 01032 if (fp != NULL) { 01033 result = dec_open(fp, &open_callback); 01034 if (result == true) { 01035 /* Executes fid_close_track() in exe_end_proc(). */ 01036 p_info->p_file_handle = fp; 01037 p_info->open_track_id = p_info->track_id; 01038 ret = true; 01039 } else { 01040 /* The opening of the decoder was failure. */ 01041 fid_close_track(fp); 01042 p_info->p_file_handle = NULL; 01043 } 01044 } 01045 if (ret != true) { 01046 print_play_time(p_info); 01047 (void) dsp_notify_print_string(PRINT_MSG_OPEN_ERR); 01048 /* Tries to open the next file. */ 01049 p_info->open_track_id = TRACK_ID_ERR; 01050 (void) change_next_track(p_info, p_data); 01051 } 01052 } 01053 } 01054 return ret; 01055 } 01056 01057 /** Executes the starting process of the playback 01058 * 01059 * @param p_info Pointer to the playback information of the playback file 01060 * @param p_data Pointer to the control data of folder scan 01061 * 01062 * @returns 01063 * Results of process. true is success. false is failure. 01064 */ 01065 static bool exe_play_proc(play_info_t * const p_info, const fid_scan_folder_t * const p_data) 01066 { 01067 bool ret = false; 01068 bool result; 01069 01070 if (p_info != NULL) { 01071 result = dec_play(); 01072 if (result == true) { 01073 ret = true; 01074 } else { 01075 /* The starting of the playback was failure. */ 01076 print_play_time(p_info); 01077 /* Tries to open the next file. */ 01078 p_info->open_track_id = TRACK_ID_ERR; 01079 (void) change_next_track(p_info, p_data); 01080 } 01081 } 01082 return ret; 01083 } 01084 01085 /** Executes the starting process of the pause 01086 * 01087 * @returns 01088 * Results of process. true is success. false is failure. 01089 */ 01090 static bool exe_pause_on_proc(void) 01091 { 01092 bool ret; 01093 01094 ret = dec_pause_on(); 01095 return ret; 01096 } 01097 01098 /** Executes the cancel process of the pause 01099 * 01100 * @returns 01101 * Results of process. true is success. false is failure. 01102 */ 01103 static bool exe_pause_off_proc(void) 01104 { 01105 bool ret; 01106 01107 ret = dec_pause_off(); 01108 return ret; 01109 } 01110 01111 /** Executes the stop process of the playback 01112 * 01113 * @returns 01114 * Results of process. true is success. false is failure. 01115 */ 01116 static bool exe_stop_proc(void) 01117 { 01118 bool ret; 01119 01120 ret = dec_stop(); 01121 return ret; 01122 } 01123 01124 /** Executes the closing process 01125 * 01126 * @returns 01127 * Results of process. true is success. false is failure. 01128 */ 01129 static bool exe_close_proc(void) 01130 { 01131 bool ret; 01132 01133 ret = dec_close(&close_callback); 01134 return ret; 01135 } 01136 01137 /** Executes the end process 01138 * 01139 * @param p_info Pointer to the playback information of the playback file 01140 */ 01141 static void exe_end_proc(play_info_t * const p_info) 01142 { 01143 if (p_info != NULL) { 01144 fid_close_track(p_info->p_file_handle); 01145 p_info->p_file_handle = NULL; 01146 p_info->open_track_id = TRACK_ID_ERR; 01147 } 01148 } 01149 01150 /** Checks the track change 01151 * 01152 * @param p_info Pointer to the playback information of the playback file 01153 * 01154 * @returns 01155 * Results of check. 01156 */ 01157 static bool is_track_changed(const play_info_t * const p_info) 01158 { 01159 bool ret = false; 01160 01161 if (p_info != NULL) { 01162 if (p_info->track_id != p_info->open_track_id) { 01163 ret = true; 01164 } 01165 } 01166 return ret; 01167 } 01168 01169 /** Changes the repeat mode 01170 * 01171 * @param p_info Pointer to the playback information of the playback file 01172 */ 01173 static void change_repeat_mode(play_info_t * const p_info) 01174 { 01175 if (p_info != NULL) { 01176 if (p_info->repeat_mode == true) { 01177 p_info->repeat_mode = false; 01178 } else { 01179 p_info->repeat_mode = true; 01180 } 01181 (void) dsp_notify_play_mode(p_info->repeat_mode); 01182 } 01183 } 01184 01185 /** Changes the next track 01186 * 01187 * @param p_info Pointer to the playback information of the playback file 01188 * @param p_data Pointer to the control data of folder scan 01189 * 01190 * @returns 01191 * Results of process. true is success. false is failure. 01192 */ 01193 static bool change_next_track(play_info_t * const p_info, const fid_scan_folder_t * const p_data) 01194 { 01195 bool ret = false; 01196 uint32_t next_trk; 01197 uint32_t total_trk; 01198 01199 if ((p_info != NULL) && (p_data != NULL)) { 01200 next_trk = p_info->track_id + 1u; 01201 total_trk = fid_get_total_track(p_data); 01202 if (next_trk < total_trk) { 01203 ret = true; 01204 } else { 01205 next_trk = 0; 01206 if (p_info->repeat_mode == true) { 01207 ret = true; 01208 } 01209 } 01210 p_info->track_id = next_trk; 01211 } 01212 return ret; 01213 } 01214 01215 /** Changes the previous track 01216 * 01217 * @param p_info Pointer to the playback information of the playback file 01218 * @param p_data Pointer to the control data of folder scan 01219 * 01220 * @returns 01221 * Results of process. true is success. false is failure. 01222 */ 01223 static bool change_prev_track(play_info_t * const p_info, const fid_scan_folder_t * const p_data) 01224 { 01225 bool ret = false; 01226 uint32_t prev_trk; 01227 uint32_t total_trk; 01228 01229 if ((p_info != NULL) && (p_data != NULL)) { 01230 prev_trk = p_info->track_id - 1u; 01231 total_trk = fid_get_total_track(p_data); 01232 if (prev_trk < total_trk) { 01233 ret = true; 01234 } else { 01235 if (p_info->repeat_mode == true) { 01236 if (total_trk > 0u) { 01237 ret = true; 01238 prev_trk = total_trk - 1u; 01239 } else { 01240 prev_trk = 0u; 01241 } 01242 } else { 01243 prev_trk = 0u; 01244 } 01245 } 01246 p_info->track_id = prev_trk; 01247 } 01248 return ret; 01249 } 01250 /** Prints the playback information of the playback file 01251 * 01252 * @param p_info Pointer to the playback information of the playback file 01253 */ 01254 static void print_play_info(const play_info_t * const p_info) 01255 { 01256 uint32_t trk_id; 01257 01258 if (p_info != NULL) { 01259 trk_id = convert_track_id(p_info->track_id); 01260 (void) dsp_notify_play_info(trk_id, p_info->sample_rate, p_info->channel_num); 01261 } 01262 } 01263 01264 /** Prints the information of the playback time 01265 * 01266 * @param p_info Pointer to the playback information of the playback file 01267 */ 01268 static void print_play_time(const play_info_t * const p_info) 01269 { 01270 uint32_t trk_id; 01271 01272 if (p_info != NULL) { 01273 trk_id = convert_track_id(p_info->track_id); 01274 (void) dsp_notify_play_time(p_info->play_stat, trk_id, 01275 p_info->play_time, p_info->total_time); 01276 } 01277 } 01278 01279 /** Prints the file name of the playback file 01280 * 01281 * @param p_info Pointer to the playback information of the playback file 01282 * @param p_data Pointer to the control data of folder scan 01283 */ 01284 static void print_file_name(const play_info_t * const p_info, const fid_scan_folder_t * const p_data) 01285 { 01286 const char_t *p_path; 01287 uint32_t trk_id; 01288 uint32_t trk_total; 01289 01290 if ((p_info != NULL) && (p_data != NULL)) { 01291 trk_id = p_info->track_id; 01292 trk_total = fid_get_total_track(p_data); 01293 if (trk_id < trk_total) { 01294 p_path = fid_get_track_name(p_data, trk_id); 01295 (void) dsp_notify_file_name(p_path); 01296 } 01297 } 01298 } 01299 01300 /** Prints the command help information 01301 * 01302 */ 01303 static void print_help_info(void) 01304 { 01305 (void) dsp_req_help(); 01306 } 01307 01308 /** Prints the information of the playback status 01309 * 01310 * @param p_info Pointer to the playback information of the playback file 01311 */ 01312 static void print_play_status(const play_info_t * const p_info) 01313 { 01314 if (p_info != NULL) { 01315 (void) dsp_notify_play_status(p_info->play_stat); 01316 } 01317 } 01318 01319 /** Changes the display mode of the TFT display. 01320 * 01321 * @param disp_mode Display mode before the change 01322 * 01323 * @returns 01324 * Display mode after changing 01325 */ 01326 static void change_display_mode(play_info_t * const p_info) 01327 { 01328 if (p_info != NULL) { 01329 if (p_info->disp_mode < DSP_DISPMODE_3) { 01330 p_info->disp_mode++; 01331 } else { 01332 p_info->disp_mode = DSP_DISPMODE_1; 01333 } 01334 (void) dsp_notify_disp_mode(p_info->disp_mode); 01335 } 01336 } 01337 01338 /** Converts the track ID of main thread into the track ID of display thread 01339 * 01340 * @param trk_id Track ID of main thread 01341 * 01342 * @returns 01343 * Track ID of display thread 01344 */ 01345 static uint32_t convert_track_id(const uint32_t trk_id) 01346 { 01347 uint32_t ret = 0u; 01348 01349 /* Track ID of main thread begins with 0. */ 01350 /* Converts the track ID of main thread into the track ID */ 01351 /* of the display thread beginning with 1. */ 01352 if (trk_id < SYS_MAX_TRACK_NUM) { 01353 ret = trk_id + 1u; 01354 } 01355 return ret; 01356 } 01357 01358 /** Sends the mail to main thread 01359 * 01360 * @param mail_id Mail ID 01361 * @param param0 Parameter 0 of this mail 01362 * @param param1 Parameter 1 of this mail 01363 * @param param2 Parameter 2 of this mail 01364 * 01365 * @returns 01366 * Results of process. true is success. false is failure. 01367 */ 01368 static bool send_mail(const SYS_MAIL_ID mail_id, const uint32_t param0, 01369 const uint32_t param1, const uint32_t param2) 01370 { 01371 bool ret = false; 01372 osStatus stat; 01373 sys_mail_t * const p_mail = mail_box.alloc(); 01374 01375 if (p_mail != NULL) { 01376 p_mail->mail_id = mail_id; 01377 p_mail->param[MAIL_PARAM0] = param0; 01378 p_mail->param[MAIL_PARAM1] = param1; 01379 p_mail->param[MAIL_PARAM2] = param2; 01380 stat = mail_box.put(p_mail); 01381 if (stat == osOK) { 01382 ret = true; 01383 } else { 01384 (void) mail_box.free(p_mail); 01385 } 01386 } 01387 return ret; 01388 } 01389 01390 /** Receives the mail to main thread 01391 * 01392 * @param p_mail_id Pointer to the variable to store the mail ID 01393 * @param p_param0 Pointer to the variable to store the parameter 0 of this mail 01394 * @param p_param1 Pointer to the variable to store the parameter 1 of this mail 01395 * @param p_param2 Pointer to the variable to store the parameter 2 of this mail 01396 * 01397 * @returns 01398 * Results of process. true is success. false is failure. 01399 */ 01400 static bool recv_mail(SYS_MAIL_ID * const p_mail_id, uint32_t * const p_param0, 01401 uint32_t * const p_param1, uint32_t * const p_param2) 01402 { 01403 bool ret = false; 01404 osEvent evt; 01405 sys_mail_t *p_mail; 01406 01407 if ((p_mail_id != NULL) && (p_param0 != NULL) && 01408 (p_param1 != NULL) && (p_param2 != NULL)) { 01409 evt = mail_box.get(RECV_MAIL_TIMEOUT_MS); 01410 if (evt.status == osEventMail) { 01411 p_mail = (sys_mail_t *)evt.value.p; 01412 if (p_mail != NULL) { 01413 *p_mail_id = p_mail->mail_id; 01414 *p_param0 = p_mail->param[MAIL_PARAM0]; 01415 *p_param1 = p_mail->param[MAIL_PARAM1]; 01416 *p_param2 = p_mail->param[MAIL_PARAM2]; 01417 ret = true; 01418 } 01419 (void) mail_box.free(p_mail); 01420 } 01421 } 01422 return ret; 01423 }
Generated on Tue Jul 12 2022 19:32:30 by 1.7.2