Перейти к содержанию
    

ATSAMD21 USB Attach/Detach

Вопрос к знатокам USB интерфейса. Микроконтроллер atsamd21j18. Инициализируется USB с поддержкой CDC. Все проходит штатно и функционирует. Необходимо на ходу отключить USB кабель от устройства. Делаем "detach" USB. Видим программное отключение. Делаем "attach". Видим програмное подключение интерфейса (enumerated). Функционирование CDC после переподключения нарушается:

detach

USB->DEVICE.CTRLB.bit.DETACH = 1;
USB->DEVICE.CTRLA.bit.ENABLE = 0;

while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1)
	;

attach
  
USB->DEVICE.CTRLA.bit.ENABLE = 1;
while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1)
	;
USB->DEVICE.CTRLB.bit.DETACH = 0;

Пробовал пере-инициализировать USB:

usb_init();

USB->DEVICE.CTRLA.bit.ENABLE = 1;
while (USB->DEVICE.SYNCBUSY.bit.ENABLE == 1)
	;
USB->DEVICE.CTRLB.bit.DETACH = 0;

CDC не функционирует. Инициализация USB:

void usb_init(void)
{
    uint32_t pad_transn, pad_transp, pad_trim;

    /* Enable USB clock */

    PM->APBBMASK.reg |= PM_APBBMASK_USB;

    #define DM_PIN PIN_PA24G_USB_DM
    #define DM_MUX MUX_PA24G_USB_DM
    #define DP_PIN PIN_PA25G_USB_DP
    #define DP_MUX MUX_PA25G_USB_DP


    /* Set up the USB DP/DN pins */
    PORT->Group[0].PINCFG[DM_PIN].bit.PMUXEN = 1;
    PORT->Group[0].PMUX[DM_PIN / 2].reg &= ~(0xF << (4 * (DM_PIN & 0x01u)));
    PORT->Group[0].PMUX[DM_PIN / 2].reg |= DM_MUX << (4 * (DM_PIN & 0x01u));
    PORT->Group[0].PINCFG[DP_PIN].bit.PMUXEN = 1;
    PORT->Group[0].PMUX[DP_PIN / 2].reg &= ~(0xF << (4 * (DP_PIN & 0x01u)));
    PORT->Group[0].PMUX[DP_PIN / 2].reg |= DP_MUX << (4 * (DP_PIN & 0x01u));

    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(USB_GCLK_ID) | GCLK_CLKCTRL_GEN(0) | GCLK_CLKCTRL_CLKEN;

    while (GCLK->STATUS.bit.SYNCBUSY)
    	;

    /* Reset */
    USB->HOST.CTRLA.bit.SWRST = 1;

    while (USB->HOST.SYNCBUSY.bit.SWRST)
        ;/* Sync wait */

    /* Load Pad Calibration */
    pad_transn = ((*((uint32_t*) USB_FUSES_TRANSN_ADDR)) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos;

    if(pad_transn == 0x1F) pad_transn = 5;

    USB->HOST.PADCAL.bit.TRANSN = pad_transn;

    pad_transp = ((*((uint32_t*) USB_FUSES_TRANSP_ADDR)) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos;

    if (pad_transp == 0x1F) pad_transp = 29;

    USB->HOST.PADCAL.bit.TRANSP = pad_transp;

    pad_trim = ((*((uint32_t*) USB_FUSES_TRIM_ADDR)) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos;

    if (pad_trim == 0x7) pad_trim = 3;

    USB->HOST.PADCAL.bit.TRIM = pad_trim;

    /* Set the configuration */
    /* Set mode to Device mode */
    USB->HOST.CTRLA.bit.MODE = 0;
    /* Enable Run in Standby */
    USB->HOST.CTRLA.bit.RUNSTDBY = true;
    /* Set the descriptor address */
    USB->HOST.DESCADD.reg = (uint32_t)(&usb_endpoint_table[0]);
    /* Set speed configuration to Full speed */
    USB->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val;
    /* Attach to the USB host */
    USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH;

    /* Initialize endpoint table RAM location to a known value 0 */
    memset((uint8_t *)(&usb_endpoint_table[0]), 0, sizeof(usb_endpoint_table));
}

 

Сброс интерфейса с последующей инициализацией, не помогает. Вариант с постоянным сбросом микроконтроллера - не вариант. Кто может подсказать, где могут лежать грабли? Заранее благодарен

 

Изменено пользователем TORNIS

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...