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 Renesas

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers system.cpp Source File

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 }