AnsweredAssumed Answered

After MCU NVIC_GenerateSystemReset(), USB TX not working

Question asked by kim.jason.002 on Oct 18, 2013
Latest reply on Oct 25, 2013 by Amel N

I don't know why I can send text from PC to MCU through usb but I can't let MCU send text to PC after MCU reset.

I am using STM32F103C8. Bootloader start address is 0x8000000, Firmware start address is 0x8004000. Of course, NVIC table base address of Bootloader and Firmware are 0x8000000 and 0x8004000, respectively.

In my firmware, PC recognized MCU using a virtual COM port, so I can tx/rx through usb VCOM port.
After backup USB-related registers to backup registers, my Firmware resets MCU by using NVIC_GenerateSystemReset().

----------FIRMWARE----------------

    BKP_WriteBackupRegister(BKP_DR5, GetCNTR());

    BKP_WriteBackupRegister(BKP_DR6, GetISTR());

    BKP_WriteBackupRegister(BKP_DR7, GetDADDR());

    BKP_WriteBackupRegister(BKP_DR8, GetBTABLE());

    BKP_WriteBackupRegister(BKP_DR9, GetENDPOINT(0));

    BKP_WriteBackupRegister(BKP_DR10, GetENDPOINT(1));

    BKP_WriteBackupRegister(BKP_DR11, GetENDPOINT(2));

    BKP_WriteBackupRegister(BKP_DR12, GetENDPOINT(3));

    BKP_WriteBackupRegister(BKP_DR3, 10); // this is for indicating a jump from firmware.

    NVIC_GenerateSystemReset();
-----------------------------------

-----------BOOTLOADER(sudo code)--------------

if((BKP_ReadBackupRegister(BKP_DR3) == 10))
{
   
    DO NOT CHANGE USB_DISCONNECT PIN which is for controlling the PULL-UP status of USBDP.

(If I do this, USB virtual com port will disconnected from PC. I don't want this happen.

But I found that if I put this pin high and then put low, tx/rx both works fine but VCOM port will be disconnected then reconnected.)
   
    USB_Init();
   
    SET CNTR, DADDR, BTABLE, ENDPOINT0, ENDPOINT1, ENDPOINT2, ENDPOINT3 according to backup registers.

}

-----------------------------------------------

After that, I found that I PC keeps the VCOM port that has been recognized during Firmware(without reconnecting after entering bootloader), and I can send characters through this usb virtual com port to MCU.

But MCU cannot send characters to PC through usb.

extern void USB_TxDByte(u8 dat)
{
 
    Delay(1);
 
    UserToPMABufferCopy(&dat, ENDP1_TXADDR,1);
 
    SetEPTxCount(ENDP1, 1);
 
    SetEPTxValid(ENDP1);
}

The following is register values (during bootloader):

EP0  EP1  EP2  EP3  CNTR  ISTR  FNR  DADDR  BTABLE

5210 0031 0622 3003 8600 0000 A475 0087 0000

5210 0031 0622 3003 8600 0000 A5B3 0087 0000

5210 0031 0622 3003 8600 0000 A6F1 0087 0000

5210 0031 0622 3003 8600 0000 6030 0087 0000

5210 0031 0622 3003 8600 0000 A16E 0087 0000

5210 0031 0622 3003 8600 0000 A2AC 0087 0000

5210 0031 0622 3003 8600 0000 63EA 0087 0000

5210 0031 0622 3003 8600 0000 6529 0087 0000

5210 0031 0622 3003 8600 0000 A667 0087 0000

5210 0031 0622 3003 8600 0000 A7A5 0087 0000

5210 0031 0622 3003 8600 0000 A0E3 0087 0000

5210 0031 0622 3003 8600 0000 A221 0087 0000

5210 0031 0622 3003 8600 0000 A360 0087 0000

5210 0031 0622 3003 8600 0000 A49E 0087 0000

5210 0031 0622 3003 8600 0000 A5DC 0087 0000

5210 0031 0622 3003 8600 0000 A71A 0087 0000

When I can do tx/rx correct in firmware, I found that only ISTR register is 0x0900, other values are the same (except FNR...). But ISTR register cannot be set, only reset is possible.

 

Outcomes