Всем привет!
Нужен пинок в правильном направлении, надеюсь у кого-то нога не дрогнет)).
Столкнулся с такой проблеммой:
Цепляю к своему девайсу USB в режиме вертуального СОМ-порта.
Проект который взят за основу тут:
https://disk.yandex.ru/d/GLNuOZ8iJHjQIwПроект рабочий и эхо посылок в VCP работает.
Но стоит только сместить старт программы и перенести вектора прерываний на другой адрес
(в девайсе у меня есть загрузчик, рабочая программа запускается с 0х08003000),
как USB отваливается (не определяется VCP).
Причем все мои прерывания работают как и положено, т.е. таблица прерываний переносится корректно.
Что еще я не учитываю?
Еще раз:
Этот пример полностью рабочий, если закомментарить код:
Код:
__disable_irq();//__set_PRIMASK(1); //отключить все прерывания
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x3000); //перенести таблицу векторов прерываний по адресу START_ADDRESS_WITH_BOOTLOADER
__enable_irq();//__set_PRIMASK(0); //включить все прерывания
ps
при переносе старта программы и векторов на 0х08003000 не попадаю в условие
(не срабатывает точка останова)
из функции void USB_Istr(void)
Код:
if (wIstr & ISTR_SOF & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_SOF);
bIntPackSOF++;
#ifdef SOF_CALLBACK
SOF_Callback();
#endif
}
проект делаю в Keil для STM32L151
Добавлено after 2 hours 19 minutes 42 seconds:"при переносе старта программы и векторов на 0х08003000 не попадаю в условие
(не срабатывает точка останова)"
Если быть точным, поведение софта после смещения векторов странное.
Если я ставлю точку останова внутри if (wIstr & ISTR_SOF & wInterrupt_Mask){},
то без смещения векторов она отрабатывается без проблем.
Смещаю на 0х08003000, то "на лету" она уже не срабатывает,
но если перед ним, например на строке wIstr = _GetISTR();
то после останова вхожу в это условие if (wIstr & ISTR_SOF & wInterrupt_Mask){}
...
как будто, скорость реакции не позволяет.... да не бред какой-то
ниже код void USB_Istr(void)
Спойлер
void USB_Istr(void)
{
uint32_t i=0;
__IO uint32_t EP[8];
wIstr = _GetISTR();
#if (IMR_MSK & ISTR_SOF)
if (wIstr & ISTR_SOF & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_SOF);
bIntPackSOF++;
#ifdef SOF_CALLBACK
SOF_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_CTR)
if (wIstr & ISTR_CTR & wInterrupt_Mask)
{
/* servicing of the endpoint correct transfer interrupt */
/* clear of the CTR flag into the sub */
CTR_LP();
#ifdef CTR_CALLBACK
CTR_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_RESET)
if (wIstr & ISTR_RESET & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_RESET);
Device_Property.Reset();
#ifdef RESET_CALLBACK
RESET_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
if (wIstr & ISTR_DOVR & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_DOVR);
#ifdef DOVR_CALLBACK
DOVR_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
if (wIstr & ISTR_ERR & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_ERR);
#ifdef ERR_CALLBACK
ERR_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
if (wIstr & ISTR_WKUP & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_WKUP);
Resume(RESUME_EXTERNAL);
#ifdef WKUP_CALLBACK
WKUP_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
if (wIstr & ISTR_SUSP & wInterrupt_Mask)
{
/* check if SUSPEND is possible */
if (fSuspendEnabled)
{
Suspend();
}
else
{
/* if not possible then resume after xx ms */
Resume(RESUME_LATER);
}
/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
_SetISTR((uint16_t)CLR_SUSP);
#ifdef SUSP_CALLBACK
SUSP_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
if (wIstr & ISTR_ESOF & wInterrupt_Mask)
{
/* clear ESOF flag in ISTR */
_SetISTR((uint16_t)CLR_ESOF);
if ((_GetFNR()&FNR_RXDP)!=0)
{
/* increment ESOF counter */
esof_counter ++;
/* test if we enter in ESOF more than 3 times with FSUSP =0 and RXDP =1=>> possible missing SUSP flag*/
if ((esof_counter >3)&&((_GetCNTR()&CNTR_FSUSP)==0))
{
/* this a sequence to apply a force RESET*/
/*Store CNTR value */
wCNTR = _GetCNTR();
/*Store endpoints registers status */
for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i);
/*apply FRES */
wCNTR|=CNTR_FRES;
_SetCNTR(wCNTR);
/*clear FRES*/
wCNTR&=~CNTR_FRES;
_SetCNTR(wCNTR);
/*poll for RESET flag in ISTR*/
while((_GetISTR()&ISTR_RESET) == 0);
/* clear RESET flag in ISTR */
_SetISTR((uint16_t)CLR_RESET);
/*restore Enpoints*/
for (i=0;i<8;i++)
_SetENDPOINT(i, EP[i]);
esof_counter = 0;
}
}
else
{
esof_counter = 0;
}
/* resume handling timing is made with ESOFs */
Resume(RESUME_ESOF); /* request without change of the machine state */
#ifdef ESOF_CALLBACK
ESOF_Callback();
#endif
}
#endif
} /* USB_Istr */