Renesas / Mbed OS GR-PEACH_Audio_Playback_Sample

Dependencies:   R_BSP TLV320_RBSP USBHost_custom

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     /* Notification of decoder process */
00117     SYS_EV_DEC_OPEN_COMP,       /* Finished the opening process */
00118     SYS_EV_DEC_OPEN_COMP_ERR,   /* Finished the opening process (An error occured)*/
00119     SYS_EV_DEC_CLOSE_COMP,      /* Finished the closing process */
00120     /* Notification of the playback status */
00121     SYS_EV_STAT_STOP,           /* Stop */
00122     SYS_EV_STAT_PLAY,           /* Play */
00123     SYS_EV_STAT_PAUSE,          /* Pause */
00124     /* Notification of USB connection */
00125     SYS_EV_USB_CONNECT,         /* Connect */
00126     SYS_EV_USB_DISCONNECT,      /* Disconnect  */
00127     SYS_EV_NUM
00128 } SYS_EVENT;
00129 
00130 /* Control data of USB memory */
00131 typedef struct {
00132     bool            usb_flag_detach;/* Detected the disconnection of USB memory */
00133 } usb_ctrl_t;
00134 
00135 /* The playback information of the playback file */
00136 typedef struct {
00137     SYS_PlayStat    play_stat;      /* Playback status */
00138     bool            repeat_mode;    /* Repeat mode */
00139     uint32_t        track_id;       /* Number of the selected track */
00140     uint32_t        open_track_id;  /* Number of the track during the open processing */
00141     FILE            *p_file_handle; /* Handle of the track */
00142     uint32_t        play_time;      /* Playback start time */
00143     uint32_t        total_time;     /* Total playback time */
00144     uint32_t        sample_rate;    /* Sampling rate in Hz of FLAC file */
00145     uint32_t        channel_num;    /* Number of channel */
00146 } play_info_t;
00147 
00148 /* Control data of main thread */
00149 typedef struct {
00150     usb_ctrl_t          usb_ctrl;
00151     fid_scan_folder_t   scan_data;
00152     play_info_t         play_info;
00153 } sys_ctrl_t;
00154 
00155 static Mail<sys_mail_t, MAIL_QUEUE_SIZE> mail_box;
00156 
00157 static void open_callback(const bool result, const uint32_t sample_freq, 
00158                                                 const uint32_t channel_num);
00159 static void close_callback(void);
00160 static void init_ctrl_data(sys_ctrl_t * const p_ctrl);
00161 static SYS_EVENT decode_mail(play_info_t * const p_info, 
00162         const fid_scan_folder_t * const p_data, const SYS_MAIL_ID mail_id, 
00163         const uint32_t * const p_param);
00164 static SYS_EVENT check_usb_event(const SYS_STATE stat, 
00165         const usb_ctrl_t * const p_ctrl, USBHostMSD * const p_msd, 
00166         FATFileSystem * const p_fs);
00167 static SYS_STATE state_trans_proc(const SYS_STATE stat, 
00168                         const SYS_EVENT event, sys_ctrl_t * const p_ctrl);
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_proc_wait_usb_connect(const SYS_STATE stat, 
00172                         const SYS_EVENT event, sys_ctrl_t * const p_ctrl);
00173 static SYS_STATE state_proc_stop(const SYS_STATE stat, 
00174                         const SYS_EVENT event, sys_ctrl_t * const p_ctrl);
00175 static SYS_STATE state_proc_play_prepare(const SYS_STATE stat, 
00176                         const SYS_EVENT event, sys_ctrl_t * const p_ctrl);
00177 static SYS_STATE state_proc_play_prepare_req(const SYS_STATE stat, 
00178                         const SYS_EVENT event, sys_ctrl_t * const p_ctrl);
00179 static SYS_STATE state_proc_play_pause(const SYS_STATE stat, 
00180                         const SYS_EVENT event, sys_ctrl_t * const p_ctrl);
00181 static SYS_STATE state_proc_stop_prepare(const SYS_STATE stat, 
00182                         const SYS_EVENT event, sys_ctrl_t * const p_ctrl);
00183 static SYS_STATE state_proc_stop_prepare_req(const SYS_STATE stat, 
00184                         const SYS_EVENT event, sys_ctrl_t * const p_ctrl);
00185 static bool exe_scan_folder_proc(play_info_t * const p_info, 
00186                                             fid_scan_folder_t * const p_data);
00187 static bool exe_open_proc(play_info_t * const p_info, 
00188                                             fid_scan_folder_t * const p_data);
00189 static bool exe_play_proc(play_info_t * const p_info, 
00190                                     const fid_scan_folder_t * const p_data);
00191 static bool exe_pause_on_proc(void);
00192 static bool exe_pause_off_proc(void);
00193 static bool exe_stop_proc(void);
00194 static bool exe_close_proc(void);
00195 static void exe_end_proc(play_info_t * const p_info);
00196 static bool is_track_changed(const play_info_t * const p_info);
00197 static void change_repeat_mode(play_info_t * const p_info);
00198 static bool change_next_track(play_info_t * const p_info, 
00199                                     const fid_scan_folder_t * const p_data);
00200 static bool change_prev_track(play_info_t * const p_info, 
00201                                     const fid_scan_folder_t * const p_data);
00202 static void print_play_time(const play_info_t * const p_info);
00203 static void print_play_info(const play_info_t * const p_info);
00204 static void print_file_name(const play_info_t * const p_info, 
00205                                     const fid_scan_folder_t * const p_data);
00206 static void print_help_info(void);
00207 static uint32_t convert_track_id(const uint32_t trk_id);
00208 static bool send_mail(const SYS_MAIL_ID mail_id, const uint32_t param0,
00209                             const uint32_t param1, const uint32_t param2);
00210 static bool recv_mail(SYS_MAIL_ID * const p_mail_id, uint32_t * const p_param0, 
00211                         uint32_t * const p_param1, uint32_t * const p_param2);
00212 
00213 void system_main(void)
00214 {
00215     SYS_STATE           sys_stat;
00216     SYS_EVENT           sys_ev;
00217     bool                result;
00218     SYS_MAIL_ID         mail_type;
00219     uint32_t            mail_param[MAIL_PARAM_NUM];
00220     static sys_ctrl_t   sys_ctrl;
00221     static FATFileSystem fs(SYS_USB_MOUNT_NAME);
00222     static USBHostMSD msd;
00223 #if (USB_HOST_CH == 1) /* Audio Shield USB1 */
00224     static DigitalOut   usb1en(P3_8);
00225 
00226     /* Audio Shield USB1 enable */
00227     usb1en.write(1);    /* Outputs high level */
00228     Thread::wait(USB1_WAIT_TIME_MS);
00229     usb1en.write(0);    /* Outputs low level */
00230 #endif /* USB_HOST_CH */
00231 
00232     /* Initializes the control data of main thread. */
00233     init_ctrl_data(&sys_ctrl);
00234     sys_stat = SYS_ST_WAIT_USB_CONNECT;
00235     while (1) {
00236         sys_ev = check_usb_event(sys_stat, &sys_ctrl.usb_ctrl, &msd, &fs);
00237         if (sys_ev == SYS_EV_NON) {
00238             result = recv_mail(&mail_type, &mail_param[MAIL_PARAM0], 
00239                         &mail_param[MAIL_PARAM1], &mail_param[MAIL_PARAM2]);
00240             if (result == true) {
00241                 sys_ev = decode_mail(&sys_ctrl.play_info, 
00242                                 &sys_ctrl.scan_data, mail_type, mail_param);
00243             }
00244         }
00245         if (sys_ev != SYS_EV_NON) {
00246             sys_stat = state_trans_proc(sys_stat, sys_ev, &sys_ctrl);
00247         }
00248     }
00249 }
00250 
00251 bool sys_notify_key_input(const SYS_KeyCode key_code)
00252 {
00253     bool    ret = false;
00254 
00255     ret = send_mail(SYS_MAILID_KEYCODE, (uint32_t)key_code, MAIL_PARAM_NON, MAIL_PARAM_NON);
00256 
00257     return ret;
00258 }
00259 
00260 bool sys_notify_play_time(const SYS_PlayStat play_stat, 
00261     const uint32_t play_time, const uint32_t total_time)
00262 {
00263     bool    ret = false;
00264 
00265     ret = send_mail(SYS_MAILID_PLAY_TIME, (uint32_t)play_stat, play_time, total_time);
00266 
00267     return ret;
00268 }
00269 
00270 /** Callback function of Decode Thread
00271  *
00272  *  @param result Result of the process.
00273  *  @param sample_freq Sampling rate in Hz of FLAC file.
00274  *  @param channel_num Number of channel.
00275  */
00276 static void open_callback(const bool result, const uint32_t sample_freq, 
00277                                                 const uint32_t channel_num)
00278 {
00279     (void) send_mail(SYS_MAILID_DEC_OPEN_FIN, (uint32_t)result, sample_freq, channel_num);
00280 }
00281 
00282 /** Callback function of Decode Thread
00283  *
00284  */
00285 static void close_callback(void)
00286 {
00287     (void) send_mail(SYS_MAILID_DEC_CLOSE_FIN, MAIL_PARAM_NON, MAIL_PARAM_NON, MAIL_PARAM_NON);
00288 }
00289 
00290 /** Initialises the control data of main thread
00291  *
00292  *  @param p_ctrl Pointer to the control data of main thread
00293  */
00294 static void init_ctrl_data(sys_ctrl_t * const p_ctrl)
00295 {
00296     if (p_ctrl != NULL) {
00297         /* Initialises the control data of USB memory. */
00298         p_ctrl->usb_ctrl.usb_flag_detach = false;
00299         /* Initialises the information of folder scan. */
00300         fid_init(&p_ctrl->scan_data);
00301         /* Initialises the playback information of the playback file */
00302         p_ctrl->play_info.play_stat = SYS_PLAYSTAT_STOP;
00303         p_ctrl->play_info.repeat_mode = true;
00304         p_ctrl->play_info.track_id = TRACK_ID_MIN;
00305         p_ctrl->play_info.open_track_id = TRACK_ID_ERR;
00306         p_ctrl->play_info.p_file_handle = NULL;
00307         p_ctrl->play_info.play_time = 0u;
00308         p_ctrl->play_info.total_time = 0u;
00309         p_ctrl->play_info.sample_rate = 0u;
00310         p_ctrl->play_info.channel_num = 0u;
00311     }
00312 }
00313 
00314 /** Converts the code of SYS_MAIL_ID into the code of SYS_EVENT
00315  *
00316  *  @param p_info Pointer to the playback information of the playback file
00317  *  @param p_data Pointer to the control data of folder scan
00318  *  @param mail_id The event code of SYS_MAIL_ID
00319  *  @param p_param Pointer to the parameter of the mail
00320  *
00321  *  @returns 
00322  *    The event code of SYS_EVENT
00323  */
00324 static SYS_EVENT decode_mail(play_info_t * const p_info, 
00325         const fid_scan_folder_t * const p_data, const SYS_MAIL_ID mail_id, 
00326         const uint32_t * const p_param)
00327 {
00328     SYS_EVENT       ret = SYS_EV_NON;
00329 
00330     if ((p_info != NULL) && (p_data != NULL) && (p_param != NULL)) {
00331         switch (mail_id) {
00332             case SYS_MAILID_KEYCODE:
00333                 switch (p_param[MAIL_KEYCODE_CODE]) {
00334                     case SYS_KEYCODE_STOP:
00335                         ret = SYS_EV_KEY_STOP;
00336                         break;
00337                     case SYS_KEYCODE_PLAYPAUSE:
00338                         ret = SYS_EV_KEY_PLAY_PAUSE;
00339                         break;
00340                     case SYS_KEYCODE_NEXT:
00341                         ret = SYS_EV_KEY_NEXT;
00342                         break;
00343                     case SYS_KEYCODE_PREV:
00344                         ret = SYS_EV_KEY_PREV;
00345                         break;
00346                     case SYS_KEYCODE_PLAYINFO:
00347                         ret = SYS_EV_KEY_PLAYINFO;
00348                         break;
00349                     case SYS_KEYCODE_REPEAT:
00350                         ret = SYS_EV_KEY_REPEAT;
00351                         break;
00352                     case SYS_KEYCODE_HELP:
00353                         ret = SYS_EV_KEY_HELP;
00354                         break;
00355                     default:
00356                         /* Unexpected cases : This is fail-safe processing. */
00357                         ret = SYS_EV_NON;
00358                         break;
00359                 }
00360                 break;
00361             case SYS_MAILID_PLAY_TIME:
00362                 switch (p_param[MAIL_PLAYTIME_STAT]) {
00363                     case SYS_PLAYSTAT_STOP:
00364                         ret = SYS_EV_STAT_STOP;
00365                         break;
00366                     case SYS_PLAYSTAT_PLAY:
00367                         ret = SYS_EV_STAT_PLAY;
00368                         break;
00369                     case SYS_PLAYSTAT_PAUSE:
00370                         ret = SYS_EV_STAT_PAUSE;
00371                         break;
00372                     default:
00373                         ret = SYS_EV_NON;
00374                         break;
00375                 }
00376                 /* Is the playback status correct? */
00377                 if (ret != SYS_EV_NON) {
00378                     p_info->play_stat  = (SYS_PlayStat)p_param[MAIL_PLAYTIME_STAT];
00379                     p_info->play_time  = p_param[MAIL_PLAYTIME_TIME];
00380                     p_info->total_time = p_param[MAIL_PLAYTIME_TOTAL];
00381                 } else {
00382                     /* Unexpected cases : This is fail-safe processing. */
00383                     p_info->play_stat  = SYS_PLAYSTAT_STOP;
00384                     p_info->play_time  = 0u;
00385                     p_info->total_time = 0u;
00386                 }
00387                 break;
00388             case SYS_MAILID_DEC_OPEN_FIN:
00389                 if ((int32_t)p_param[MAIL_DECOPEN_RESULT] == true) {
00390                     ret = SYS_EV_DEC_OPEN_COMP;
00391                     p_info->sample_rate = p_param[MAIL_DECOPEN_FREQ];
00392                     p_info->channel_num = p_param[MAIL_DECOPEN_CH];
00393                 } else {
00394                     /* The opening of the decoder was failure. */
00395                     ret = SYS_EV_DEC_OPEN_COMP_ERR;
00396                     p_info->sample_rate = 0u;
00397                     p_info->channel_num = 0u;
00398                     /* Tries to open the next file. */
00399                     print_play_time(p_info);
00400                     p_info->open_track_id = TRACK_ID_ERR;
00401                     (void) change_next_track(p_info, p_data);
00402                 }
00403                 break;
00404             case SYS_MAILID_DEC_CLOSE_FIN:
00405                 ret = SYS_EV_DEC_CLOSE_COMP;
00406                 p_info->play_time  = 0u;
00407                 p_info->total_time = 0u;
00408                 break;
00409             default:
00410                 /* Unexpected cases : This is fail-safe processing. */
00411                 ret = SYS_EV_NON;
00412                 break;
00413         }
00414     }
00415     return ret;
00416 }
00417 
00418 /** Checks the event of USB connection
00419  *
00420  *  @param stat Status of main thread
00421  *  @param p_ctrl Pointer to the control data of USB memory
00422  *  @param p_msd Pointer to the class object of USBHostMSD
00423  *  @param P_fs Pointer to the class oblect of FATFileSystem
00424  *
00425  *  @returns 
00426  *    The event code of SYS_EVENT
00427  */
00428 static SYS_EVENT check_usb_event(const SYS_STATE stat, 
00429         const usb_ctrl_t * const p_ctrl, 
00430         USBHostMSD * const p_msd, FATFileSystem * const p_fs)
00431 {
00432     SYS_EVENT       ret = SYS_EV_NON;
00433     int             iRet;
00434     bool            result;
00435 
00436     if ((p_ctrl != NULL) && (p_msd != NULL)) {
00437         if (stat == SYS_ST_WAIT_USB_CONNECT) {
00438             /* Mounts the FAT filesystem again. */
00439             /* Because the connecting USB memory is changed. */
00440             result = p_msd->connect();
00441             if (result == true) {
00442                 iRet = p_fs->unmount();
00443                 iRet = p_fs->mount(p_msd);
00444                 ret = SYS_EV_USB_CONNECT;
00445             }
00446         } else if (p_ctrl->usb_flag_detach != true) {
00447             result = p_msd->connected();
00448             if (result != true) {
00449                 ret = SYS_EV_USB_DISCONNECT;
00450             }
00451         } else {
00452             /* DO NOTHING */
00453         }
00454     }
00455     return ret;
00456 }
00457 
00458 /** Executes the state transition processing
00459  *
00460  *  @param stat Status of main thread
00461  *  @param event Event code of main thread
00462  *  @param p_ctrl Pointer to the control data of main thread
00463  *
00464  *  @returns 
00465  *    Next status of main thread
00466  */
00467 static SYS_STATE state_trans_proc(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl)
00468 {
00469     SYS_STATE       next_stat = stat;
00470 
00471     if (p_ctrl != NULL) {
00472         /* State transition processing */
00473         switch (stat) {
00474             case SYS_ST_WAIT_USB_CONNECT:   /* Wait the USB connection */
00475                 next_stat = state_proc_wait_usb_connect(stat, event, p_ctrl);
00476                 break;
00477             case SYS_ST_STOP:               /* Stop the playback */
00478                 next_stat = state_proc_stop(stat, event, p_ctrl);
00479                 break;
00480             case SYS_ST_PLAY_PREPARE:       /* Preparation of the playback */
00481                 next_stat = state_proc_play_prepare(stat, event, p_ctrl);
00482                 break;
00483             case SYS_ST_PLAY_PREPARE_REQ:   /* Holds the stop request until completion */
00484                                             /* of the playback preparation */
00485                 next_stat = state_proc_play_prepare_req(stat, event, p_ctrl);
00486                 break;
00487             case SYS_ST_PLAY:               /* Play */
00488             case SYS_ST_PAUSE:              /* Pause */
00489                 next_stat = state_proc_play_pause(stat, event, p_ctrl);
00490                 break;
00491             case SYS_ST_STOP_PREPARE:       /* Preparation of the stop */
00492                 next_stat = state_proc_stop_prepare(stat, event, p_ctrl);
00493                 break;
00494             case SYS_ST_STOP_PREPARE_REQ:   /* Holds the playback request until completion */
00495                                             /* of the stop preparation */
00496                 next_stat = state_proc_stop_prepare_req(stat, event, p_ctrl);
00497                 break;
00498             default:
00499                 /* Unexpected cases : This is fail-safe processing. */
00500                 next_stat = SYS_ST_WAIT_USB_CONNECT;
00501                 break;
00502         }
00503     }
00504     return next_stat;
00505 }
00506 
00507 /** Executes the state transition processing in the state of SYS_ST_WAIT_USB_CONNECT.
00508  *
00509  *  @param stat Status of main thread
00510  *  @param event Event code of main thread
00511  *  @param p_ctrl Pointer to the control data of main thread
00512  *
00513  *  @returns 
00514  *    Next status of main thread
00515  */
00516 static SYS_STATE state_proc_wait_usb_connect(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl)
00517 {
00518     SYS_STATE       next_stat = stat;
00519 
00520     if (p_ctrl != NULL) {
00521         if (event == SYS_EV_USB_CONNECT) {
00522             p_ctrl->usb_ctrl.usb_flag_detach = false;
00523             (void) exe_scan_folder_proc(&p_ctrl->play_info, &p_ctrl->scan_data);
00524             (void) dsp_notify_print_string(PRINT_MSG_USB_CONNECT);
00525             next_stat = SYS_ST_STOP;
00526         } else if (event == SYS_EV_KEY_HELP) {
00527             print_help_info();
00528         } else {
00529             /* DO NOTHING */
00530         }
00531     }
00532     return next_stat;
00533 }
00534 
00535 /** Executes the state transition processing in the state of SYS_ST_STOP.
00536  *
00537  *  @param stat Status of main thread
00538  *  @param event Event code of main thread
00539  *  @param p_ctrl Pointer to the control data of main thread
00540  *
00541  *  @returns 
00542  *    Next status of main thread
00543  */
00544 static SYS_STATE state_proc_stop(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl)
00545 {
00546     SYS_STATE       next_stat = stat;
00547     bool            result;
00548 
00549     if (p_ctrl != NULL) {
00550         switch (event) {
00551             case SYS_EV_KEY_PLAY_PAUSE:
00552                 print_file_name(&p_ctrl->play_info, &p_ctrl->scan_data);
00553                 result = exe_open_proc(&p_ctrl->play_info, &p_ctrl->scan_data);
00554                 if (result == true) {
00555                     next_stat = SYS_ST_PLAY_PREPARE;
00556                 }
00557                 break;
00558             case SYS_EV_KEY_REPEAT:
00559                 change_repeat_mode(&p_ctrl->play_info);
00560                 break;
00561             case SYS_EV_KEY_HELP:
00562                 print_help_info();
00563                 break;
00564             case SYS_EV_USB_DISCONNECT:
00565                 p_ctrl->usb_ctrl.usb_flag_detach = true;
00566                 next_stat = SYS_ST_WAIT_USB_CONNECT;
00567                 break;
00568             default:
00569                 /* Does not change the state. There is not the action. */
00570                 next_stat = stat;
00571                 break;
00572         }
00573     }
00574     return next_stat;
00575 }
00576 
00577 /** Executes the state transition processing in the state of SYS_ST_PLAY_PREPARE.
00578  *
00579  *  @param stat Status of main thread
00580  *  @param event Event code of main thread
00581  *  @param p_ctrl Pointer to the control data of main thread
00582  *
00583  *  @returns 
00584  *    Next status of main thread
00585  */
00586 static SYS_STATE state_proc_play_prepare(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl)
00587 {
00588     SYS_STATE       next_stat = stat;
00589     bool            result;
00590 
00591     if (p_ctrl != NULL) {
00592         switch (event) {
00593             case SYS_EV_KEY_STOP:
00594                 next_stat = SYS_ST_PLAY_PREPARE_REQ;
00595                 break;
00596             case SYS_EV_KEY_NEXT:
00597                 result = change_next_track(&p_ctrl->play_info, &p_ctrl->scan_data);
00598                 if (result != true) {
00599                     /* Selected track was out of the playback range. */
00600                     next_stat = SYS_ST_PLAY_PREPARE_REQ;
00601                 }
00602                 break;
00603             case SYS_EV_KEY_PREV:
00604                 result = change_prev_track(&p_ctrl->play_info, &p_ctrl->scan_data);
00605                 if (result != true) {
00606                     next_stat = SYS_ST_PLAY_PREPARE_REQ;
00607                 }
00608                 break;
00609             case SYS_EV_KEY_REPEAT:
00610                 change_repeat_mode(&p_ctrl->play_info);
00611                 break;
00612             case SYS_EV_KEY_HELP:
00613                 print_help_info();
00614                 break;
00615             case SYS_EV_DEC_OPEN_COMP:
00616                 result = is_track_changed(&p_ctrl->play_info);
00617                 if (result == true) {
00618                     /* Track was changed during the waiting of callback. */
00619                     print_play_time(&p_ctrl->play_info);
00620                     result = exe_close_proc();
00621                     if (result == true) {
00622                         next_stat = SYS_ST_STOP_PREPARE_REQ;
00623                     } else {
00624                         /* Unexpected cases : This is fail-safe processing. */
00625                         exe_end_proc(&p_ctrl->play_info);
00626                         next_stat = SYS_ST_STOP;
00627                     }
00628                 } else {
00629                     print_play_info(&p_ctrl->play_info);
00630                     result = exe_play_proc(&p_ctrl->play_info, &p_ctrl->scan_data);
00631                     if (result == true) {
00632                         next_stat = SYS_ST_PLAY;
00633                     } else {
00634                         result = exe_close_proc();
00635                         if (result == true) {
00636                             next_stat = SYS_ST_STOP_PREPARE;
00637                         } else {
00638                             /* Unexpected cases : This is fail-safe processing. */
00639                             exe_end_proc(&p_ctrl->play_info);
00640                             next_stat = SYS_ST_STOP;
00641                         }
00642                     }
00643                 }
00644                 break;
00645             case SYS_EV_DEC_OPEN_COMP_ERR:
00646                 /* Output error message to PC */
00647                 (void) dsp_notify_print_string(PRINT_MSG_DECODE_ERR);
00648                 exe_end_proc(&p_ctrl->play_info);
00649                 next_stat = SYS_ST_STOP;
00650                 break;
00651             case SYS_EV_USB_DISCONNECT:
00652                 p_ctrl->usb_ctrl.usb_flag_detach = true;
00653                 next_stat = SYS_ST_PLAY_PREPARE_REQ;
00654                 break;
00655             default:
00656                 /* Does not change the state. There is not the action. */
00657                 next_stat = stat;
00658                 break;
00659         }
00660     }
00661     return next_stat;
00662 }
00663 
00664 /** Executes the state transition processing in the state of SYS_ST_PLAY_PREPARE_REQ.
00665  *
00666  *  @param stat Status of main thread
00667  *  @param event Event code of main thread
00668  *  @param p_ctrl Pointer to the control data of main thread
00669  *
00670  *  @returns 
00671  *    Next status of main thread
00672  */
00673 static SYS_STATE state_proc_play_prepare_req(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl)
00674 {
00675     SYS_STATE       next_stat = stat;
00676     bool            result;
00677 
00678     if (p_ctrl != NULL) {
00679         switch (event) {
00680             case SYS_EV_KEY_REPEAT:
00681                 change_repeat_mode(&p_ctrl->play_info);
00682                 break;
00683             case SYS_EV_KEY_HELP:
00684                 print_help_info();
00685                 break;
00686             case SYS_EV_DEC_OPEN_COMP:
00687                 print_play_time(&p_ctrl->play_info);
00688                 result = exe_close_proc();
00689                 if (result == true) {
00690                     next_stat = SYS_ST_STOP_PREPARE;
00691                 } else {
00692                     /* Unexpected cases : This is fail-safe processing. */
00693                     exe_end_proc(&p_ctrl->play_info);
00694                     if (p_ctrl->usb_ctrl.usb_flag_detach == true) {
00695                         next_stat = SYS_ST_WAIT_USB_CONNECT;
00696                     } else {
00697                         next_stat = SYS_ST_STOP;
00698                     }
00699                 }
00700                 break;
00701             case SYS_EV_DEC_OPEN_COMP_ERR:
00702                 /* Output error message to PC */
00703                 (void) dsp_notify_print_string(PRINT_MSG_DECODE_ERR);
00704                 exe_end_proc(&p_ctrl->play_info);
00705                 if (p_ctrl->usb_ctrl.usb_flag_detach == true) {
00706                     next_stat = SYS_ST_WAIT_USB_CONNECT;
00707                 } else {
00708                     next_stat = SYS_ST_STOP;
00709                 }
00710                 break;
00711             case SYS_EV_USB_DISCONNECT:
00712                 p_ctrl->usb_ctrl.usb_flag_detach = true;
00713                 break;
00714             default:
00715                 /* Does not change the state. There is not the action. */
00716                 next_stat = stat;
00717                 break;
00718         }
00719     }
00720     return next_stat;
00721 }
00722 
00723 /** Executes the state transition processing in the state of SYS_ST_PLAY / SYS_ST_PAUSE.
00724  *
00725  *  @param stat Status of main thread
00726  *  @param event Event code of main thread
00727  *  @param p_ctrl Pointer to the control data of main thread
00728  *
00729  *  @returns 
00730  *    Next status of main thread
00731  */
00732 static SYS_STATE state_proc_play_pause(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl)
00733 {
00734     SYS_STATE       next_stat = stat;
00735     bool            result;
00736 
00737     if (p_ctrl != NULL) {
00738         switch (event) {
00739             case SYS_EV_KEY_STOP:
00740                 result = exe_stop_proc();
00741                 if (result == true) {
00742                     next_stat = SYS_ST_STOP_PREPARE;
00743                 }
00744                 break;
00745             case SYS_EV_KEY_PLAY_PAUSE:
00746                 if (stat == SYS_ST_PLAY) {
00747                     (void) exe_pause_on_proc();
00748                 } else {
00749                     (void) exe_pause_off_proc();
00750                 }
00751                 break;
00752             case SYS_EV_KEY_NEXT:
00753             case SYS_EV_KEY_PREV:
00754                 result = exe_stop_proc();
00755                 if (result == true) {
00756                     if (event == SYS_EV_KEY_PREV) {
00757                         result = change_prev_track(&p_ctrl->play_info, &p_ctrl->scan_data);
00758                     } else {
00759                         result = change_next_track(&p_ctrl->play_info, &p_ctrl->scan_data);
00760                     }
00761                     if (result == true) {
00762                         next_stat = SYS_ST_STOP_PREPARE_REQ;
00763                     } else {
00764                         next_stat = SYS_ST_STOP_PREPARE;
00765                     }
00766                 }
00767                 break;
00768             case SYS_EV_KEY_PLAYINFO:
00769                 print_play_info(&p_ctrl->play_info);
00770                 break;
00771             case SYS_EV_KEY_REPEAT:
00772                 change_repeat_mode(&p_ctrl->play_info);
00773                 break;
00774             case SYS_EV_KEY_HELP:
00775                 print_help_info();
00776                 break;
00777             case SYS_EV_STAT_STOP:
00778                 print_play_time(&p_ctrl->play_info);
00779                 result = exe_close_proc();
00780                 if (result == true) {
00781                     result = change_next_track(&p_ctrl->play_info, &p_ctrl->scan_data);
00782                     if (result == true) {
00783                         next_stat = SYS_ST_STOP_PREPARE_REQ;
00784                     } else {
00785                         next_stat = SYS_ST_STOP_PREPARE;
00786                     }
00787                 } else {
00788                     /* Unexpected cases : This is fail-safe processing. */
00789                     exe_end_proc(&p_ctrl->play_info);
00790                     if (p_ctrl->usb_ctrl.usb_flag_detach == true) {
00791                         next_stat = SYS_ST_WAIT_USB_CONNECT;
00792                     } else {
00793                         next_stat = SYS_ST_STOP;
00794                     }
00795                 }
00796                 break;
00797             case SYS_EV_STAT_PLAY:
00798                 print_play_time(&p_ctrl->play_info);
00799                 next_stat = SYS_ST_PLAY;
00800                 break;
00801             case SYS_EV_STAT_PAUSE:
00802                 print_play_time(&p_ctrl->play_info);
00803                 next_stat = SYS_ST_PAUSE;
00804                 break;
00805             case SYS_EV_USB_DISCONNECT:
00806                 p_ctrl->usb_ctrl.usb_flag_detach = true;
00807                 result = exe_stop_proc();
00808                 if (result == true) {
00809                     next_stat = SYS_ST_STOP_PREPARE;
00810                 } else {
00811                     /* Unexpected cases : This is fail-safe processing. */
00812                     /* In this case, main thread wait the notification of the stop status. */
00813                     /* An error will occur by the disconnection of USB memory.  */
00814                 }
00815                 break;
00816             default:
00817                 /* Does not change the state. There is not the action. */
00818                 next_stat = stat;
00819                 break;
00820         }
00821     }
00822     return next_stat;
00823 }
00824 
00825 /** Executes the state transition processing in the state of SYS_ST_STOP_PREPARE.
00826  *
00827  *  @param stat Status of main thread
00828  *  @param event Event code of main thread
00829  *  @param p_ctrl Pointer to the control data of main thread
00830  *
00831  *  @returns 
00832  *    Next status of main thread
00833  */
00834 static SYS_STATE state_proc_stop_prepare(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl)
00835 {
00836     SYS_STATE       next_stat = stat;
00837     bool            result;
00838 
00839     if (p_ctrl != NULL) {
00840         switch (event) {
00841             case SYS_EV_KEY_REPEAT:
00842                 change_repeat_mode(&p_ctrl->play_info);
00843                 break;
00844             case SYS_EV_KEY_HELP:
00845                 print_help_info();
00846                 break;
00847             case SYS_EV_DEC_CLOSE_COMP:
00848                 exe_end_proc(&p_ctrl->play_info);
00849                 if (p_ctrl->usb_ctrl.usb_flag_detach == true) {
00850                     next_stat = SYS_ST_WAIT_USB_CONNECT;
00851                 } else {
00852                     next_stat = SYS_ST_STOP;
00853                 }
00854                 break;
00855             case SYS_EV_STAT_STOP:
00856                 result = exe_close_proc();
00857                 if (result != true) {
00858                     /* Unexpected cases : This is fail-safe processing. */
00859                     exe_end_proc(&p_ctrl->play_info);
00860                     if (p_ctrl->usb_ctrl.usb_flag_detach == true) {
00861                         next_stat = SYS_ST_WAIT_USB_CONNECT;
00862                     } else {
00863                         next_stat = SYS_ST_STOP;
00864                     }
00865                 }
00866                 break;
00867             case SYS_EV_STAT_PLAY:
00868             case SYS_EV_STAT_PAUSE:
00869                 break;
00870             case SYS_EV_USB_DISCONNECT:
00871                 p_ctrl->usb_ctrl.usb_flag_detach = true;
00872                 break;
00873             default:
00874                 /* Does not change the state. There is not the action. */
00875                 next_stat = stat;
00876                 break;
00877         }
00878     }
00879     return next_stat;
00880 }
00881 
00882 /** Executes the state transition processing in the state of SYS_ST_STOP_PREPARE_REQ.
00883  *
00884  *  @param stat Status of main thread
00885  *  @param event Event code of main thread
00886  *  @param p_ctrl Pointer to the control data of main thread
00887  *
00888  *  @returns 
00889  *    Next status of main thread
00890  */
00891 static SYS_STATE state_proc_stop_prepare_req(const SYS_STATE stat, const SYS_EVENT event, sys_ctrl_t * const p_ctrl)
00892 {
00893     SYS_STATE       next_stat = stat;
00894     bool            result;
00895 
00896     if (p_ctrl != NULL) {
00897         switch (event) {
00898             case SYS_EV_KEY_STOP:
00899                 next_stat = SYS_ST_STOP_PREPARE;
00900                 break;
00901             case SYS_EV_KEY_NEXT:
00902                 result = change_next_track(&p_ctrl->play_info, &p_ctrl->scan_data);
00903                 if (result != true) {
00904                     /* Selected track was out of the playback range. */
00905                     next_stat = SYS_ST_STOP_PREPARE;
00906                 }
00907                 break;
00908             case SYS_EV_KEY_PREV:
00909                 result = change_prev_track(&p_ctrl->play_info, &p_ctrl->scan_data);
00910                 if (result != true) {
00911                     next_stat = SYS_ST_STOP_PREPARE;
00912                 }
00913                 break;
00914             case SYS_EV_KEY_REPEAT:
00915                 change_repeat_mode(&p_ctrl->play_info);
00916                 break;
00917             case SYS_EV_KEY_HELP:
00918                 print_help_info();
00919                 break;
00920             case SYS_EV_DEC_CLOSE_COMP:
00921                 exe_end_proc(&p_ctrl->play_info);
00922                 print_file_name(&p_ctrl->play_info, &p_ctrl->scan_data);
00923                 result = exe_open_proc(&p_ctrl->play_info, &p_ctrl->scan_data);
00924                 if (result == true) {
00925                     next_stat = SYS_ST_PLAY_PREPARE;
00926                 } else {
00927                     next_stat = SYS_ST_STOP;
00928                 }
00929                 break;
00930             case SYS_EV_STAT_STOP:
00931                 result = exe_close_proc();
00932                 if (result != true) {
00933                     /* Unexpected cases : This is fail-safe processing. */
00934                     exe_end_proc(&p_ctrl->play_info);
00935                     next_stat = SYS_ST_STOP;
00936                 }
00937                 break;
00938             case SYS_EV_STAT_PLAY:
00939             case SYS_EV_STAT_PAUSE:
00940                 break;
00941             case SYS_EV_USB_DISCONNECT:
00942                 p_ctrl->usb_ctrl.usb_flag_detach = true;
00943                 next_stat = SYS_ST_STOP_PREPARE;
00944                 break;
00945             default:
00946                 /* Does not change the state. There is not the action. */
00947                 next_stat = stat;
00948                 break;
00949         }
00950     }
00951     return next_stat;
00952 }
00953 
00954 /** Executes the scan of the folder structure
00955  *
00956  *  @param p_info Pointer to the playback information of the playback file
00957  *  @param p_data Pointer to the control data of folder scan
00958  *
00959  *  @returns 
00960  *    Results of process. true is success. false is failure.
00961  */
00962 static bool exe_scan_folder_proc(play_info_t * const p_info, fid_scan_folder_t * const p_data)
00963 {
00964     bool        ret = false;
00965 
00966     if ((p_info != NULL) && (p_data != NULL)) {
00967         (void) fid_scan_folder_struct(p_data);
00968         p_info->track_id = TRACK_ID_MIN;
00969         ret = true;
00970     }
00971     return ret;
00972 }
00973 
00974 /** Executes the opening process
00975  *
00976  *  @param p_info Pointer to the playback information of the playback file
00977  *  @param p_data Pointer to the control data of folder scan
00978  *
00979  *  @returns 
00980  *    Results of process. true is success. false is failure.
00981  */
00982 static bool exe_open_proc(play_info_t * const p_info, fid_scan_folder_t * const p_data)
00983 {
00984     bool        ret = false;
00985     bool        result;
00986     FILE        *fp;
00987     uint32_t    total_trk;
00988 
00989     if ((p_info != NULL) && (p_data != NULL)) {
00990         total_trk = fid_get_total_track(p_data);
00991         if (p_info->track_id < total_trk) {
00992             fp = fid_open_track(p_data, p_info->track_id);
00993             if (fp != NULL) {
00994                 result = dec_open(fp, &open_callback);
00995                 if (result == true) {
00996                     /* Executes fid_close_track() in exe_end_proc(). */
00997                     p_info->p_file_handle = fp;
00998                     p_info->open_track_id = p_info->track_id;
00999                     ret = true;
01000                 } else {
01001                     /* The opening of the decoder was failure. */
01002                     fid_close_track(fp);
01003                     p_info->p_file_handle = NULL;
01004                 }
01005             }
01006             if (ret != true) {
01007                 print_play_time(p_info);
01008                 (void) dsp_notify_print_string(PRINT_MSG_OPEN_ERR);
01009                 /* Tries to open the next file. */
01010                 p_info->open_track_id = TRACK_ID_ERR;
01011                 (void) change_next_track(p_info, p_data);
01012             }
01013         }
01014     }
01015     return ret;
01016 }
01017 
01018 /** Executes the starting process of the playback
01019  *
01020  *  @param p_info Pointer to the playback information of the playback file
01021  *  @param p_data Pointer to the control data of folder scan
01022  *
01023  *  @returns 
01024  *    Results of process. true is success. false is failure.
01025  */
01026 static bool exe_play_proc(play_info_t * const p_info, const fid_scan_folder_t * const p_data)
01027 {
01028     bool        ret = false;
01029     bool        result;
01030 
01031     if (p_info != NULL) {
01032         result = dec_play();
01033         if (result == true) {
01034             ret = true;
01035         } else {
01036             /* The starting of the playback was failure. */
01037             print_play_time(p_info);
01038             /* Tries to open the next file. */
01039             p_info->open_track_id = TRACK_ID_ERR;
01040             (void) change_next_track(p_info, p_data);
01041         }
01042     }
01043     return ret;
01044 }
01045 
01046 /** Executes the starting process of the pause
01047  *
01048  *  @returns 
01049  *    Results of process. true is success. false is failure.
01050  */
01051 static bool exe_pause_on_proc(void)
01052 {
01053     bool    ret;
01054 
01055     ret = dec_pause_on();
01056     return ret;
01057 }
01058 
01059 /** Executes the cancel process of the pause
01060  *
01061  *  @returns 
01062  *    Results of process. true is success. false is failure.
01063  */
01064 static bool exe_pause_off_proc(void)
01065 {
01066     bool    ret;
01067 
01068     ret = dec_pause_off();
01069     return ret;
01070 }
01071 
01072 /** Executes the stop process of the playback
01073  *
01074  *  @returns 
01075  *    Results of process. true is success. false is failure.
01076  */
01077 static bool exe_stop_proc(void)
01078 {
01079     bool    ret;
01080 
01081     ret = dec_stop();
01082     return ret;
01083 }
01084 
01085 /** Executes the closing process
01086  *
01087  *  @returns 
01088  *    Results of process. true is success. false is failure.
01089  */
01090 static bool exe_close_proc(void)
01091 {
01092     bool    ret;
01093 
01094     ret = dec_close(&close_callback);
01095     return ret;
01096 }
01097 
01098 /** Executes the end process
01099  *
01100  *  @param p_info Pointer to the playback information of the playback file
01101  */
01102 static void exe_end_proc(play_info_t * const p_info)
01103 {
01104     if (p_info != NULL) {
01105         fid_close_track(p_info->p_file_handle);
01106         p_info->p_file_handle = NULL;
01107         p_info->open_track_id = TRACK_ID_ERR;
01108     }
01109 }
01110 
01111 /** Checks the track change
01112  *
01113  *  @param p_info Pointer to the playback information of the playback file
01114  *
01115  *  @returns 
01116  *    Results of check.
01117  */
01118 static bool is_track_changed(const play_info_t * const p_info)
01119 {
01120     bool        ret = false;
01121 
01122     if (p_info != NULL) {
01123         if (p_info->track_id != p_info->open_track_id) {
01124             ret = true;
01125         }
01126     }
01127     return ret;
01128 }
01129 
01130 /** Changes the repeat mode
01131  *
01132  *  @param p_info Pointer to the playback information of the playback file
01133  */
01134 static void change_repeat_mode(play_info_t * const p_info)
01135 {
01136     if (p_info != NULL) {
01137         if (p_info->repeat_mode == true) {
01138             p_info->repeat_mode = false;
01139         } else {
01140             p_info->repeat_mode = true;
01141         }
01142         (void) dsp_notify_play_mode(p_info->repeat_mode);
01143     }
01144 }
01145 
01146 /** Changes the next track
01147  *
01148  *  @param p_info Pointer to the playback information of the playback file
01149  *  @param p_data Pointer to the control data of folder scan
01150  *
01151  *  @returns 
01152  *    Results of process. true is success. false is failure.
01153  */
01154 static bool change_next_track(play_info_t * const p_info, const fid_scan_folder_t * const p_data)
01155 {
01156     bool        ret = false;
01157     uint32_t    next_trk;
01158     uint32_t    total_trk;
01159 
01160     if ((p_info != NULL) && (p_data != NULL)) {
01161         next_trk = p_info->track_id + 1u;
01162         total_trk = fid_get_total_track(p_data);
01163         if (next_trk < total_trk) {
01164             ret = true;
01165         } else {
01166             next_trk = 0;
01167             if (p_info->repeat_mode == true) {
01168                 ret = true;
01169             }
01170         }
01171         p_info->track_id = next_trk;
01172     }
01173     return ret;
01174 }
01175 
01176 /** Changes the previous track
01177  *
01178  *  @param p_info Pointer to the playback information of the playback file
01179  *  @param p_data Pointer to the control data of folder scan
01180  *
01181  *  @returns 
01182  *    Results of process. true is success. false is failure.
01183  */
01184 static bool change_prev_track(play_info_t * const p_info, const fid_scan_folder_t * const p_data)
01185 {
01186     bool        ret = false;
01187     uint32_t    prev_trk;
01188     uint32_t    total_trk;
01189 
01190     if ((p_info != NULL) && (p_data != NULL)) {
01191         prev_trk = p_info->track_id - 1u;
01192         total_trk = fid_get_total_track(p_data);
01193         if (prev_trk < total_trk) {
01194             ret = true;
01195         } else {
01196             if (p_info->repeat_mode == true) {
01197                 if (total_trk > 0u) {
01198                     ret = true;
01199                     prev_trk = total_trk - 1u;
01200                 } else {
01201                     prev_trk = 0u;
01202                 }
01203             } else {
01204                 prev_trk = 0u;
01205             }
01206         }
01207         p_info->track_id = prev_trk;
01208     }
01209     return ret;
01210 }
01211 /** Prints the playback information of the playback file
01212  *
01213  *  @param p_info Pointer to the playback information of the playback file
01214  */
01215 static void print_play_info(const play_info_t * const p_info)
01216 {
01217     uint32_t        trk_id;
01218 
01219     if (p_info != NULL) {
01220         trk_id = convert_track_id(p_info->track_id);
01221         (void) dsp_notify_play_info(trk_id, p_info->sample_rate, p_info->channel_num);
01222     }
01223 }
01224 
01225 /** Prints the information of the playback time
01226  *
01227  *  @param p_info Pointer to the playback information of the playback file
01228  */
01229 static void print_play_time(const play_info_t * const p_info)
01230 {
01231     uint32_t        trk_id;
01232 
01233     if (p_info != NULL) {
01234         trk_id = convert_track_id(p_info->track_id);
01235         (void) dsp_notify_play_time(p_info->play_stat, trk_id, 
01236                                     p_info->play_time, p_info->total_time);
01237     }
01238 }
01239 
01240 /** Prints the file name of the playback file
01241  *
01242  *  @param p_info Pointer to the playback information of the playback file
01243  *  @param p_data Pointer to the control data of folder scan
01244  */
01245 static void print_file_name(const play_info_t * const p_info, const fid_scan_folder_t * const p_data)
01246 {
01247     const char_t    *p_path;
01248     uint32_t        trk_id;
01249     uint32_t        trk_total;
01250 
01251     if ((p_info != NULL) && (p_data != NULL)) {
01252         trk_id = p_info->track_id;
01253         trk_total = fid_get_total_track(p_data);
01254         if (trk_id < trk_total) {
01255             p_path = fid_get_track_name(p_data, trk_id);
01256             (void) dsp_notify_file_name(p_path);
01257         }
01258     }
01259 }
01260 
01261 /** Prints the command help information
01262  *
01263  */
01264 static void print_help_info(void)
01265 {
01266     (void) dsp_req_help();
01267 }
01268 
01269 /** Converts the track ID of main thread into the track ID of display thread
01270  *
01271  *  @param trk_id Track ID of main thread
01272  *
01273  *  @returns 
01274  *    Track ID of display thread
01275  */
01276 static uint32_t convert_track_id(const uint32_t trk_id)
01277 {
01278     uint32_t        ret = 0u;
01279 
01280     /* Track ID of main thread begins with 0. */
01281     /* Converts the track ID of main thread into the track ID */
01282     /* of the display thread beginning with 1. */
01283     if (trk_id < SYS_MAX_TRACK_NUM) {
01284         ret = trk_id + 1u;
01285     }
01286     return ret;
01287 }
01288 
01289 /** Sends the mail to main thread
01290  *
01291  *  @param mail_id Mail ID
01292  *  @param param0 Parameter 0 of this mail
01293  *  @param param1 Parameter 1 of this mail
01294  *  @param param2 Parameter 2 of this mail
01295  *
01296  *  @returns 
01297  *    Results of process. true is success. false is failure.
01298  */
01299 static bool send_mail(const SYS_MAIL_ID mail_id, const uint32_t param0,
01300                             const uint32_t param1, const uint32_t param2)
01301 {
01302     bool            ret = false;
01303     osStatus        stat;
01304     sys_mail_t      * const p_mail = mail_box.alloc();
01305 
01306     if (p_mail != NULL) {
01307         p_mail->mail_id = mail_id;
01308         p_mail->param[MAIL_PARAM0] = param0;
01309         p_mail->param[MAIL_PARAM1] = param1;
01310         p_mail->param[MAIL_PARAM2] = param2;
01311         stat = mail_box.put(p_mail);
01312         if (stat == osOK) {
01313             ret = true;
01314         } else {
01315             (void) mail_box.free(p_mail);
01316         }
01317     }
01318     return ret;
01319 }
01320 
01321 /** Receives the mail to main thread
01322  *
01323  *  @param p_mail_id Pointer to the variable to store the mail ID
01324  *  @param p_param0 Pointer to the variable to store the parameter 0 of this mail
01325  *  @param p_param1 Pointer to the variable to store the parameter 1 of this mail
01326  *  @param p_param2 Pointer to the variable to store the parameter 2 of this mail
01327  *
01328  *  @returns 
01329  *    Results of process. true is success. false is failure.
01330  */
01331 static bool recv_mail(SYS_MAIL_ID * const p_mail_id, uint32_t * const p_param0, 
01332                         uint32_t * const p_param1, uint32_t * const p_param2)
01333 {
01334     bool            ret = false;
01335     osEvent         evt;
01336     sys_mail_t      *p_mail;
01337 
01338     if ((p_mail_id != NULL) && (p_param0 != NULL) && 
01339         (p_param1 != NULL) && (p_param2 != NULL)) {
01340         evt = mail_box.get(RECV_MAIL_TIMEOUT_MS);
01341         if (evt.status == osEventMail) {
01342             p_mail = (sys_mail_t *)evt.value.p;
01343             if (p_mail != NULL) {
01344                 *p_mail_id = p_mail->mail_id;
01345                 *p_param0 = p_mail->param[MAIL_PARAM0];
01346                 *p_param1 = p_mail->param[MAIL_PARAM1];
01347                 *p_param2 = p_mail->param[MAIL_PARAM2];
01348                 ret = true;
01349             }
01350             (void) mail_box.free(p_mail);
01351         }
01352     }
01353     return ret;
01354 }