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.

[参考译文] TMS320F28379D:闪烁 LED -包括 USB_Boot ROM 代码以更新固件- USB 不枚举

Guru**** 666710 points
Other Parts Discussed in Thread: C2000WARE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1252485/tms320f28379d-blink-led---including-usb_boot-rom-code-to-update-firmware---usb-not-enumerating

器件型号:TMS320F28379D
主题中讨论的其他器件:C2000WARE

您好!

我正在尝试向闪存中运行的闪烁 LED 程序添加功能、以允许它通过 USB 使用 USB_FLASH_programmer.exe 进行更新。 我关注的主题是:

(+) TMS320F28379D:配置 OTP BOOTCTRL 寄存器- C2000微控制器论坛- C2000 ︎ 微控制器- TI E2E 支持论坛

Blink LED 程序位于: C:\ti\c2000\C2000Ware_5_00_00_00\device_support\f2837xd\examples\cpu1\blinky

我包含了以下位置的 USB 引导 ROM 代码:C:\ti\c2000\C2000Ware_5_00_00_00\libraries\boot_rom\f2837xd\RevB\ROM_SOURCES

在 Blink LED 应用程序的 main()的开头,我添加了检查以查看 GPIO 46是否已设置。 如果它被置位,则表示 USB 连接到 PC,然后调用 USB_Boot ()。  否则、它将继续初始化所有内容、并开始运行程序的主循环。

Uint32 main(void)
{
    uint32_t gpio46_value = GPIO_readPin(46);
    if(gpio46_value == 1) //Checking whether USB is connected or not.
    {
        DevCfgRegs.DC12.bit.USB_A = 1;
        Uint32 EntryAddr = USB_Boot(USB_BOOT); //Calling USB_Boot function.
        return EntryAddr;
    }

//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//
    InitSysCtrl();

//
// 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();
    GPIO_SetupPinMux(BLINKY_LED_GPIO, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(BLINKY_LED_GPIO, GPIO_OUTPUT, GPIO_PUSHPULL);

//
// 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();

//
// Enable global Interrupts and higher priority real-time debug events:
//
    EINT;  // Enable Global interrupt INTM
    ERTM;  // Enable Global realtime interrupt DBGM

//
// Step 6. IDLE loop. Just sit and loop forever (optional):
//
    for(;;)
    {
        //
        // Turn on LED
        //
        GPIO_WritePin(BLINKY_LED_GPIO, 0);

        //
        // Delay for a bit.
        //
        DELAY_US(1000*500);

        //
        // Turn off LED
        //
        GPIO_WritePin(BLINKY_LED_GPIO, 1);

        //
        // Delay for a bit.
        //
        DELAY_US(1000*500);
    }
}

以下是来自  C:\ti\c2000\C2000Ware_5_00_00_00\libraries\boot_rom\f2837xd\RevB\ROM_SOURCES 的 USB_Boot 代码。 我为 EntryAddr 检查添加了注释。

Uint32 USB_Boot(Uint16 bootMode)
{
	uint32_t entryAddr = FLASH_ENTRY_POINT;
	uint32_t EntryAddr = 0xFFFFFFFF;
	uint32_t disconnectDelay;

	//If the USB module is not enabled, bypass the bootloader
	if (DevCfgRegs.DC12.bit.USB_A == 0)
		return FLASH_ENTRY_POINT;

	//Assign the USB data reader function to the global
	//function pointer for loading data.
	GetWordData = &USB_GetWordData;

	//Set up the USB to receive data
	USB_Boot_Init();

	/*
    EntryAddr = TI_OTP_C1BROM_ESCAPE_POINT_13;
    if((EntryAddr != 0xFFFFFFFF) &&
            (EntryAddr != 0x00000000))
    {
        // if OTP is programmed, then call OTP function
        ((void (*)(void))EntryAddr)();
    }
    */

	//The first data word should be a valid key. If it's not,
	//bypass the bootloader.
	if (USB_GetWordData() != 0x08AA)
		return FLASH_ENTRY_POINT;

	//Use the shared utility functions to load the data.
	ReadReservedFn();
	entryAddr = GetLongData();
	CopyData();

	/*
    EntryAddr = TI_OTP_C1BROM_ESCAPE_POINT_13;
    if((EntryAddr != 0xFFFFFFFF) &&
            (EntryAddr != 0x00000000))
    {
        // if OTP is programmed, then call OTP function
        ((void (*)(void))EntryAddr)();
    }
    */

	//Disconnect from the bus, disable USB interrupts, and
	//reset the USB module. But first, wait for any ongoing
    //transfers to complete.
    for (disconnectDelay = 0; disconnectDelay < 10000; disconnectDelay++) {;}
	USBREG8(USB_O_POWER) &= ~USB_POWER_SOFTCONN;
	EALLOW;
	PieCtrlRegs.PIEIER9.bit.INTx15 = 0;
	IER &= ~M_INT9;
	DevCfgRegs.SOFTPRES11.bit.USB_A = 1;
	DevCfgRegs.SOFTPRES11.bit.USB_A = 0;
	EDIS;

	//Bypass and disable the main and aux PLLs
	EALLOW;
	ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 0;
	ClkCfgRegs.SYSPLLMULT.bit.IMULT = 0;
	ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 0;
	ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 0;
	ClkCfgRegs.AUXPLLMULT.bit.IMULT = 0;
	ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 0;
	EDIS;

	/*
    EntryAddr = TI_OTP_C1BROM_ESCAPE_POINT_13;
    if((EntryAddr != 0xFFFFFFFF) &&
            (EntryAddr != 0x00000000))
    {
        // if OTP is programmed, then call OTP function
        ((void (*)(void))EntryAddr)();
    }
    */

	return entryAddr;
}

以下是来自  C:\ti\c2000\C2000Ware_5_00_00_00\libraries\boot_rom\f2837xd\RevB\ROM_SOURCES 的 USB_Boot_Init ()函数。 我还为 EntryAddr 检查添加了注释。

void USB_Boot_Init()
{
	uint32_t EntryAddr = 0xFFFFFFFF;

	//Soprano
	//Lock the main PLL< aux PLL and enable the USB module clock
	//
	//USBCLK = 120 MHz / 2, sourced from the external oscillator for precision
	//
	//SYSCLK must be greater than USBCLK / 2, according to Design. The PLL minimum
	//Fout is 110 MHz, so let's set the multiplier to give 120 MHz and keep the
	//output divider at 1.
	EALLOW;
	ClkCfgRegs.CLKSRCCTL1.bit.OSCCLKSRCSEL = 0x0;       //Use INTOSC2 (~10 MHz) as the main PLL clock source
    ClkCfgRegs.SYSPLLMULT.all = 12;                     //Set IMULT to 12, clear FMULT
	ClkCfgRegs.SYSPLLCTL1.bit.PLLEN = 1;                //Enable the main PLL
	ClkCfgRegs.SYSCLKDIVSEL.bit.PLLSYSCLKDIV = 0;       //Set PLLSYSCLKDIV to 1
    while (ClkCfgRegs.SYSPLLSTS.bit.LOCKS != 1) {;}     //Wait for the PLL to lock
    ClkCfgRegs.SYSPLLCTL1.bit.PLLCLKEN = 1;             //Turn off the main PLL bypass

    ClkCfgRegs.CLKSRCCTL2.bit.AUXOSCCLKSRCSEL = 0x1;    //Use XTAL (20 MHz) as the aux PLL clock source
    ClkCfgRegs.AUXPLLMULT.all = 6;                      //Set IMULT to 6, clear FMULT - 120MHz
    ClkCfgRegs.AUXPLLCTL1.bit.PLLEN = 1;                //Enable the aux PLL
    ClkCfgRegs.AUXCLKDIVSEL.bit.AUXPLLDIV = 2/2;        //Set AUXPLLDIV to 2
    while (ClkCfgRegs.AUXPLLSTS.bit.LOCKS != 1) {;}     //Wait for the PLL to lock
    ClkCfgRegs.AUXPLLCTL1.bit.PLLCLKEN = 1;             //Turn off aux PLL bypass
	CpuSysRegs.PCLKCR11.bit.USB_A = 1;                  //Enable the clock to the USB module

	/*
    EntryAddr = TI_OTP_C1BROM_ESCAPE_POINT_13;
    if((EntryAddr != 0xFFFFFFFF) &&
            (EntryAddr != 0x00000000))
    {
        // if OTP is programmed, then call OTP function
        ((void (*)(void))EntryAddr)();
    }
    */

    //Connect the PHY to the GPIO pins by setting the GPBAMSEL
    //bits for GPIOs 42 and 43. VBUS and ID are now de-spec'd
    //due to the lack of a 5V fail-safe ESD structure, so
    //GPIOs 46 and 47 are not muxed out.
    GpioCtrlRegs.GPBAMSEL.bit.GPIO42 = 1;
    GpioCtrlRegs.GPBAMSEL.bit.GPIO43 = 1;
	EDIS;


	//Register the USB interrupt handler and enable CPU interrupts
	c1brom_enable_pie_in_boot(0);
	EALLOW;
	PieVectTable.USBA_INT = &UsbIntHandler;
	PieCtrlRegs.PIEIER9.bit.INTx15 = 1;
	EDIS;
	IER |= M_INT9;
	EINT;

	/*
    EntryAddr = TI_OTP_C1BROM_ESCAPE_POINT_13;
    if((EntryAddr != 0xFFFFFFFF) &&
            (EntryAddr != 0x00000000))
    {
        // if OTP is programmed, then call OTP function
        ((void (*)(void))EntryAddr)();
    }
    */

    //Reset the USB driver's global variables
    ResetUsbDriver();

    //Force USB device mode by setting DEVMODOTG and DEVMOD
	USBREG32(USB_O_GPCS) = 0x3;

	//Clear active interrupts
	USBREG16(USB_O_TXIS);
	USBREG16(USB_O_RXIS);
	USBREG8(USB_O_IS);

	//Set up endpoint 1 for bulk transfers with a 64-byte FIFO
	USBREG8(USB_O_EPIDX) = 1;
	USBREG8(USB_O_RXFIFOSZ) = 0x03;
	USBREG16(USB_O_RXFIFOADD) = 0x100;
	USBREG8(USB_O_RXCSRH1) = 0x40;

	//Enable USB interrupts for EP0 transmit/receive, EP1 receive, disconnection, and reset
	USBREG16(USB_O_TXIE) = 0x0001;
	USBREG16(USB_O_RXIE) = 0x0002;
	USBREG8(USB_O_IE) = (USB_IE_DISCON | USB_IE_RESET);

	//Attach the USB PHY to the bus
	USBREG8(USB_O_POWER) |= USB_POWER_SOFTCONN;
}

当我运行的程序与 USB 连接到一台 PC 它是卡在 while 循环在第一个 USB_GetWordData ()调用。

//Read 16 bits from an incoming USB message
Uint16 USB_GetWordData()
{
	Uint16 retVal;

	//Wait for the USB receive buffer to be refilled
	while (g_UsbRxBuffer == 0) {;}

	//Read the next data value, update the buffer pointer and length,
	//and do end-of-packet handling.
	retVal = *g_UsbRxBuffer++;
	g_UsbRxPacketLength -= 2;
	if (g_UsbRxPacketLength == 0)
	{
		g_UsbRxBuffer = 0;
		AckEp1();
	}

	return retVal;
}

我从未在设备管理器中看到在 PC 上枚举的 USB。  

对我的行为是否有任何错误的想法?

我可以检查哪些东西?

谢谢。

布伦特

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    问题是最初我没有执行 GPIO 检查,并在开始时调用 USB_Boot()。