cherry-embedded / CherryUSB

CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP
https://cherryusb.cherry-embedded.org
Apache License 2.0
1.32k stars 284 forks source link

EHCI timeouts on BL616 as host #128

Closed harbaum closed 1 year ago

harbaum commented 1 year ago

I do see many timeouts when using the USB host on a BL616. This can be "fixed" by adding a delay to EHCI usbh_submit_urb() like so:

    if (urb->timeout > 0) {
        usb_osal_msleep(1);      // <--- add a delay of 1ms
        /* wait until timeout or sem give */
        ret = usb_osal_sem_take(pipe->waitsem, urb->timeout);
        if (ret < 0) {
            goto errout_timeout;
        }
        ret = urb->errorcode;
    }

This makes the setup stable and e.g. running FATFS on top of MSC just works fine. But I am sure this delay is not a good solution and this will sure have a massive negative impact on performance.

I am seeing this on the current master, integrated into the latest bouffalo SDK.

Example usbhost with fatfs enabled. Without this delay:

  ____               __  __      _       _       _     
 |  _ \             / _|/ _|    | |     | |     | |    
 | |_) | ___  _   _| |_| |_ __ _| | ___ | | __ _| |__  
 |  _ < / _ \| | | |  _|  _/ _` | |/ _ \| |/ _` | '_ \ 
 | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
 |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/ 

Build:19:15:52,Aug 12 2023
Copyright (c) 2022 Bouffalolab team
======== flash cfg ========
flash size 0x00400000
jedec id     0xC86016
mid              0xC8
iomode           0x04
clk delay        0x01
clk invert       0x01
read reg cmd0    0x05
read reg cmd1    0x35
write reg cmd0   0x01
write reg cmd1   0x01
qe write len     0x02
cread support    0x01
cread code       0x20
burst wrap cmd   0x77
===========================
dynamic memory init success, ocram heap size = 173 Kbyte 
sig1:ffffffff
sig2:0000f32f
cgen1:9f7ffffd
Starting usb host task...
starting scheduler
do not find /dev/ttyACM0
do not fi[I/USB] EHCI HCIVERSION:0100
[I/USB] EHCI HCSPARAMS:000001
[I/USB] EHCI HCCPARAMS:0006
t0 not finnd /dev/inpud /dev/sda

[I/USB] New high-speed device on Hub 1, Port 1 connected
[I/USB] New device found,idVendor:054c,idProduct:0243,bcdDevice:0100
[I/USB] The device has 1 interfaces
[I/USB] Enumeration success, start loading class driver
[I/USB] Loading msc class driver
[I/USB] Get max LUN:1
[I/USB] Ep=81 Attr=02 Mps=512 Interval=255 Mult=00
[I/USB] Ep=02 Attr=02 Mps=512 Interval=255 Mult=00
[I/USB] Capacity info:
[I/USB] Block num:7831552,block size:512
[I/USB] Register MSC Class:/dev/sda
do not find /dev/ttyACM0
do not find /dev/input0
do not find /dev/ttyACM0
data len:25
[I/USB] MSC_disk_read(0x22fc93c0,0,1)
[I/USB] MSC_disk_read(0x22fc93c0,62,1)
[I/USB] MSC_disk_read(0x22fc93c0,63,1)
test fatfs write
[I/USB] MSC_disk_read(0x22fc93c0,16446,1)
[I/USB] MSC_disk_read(0x22fc93c0,16447,1)
[I/USB] MSC_disk_read(0x22fc93c0,16448,1)
[I/USB] MSC_disk_write(0x22fc93c0,16448,1)
[I/USB] MSC_disk_read(0x22fc93c0,5496,1)
[I/USB] MSC_disk_write(0x22fc9a00,4423918,4)
write success, write len:2500
[I/USB] MSC_disk_write(0x22fc9600,4423922,1)
[I/USB] MSC_disk_write(0x22fc93c0,5496,1)
[I/USB] MSC_disk_write(0x22fc93c0,13123,1)
[I/USB] MSC_disk_read(0x22fc93c0,16448,1)
[I/USB] MSC_disk_write(0x22fc93c0,16448,1)
[I/USB] MSC_disk_write(0x22fc93c0,63,1)
[I/USB] MSC_disk_ioctl(0,(nil))
test fatfs read
[I/USB] MSC_disk_read(0x22fc93c0,16446,1)
[I/USB] MSC_disk_read(0x22fc93c0,16447,1)
[I/USB] MSC_disk_read(0x22fc93c0,16448,1)
[I/USB] MSC_disk_read(0x22fc9a00,4423918,4)
[I/USB] MSC_disk_read(0x22fc9600,4423922,1)
do not find /dev/ttyACM0
do not find /dev/input0
do not find /dev/ttyACM0
do not find /dev/input0
do not find /dev/ttyACM0
do not find /dev/ttyACM0
do not find /dev/input0
do not find /dev/ttyACM0
[E/USB] usbh_msc_bulk_in_transfer()=-116
[E/USB] msc data transfer error
read fail

With the delay:

  ____               __  __      _       _       _     
 |  _ \             / _|/ _|    | |     | |     | |    
 | |_) | ___  _   _| |_| |_ __ _| | ___ | | __ _| |__  
 |  _ < / _ \| | | |  _|  _/ _` | |/ _ \| |/ _` | '_ \ 
 | |_) | (_) | |_| | | | || (_| | | (_) | | (_| | |_) |
 |____/ \___/ \__,_|_| |_| \__,_|_|\___/|_|\__,_|_.__/ 

Build:19:15:52,Aug 12 2023
Copyright (c) 2022 Bouffalolab team
======== flash cfg ========
flash size 0x00400000
jedec id     0xC86016
mid              0xC8
iomode           0x04
clk delay        0x01
clk invert       0x01
read reg cmd0    0x05
read reg cmd1    0x35
write reg cmd0   0x01
write reg cmd1   0x01
qe write len     0x02
cread support    0x01
cread code       0x20
burst wrap cmd   0x77
===========================
dynamic memory init success, ocram heap size = 173 Kbyte 
sig1:ffffffff
sig2:0000f32f
cgen1:9f7ffffd
Starting usb host task...
starting scheduler
do not find /dev/ttyACM0
do not fi[I/USB] EHCI HCIVERSION:0100
[I/USB] EHCI HCSPARAMS:000001
[I/USB] EHCI HCCPARAMS:0006
t0 not finnd /dev/inpud /dev/sda

[I/USB] New high-speed device on Hub 1, Port 1 connected
[I/USB] New device found,idVendor:054c,idProduct:0243,bcdDevice:0100
[I/USB] The device has 1 interfaces
[I/USB] Enumeration success, start loading class driver
[I/USB] Loading msc class driver
[I/USB] Get max LUN:1
[I/USB] Ep=81 Attr=02 Mps=512 Interval=255 Mult=00
[I/USB] Ep=02 Attr=02 Mps=512 Interval=255 Mult=00
[I/USB] Capacity info:
[I/USB] Block num:7831552,block size:512
[I/USB] Register MSC Class:/dev/sda
do not find /dev/ttyACM0
do not find /dev/input0
do not find /dev/ttyACM0
data len:25
[I/USB] MSC_disk_read(0x22fc93c0,0,1)
[I/USB] MSC_disk_read(0x22fc93c0,62,1)
[I/USB] MSC_disk_read(0x22fc93c0,63,1)
test fatfs write
[I/USB] MSC_disk_read(0x22fc93c0,16446,1)
[I/USB] MSC_disk_read(0x22fc93c0,16447,1)
[I/USB] MSC_disk_read(0x22fc93c0,16448,1)
[I/USB] MSC_disk_write(0x22fc93c0,16448,1)
[I/USB] MSC_disk_read(0x22fc93c0,5496,1)
[I/USB] MSC_disk_write(0x22fc93c0,5496,1)
[I/USB] MSC_disk_write(0x22fc93c0,13123,1)
[I/USB] MSC_disk_read(0x22fc93c0,16448,1)
[I/USB] MSC_disk_read(0x22fc93c0,5496,1)
[I/USB] MSC_disk_write(0x22fc9a00,4423918,4)
write success, write len:2500
[I/USB] MSC_disk_write(0x22fc9600,4423922,1)
[I/USB] MSC_disk_write(0x22fc93c0,5496,1)
[I/USB] MSC_disk_write(0x22fc93c0,13123,1)
[I/USB] MSC_disk_read(0x22fc93c0,16448,1)
[I/USB] MSC_disk_write(0x22fc93c0,16448,1)
[I/USB] MSC_disk_write(0x22fc93c0,63,1)
[I/USB] MSC_disk_ioctl(0,(nil))
test fatfs read
[I/USB] MSC_disk_read(0x22fc93c0,16446,1)
[I/USB] MSC_disk_read(0x22fc93c0,16447,1)
[I/USB] MSC_disk_read(0x22fc93c0,16448,1)
[I/USB] MSC_disk_read(0x22fc9a00,4423918,4)
[I/USB] MSC_disk_read(0x22fc9600,4423922,1)
read success, read len:2500
sakumisu commented 1 year ago

Many echi cpu works fine, check it by yourself

harbaum commented 1 year ago

I am not sure I understand you correctly.

So the BL616 EHCI host is not supported and problems like this will not be addressed? And you suggest to use a different MCU or to fix any issues myself, correct?

Which MCU would you suggest to use with cherryUSB in host mode?

sakumisu commented 1 year ago

No problem in BL616, and others like d1s/hpm6750 and so on with ehci.Just check by yourself.

harbaum commented 1 year ago

I am checking this myself. This report is a result of tests with real hardware. I use a BL616 in host mode with various USB devices as I am going to decide if we build a device based on that chip

Most USB host tests are unstable. Some very basic tests work. That's how I did the joystick demo: https://m.youtube.com/shorts/Z1DRsI0xd8o

But hubs, mass storage and even some joysticks run into timeouts.

I am checking real hardware and would like to understand if the BL616 is supported in a way that we can base a project on it.

So what do you mean by "check it yourself" other than using the BL616 to do tests with real USB devices?

sakumisu commented 1 year ago

I do not want to waste my time on these unofficial board, no one knows if the board usb is ok, so solve by yourself.

harbaum commented 1 year ago

I do not want to waste my time on these unofficial board, no one knows if the board usb is ok, so solve by yourself.

Ah ... now we are getting somewhere. This is some internal conflict between Bouffalo and SiPeed. Interesting. So only Bouffalo's own dev kit is supported? This would mean that we cannot use the BL616 for our own designs, since there won't be any support then?

BTW: The delay actually doesn't hurt as much as expected. I copied your SD card test over to the USB demo and get these results with my delay in place:

[I/USB] EHCI HCIVERSION:0100
[I/USB] EHCI HCSPARAMS:000001
[I/USB] EHCI HCCPARAMS:0006
[I/USB] New high-speed device on Hub 1, Port 1 connected
[I/USB] New device found,idVendor:054c,idProduct:0243,bcdDevice:0100
[I/USB] The device has 1 interfaces
[I/USB] Enumeration success, start loading class driver
[I/USB] Loading msc class driver
[I/USB] Get max LUN:1
[I/USB] Ep=81 Attr=02 Mps=512 Interval=255 Mult=00
[I/USB] Ep=02 Attr=02 Mps=512 Interval=255 Mult=00
[I/USB] Capacity info:
[I/USB] Block num:7831552,block size:512
[I/USB] Register MSC Class:/dev/sda
[I/USB] ******************** be about to write test... **********************
[I/USB] Write Test Succeed! 
[I/USB] Single data size:32768 Byte, Write the number:1024, Total size:32768 KB
[I/USB] Time:9846ms, Write Speed:3328 KB/s 
[I/USB] ******************** be about to read test... **********************
[I/USB] Read Test Succeed! 
[I/USB] Single data size:32768Byte, Read the number:1024, Total size:32768 KB
[I/USB] Time:4289ms, Read Speed:7640 KB/s 
[I/USB] ******************** be about to check test... **********************
[I/USB] Check Test Succeed! 
[I/USB] All Data Is Good! 

3.3MBytes/s writing and 7.6 MBytes/s reading doesn't sound too bad for some cheap little microcontroller.

harbaum commented 1 year ago

BTW: What is the official board for the BL616? I see someone testing a BL616DK at https://codingfield.com/blog/2023-01/getting-started-with-bl618dk/, but that seems to be in fact a BL618 and I don't see where this can be purchased nor are there any schematics, so I cannot compare the USB implementation of the official board with the unofficial one from SiPeed.

Furthermore, I doubt that this is a hardware issue, as this tiny delay makes everything work way more reliable. Without delay, the system won't barely see the flash drive at all. With delay, it reads and writes 32 MBytes without any trouble.

sakumisu commented 1 year ago

You can design sch and pcb by yourself, m0s dock is designed only for debugger.

harbaum commented 1 year ago

I don't understand that. What kind of debugger?

sakumisu commented 1 year ago

cklink, daplink, usb2uart

harbaum commented 1 year ago

You can flash the M0S dock without any debugger and just flash it via USB as I explain e.g. at https://github.com/harbaum/Pacman-TangNano9k/tree/main/m0sdock_usb_joystick

Would you consider the Ai-M62-12F a valid device and accept feedback for it? Full specs.

I really like to test the stuff before designing a new device.

sakumisu commented 1 year ago

I mean that M0s is only a usb device, its function is a debugger or a usb2uart, thanks, please stop for this issue.

harbaum commented 1 year ago

I'll stop now. Just to make this clear: There is no BL616 based board that I could use and get cherryusb support for, right? If there is one, then please tell me. The BL616 seems to have much potential and it seems to be one of the few cheap chips that can do high speed USB. But without support this chip is of course way less useful.

sakumisu commented 1 year ago

Hi, i have updated ehci driver just now, you can have a tryand copy them to sdk to see if it works or not. PS: if you want to use usb host, recommand you to use ai-thinker board.

harbaum commented 1 year ago

Thanks a lot. I recently received the ai thinker boards and will give the updated version a try asap ...

harbaum commented 1 year ago

I just tested on the M0S and now USB host isn't working at all, anymore. No events are reported. And adding my old delay also doesn't help.

I tried a) using the entire latest cherryusb from github master and b) using only the latest ehci from github master. This makes no difference. Neither works.

I'll try again on Monday using the AI Thinker board instead of the M0S.

Thanks for your support!

If there's anything I can help in debugging, please say so.

sakumisu commented 1 year ago

I think it is your incorrect copying....

sakumisu commented 1 year ago

please do not modify usb_config in bouffalo sdk, it is not a standard ehci. Only copy files in ehci directory, all of our ehci chips like hpm,nuc,d1 are all ok.

sakumisu commented 1 year ago

Ok, i know what is wrong, please modify CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE in usb_config.h, in bouffalo_sdk it is CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE, it is a spelling error.

sakumisu commented 1 year ago

If you have other problems, you can contact my twitter, maybe solve problems more quickly.

harbaum commented 1 year ago

Ok, i know what is wrong, please modify CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE in usb_config.h, in bouffalo_sdk it is CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE, it is a spelling error.

Ah! Yes, now it works without my delay patch. Great. The simple demos from the SDK now work.

I have ported the more complex fatfs test from the SD card demo to the USB host demo. I do see sporadic write errors in the big file there. The SD card has a very similar problem but when reading (writing seems to work fine with SD card). See https://github.com/bouffalolab/bouffalo_sdk/issues/170

Since the errors are very similar (chunks 32 bytes get lost during reading from SD card and during writing to USB stick) I think this is not an issue with USB, but with the BL616 in general. So I won't bother you with that.

If you have other problems, you can contact my twitter, maybe solve problems more quickly

I don't have a twitter account. Do you use discord?

sakumisu commented 1 year ago

Sorry, i do not have and join for some reason. Maybe only in github, could you give my repo a star and push some issues here, i feel sorry for only this way.

harbaum commented 1 year ago

No problem. I gave this repo a star.

This is the code for the updated usb_host.c demo from the bouffalo SDK which will do extensive USB file testing and finally fail. I can open an issue for this (is this what you mean by "push some issues"?).

But as I said, I see the same problem with the SD card, so I don't think it's a USB specific issue. It is either a problem with the SDK in general or with the BL616 itself.

#include "usbh_core.h"
#include "usbh_msc.h"

#include "ff.h"
#include "diskio.h"

USB_NOCACHE_RAM_SECTION FATFS fs;
USB_NOCACHE_RAM_SECTION FIL fnew;
UINT fnum;
FRESULT res_msc = 0;

int MSC_disk_status() { return 0; }
int MSC_disk_initialize() { return 0; }
int MSC_disk_read(BYTE *buff, LBA_t sector, UINT count) {
  struct usbh_msc *msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
  // USB_LOG_INFO("MSC_disk_read(%p,%d,%d)\r\n", buff, sector, count);  
  return usbh_msc_scsi_read10(msc_class, sector, buff, count);
}

int MSC_disk_write(const BYTE *buff, LBA_t sector, UINT count) {
  struct usbh_msc *msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
  // USB_LOG_INFO("MSC_disk_write(%p,%d,%d)\r\n", buff, sector, count);  
  return usbh_msc_scsi_write10(msc_class, sector, buff, count);
}

int MSC_disk_ioctl(BYTE cmd, void *buff) {
  USB_LOG_INFO("MSC_disk_ioctl(%d,%p)\r\n", cmd, buff);

    switch (cmd) {
        // Get R/W sector size (WORD)
        case GET_SECTOR_SIZE:
            break;

        // Get erase block size in unit of sector (DWORD)
        case GET_BLOCK_SIZE:
            break;

        case GET_SECTOR_COUNT:
            break;

        case CTRL_SYNC:
            break;

        default:
            break;
    }

    return 0;
}

DSTATUS Translate_Result_Code(int result)
{
    return result;
}

#define SDU_DATA_CHECK 1

char test_data[512] =
    "I've been reading books of old \r\n\
    The legends and the myths \r\n\
    Achilles and his gold \r\n\
    Hercules and his gifts \r\n\
    Spiderman's control \r\n\
    And Batman with his fists \r\n\
    And clearly I don't see myself upon that list\r\n\
    But she said, where'd you wanna go?\r\n\
    How much you wanna risk?\r\n\
    I'm not looking for somebody\r\n\
    With some superhuman gifts\r\n\
    Some superhero\r\n\
    Some fairytale bliss\r\n\
    Just something I can turn to\r\n\
    Somebody I can kiss\r\n\
    I want something just like this\r\n\r\n";

BYTE RW_Buffer[32 * 1024] = { 0 };
#if SDU_DATA_CHECK
BYTE Check_Buffer[sizeof(RW_Buffer)] = { 0 };
#endif

static void hexdump(const unsigned char *buf, int len) {
  static const char hexdigits[] = "0123456789abcdef";
  char str[68];
  int i;

  if (!len) return;

  for (i = 0; i < len; i++) {
    str[((i % 16) * 3) + 0] = hexdigits[buf[i] >> 4];
    str[((i % 16) * 3) + 1] = hexdigits[buf[i] & 0xf];
    str[((i % 16) * 3) + 2] = ' ';
    str[(i % 16) + 49] = isprint(buf[i]) ? buf[i] : '.';

    if ((i + 1) % 16 == 0) {
      str[47] = ' ';
      str[48] = ' ';
      str[65] = '\0';
      printf("%08x%-2c%s\r\n", i-15, ' ', str);
      str[0] = ' ';
    }
  }
}

int usb_msc_fatfs_test()
{
    uint32_t time_node, i, j;
    FRESULT ret;

    FATFS_DiskioDriverTypeDef MSC_DiskioDriver = { NULL };
    MSC_DiskioDriver.disk_status = MSC_disk_status;
    MSC_DiskioDriver.disk_initialize = MSC_disk_initialize;
    MSC_DiskioDriver.disk_write = MSC_disk_write;
    MSC_DiskioDriver.disk_read = MSC_disk_read;
    MSC_DiskioDriver.disk_ioctl = MSC_disk_ioctl;
    MSC_DiskioDriver.error_code_parsing = Translate_Result_Code;

    disk_driver_callback_init(DEV_USB, &MSC_DiskioDriver);

    res_msc = f_mount(&fs, "/usb", 1);
    if (res_msc != FR_OK) {
        USB_LOG_RAW("mount fail,res:%d\r\n", res_msc);
        return -1;
    }

    /* full test data to buff */
    for (uint32_t size = 0; size < sizeof(RW_Buffer); size += sizeof(test_data)) {
        memcpy(&RW_Buffer[size], test_data, sizeof(test_data));
#if SDU_DATA_CHECK
        memcpy(&Check_Buffer[size], test_data, sizeof(test_data));
#endif
    }

#if 1
    /* write test */
    USB_LOG_INFO("\r\n");
    USB_LOG_INFO("******************** be about to write test... **********************\r\n");
    ret = f_open(&fnew, "/usb/test_file_2.txt", FA_CREATE_ALWAYS | FA_WRITE);
    if (ret == FR_OK) {
        time_node = (uint32_t)bflb_mtimer_get_time_ms();
        /*write into file*/
        // ret = f_write(&fnew, RW_Buffer, 1024, &fnum);
        for (i = 0; i < 1024; i++) {
      ret = f_write(&fnew, RW_Buffer, sizeof(RW_Buffer), &fnum);
      if (ret) {
        break;
      }
        }

        /* close file */
        ret |= f_close(&fnew);
        /* get time */
        time_node = (uint32_t)bflb_mtimer_get_time_ms() - time_node;

        if (ret == FR_OK) {
            USB_LOG_INFO("Write Test Succeed! \r\n");
            USB_LOG_INFO("Single data size:%d Byte, Write the number:%d, Total size:%d KB\r\n", sizeof(RW_Buffer), i, sizeof(RW_Buffer) * i >> 10);
            USB_LOG_INFO("Time:%dms, Write Speed:%d KB/s \r\n", time_node, ((sizeof(RW_Buffer) * i) >> 10) * 1000 / time_node);
        } else {
            USB_LOG_ERR("Fail to write files(%d) num:%d\n", ret, i);
        goto unmount;
        }
    } else {
        USB_LOG_ERR("Fail to open or create files: %d.\r\n", ret);
    goto unmount;
    }
#endif

#if 1
    /* read test */
    USB_LOG_INFO("\r\n");
    USB_LOG_INFO("******************** be about to read test... **********************\r\n");
    ret = f_open(&fnew, "/usb/test_file.txt", FA_OPEN_EXISTING | FA_READ);
    if (ret == FR_OK) {
        time_node = (uint32_t)bflb_mtimer_get_time_ms();

        // ret = f_read(&fnew, RW_Buffer, 1024, &fnum);
        for (i = 0; i < 1024; i++) {
            ret = f_read(&fnew, RW_Buffer, sizeof(RW_Buffer), &fnum);
            if (ret) {
                break;
            }
        }
        /* close file */
        ret |= f_close(&fnew);
        /* get time */
        time_node = (uint32_t)bflb_mtimer_get_time_ms() - time_node;

        if (ret == FR_OK) {
            USB_LOG_INFO("Read Test Succeed! \r\n");
            USB_LOG_INFO("Single data size:%dByte, Read the number:%d, Total size:%d KB\r\n", sizeof(RW_Buffer), i, sizeof(RW_Buffer) * i >> 10);
            USB_LOG_INFO("Time:%dms, Read Speed:%d KB/s \r\n", time_node, ((sizeof(RW_Buffer) * i) >> 10) * 1000 / time_node);
        } else {
            USB_LOG_ERR("Fail to read file: (%d), num:%d\n", ret, i);
        goto unmount;
        }
    } else {
        USB_LOG_ERR("Fail to open files.\r\n");
    goto unmount;
    }
#endif

    /* check data */
#if SDU_DATA_CHECK
    USB_LOG_INFO("\r\n");
    USB_LOG_INFO("******************** be about to check test... **********************\r\n");
    ret = f_open(&fnew, "/usb/test_file_2.txt", FA_OPEN_EXISTING | FA_READ);
    if (ret == FR_OK) {
        for (i = 0; i < 1024; i++) {
        memset(RW_Buffer, 0x55, sizeof(RW_Buffer));
        ret = f_read(&fnew, RW_Buffer, sizeof(RW_Buffer), &fnum);
        if (ret) break;
            for (j = 0; j < sizeof(RW_Buffer); j++) {
                if (RW_Buffer[j] != Check_Buffer[j]) {
                    break;
                }
            }
            if (j < sizeof(RW_Buffer)) {
                break;
            }
        }
        /* close file */
        ret |= f_close(&fnew);

        if (ret == FR_OK) {
            if (i < 1024 || j < sizeof(RW_Buffer)) {
                USB_LOG_INFO("Check Test Error! \r\n");
                USB_LOG_INFO("Data Error!  Num:%d/1024, Byte:%d($%04x)/%d\r\n", i, j, j, sizeof(RW_Buffer));

        hexdump(RW_Buffer, 32768);
        // hexdump(Check_Buffer, 32768);
        } else {
                USB_LOG_INFO("Check Test Succeed! \r\n");
                USB_LOG_INFO("All Data Is Good! \r\n");
            }

        } else {
            USB_LOG_ERR("Fail to read file: (%d), num:%d\n", ret, i);
        goto unmount;
        }
    } else {
        USB_LOG_ERR("Fail to open files.\r\n");
    goto unmount;
    }
#endif

    f_mount(NULL, "/usb", 1);
    return 0;
unmount:
    f_mount(NULL, "/usb", 1);
    return -1;
}

static void usbh_msc_thread(void *argument)
{
    int ret;
    struct usbh_msc *msc_class;

    while (1) {
        // clang-format off
find_class:
        // clang-format on
        msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
        if (msc_class == NULL) {
            USB_LOG_RAW("do not find /dev/sda\r\n");
            usb_osal_msleep(2000);
            continue;
        }

        usb_msc_fatfs_test();

        while (1) {
            msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
            if (msc_class == NULL) {
                goto find_class;
            }
            usb_osal_msleep(2000);
        }
    }
}

void usbh_msc_run(struct usbh_msc *msc_class) { }

void usbh_msc_stop(struct usbh_msc *msc_class) { }

void usbh_class_test(void) {
  usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, NULL);
}
sakumisu commented 1 year ago

I think it is cache problem, and you should set USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX before RW_Buffer, at least usb host need. You can refer to my demo, it is a limitation.

USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX RW_Buffer[32*1024];

sakumisu commented 1 year ago

And i must say, all of buffer for usb, must be in nocache ram section, thanks.

USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_write_buffer[25 * 100];

USB_NOCACHE_RAM_SECTION FATFS fs;
USB_NOCACHE_RAM_SECTION FIL fnew;
sakumisu commented 1 year ago

And MSC_disk_ioctl must be implemented for GET_SECTOR_SIZE , GET_SECTOR_SIZE and GET_SECTOR_COUNT.

harbaum commented 1 year ago

Using a small no-cache transfer buffer makes the MSC demo work with full filesystem support and ends in a successful 32MB read/write test.

Thanks a lot!

harbaum commented 1 year ago

Using

bflb_l1c_dcache_clean_range((void *)(RW_Buffer), sizeof(RW_Buffer)); and

bflb_l1c_dcache_invalidate_range((void *)(RW_Buffer), sizeof(RW_Buffer));

works even better and has much less impact on the performance.

sakumisu commented 1 year ago

Right, with cache, you must do these. But many users do not know cache, this is why exists nocache ram.

harbaum commented 1 year ago

How long is a cache line on the BL616? Sometimes you align to 32 bytes (e.g. in the USB) and sometimes to 64 bytes (e.g. in SDH).

sakumisu commented 1 year ago

How long is a cache line on the BL616? Sometimes you align to 32 bytes (e.g. in the USB) and sometimes to 64 bytes (e.g. in SDH).

Cache line 32, so set 32 or 64 is ok, just you like.