abcminiuser / lufa

LUFA - the Lightweight USB Framework for AVRs.
http://www.lufa-lib.org
1.03k stars 321 forks source link

Mass storage device m16u2, issues with larger size file #176

Closed audiobird closed 9 months ago

audiobird commented 3 years ago

I'm using the atmega16u2 as a mass storage device to simply pass through data to a second processor running a bootloader.

Here is my WriteBlocks function below

void DataflashManager_WriteBlocks(USB_ClassInfo_MS_Device_t *const MSInterfaceInfo,
                                  const uint32_t BlockAddress, uint16_t TotalBlocks) {
    uint8_t buf[MASS_STORAGE_IO_EPSIZE];
    uint8_t isUF2 = 0;
    uint8_t i;
    uint8_t temp_byte_out;
    uint8_t temp_byte_in;

    /* Wait until endpoint is ready before continuing */
    if (Endpoint_WaitUntilReady())
        return;

    while (TotalBlocks) {

        for (uint8_t bufno = 0; bufno < 512 / MASS_STORAGE_IO_EPSIZE; ++bufno) {

            /* Check if the endpoint is currently empty */
            if (!(Endpoint_IsReadWriteAllowed())) {
                /* Clear the current endpoint bank */
                Endpoint_ClearOUT();

                /* Wait until the host has sent another packet */
                if (Endpoint_WaitUntilReady())
                    return;
            }

            for (i = 0; i < MASS_STORAGE_IO_EPSIZE; ++i)
            {
                buf[i] = Endpoint_Read_8();
            }

            /* Check if the current command is being aborted by the host */
            if (MSInterfaceInfo->State.IsMassStoreReset)
                return;

            /* we should make sure the data is uf2 */
            if (bufno == 0) {
                isUF2 = 1;
                for (i = 0; i < 4; ++i) {
                    if (buf[i] != pgm_read_byte(uf2magic + i)) {
                        isUF2 = 0;
                        break;
                    }
                }
            }

            if (!isUF2)
            {
                continue;
            }

            for (i = 0; i < MASS_STORAGE_IO_EPSIZE; ++i)
            {
                temp_byte_out = buf[i];
                Serial_SendByte(temp_byte_out);

                //here we need to wait for conformation from the avr128 that data was received and interpreted.
                while(!(Serial_IsCharReceived()))
                ;

                temp_byte_in = Serial_ReceiveByte();

                //if data received does NOT match data sent
                //we need to quit and reset...
                if (temp_byte_in != temp_byte_out)
                {
                    targetReset();
                    wdt_enable(WDTO_60MS);
                    _delay_ms(600);
                }
            }
        }
        /* Decrement the blocks remaining counter */
        TotalBlocks--;
    }

    /* If the endpoint is empty, clear it ready for the next packet from the host */
    if (!(Endpoint_IsReadWriteAllowed()))
        Endpoint_ClearOUT();

}

Basically, the second processor just echoes each byte it receives back to the m16u2.

I have a 1024 byte UF2 file that gets passed through the 16u2 and successfully flashes the second micro.

The problem: I have a second UF2 file that is 13 KB. After copying it to the mass storage device my second micro starts flashing itself but it never stops. It seems that Windows tries and tries to copy the file until it finally quits with Error 0x80070079: The semaphore timeout period has expired.

So 1KB is fine but 13 is not. I imagine this is because I'm spending too much time in the WriteBlocks function. Perhaps waiting for the echoed byte is breaking things..

I tried inserting

MS_Device_USBTask(MSInterfaceInfo);
USB_USBTask();

In the while loop that's waiting for serial data but that didn't help.

Apologies if there is something simple I'm missing. I'm new to working with USB.

abcminiuser commented 3 years ago

Have you got a serial terminal, logic analyzer, or oscilloscope to verify what's happening with the serial link to the slave device? It certainly sounds like the USB communications are getting stuck waiting on the slave to acknowledge the data, which never comes.

There will indeed be a timeout on the mass storage request from the host, but it's normally fairly generous. As long as your link isn't running at one bit per second or incurring multiple second delays, it should still be able to complete each part of the transaction before hitting any timeout.

audiobird commented 3 years ago

Thanks for the response. I ended up getting it to work eventually. You were correct, the slave device was not acknowledging the data properly. It was a problem with the slave device's bootloader. Everything is working well now, thanks again. Lufa is awesome!