FatFs halting sometimes

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

 

I'm using the FatFs module to access a USB FLASH drive on a project for the ATSAM4LC2AA microcontroller. Everything is working fine except for one detail: Sometimes when I plug my USB FLASH drive on the USB port of my board, the MCU will detect the unit, fire the related interrupt service routines, the code below (which is within the main loop) will run (when main_usb_sof_counter passes 2000; it's incremented at the interrupt service: main_usb_sof_event), it will then detect that a "LUN" is present, it'll mount the file system on it using f_mount, f_mount will return FR_OK as a response indicating success, and then here starts the issue:

 

Sometimes after that (after LUN detected / f_mount called), any access operation to the file system (i.e.: f_getlabel) will halt the MCU and a watchdog reset will then occur. After the watchdog reset, the firmware will restart, redetect the USB FLASH drive that's already plugged, go thru the same process, and then it'll probably work. It might reset again, but if you just plug the USB FLASH drive and wait a bit it will eventually work (after 1 or 2 watchdog resets). I believe that 50% of the times it'll work at first though.

 

Here's the main loop code that will detect the LUN and call f_mount. All the UART_TX_STR calls have been placed for debugging on a UART terminal:

 

if (main_usb_sof_counter > 2000)
	{
		main_usb_sof_counter = 0;
		volatile uint8_t lun;
		FRESULT res;

		for (lun = LUN_ID_USB; (lun < LUN_ID_USB + uhi_msc_mem_get_lun()) && (lun < MAX_DRIVE); lun++)
		{
			// Check if LUN has been already tested

			if (TEST_OK == lun_states[lun] || TEST_ERROR == lun_states[lun]) continue;

			// If LUN hasn't already been tested, it's a new LUN. Continue down.

			UART_TX_STR("\n\rNew USB device found.");

			memset(&fs, 0, sizeof(FATFS));			// Mount drive
			res = f_mount(lun, &fs);

			if (FR_INVALID_DRIVE == res)			// If LUN is not present...
			{
				lun_states[lun] = TEST_NO_PRESENT;
				UART_TX_STR("\n\rERROR: ");
				UART_TX_STR(FR_Responses[res]);
				continue;
			}

			if (FR_OK != res)				// If f_mount returned anything other than success...
			{
				UART_TX_STR("\n\rERROR: ");
				UART_TX_STR(FR_Responses[res]);
				continue;
			}

			UART_TX_STR("\n\rFile system ready."); 	

			res = f_getlabel("", buffer, 0);		// Get volume label

			if (res == FR_OK) {
				UART_TX_STR("\n\rUSB device label: ");
				UART_TX_STR(buffer);
			} else {
				UART_TX_STR("\n\rError getting label: ");
				UART_TX_STR(FR_Responses[res]);
			}

			lun_states[lun] = TEST_OK;
			FAILED_ATTEMPTS=0;
			cur_path[0]=0;
			UART_TX_STR("\n\r");
			UART_TX_STR(cur_path);
			UART_TX_STR("> ");
		}
	}

Follows the interrupt services routines:

void main_usb_sof_event(void)
{
	main_usb_sof_counter++;
}

void main_usb_connection_event(uhc_device_t * dev, bool b_present)
{
	UART_TX_STR("\n\rUCE: ");
	if (!b_present) {
		main_reset_states();			// LUN is unplugged, reset flags
		UART_TX_STR("Disconnected\n\r");
	} else {
		UART_TX_STR("Connected\n\r");
	}
}

Function called from ISR main_usb_connection_event:

static void main_reset_states(void)
{
	int i;
	for (i = 0; i < MAX_DRIVE; i ++) {
		lun_states[i] = TEST_NULL;
	}
}

Once the file system is mounted and a FatFs function works (i.e.: f_getlabel works), everything will continue to work fine until the USB FLASH drive is unplugged. But strange that in all cases f_mount will always return FR_OK.

 

Anyone have any idea of what could be happening?

Thanks in advance!

Last Edited: Tue. Apr 3, 2018 - 08:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Update: Apparently this is a known bug, described on the Errata section of the ATSAM4L datasheet (pg.1192). 

 

The bug (as described on the datasheet) is:

 

In USB host mode, the asynchronous attach detection (UDINT.HWUPI) can fail when the USB clock freeze (USBCON.FRZCLK=1) is done just after setting the USBSTA.VBUSRQ bit.

 

Fix/Workaround: After setting USBSTA.VBUSRQ bit, wait until the USBFSM register value is ‘A_WAIT_BCON’ before setting the USBCON.FRZCLK bit.

 

My question is: there are many instances on the USB host driver files provided by Atmel where the USBSTA.VBUSRQ and USBCON.FRZCLK bits are set. Should I then modify those files? Or are there new files provided by Atmel with this fix already applied?