This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

usblib causes hardfault on launchpad

Other Parts Discussed in Thread: SW-TM4C

Hello i have recently gotten my hands on the launchpad with the tm4c123g

I am now trying to get the launchpad connected to the PC as a mass storage device using the usblib that i downloaded from here:

http://www.ti.com/tool/sw-tm4c

My (Basic) code looks like this:

	// *******************************************************************************************
	//
	// System clock settings
	//
	// *******************************************************************************************

	// Set clock settings to the default of 12.5Mhz, used crystal is 16 Mhz
	uint32_t RCC = (SYSCTL_RCC_XTAL_16MHZ | SYSCTL_RCC_USESYSDIV |  (0x15 << SYSCTL_RCC_SYSDIV_S) );			// Oscillator is a 16MhZ crystal, PLL is used so SYSDIV is needed (defaults to 15 for 12.5Mhz clock)
	SYSCTL_RCC_R = RCC;

	// Override certain register values of the RCC register with the values of the RCC2 register so that we can set the clock speed to 80Mhz
	uint32_t RCC2 = (SYSCTL_RCC2_USERCC2 | SYSCTL_RCC2_DIV400 | (2 << SYSCTL_RCC2_SYSDIV2_S) );
	SYSCTL_RCC2_R = RCC2;

 	//***************************************************************
	//
	// string descriptors for USB
	//
	//***************************************************************

	// language
	const uint8_t langDescriptor[] = {
		    4,									// 1st byte gives descriptor length in bytes.
		    USB_DTYPE_STRING,					// Descriptor type
		    USBShort(USB_LANG_EN_US)			// Language code in 2 bytes (0x0409)
	};

	// Manufacturer
	const uint8_t manuDescriptor[] = {
			( 7 + 1 ) * 2 ,					// 1st byte gives descriptor length in bytes.
			USB_DTYPE_STRING,				// Descriptor type
		    'A', 0, 'r', 0, 't', 0, 'i', 0, 'n', 0, 'i', 0, 's', 0,
	};

	// Product
	const uint8_t productDescriptor[] = {
			( 7 + 1 ) * 2 ,					// 1st byte gives descriptor length in bytes.
			USB_DTYPE_STRING,				// Descriptor type
		    'A', 0, 'r', 0, 't', 0, 'i', 0, 'n', 0, 'i', 0, 's', 0,

	};

	// Serial number
	const uint8_t serialDescriptor[] = {
			( 7 + 1 ) * 2 ,					// 1st byte gives descriptor length in bytes.
			USB_DTYPE_STRING,				// Descriptor type
		    'A', 0, 'r', 0, 't', 0, 'i', 0, 'n', 0, 'i', 0, 's', 0,
	};

	const uint8_t * const stringDescriptors[] = {
			langDescriptor,
			manuDescriptor,
			productDescriptor,
			serialDescriptor,
			productDescriptor,
			productDescriptor
	};

	tUSBDMSCDevice deviceInfo = {
		USB_VID_TI_1CBE,												// UID
		USB_PID_MSC,													// PID
		"Artinis ",														// Vendor
		"PortaProto      ",																		// Product
		"0.01",																					// Revision
		500,																					// Power usage
		USB_CONF_ATTR_SELF_PWR,																	// Power type, bus powered
		stringDescriptors,																		// String descriptors
		6,
		{
			USBDMSCStorageOpen,
			USBDMSCStorageClose,
			USBDMSCStorageRead,
			USBDMSCStorageWrite,
			USBDMSCStorageNumBlocks
		},

		usbEventCallback,																		// USB callback function
		0																						// We dont use DMA
	};
	void* result = USBDMSCInit(0,  &deviceInfo);
        while(1);

 

Now when running this code as soon as it enters the main i get these errors in the debug window:

And the device enters the FaultISR(void) routine.

When is remove the tUSBDMSCDevice struct initialization and replace it with the following:

	/*tUSBDMSCDevice deviceInfo = {
		USB_VID_TI_1CBE,																		// UID
		USB_PID_MSC,																			// PID
		"Artinis ",																			// Vendor
		"PortaProto      ",																		// Product
		"0.01",																					// Revision
		500,																					// Power usage
		USB_CONF_ATTR_SELF_PWR,																	// Power type, bus powered
		stringDescriptors,																		// String descriptors
		6,
		{
			USBDMSCStorageOpen,
			USBDMSCStorageClose,
			USBDMSCStorageRead,
			USBDMSCStorageWrite,
			USBDMSCStorageNumBlocks
		},

		usbEventCallback,																		// USB callback function
		0																						// We dont use DMA
	};

	void *result = USBDMSCInit(0, &deviceInfo);*/

        void *result = USBDMSCInit(0, NULL);

 

The code runs fine! (without usb offcourse)

Can anyone help me with debugging this problem? The code compiles without error or warnings.

Thank you,

Sisco

  • Here are two options I would use to track this down.

    Option 1:

    Diagnosing Software Faults in Stellaris® Microcontrollers:

    www.ti.com/lit/pdf/spma043

    Option 2:

    Rebuild usblib adding the DEBUG define to both usblib and your project. You can rebuild the driver lib too. This will enable the ASSERT macro in the library and usually checks that the library function arguments are valid. Then add __error__() to your project and set a breakpoint on it.

    //*****************************************************************************
    //
    // The error routine that is called if the driver library encounters an error.
    //
    //*****************************************************************************
    #ifdef DEBUG
    void
    __error__(char *pcFilename, uint32_t ui32Line)
    {
        while(1)
        {
        }
    }
    #endif
  • Hello and thank you for your reply,

    If have tried diagnosing the fault using the document you provided but ended up at nothing, The fault stat register gives the following value: 0x00009600 which means (i think) that the fault address should be written in the FAULTADDR register.

    Looking at this register it gives me the address values that were in the first post: 0x1FFFXXXX, which according to the datasheet is reserved memory.

    I have also tried rebuilding usblib by adding DEBUG to the predefined symbols of the project but this did not do anything. as the code went straight to the FaultISR

  • I went ahead and tried your code. I believe you are overflowing the stack because you are declaring the USB structures in main(). The tUSBDMSCDevice structure is very large (4k) and variables in a function end up on the stack. Move them out of main to be globals.

    The general way I figured it out:

    1. I suspected a stack overflow :-)
    2. Compiled code noticed that .const section was very large
    3. Ran code and noticed the memcpy being run (I pointed the debugger to the unzipped rtssrc dir for more a source trace)
    4. when the fault isr is hit, the SP was 0x1FFFF300 which is invalid.
    5. Following the debug guide, checked NVIC_FAULT_STAT reg and the BSTKE and IMPRE bits were set.
  • thank you, this did it!

    i can now run the code without any problems. Now i just need to find a way to actually use the library functions. Do you know where i can find any extra information on mass storage usage?

    The Media Access functions do not seem to be documented in the USB Library  user's guide.

    Sisco

  • You have to define your own functions to access whatever storage you are using.

    The Development Kit has an example in examples\boards\dk-tm4c123g\usb_dev_msc of tivaware. This uses SPI to talk to an SD card using the provided fatfs driver. Obviously you'll have to rig up the physical SD interface as your launchpad doesn't have this.