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
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 }
Generated on Tue Jul 12 2022 19:32:28 by 1.7.2