Other Parts Discussed in Thread: C2000WARE, , TMDSCNCD28388D, TMS320F28379D
As part of the SDK, TI provides a USB flash programmer - C:\ti\c2000\C2000Ware_4_03_00_00\utilities\flash_programmers\usb_flash_programmer.
This USB on the device is configured in device mode where the USB host is the computer the device is attached to.
We want to be able to perform a firmware update by plugging in a USB FLASH drive (Pen drive). To accomplish this I believe I need a custom bootloader and custom flash kernel.
For the custom bootloader I started with the usb_ex7_host_msc.c project found at - C:\ti\c2000\C2000Ware_4_03_00_00\driverlib\f2837xd\examples\cpu1\usb and incorporated some of the boot rom code found at - C:\ti\c2000\C2000Ware_4_03_00_00\libraries\boot_rom\f2837xd\revB\rom_sources.
With this I am able to run this application from FLASH. I have a USB FLASH drive (Pen drive) with a led_ex1_blinky.dat file on it. When I plug in the FLASH drive the custom bootloader running from FLASH reads the led_ex1_blinky.dat file and writes it to RAM. After completing the writing to RAM, it jumps to the new main() in RAM and starts executed properly (i.e. LED starts blinking). So, I think my custom bootloader is working.
For the custom flash kernel, I started with the following USB flash kernel - C:\ti\c2000\C2000Ware_4_03_00_00\device_support\f2837xd\examples\dual\F2837xD_usb_flash_kernels\cpu01. I modified this incorporating usb_ex7_host_msc.c functionality.
With this I am able to run this application from RAM. I have a USB FLASH drive (Pen drive) with a led_ex1_blinky.dat file on it. When I plug in the FLASH drive the custom flash kernel running from RAM reads the led_ex1_blinky.dat file and writes it to FLASH. After completing the writing to FLASH, it jumps to the new main() in FLASH and starts executed properly (i.e. LED starts blinking). So, I think my custom flash kernel is working.
The issue I am having is when I try to combine the two. I start with the custom FLASH bootloader running out of FLASH. I have two .dat files on the USB FLASH drive. The new custom flash kernel and the led_ex1_blinky.dat. The process should mimic the USB flash programmer.
1) Custom FLASH bootloader reads in custom flash kernel .dat file and writes it to RAM
2) After completing the writing of the custom flash kernel to RAM it should jump to the new main() in RAM and start executing
3) During the execution of the custom flash kernel it should read in the led_ex1_blinky.dat and start writing it to FLASH
4) Onces the custom flash kernel is done writing the led_ex1_blinky.dat image to FLASH it should jump to the new main() in FLASH and start executing
Well I am seeing steps 1) and 2). Once the freshly programmed into RAM flash kernel starts executing it is waiting for the USB to enumerate even though it is plugged in. I do not want to have to unplug the USB drive and plug it back in to program the led_ex1_blinky.dat.
I do try to unplug the USB drive and plug it back in at which point it looks like it is detected but it is failing in device.c -
void __error__(const char *filename, uint32_t line)
NOTE - it is pretty difficult to debug the custom flash kernel in RAM since it is all assembly at this point (i.e. no symbols). From this error function I can see the file where the assert takes place:
C:\ti\c2000\C2000Ware_4_03_00_00\libraries\communications\usb\f2837xd\source\host\usbhostenum.c. Specifically line 5013 -
//***************************************************************************** // //! This function completes a control transaction to a device. //! //! \param ui32Index is the controller index to use for this transfer. //! \param psSetupPacket is the setup request to be sent. //! \param psDevice is the device instance pointer for this request. //! \param pui8Data is the data to send for OUT requests or the receive buffer //! for IN requests. //! \param ui32Size is the size of the buffer in \e pui8Data. //! \param ui32MaxPacketSize is the maximum packet size for the device for this //! request. //! //! This function handles the state changes necessary to send a control //! transaction to a device. This function should not be called from within //! an interrupt callback as it is a blocking function. //! //! \return The number of bytes of data that were sent or received as a result //! of this request. // //***************************************************************************** uint32_t USBHCDControlTransfer(uint32_t ui32Index, tUSBRequest *psSetupPacket, tUSBHostDevice *psDevice, uint8_t *pui8Data, uint32_t ui32Size, uint32_t ui32MaxPacketSize) { uint32_t ui32Remaining; uint32_t ui32DataSize; // // Debug sanity check. // ASSERT(g_sUSBHEP0State.iState == eEP0StateIdle);
Again, since I do not have any symbols, just assembly it makes debugging pretty hard.
In the custom bootloader I have tried calling
SysCtl_resetPeripheral(SYSCTL_PERIPH_RES_USBA);
in the custom bootloader just prior to jumping to the flash kernel main() to reset the USB where in the custom flash kernel it makes the following calls to initialize the device (including USB) NOTE this is mainly from the usb_ex7_host_msc.c:
uint32_t main(void) { // // Step 1. Initialize System Control: // Enable Peripheral Clocks // This example function is found in the F2837xD_SysCtrl.c file. // InitSysCtrl(); //PLL activates // // Step 2. Initialize GPIO: // This example function is found in the F2837xD_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // // Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interrupts // DINT; // // Initialize the PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared. // This function is found in the F2837xD_PieCtrl.c file. // InitPieCtrl(); // // Disable CPU interrupts and clear all CPU interrupt flags: // IER = 0x0000; IFR = 0x0000; // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in F2837xD_DefaultIsr.c. // This function is found in F2837xD_PieVect.c. // InitPieVectTable(); InitFlash(); // // Gain pump semaphore // SeizeFlashPump(); Init_Flash_Sectors(); Board_init(); C2000Ware_libraries_init(); EINT; ERTM; Interrupt_enableMaster(); UsbHost_Initialize();
where UsbHost_Initialize() is (basically from main() in usb_ex7_host_msc.c)
void UsbHost_Initialize() { g_UsbRxBuffer = &g_cTmpBuf[0]; startAddress = g_UsbRxBuffer; // initially wait for device connection. g_eState = STATE_NO_DEVICE; g_eUIState = STATE_NO_DEVICE; // configure the required pins for USB operation. USBGPIOEnable(); // register the interrupt handler for USB Interrupts. //Interrupt_register(INT_USBA, INT_myUSB0_ISR); // Initialize the USB stack mode and pass in a mode callback. //USBStackModeSet(0, eUSBModeForceHost, ModeCallback); // Register the host class drivers. USBHCDRegisterDrivers(0, g_ppHostClassDrivers, NUM_CLASS_DRIVERS); // Open an instance of the mass storage class driver. g_psMSCInstance = USBHMSCDriveOpen(0, (tUSBHMSCCallback)MSCCallback); // initialize the power configuration. This sets the power enable signal // to be active high and does not enable the power fault. //USBHCDPowerConfigInit(0, USBHCD_VBUS_AUTO_HIGH | USBHCD_VBUS_FILTER); // initialize the USB controller for OTG operation with a 2ms polling // rate. //USBHCDInit(0,g_pHCDPool, HCD_MEMORY_SIZE); // initialize the file system. f_mount(0, &g_sFatFs); }
I am kind of stuck at this point. If I run the custom bootloader from FLASH and load led_ex1_blinky.dat into RAM it works. If I run the custom flash kernel from RAM and load led_ex1_blinky.dat into FLASH it works. The issue is when the custom bootloader loads the custom flash kernel. At the point the custom flash kernel starts running the USB is not in a good state. It does not enumerate the USB (see USB FLASH drive attached) and if I unplug it and plug it back in it errors out.
The bottom line is that the USB is not in a good state (initialized/configured) when running the flash kernel after it has been programmed by the custom bootloader.
Any thoughts on the resetting / initialization / configuration of the USB from when I leave the custom bootloader to initializing the USB in the custom flash kernel?
Anything i can try or to look at?
Thanks for your help,
Brent