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

disp_tft.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 #include "DisplayBace.h"
00028 #include "display.h"
00029 #include "disp_tft.h"
00030 #include "disp_tft_scrn.h"
00031 
00032 /*--- Macro definition of LCD display driver ---*/
00033 #define LCD_INPUT_CLK           (66.67)     /* Input clock: P1 clk [MHz] */
00034 #define LCD_OUTPUT_CLK          (33.26)     /* Output clock: LCD clk [MHz] */
00035 #define LCD_HSYNC_PERIOD        (1056)      /* Free-running Hsync period: 800 + 92 + 128 + 36 */
00036 #define LCD_VSYNC_PERIOD        (525)       /* Free-running Vsync period: 480 + 5 + 35 + 5 */
00037 #define LCD_H_BACK_PORCH        (164)       /* LCD display horizontal back porch period: 128 + 36 */
00038 #define LCD_V_BACK_PORCH        (40)        /* LCD display vertical back porch period: 35 + 5 */
00039 #define LCD_PIN_NUM             (8)
00040 #define LCD_INPUT_FORMAT_SIZE   (4u)
00041 
00042 /* Power ON sequence */
00043 #define BLON_WAIT_TIME_MS       (200)       /* Wait time of milisecond before the backlight ON. */
00044 
00045 /* Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128 */
00046 /* in accordance with the frame buffer burst transfer mode. */
00047 #define BUF_STRIDE              (((DSP_TFT_WIDTH * LCD_INPUT_FORMAT_SIZE) + 31u) & ~31u)
00048 #define BUF_HEIGHT              (DSP_TFT_HEIGHT)
00049 #define BUF_SIZE                (BUF_STRIDE * BUF_HEIGHT)
00050 
00051 #if defined( __CC_ARM )
00052 #define VRAM_SECTION1           __attribute((at(0x60100000)))
00053 #define VRAM_SECTION2           __attribute((at(0x60480000)))
00054 #define VRAM_SECTION3           __attribute((at(0x60600000)))
00055 #define VRAM_SECTION4           __attribute((at(0x60780000)))
00056 #else  /* !defined( __CC_ARM ) */
00057 /* CAUTION! */
00058 /* Modify the start address of "NC_BSS" section in "RZA1H.ld" file. */
00059 #define VRAM_SECTION            __attribute((section("NC_BSS"),aligned(16)))
00060 #define VRAM_SECTION1           VRAM_SECTION
00061 #define VRAM_SECTION2           VRAM_SECTION
00062 #define VRAM_SECTION3           VRAM_SECTION
00063 #define VRAM_SECTION4           VRAM_SECTION
00064 #endif /* defined( __CC_ARM ) */
00065 
00066 #define SHIFT_1BIT_SIZE         (1u)
00067 
00068 static void init_lcd_driver(const dsp_tft_ctrl_t * const p_tft);
00069 static void update_tft_display(dsp_tft_ctrl_t * const p_tft, const uint32_t layer_id);
00070 static void update_tft_audio_data(const dsp_com_ctrl_t * const p_com, dsp_tft_ctrl_t * const p_tft);
00071 static void vsync_callback(DisplayBase::int_type_t int_type);
00072 static DisplayBase::graphics_layer_t convert_layer_id(const uint32_t layer_id);
00073 static void swap_frame_buffer(dsp_tftlayer_t * const p_info);
00074 
00075 static DisplayBase lcd;
00076 
00077 void dsp_init_tft(dsp_tft_ctrl_t * const p_tft)
00078 {
00079     static uint32_t VRAM_SECTION1   frame_buffer_1[BUF_SIZE/sizeof(uint32_t)];
00080     static uint32_t VRAM_SECTION2   frame_buffer_2[BUF_SIZE/sizeof(uint32_t)];
00081     static uint32_t VRAM_SECTION3   frame_buffer_3[BUF_SIZE/sizeof(uint32_t)];
00082     static uint32_t VRAM_SECTION4   frame_buffer_4[BUF_SIZE/sizeof(uint32_t)];
00083     uint32_t                        i;
00084 
00085     if (p_tft != NULL) {
00086         p_tft->key_code = SYS_KEYCODE_NON;
00087         (void) memset(frame_buffer_1, 0, sizeof(frame_buffer_1));
00088         (void) memset(frame_buffer_2, 0, sizeof(frame_buffer_2));
00089         (void) memset(frame_buffer_3, 0, sizeof(frame_buffer_3));
00090         (void) memset(frame_buffer_4, 0, sizeof(frame_buffer_4));
00091         p_tft->tft_info[DSP_TFT_LAYER_0].p_disp_buf = &frame_buffer_1[0];
00092         p_tft->tft_info[DSP_TFT_LAYER_0].p_back_buf = &frame_buffer_2[0];
00093         p_tft->tft_info[DSP_TFT_LAYER_1].p_disp_buf = &frame_buffer_3[0];
00094         p_tft->tft_info[DSP_TFT_LAYER_1].p_back_buf = &frame_buffer_4[0];
00095         for (i = 0u; i < DSP_TFT_LAYER_NUM; i++) {
00096             p_tft->tft_info[i].width  = DSP_TFT_WIDTH;
00097             p_tft->tft_info[i].height = DSP_TFT_HEIGHT;
00098             p_tft->tft_info[i].stride = BUF_STRIDE;
00099         }
00100         init_lcd_driver(p_tft);
00101         dsp_init_tft_scrn(p_tft);
00102     }
00103 }
00104 
00105 void dsp_output_tft(const DSP_MAIL_ID mail_id, 
00106                     const dsp_com_ctrl_t * const p_com, dsp_tft_ctrl_t * const p_tft)
00107 {
00108     uint32_t                        result = DSP_TFT_LAYER_NON;
00109 
00110     if ((p_com != NULL) && (p_tft != NULL)) {
00111         switch (mail_id) {
00112             case DSP_MAILID_CYCLE_IND :
00113                 /* Executes main function of the playback screen. */
00114                 result = dsp_make_tft_scrn(p_com, p_tft);
00115                 break;
00116             case DSP_MAILID_PLAY_TIME :
00117             case DSP_MAILID_PLAY_INFO :
00118             case DSP_MAILID_PLAY_STAT :
00119                 if (p_com->edge_track_change == true) {
00120                     dsp_clear_tft_audio_data(p_tft);
00121                 }
00122                 result = DSP_TFT_LAYER_NON;
00123                 break;
00124             case DSP_MAILID_AUDIO_FIN:
00125                 update_tft_audio_data(p_com, p_tft);
00126                 result = DSP_TFT_LAYER_NON;
00127                 break;
00128             case DSP_MAILID_CMD_STR :
00129             case DSP_MAILID_PRINT_STR :
00130             case DSP_MAILID_FILE_NAME :
00131             default :
00132                 result = DSP_TFT_LAYER_NON;
00133                 break;
00134         }
00135         if (result < DSP_TFT_LAYER_NUM) {
00136             /* Updates the TFT display. */
00137             update_tft_display(p_tft, result);
00138         }
00139     }
00140 }
00141 
00142 SYS_KeyCode dsp_convert_key_tft(const uint32_t disp_mode, const uint32_t pos_x, const uint32_t pos_y)
00143 {
00144     SYS_KeyCode     ret;
00145 
00146     switch (disp_mode) {
00147         case DSP_DISPMODE_1:
00148         case DSP_DISPMODE_2:
00149         case DSP_DISPMODE_3:
00150             ret = dsp_convert_key_tft_scrn(pos_x, pos_y);
00151             break;
00152         default:
00153             ret = SYS_KEYCODE_NON;
00154             break;
00155     }
00156     return ret;
00157 }
00158 
00159 void dsp_clear_tft_audio_data(dsp_tft_ctrl_t * const p_tft)
00160 {
00161     dsp_audio_t     *p_aud;
00162 
00163     if (p_tft != NULL) {
00164         p_aud = &p_tft->audio_data;
00165         p_aud->m2_buf_cnt = 0u;
00166         (void) memset(&p_aud->m2_buf[0], 0u, sizeof(p_aud->m2_buf));
00167         p_aud->m3_buf_cnt = 0u;
00168         (void) memset(&p_aud->m3_buf[0], 0u, sizeof(p_aud->m3_buf));
00169         p_aud->m3_sample_cnt = 0u;
00170         p_aud->m3_target_cnt = 0u;
00171         p_aud->m3_pause_flag = false;
00172     }
00173 }
00174 
00175 /** Initializes LCD driver using DisplayBase class.
00176  *
00177  *  @param p_tft Pointer to management data of TFT module.
00178  */
00179 static void init_lcd_driver(const dsp_tft_ctrl_t * const p_tft)
00180 {
00181     DisplayBase::graphics_error_t   grap_err;
00182     DisplayBase::rect_t             rect;
00183     DisplayBase::lcd_config_t       lcd_config = {
00184         DisplayBase::LCD_TYPE_LVDS,         /* LVDS or Pararel RGB */
00185         LCD_INPUT_CLK,                      /* P1  clk [MHz] */
00186         LCD_OUTPUT_CLK,                     /* LCD clk [MHz] */
00187 
00188         DisplayBase::LCD_OUTFORMAT_RGB888,  /* Output format select */
00189         DisplayBase::EDGE_RISING,           /* Output phase control of LCD_DATA23 to LCD_DATA0 pin */
00190 
00191         LCD_HSYNC_PERIOD,                   /* Free-running Hsync period */
00192         LCD_VSYNC_PERIOD,                   /* Free-running Vsync period */
00193         (uint16_t)DSP_TFT_WIDTH,            /* LCD display area size, horizontal width */
00194         (uint16_t)DSP_TFT_HEIGHT,           /* LCD display area size, vertical width */
00195         LCD_H_BACK_PORCH,                   /* LCD display horizontal back porch period */
00196         LCD_V_BACK_PORCH,                   /* LCD display vertical back porch period */
00197 
00198         DisplayBase::LCD_TCON_PIN_NON,      /* TCONn or Not use(-1) */
00199         DisplayBase::SIG_POL_NOT_INVERTED,  /* Polarity inversion control of signal */
00200         0,                                  /* Hsync width */
00201 
00202         DisplayBase::LCD_TCON_PIN_NON,      /* TCONn or Not use(-1) */
00203         DisplayBase::SIG_POL_NOT_INVERTED,  /* Polarity inversion control of signal */
00204         0,                                  /* Vsync width  */
00205 
00206         DisplayBase::LCD_TCON_PIN_3,        /* TCONn or Not use(-1) */
00207         DisplayBase::SIG_POL_NOT_INVERTED   /* Polarity inversion control of signal */
00208     };
00209     PinName                         lvds_pin[LCD_PIN_NUM] = {
00210         P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0  /* Data pin */
00211     };
00212     static DigitalOut               lcd_pwon(P7_15);
00213     static DigitalOut               lcd_blon(P8_1);
00214     static PwmOut                   lcd_cntrst(P8_15);
00215     uint32_t                        i;
00216     DisplayBase::graphics_layer_t   layer_id;
00217 
00218     if (p_tft != NULL) {
00219         lcd_pwon.write(1);                  /* LCD panel power ON. */
00220         /* Graphics initialization process */
00221         grap_err = lcd.Graphics_init(&lcd_config);
00222         if (grap_err == DisplayBase::GRAPHICS_OK) {
00223             /* Interrupt callback function setting (Vsync signal output from scaler 0) */
00224             grap_err = lcd.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_LO_VSYNC, 0, &vsync_callback);
00225             if (grap_err == DisplayBase::GRAPHICS_OK) {
00226                 lcd.Graphics_Lvds_Port_Init(lvds_pin, LCD_PIN_NUM);
00227                 rect.vs = 0;
00228                 rect.vw = (uint16_t)DSP_TFT_HEIGHT;
00229                 rect.hs = 0;
00230                 rect.hw = (uint16_t)DSP_TFT_WIDTH;
00231                 for (i = 0u; i < DSP_TFT_LAYER_NUM; i++) {
00232                     layer_id = convert_layer_id(i);
00233                     lcd.Graphics_Read_Setting(layer_id, (void *)p_tft->tft_info[i].p_disp_buf, 
00234                                             BUF_STRIDE, DisplayBase::GRAPHICS_FORMAT_ARGB8888, 
00235                                             DisplayBase::WR_RD_WRSWA_32BIT, &rect);
00236                     lcd.Graphics_Start(layer_id);
00237                 }
00238 
00239                 Thread::wait(BLON_WAIT_TIME_MS);
00240                 lcd_blon.write(1);          /* LCD panel backlight ON. */
00241                 lcd_cntrst.write(1.0);
00242             }
00243         }
00244     }
00245 }
00246 
00247 /** Interrupt callback function for Vsync interruption.
00248  *
00249  *  @param int_type The number of VDC5 interrupt types
00250  */
00251 static void vsync_callback(DisplayBase::int_type_t int_type)
00252 {
00253     UNUSED_ARG(int_type);
00254     (void) dsp_notify_cycle_time();
00255 }
00256 
00257 /** Updates the display of the specified layer.
00258  *
00259  *  @param p_tft Pointer to management data of TFT module.
00260  *  @param layer_id The number of the display layer of TFT module.
00261  */
00262 static void update_tft_display(dsp_tft_ctrl_t * const p_tft, const uint32_t layer_id)
00263 {
00264     DisplayBase::graphics_layer_t   result;
00265     DisplayBase::graphics_error_t   grap_err;
00266 
00267     if ((p_tft != NULL) && (layer_id < DSP_TFT_LAYER_NUM)) {
00268         result = convert_layer_id(layer_id);
00269         grap_err = lcd.Graphics_Read_Change(result, p_tft->tft_info[layer_id].p_back_buf);
00270         if (grap_err == DisplayBase::GRAPHICS_OK) {
00271             swap_frame_buffer(&p_tft->tft_info[layer_id]);
00272         }
00273     }
00274 }
00275 
00276 /** Updates the audio data.
00277  *
00278  *  @param p_com Pointer to common data in all display module.
00279  *  @param p_tft Pointer to management data of TFT module.
00280  */
00281 static void update_tft_audio_data(const dsp_com_ctrl_t * const p_com, dsp_tft_ctrl_t * const p_tft)
00282 {
00283     dsp_audio_t     *p_aud;
00284     uint32_t        i;
00285     uint32_t        buf_id;
00286     int32_t         total_val;
00287     bool            update_flag;
00288     int16_t         new_data[DSP_TFT_M3_AUDIO_SAMPLE_PER_100MS];
00289     uint32_t        valid_data;
00290 
00291     if ((p_com != NULL) && (p_tft != NULL)) {
00292         p_aud = &p_tft->audio_data;
00293         /* Stores the display data using the display mode 2. */
00294         (void) memcpy(&p_aud->m2_buf[0], &p_aud->req_buf[0], sizeof(p_aud->m2_buf));
00295         p_aud->m2_buf_cnt = sizeof(p_aud->m2_buf)/sizeof(p_aud->m2_buf[0]);
00296         /* Stores the display data using the display mode 3. */
00297         buf_id = 0u;
00298         valid_data = 0u;
00299         for (i = 0u; i < DSP_TFT_M3_AUDIO_SAMPLE_PER_100MS; i++) {
00300             /* Calculates the average of 2 channels. */
00301             total_val = p_aud->req_buf[buf_id] + p_aud->req_buf[buf_id + 1u];
00302             new_data[i] = (int16_t)((uint32_t)total_val >> SHIFT_1BIT_SIZE);
00303             buf_id += (DSP_TFT_M2_AUDIO_BUF_SIZE / DSP_TFT_M3_AUDIO_SAMPLE_PER_100MS);
00304             /* Checks the zero data */
00305             valid_data |= (uint32_t)new_data[i];
00306         }
00307         update_flag = false;
00308         if (p_com->play_stat == SYS_PLAYSTAT_PAUSE) {
00309             p_aud->m3_pause_flag = true;
00310             if (valid_data == 0u) {
00311                 /* Current sampling data are not used. */
00312             } else {
00313                 update_flag = true;
00314             }
00315         } else if (p_com->play_stat == SYS_PLAYSTAT_PLAY) {
00316             if ((p_aud->m3_pause_flag == true) && 
00317                 (p_aud->m3_sample_cnt > (p_aud->m3_target_cnt + DSP_TFT_M3_AUDIO_SAMPLE_PER_100MS))) {
00318                 /* Current sampling data are not used. */
00319             } else if ((p_aud->m3_pause_flag == true) && (valid_data == 0u)) {
00320                 /* Current sampling data are not used. */
00321                 p_aud->m3_pause_flag = false;
00322             } else {
00323                 update_flag = true;
00324                 p_aud->m3_pause_flag = false;
00325             }
00326         } else {
00327             p_aud->m3_pause_flag = false;
00328         }
00329         if (update_flag == true) {
00330             if (p_aud->m3_buf_cnt >= DSP_TFT_M3_AUDIO_BUF_SIZE) {
00331                 p_aud->m3_buf_cnt = DSP_TFT_M3_AUDIO_BUF_SIZE - DSP_TFT_M3_AUDIO_SAMPLE_PER_100MS;
00332                 for (i = 0u; i < p_aud->m3_buf_cnt; i++) {
00333                     p_aud->m3_buf[i] = p_aud->m3_buf[i + DSP_TFT_M3_AUDIO_SAMPLE_PER_100MS];
00334                 }
00335             }
00336             for (i = 0u; i < DSP_TFT_M3_AUDIO_SAMPLE_PER_100MS; i++) {
00337                 p_aud->m3_buf[p_aud->m3_buf_cnt] = new_data[i];
00338                 p_aud->m3_buf_cnt++;
00339             }
00340             p_aud->m3_sample_cnt += DSP_TFT_M3_AUDIO_SAMPLE_PER_100MS;
00341             p_aud->m3_target_cnt += DSP_TFT_M3_AUDIO_SAMPLE_PER_100MS;
00342         }
00343     }
00344 }
00345 
00346 /** Converts the layer number of TFT module into the layer number of DisplayBase class.
00347  *
00348  *  @param layer_id The number of the display layer of TFT module.
00349  *
00350  *  @returns 
00351  *    Returns the layer number of DisplayBase class.
00352  */
00353 static DisplayBase::graphics_layer_t convert_layer_id(const uint32_t layer_id)
00354 {
00355     DisplayBase::graphics_layer_t   ret;
00356 
00357     switch (layer_id) {
00358         case DSP_TFT_LAYER_1:
00359             ret = DisplayBase::GRAPHICS_LAYER_1;
00360             break;
00361         case DSP_TFT_LAYER_0:
00362         default:
00363             ret = DisplayBase::GRAPHICS_LAYER_0;
00364             break;
00365     }
00366     return ret;
00367 }
00368 
00369 /** Swaps the frame buffers
00370  *
00371  *  @param p_info Pointer to VRAM structure
00372  */
00373 static void swap_frame_buffer(dsp_tftlayer_t * const p_info)
00374 {
00375     uint32_t                        *p_tmp;
00376     
00377     if (p_info != NULL) {
00378         p_tmp = p_info->p_disp_buf;
00379         p_info->p_disp_buf = p_info->p_back_buf;
00380         p_info->p_back_buf = p_tmp;
00381     }
00382 }