GR-MANGO sample using mbed-os library from my repository.
Diff: sample_programs/sample_17_usb_func_msd_2.cpp
- Revision:
- 0:b4c1e32627f2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sample_programs/sample_17_usb_func_msd_2.cpp Mon Oct 12 02:25:49 2020 +0000
@@ -0,0 +1,305 @@
+/*******************************************************************************
+* DISCLAIMER
+* This software is supplied by Renesas Electronics Corporation and is only
+* intended for use with Renesas products. No other uses are authorized. This
+* software is owned by Renesas Electronics Corporation and is protected under
+* all applicable laws, including copyright laws.
+* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
+* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
+* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
+* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
+* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
+* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
+* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
+* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+* Renesas reserves the right, without notice, to make changes to this software
+* and to discontinue the availability of this software. By using this software,
+* you agree to the additional terms and conditions found by accessing the
+* following link:
+* http://www.renesas.com/disclaimer
+*
+* Copyright (C) 2019 Renesas Electronics Corporation. All rights reserved.
+*******************************************************************************/
+#include "sample_select.h"
+
+#if (SAMPLE_PROGRAM_NO == 17)
+// SAMPLE_PROGRAM_NO 17 : USBMSD and FlashAPI sample advanced version
+//
+// USBMSD and FlashAPI sample advanced version
+// It is a sample program that can read and write serial flash from the PC via Filesystem.
+// By connecting the board and the PC with a USB cable, you can refer inside the device as a mass storage device.
+// (The format is required when connecting for the first time.)
+// When you write a JPEG file (.jpg) from the PC to the storage, the image is displayed.
+// By pressing SW3, change the save destination to heap memory.
+// [Attention!] Delete the "OVERRIDE_CONSOLE_USBSERIAL" macro in "mbed_app.json" file if it is set.
+
+#include "mbed.h"
+#include "USBMSD.h"
+#include "ObservingBlockDevice.h"
+#include "FlashIAPBlockDevice.h"
+#include "mbed_drv_cfg.h"
+#include "HeapBlockDevice.h"
+#include "dcache-control.h"
+#include "EasyAttach_CameraAndLCD.h"
+#include "FATFileSystem.h"
+#include "JPEG_Converter.h"
+
+#define FILE_NAME_LEN (64)
+#define FRAME_BUFFER_STRIDE (((LCD_PIXEL_WIDTH * 2) + 31u) & ~31u)
+#define FRAME_BUFFER_HEIGHT (LCD_PIXEL_HEIGHT)
+
+static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((aligned(32)));
+static uint8_t JpegBuffer[1024 * 128]__attribute((aligned(32)));
+DisplayBase Display;
+
+typedef enum {
+ BD_FLASHIAP,
+ BD_HEAP,
+ BD_NUM
+} bd_type_t;
+
+static FlashIAPBlockDevice flashiap_bd(FLASH_BASE + 0x100000, FLASH_SIZE - 0x100000);
+static HeapBlockDevice heap_bd(0x100000);
+
+static BlockDevice * base_bd[BD_NUM] = {
+ &flashiap_bd, // BD_FLASHIAP
+ &heap_bd // BD_HEAP
+};
+
+static const char * base_bd_str[BD_NUM] = {
+ "FlashIAP", // BD_FLASHIAP
+ "Heap" // BD_HEAP
+};
+
+static InterruptIn storage_btn(USER_BUTTON0);
+static int tmp_bd_index = 0;
+static int bd_index = -1;
+static bool storage_change_flg = false;
+static Timer storage_change_timer;
+static FATFileSystem * p_fs = NULL;
+static ObservingBlockDevice * p_observing_bd = NULL;
+static USBMSD * p_usb = NULL;
+static Thread msdTask(osPriorityAboveNormal);
+static Semaphore usb_sem(0);
+static bool heap_bd_format = false;
+static bool image_disp = false;
+
+// Function prototypes
+static void msd_task(void);
+static void storage_change(BlockDevice * p_bd);
+static void chk_storage_change(void);
+static void chk_bd_change(void);
+static void storage_btn_fall(void);
+static void clear_display(void);
+static void Start_LCD_Display(void);
+
+static void usb_callback_func(void) {
+ usb_sem.release();
+}
+
+static void msd_task(void) {
+ while (true) {
+ usb_sem.acquire();
+ if (p_usb != NULL) {
+ p_usb->process();
+ }
+ }
+}
+
+static void storage_change(BlockDevice * p_bd) {
+ storage_change_flg = true;
+ storage_change_timer.reset();
+ storage_change_timer.start();
+ if (image_disp) {
+ clear_display();
+ image_disp = false;
+ }
+}
+
+static void chk_storage_change(void) {
+ if (!storage_change_flg) {
+ return;
+ }
+
+ // wait storage change
+ while (storage_change_timer.read_ms() < 1000) {
+ ThisThread::sleep_for(100);
+ }
+ storage_change_timer.stop();
+ storage_change_timer.reset();
+ storage_change_flg = false;
+
+ p_fs->unmount();
+ chk_bd_change();
+ p_fs->mount(base_bd[bd_index]);
+}
+
+static void chk_bd_change(void) {
+ if (bd_index == tmp_bd_index) {
+ return;
+ }
+ if (p_usb != NULL) {
+ USBMSD * wk = p_usb;
+ p_usb = NULL;
+ delete wk;
+ }
+ if (p_observing_bd != NULL) {
+ delete p_observing_bd;
+ }
+ if (p_fs != NULL) {
+ delete p_fs;
+ }
+ bd_index = tmp_bd_index;
+ printf("\r\nconnecting %s\r\n", base_bd_str[bd_index]);
+ if (bd_index == BD_HEAP) {
+ if (!heap_bd_format) {
+ FATFileSystem::format(&heap_bd);
+ heap_bd_format = true;
+ }
+ }
+ p_fs = new FATFileSystem(base_bd_str[bd_index]);
+ p_observing_bd = new ObservingBlockDevice(base_bd[bd_index]);
+ p_observing_bd->attach(&storage_change);
+ p_usb = new USBMSD(p_observing_bd);
+ p_usb->attach(&usb_callback_func);
+}
+
+static void storage_btn_fall(void) {
+ if ((tmp_bd_index + 1) < BD_NUM) {
+ tmp_bd_index++;
+ } else {
+ tmp_bd_index = 0;
+ }
+ storage_change(NULL);
+}
+
+static void clear_display(void) {
+ // Initialize the background to black
+ for (uint32_t i = 0; i < sizeof(user_frame_buffer0); i += 2) {
+ user_frame_buffer0[i + 0] = 0x00;
+ user_frame_buffer0[i + 1] = 0x80;
+ }
+ dcache_clean(user_frame_buffer0, sizeof(user_frame_buffer0));
+}
+
+static void Start_LCD_Display(void) {
+ DisplayBase::rect_t rect;
+
+ rect.vs = 0;
+ rect.vw = LCD_PIXEL_HEIGHT;
+ rect.hs = 0;
+ rect.hw = LCD_PIXEL_WIDTH;
+ Display.Graphics_Read_Setting(
+ DisplayBase::GRAPHICS_LAYER_0,
+ (void *)user_frame_buffer0,
+ FRAME_BUFFER_STRIDE,
+ DisplayBase::GRAPHICS_FORMAT_YCBCR422,
+ DisplayBase::WR_RD_WRSWA_32_16BIT,
+ &rect
+ );
+ Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0);
+
+ ThisThread::sleep_for(50);
+ EasyAttach_LcdBacklight(true);
+}
+
+int main() {
+ FILE * fp;
+ DIR * d;
+ struct dirent * p;
+ char file_path[10 + FILE_NAME_LEN];
+ int file_num;
+ JPEG_Converter Jcu;
+ long file_size;
+
+ clear_display();
+ EasyAttach_Init(Display);
+ Start_LCD_Display();
+
+ // Start usb task
+ msdTask.start(&msd_task);
+
+ // Set BlockDevice
+ chk_bd_change();
+ p_fs->mount(base_bd[bd_index]);
+
+ // Button setting
+ storage_btn.fall(&storage_btn_fall);
+
+ while (true) {
+ // Confirm storage change
+ chk_storage_change();
+
+ // File search
+ file_num = 0;
+ sprintf(file_path, "/%s/", base_bd_str[bd_index]);
+ d = opendir(file_path);
+ if (d != NULL) {
+ while ((p = readdir(d)) != NULL) {
+ size_t len = strlen(p->d_name);
+ if (len < FILE_NAME_LEN) {
+ // Make file path
+ sprintf(file_path, "/%s/%s", base_bd_str[bd_index], p->d_name);
+ printf("%s\r\n", file_path);
+
+ char *extension = strstr(file_path, ".");
+ if ((extension != NULL) && (memcmp(extension, ".jpg", 4) == 0)) {
+ fp = fopen(file_path, "rb");
+ if (fp != NULL) {
+ fseek(fp, 0, SEEK_END);
+ file_size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ if (file_size <= (long)sizeof(JpegBuffer)) {
+ JPEG_Converter::bitmap_buff_info_t bitmap_buff_info;
+ JPEG_Converter::decode_options_t decode_options;
+
+ bitmap_buff_info.width = LCD_PIXEL_WIDTH;
+ bitmap_buff_info.height = LCD_PIXEL_HEIGHT;
+ bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422;
+ bitmap_buff_info.buffer_address = (void *)user_frame_buffer0;
+
+ decode_options.output_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT;
+
+ setvbuf(fp, NULL, _IONBF, 0); // unbuffered
+ fread(JpegBuffer, sizeof(char), file_size, fp);
+ dcache_clean(JpegBuffer, file_size);
+
+ if (Jcu.decode((void *)JpegBuffer, &bitmap_buff_info, &decode_options) == JPEG_Converter::JPEG_CONV_OK) {
+ image_disp = true;
+ file_num++;
+ } else {
+ printf("Decode error.\r\n");
+ }
+ } else {
+ printf("File size over.\r\n");
+ }
+ fclose(fp);
+
+ for (int i = 0; (i < 50) && (storage_change_flg == false); i++) {
+ ThisThread::sleep_for(100);
+ }
+ } else {
+ printf("File open error.\r\n");
+ }
+ }
+ }
+ if (storage_change_flg) {
+ clear_display();
+ break;
+ }
+ }
+ closedir(d);
+ }
+
+ // If there is no files, wait until the storage is changed
+ if ((file_num == 0) && (!storage_change_flg)) {
+ printf("No files\r\n");
+ while (!storage_change_flg) {
+ ThisThread::sleep_for(100);
+ }
+ }
+ }
+}
+
+#endif