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 key.cpp Source File

key.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 "misratypes.h"
00027 
00028 #include "key.h"
00029 #include "key_cmd.h"
00030 #include "system.h"
00031 #include "display.h"
00032 #include "disp_tft.h"
00033 
00034 /*--- Macro definition of mbed-rtos mail ---*/
00035 #define MAIL_QUEUE_SIZE     (3)     /* Queue size */
00036 #define MAIL_PARAM_NUM      (1)     /* Elements number of mail parameter array */
00037 
00038 /* key_mail_t */
00039 #define MAIL_PARAM0         (0)     /* Index number of mail parameter array */
00040 
00041 /* mail_id = KEY_MAILID_DISP_MODE */
00042 #define MAIL_DISPMODE_MODE  (MAIL_PARAM0)   /* Display mode */
00043 
00044 #define RECV_MAIL_TIMEOUT_MS (0u)
00045 
00046 /*--- Macro definition of key thread ---*/
00047 #define PROC_CYCLE_SW       (10u)   /* The process cycle of SW module */
00048 #define PROC_CYCLE_TFT      (50u)   /* The process cycle of TFT module */
00049 #define PROC_CYCLE_CMD      (20u)   /* The process cycle of command-line module */
00050 #define PROC_CYCLE_REFRESH  (50u)   /* Refresh cycle of counter */
00051 #define UNIT_TIME_MS        (2u)
00052 
00053 #define PROC_CNT_SW         (PROC_CYCLE_SW / UNIT_TIME_MS)      /* Counter for 10ms period */
00054 #define PROC_CNT_TFT        (PROC_CYCLE_TFT / UNIT_TIME_MS)     /* Counter for 50ms period */
00055 #define PROC_CNT_CMD        (PROC_CYCLE_CMD / UNIT_TIME_MS)     /* Counter for 2ms period */
00056 #define PROC_CNT_REFRESH    (PROC_CYCLE_REFRESH / UNIT_TIME_MS) /* Counter for 50ms period */
00057 
00058 /*--- Macro definition of SW module ---*/
00059 #define SW0_ACTIVE_LEVEL    (0)
00060 #define SW0_DECISION_TIME   (50u)   /* Time until the decision of the input status. */
00061 #define SW0_DECISION_CNT    (SW0_DECISION_TIME / PROC_CYCLE_SW) /* Counter for 50ms period */
00062 
00063 /*--- Macro definition of Touch panel module ---*/
00064 #define TP_IIC_DEV_ADR      (0x55 << 1) /* I2C device address */
00065 #define TP_REG_ADR_NUM      (6u)        /* The number of the reading of the register. */
00066 
00067 /* Register address */
00068 #define TP_REG_ADR_FINGER   (0u)        /* Number of touch points[3:0] */
00069 #define TP_REG_ADR_STATUS   (2u)        /* 1st Touch valid / 1st Touch X Position[11:8] / 1st Touch Y Position[11:8] */
00070 #define TP_REG_ADR_TOUCH_XL (3u)        /* 1st Touch X Position[7:0] */
00071 #define TP_REG_ADR_TOUCH_YL (4u)        /* 1st Touch Y Position[7:0] */
00072 
00073 /* Mask for the register */
00074 #define TP_MASK_FINGER      (0x0Fu)     /* Used in the finger register */
00075 #define TP_MASK_TOUCH_YH    (0x07u)     /* Used in the status register for Y Position */
00076 #define TP_MASK_TOUCH_XH    (0x70u)     /* Used in the status register for X Position */
00077 #define TP_MASK_VALID       (0x80u)     /* Used in the status register for valid */
00078 
00079 #define TP_SHIFT_TOUCH_YH   (8u)        /* Used in combination with the upper and lower bits of the Y position */
00080 #define TP_SHIFT_TOUCH_XH   (4u)        /* Used in combination with the upper and lower bits of the X position */
00081 
00082 #define TP_TOUCH_MAX_NUM    (1u)
00083 #define TP_DEFAULT_POS      (0u)
00084 
00085 #define TP_RELEASE_NUM      (0u)
00086 #define TP_PRESS_NUM        (1u)
00087 
00088 #define TP_MAX_WIDHT        (DSP_TFT_WIDTH - 1u)
00089 #define TP_MAX_HEIGHT       (DSP_TFT_HEIGHT - 1u)
00090 
00091 /*--- User defined types of mbed-rtos mail ---*/
00092 typedef enum {
00093     KEY_MAILID_DUMMY = 0,
00094     KEY_MAILID_DISP_MODE,           /* Change display mode */
00095     KEY_MAILID_NUM
00096 } KEY_MAIL_ID;
00097 
00098 typedef struct {
00099     KEY_MAIL_ID     mail_id;
00100     uint32_t        param[MAIL_PARAM_NUM];
00101 } key_mail_t;
00102 
00103 /*--- User defined types ---*/
00104 /* Control data of SW module */
00105 typedef struct {
00106     uint32_t        sampling_count; /* Sampling count for decision of input. */
00107     bool            current_status; /* Current input status. true=push, false=release. */
00108 } sw_ctrl_t;
00109 
00110 /* Control data of TFT module */
00111 typedef struct {
00112     uint32_t        disp_mode;
00113     SYS_KeyCode     prev_key_event;
00114     uint32_t        prev_key_num;
00115 } tft_ctrl_t;
00116 
00117 /* Control data of key thread */
00118 typedef struct {
00119     sw_ctrl_t       sw_data;
00120     tft_ctrl_t      tft_data;
00121     cmd_ctrl_t      cmd_data;
00122 } key_ctrl_t;
00123 
00124 static Mail<key_mail_t, MAIL_QUEUE_SIZE> mail_box;
00125 
00126 static void sw_init_proc(sw_ctrl_t * const p_ctrl);
00127 static SYS_KeyCode sw_main_proc(sw_ctrl_t * const p_ctrl);
00128 static void tft_init_proc(tft_ctrl_t * const p_ctrl);
00129 static SYS_KeyCode tft_main_proc(tft_ctrl_t * const p_ctrl);
00130 static bool tft_get_key_code(const uint32_t disp_mode, SYS_KeyCode * const p_key_ev, uint32_t * const p_key_num);
00131 static bool send_mail(const KEY_MAIL_ID mail_id, const uint32_t param0);
00132 static bool recv_mail(KEY_MAIL_ID * const p_mail_id, uint32_t * const p_param0);
00133 
00134 void key_thread(void const *argument)
00135 {
00136     static key_ctrl_t   key_data;
00137     SYS_KeyCode         key_ev;
00138     SYS_KeyCode         tmp_ev;
00139     uint32_t            cnt = 0u;
00140     KEY_MAIL_ID         mail_type;
00141     uint32_t            mail_param[MAIL_PARAM_NUM];
00142     bool                result;
00143 
00144     UNUSED_ARG(argument);
00145     
00146     /* Initializes the control data of key thread. */
00147     sw_init_proc(&key_data.sw_data);
00148     tft_init_proc(&key_data.tft_data);
00149     cmd_init_proc(&key_data.cmd_data);
00150     while(1) {
00151         key_ev = SYS_KEYCODE_NON;
00152         result = recv_mail(&mail_type, &mail_param[MAIL_PARAM0]);
00153         if (result == true) {
00154             if (mail_type == KEY_MAILID_DISP_MODE) {
00155                 /* Changes display mode. */
00156                 key_data.tft_data.disp_mode = mail_param[MAIL_DISPMODE_MODE];
00157             }
00158         }
00159 
00160         /* Is it a timing of the SW module processing? */
00161         if((cnt % PROC_CNT_SW) == 0u) {
00162             /* Executes main process of SW module. */
00163             tmp_ev = sw_main_proc(&key_data.sw_data);
00164             if(tmp_ev != SYS_KEYCODE_NON) {
00165                 key_ev = tmp_ev;
00166             }
00167         }
00168         /* Is it a timing of TFT module processing? */
00169         if((cnt % PROC_CNT_TFT) == 0u) {
00170             /* Executes main process of TFT module. */
00171             tmp_ev = tft_main_proc(&key_data.tft_data);
00172             if(tmp_ev != SYS_KEYCODE_NON) {
00173                 if(key_ev == SYS_KEYCODE_NON) {
00174                     /* There is no input from other modules. */
00175                     key_ev = tmp_ev;
00176                 }
00177             }
00178         }
00179         /* Is it a timing of command-line module processing? */
00180         if((cnt % PROC_CNT_CMD) == 0u) {
00181             /* Executes main process of command-line module. */
00182             tmp_ev = cmd_main_proc(&key_data.cmd_data);
00183             if(tmp_ev != SYS_KEYCODE_NON) {
00184                 if(key_ev == SYS_KEYCODE_NON) {
00185                     /* There is no input from other modules. */
00186                     key_ev = tmp_ev;
00187                 }
00188             }
00189         }
00190         /* Is it a refresh timing of the counter? */
00191         if(cnt >= PROC_CNT_REFRESH) {
00192             cnt = 0u;
00193         }
00194         /* When the event occurs, this mail is sent to main thread. */
00195         if(key_ev != SYS_KEYCODE_NON) {
00196             (void) sys_notify_key_input(key_ev);
00197         }
00198         Thread::wait(UNIT_TIME_MS);
00199         cnt++;
00200     }
00201 }
00202 
00203 bool key_notify_disp_mode(const uint32_t disp_mode)
00204 {
00205     bool ret = false;
00206 
00207     ret = send_mail(KEY_MAILID_DISP_MODE, disp_mode);
00208 
00209     return ret;
00210 }
00211 
00212 /** Initialises SW module
00213  *
00214  *  @param p_ctrl Pointer to the control data of SW module.
00215  */
00216 static void sw_init_proc(sw_ctrl_t * const p_ctrl)
00217 {
00218     if (p_ctrl != NULL) {
00219         p_ctrl->sampling_count = 0u;
00220         p_ctrl->current_status = false;
00221     }
00222 }
00223 
00224 /** Executes the main processing of SW module
00225  *
00226  *  @param p_ctrl Pointer to the control data of SW module.
00227  *
00228  *  @returns 
00229  *    Key code.
00230  */
00231 static SYS_KeyCode sw_main_proc(sw_ctrl_t * const p_ctrl)
00232 {
00233     SYS_KeyCode         key_ev = SYS_KEYCODE_NON;
00234     int32_t             pin_level;
00235     static DigitalIn    sw0(P6_0);
00236 
00237     if (p_ctrl != NULL) {
00238         pin_level = sw0.read();
00239         if (pin_level == SW0_ACTIVE_LEVEL) {
00240             /* SW0 is pushed. */
00241             if (p_ctrl->sampling_count < SW0_DECISION_CNT) {
00242                 p_ctrl->sampling_count++;
00243                 if (p_ctrl->sampling_count == SW0_DECISION_CNT) {
00244                     key_ev = SYS_KEYCODE_PLAYPAUSE;
00245                 }
00246             }
00247             p_ctrl->current_status = true;
00248         } else {
00249             /* SW0 is released. */
00250             p_ctrl->sampling_count = 0u;
00251             p_ctrl->current_status = false;
00252         }
00253     }
00254     return key_ev;
00255 }
00256 
00257 /** Initialises TFT module
00258  *
00259  *  @param p_ctrl Pointer to the control data of TFT module.
00260  */
00261 static void tft_init_proc(tft_ctrl_t * const p_ctrl)
00262 {
00263     if (p_ctrl != NULL) {
00264         /* Initialization of the TFT key variables. */
00265         /* Initializes it to a status pushing down an invalid key. */
00266         /* This is to detect the edge of pushing down a key after having released all keys. */
00267         p_ctrl->disp_mode      = 0u;
00268         p_ctrl->prev_key_event = SYS_KEYCODE_NON;
00269         p_ctrl->prev_key_num   = TP_PRESS_NUM;
00270     }
00271 }
00272 
00273 /** Executes the main processing of TFT module
00274  *
00275  *  @param p_ctrl Pointer to the control data of TFT module.
00276  *
00277  *  @returns 
00278  *    Key code.
00279  */
00280 static SYS_KeyCode tft_main_proc(tft_ctrl_t * const p_ctrl)
00281 {
00282     SYS_KeyCode     key_ev = SYS_KEYCODE_NON;
00283     SYS_KeyCode     cur_key_ev;
00284     uint32_t        cur_key_num;
00285     bool            result;
00286 
00287     if (p_ctrl != NULL) {
00288         result = tft_get_key_code(p_ctrl->disp_mode, &cur_key_ev, &cur_key_num);
00289         if (result == true) {
00290             if ((p_ctrl->prev_key_num == cur_key_num) &&
00291                 (p_ctrl->prev_key_event == cur_key_ev)) {
00292                 /* The touch position on the touch panel did not change. */
00293             } else {
00294                 /* The touch position on the touch panel changed. */
00295                 if ((p_ctrl->prev_key_num == TP_RELEASE_NUM) && (cur_key_num == TP_PRESS_NUM)) {
00296                     /* Press check */
00297                     if (cur_key_ev != SYS_KEYCODE_NON) {
00298                         key_ev = cur_key_ev;
00299                         /* Notify the touched TFT key information. */
00300                         (void) dsp_notify_tft_key(key_ev);
00301                     }
00302                     p_ctrl->prev_key_event = cur_key_ev;
00303                 } else {
00304                     /* Release check */
00305                     key_ev = SYS_KEYCODE_NON;
00306                     if (p_ctrl->prev_key_event != SYS_KEYCODE_NON) {
00307                         /* Notify the touched TFT key information. */
00308                         (void) dsp_notify_tft_key(key_ev);
00309                     }
00310                     p_ctrl->prev_key_event = SYS_KEYCODE_NON;
00311                 }
00312             }
00313             p_ctrl->prev_key_num   = cur_key_num;
00314         } else {
00315             p_ctrl->prev_key_event = SYS_KEYCODE_NON;
00316             p_ctrl->prev_key_num   = 0u;
00317         }
00318     }
00319     return key_ev;
00320 }
00321 
00322 /** Gets the key code of the touch panel via IIC communication.
00323  *
00324  *  @param disp_mode Display mode
00325  *  @param p_key_ev Pointer to variable to store the event code of the detected key
00326  *  @param p_key_num Pointer to variable to store the number of the detected key
00327  *
00328  *  @returns 
00329  *    Returns true if the API is successful. Returns false if the API fails.
00330  */
00331 static bool tft_get_key_code(const uint32_t disp_mode, SYS_KeyCode * const p_key_ev, uint32_t * const p_key_num)
00332 {
00333     bool        ret = false;
00334     SYS_KeyCode touch_ev;
00335     uint32_t    touch_num;
00336     uint32_t    valid;
00337     uint32_t    data_h;
00338     uint32_t    data_l;
00339     uint32_t    pos_x;
00340     uint32_t    pos_y;
00341     int32_t     i2c_err;
00342     char_t      tp_buf[TP_REG_ADR_NUM];
00343     static I2C  tft_i2c(I2C_SDA, I2C_SCL);
00344     
00345     if ((p_key_ev != NULL) && (p_key_num != NULL)) {
00346         i2c_err = tft_i2c.read(TP_IIC_DEV_ADR, tp_buf, sizeof(tp_buf));
00347         if (i2c_err == 0) {
00348             /* Touch num check */
00349             touch_num = (uint32_t) tp_buf[TP_REG_ADR_FINGER] & TP_MASK_FINGER;
00350             if (touch_num == TP_TOUCH_MAX_NUM) {
00351                 /* Valid check */
00352                 valid = (uint32_t) tp_buf[TP_REG_ADR_STATUS] & TP_MASK_VALID;
00353                 if (valid == TP_MASK_VALID) {
00354                     /* X position */
00355                     data_h = (uint32_t) tp_buf[TP_REG_ADR_STATUS] & TP_MASK_TOUCH_XH;
00356                     data_l = (uint32_t) tp_buf[TP_REG_ADR_TOUCH_XL];
00357                     pos_x  = (data_h << TP_SHIFT_TOUCH_XH) | data_l;
00358                     /* Converts the touch position into TFT display position. */
00359                     if (pos_x > TP_MAX_WIDHT) {
00360                         pos_x = TP_DEFAULT_POS;
00361                     }
00362 
00363                     /* Y position */
00364                     data_h = (uint32_t) tp_buf[TP_REG_ADR_STATUS] & TP_MASK_TOUCH_YH;
00365                     data_l = (uint32_t) tp_buf[TP_REG_ADR_TOUCH_YL];
00366                     pos_y  = (data_h << TP_SHIFT_TOUCH_YH) | data_l;
00367                     /* Converts the touch position into TFT display position. */
00368                     if (pos_y > TP_MAX_HEIGHT) {
00369                         pos_y = TP_DEFAULT_POS;
00370                     }
00371 
00372                     /* Converts TFT display position into the key code. */
00373                     touch_ev = dsp_convert_key(disp_mode, pos_x, pos_y);
00374                 } else {
00375                     touch_ev = SYS_KEYCODE_NON;
00376                 }
00377             } else {
00378                 touch_ev = SYS_KEYCODE_NON;
00379             }
00380             ret = true;
00381             *p_key_ev  = touch_ev;
00382             *p_key_num = touch_num;
00383         }
00384     }
00385 
00386     return ret;
00387 }
00388 
00389 /** Sends the mail to key thread
00390  *
00391  *  @param mail_id Mail ID
00392  *  @param param0 Parameter 0 of this mail
00393  *
00394  *  @returns 
00395  *    Results of process. true is success. false is failure.
00396  */
00397 static bool send_mail(const KEY_MAIL_ID mail_id, const uint32_t param0)
00398 {
00399     bool            ret = false;
00400     osStatus        stat;
00401     key_mail_t      * const p_mail = mail_box.alloc();
00402 
00403     if (p_mail != NULL) {
00404         p_mail->mail_id = mail_id;
00405         p_mail->param[MAIL_PARAM0] = param0;
00406         stat = mail_box.put(p_mail);
00407         if (stat == osOK) {
00408             ret = true;
00409         } else {
00410             (void) mail_box.free(p_mail);
00411         }
00412     }
00413     return ret;
00414 }
00415 
00416 /** Receives the mail to key thread
00417  *
00418  *  @param p_mail_id Pointer to the variable to store the mail ID
00419  *  @param p_param0 Pointer to the variable to store the parameter 0 of this mail
00420  *
00421  *  @returns 
00422  *    Results of process. true is success. false is failure.
00423  */
00424 static bool recv_mail(KEY_MAIL_ID * const p_mail_id, uint32_t * const p_param0)
00425 {
00426     bool            ret = false;
00427     osEvent         evt;
00428     key_mail_t      *p_mail;
00429 
00430     if ((p_mail_id != NULL) && (p_param0 != NULL)) {
00431         evt = mail_box.get(RECV_MAIL_TIMEOUT_MS);
00432         if (evt.status == osEventMail) {
00433             p_mail = (key_mail_t *)evt.value.p;
00434             if (p_mail != NULL) {
00435                 *p_mail_id = p_mail->mail_id;
00436                 *p_param0 = p_mail->param[MAIL_PARAM0];
00437                 ret = true;
00438             }
00439             (void) mail_box.free(p_mail);
00440         }
00441     }
00442     return ret;
00443 }