Например TDA7294

Форум РадиоКот • Просмотр темы - STM32 и USB (практика)
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Пт июл 25, 2025 04:56:24

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 583 ]     ... , , , 8, , , ...  
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Ср июл 20, 2016 12:16:02 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Z_h_e писал(а):
Делаю вывод, Bit Banding это аппаратный |= и по факту нет доступа к конкретному биту

А на картинках-то так все красиво расписано :) .
СпойлерИзображение

Вашу функцию пока не пробовал - хотел докопаться до правды. Как появится время обязательно попробую...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Ср июл 20, 2016 12:28:45 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2708
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
isx писал(а):
А на картинках-то так все красиво расписано .
В целом то все верно, регистров с битами тогл врядли много, или даже только в USB. С Bit Banding не надо переживать за соблюдение атомарности. Быстродействие опять, Сишное |= будем скомпилированно как минимум в три команды, Bit Banding в одну.

Весьма вероятно, что в какой-то документации указан этот нюанс работы Bit Banding. Скорее всего не в STM, а в ARM.

Цитата:
Вашу функцию пока не пробовал - хотел докопаться до правды
Думаете она у меня какая-то не правдивая :) ?

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Сб июл 23, 2016 13:33:48 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Z_h_e писал(а):
Скорее всего не в STM, а в ARM.

Уууу... Так глубоко я еще не копаю :) .
Z_h_e писал(а):
Думаете она у меня какая-то не правдивая ?

Не то что бы не правдивая, просто когда сам все собираешь запоминается лучше :) .

Я правильно понимаю, что bit15 и bit7 это:
Код:
const uint16_t bit15 = 0x8000;
const uint16_t bit7 = 0x0080;


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Сб июл 23, 2016 14:58:03 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2708
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
isx писал(а):
Уууу... Так глубоко я еще не копаю .
Так то с него бы и надо начинать, основа, это ж ядро проца, единое для всех, а вот перефирия это уже от марки контроллера. Но не буду врать, я много чего забыл уже сам. Сразу в голове не все откладывается, особенно когда работаешь с контроллером иногда.
isx писал(а):
Я правильно понимаю, что bit15 и bit7 это:
Код:
const uint16_t bit15 = 0x8000;
const uint16_t bit7 = 0x0080;
Когда я начал изучать STM, начал с самого легкого, с USB :) . И не знал, что не только для каждого регистра уже есть определения, но и для каждого бита тоже. Я собственно и для регистров USB сам сделал определения. Кстати, тоже хорошо помогает для понимания. По большому счету и СИ то тоже начал одновременно с STM изучать. Вы значения правильно определили, только у меня это не константы, а макроопределения.
Код:
#define  bit7  ((uint32_t)0x00000080)                         
#define  bit15 ((uint32_t)0x00008000)
Будет работать и так как у Вас, только возможно компилятор под константы выделить память.

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Сб июл 23, 2016 15:43:20 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Z_h_e писал(а):
Так то с него бы и надо начинать, основа, это ж ядро проца, единое для всех

Это я понимаю. Врать не буду, начинал несколько раз читать про ядра, но не осилял такой поток информации :dont_know: . Наверное, пока рано.
Z_h_e писал(а):
Когда я начал изучать STM, начал с самого легкого, с USB

Я к нему постепенно шел, да вот только не чувствую особого различия. Все с ним наизнанку выворачивается :)
Z_h_e писал(а):
Я собственно и для регистров USB сам сделал определения

Я тоже сам начинал, но потом в 5-ом кейле встретил готовые определения... Эх, жаль тогда мне никто не сказал, что STAT-дефайны оттуда можно только для чтения использовать. Сколько я из-за этого времени убил :facepalm:
Не знаю почему, но кейл у меня напрочь отвергает case-ы со значениями Valid и Stall. Просит значения Int.
Параллельно пробую свою функцию городить. Это уже просто дело принципа, завести этот чертов USB со своим кодом :))) :kill:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Сб июл 23, 2016 15:47:11 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2708
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Ну на счет самого легкого я пошутил конечно.

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Распродажа паяльного оборудования ATTEN!
Паяльные станции, паяльники и аксессуары по самой выгодной цене.

По промокоду radiokot скидка 10%
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Сб июл 23, 2016 19:26:43 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Сделал функцию, прям вот по-топорному, чтоб все перед глазами было. Прогнал на тесте - вроде все правильно пашет. Только вот чертов второй запрос так и не приходит... :kill:
Кину код. Он кошмарный, вряд ли кто-то захочет читать, но вдруг. А я ушел глубокие думы думать :solder:
Спойлер
Код:
#include "stm32f303xc.h"

//#define USB_MAX_PACKET0 ((uint8_t) 0x40)
#define USB_EP0_BIT ((uint32_t *)(0x420B8000))


uint32_t test1 = 0x00000000;
uint32_t test2 = 0x00000000;
uint32_t test3 = 0x00000000;
uint32_t test4 = 0x00000000;
uint32_t test5 = 0x00000000;
uint32_t test6 = 0x00000000;
uint16_t testMASK = 0x0000;
uint32_t BTableOffset = 0x00000000; // указываем значение BTABLE
uint8_t i = 0;
uint16_t TXBuff = 0;
 
 void SetRXTX (uint8_t EPNum, uint8_t EPStatus, uint8_t RXTX)
  {
/*
    EPNum         EPStatus       RXTX     
    0 to 7     0 - Disable      0 - RX 
              1 - Stall       1 - TX 
               2 - NAK
              3 - VALID 
*/   
   
   
   uint32_t buff;
    uint32_t stat;
   buff=((uint32_t*)0x40005C00)[EPNum]; //0x40005C00 базовый адрес регистров юсб
   

   
   if (RXTX == 1)////////////////////////////////RXTX = 1 = TX
    {
       stat = (buff>>4) & 3;
      switch (stat)
          {
         case 0: //DISABLE
               switch (EPStatus)
               {
                  case 0:
                    break;
                  case 1:
                     buff^=0x0010; buff&=0x8FBF; break; //TX
                  case 2:
                     buff^=0x0020; buff&=0x8FBF; break; //TX
                  case 3:
                     buff^=0x0030; buff&=0x8FBF; break; //TX
               }
            break;

         case 1: //STALL
               switch (EPStatus)
               {
                  case 0:
                    buff^=0x0010; buff&=0x8FBF; break; //TX
                  case 1:
                    break;
                  case 2:
                     buff^=0x0030; buff&=0x8FBF; break; //TX
                  case 3:
                     buff^=0x0020; buff&=0x8FBF; break; //TX
               }
            break;
               
         case 2: //NAK
               switch (EPStatus)
               {
                  case 0:
                    buff^=0x0020; buff&=0x8FBF; break; //TX
                  case 1:
                     buff^=0x0030; buff&=0x8FBF; break; //TX
                  case 2:
                     break;
                  case 3:
                     buff^=0x0010; buff&=0x8FBF; break; //TX
               }
            break;
   
         case 3: //VALID
               switch (EPStatus)
               {
                  case 0:
                    buff^=0x0030; buff&=0x8FBF; break; //TX
                  case 1:
                     buff^=0x0020; buff&=0x8FBF; break; //TX
                  case 2:
                     buff^=0x0010; buff&=0x8FBF; break; //TX
                  case 3:
                     break;
               }
            break;


         default: break;
        }
    }
   
    else  //////////////////////////////////////// RXTX = 0 = RX
    {
       stat = (buff>>12) & 3;
      switch (stat)
          {
         case 0: //DISABLE
               switch (EPStatus)
               {
                  case 0:
                    break;
                  case 1:
                     buff^=0x1000; buff&=0xBF8F; break; //RX
                  case 2:
                     buff^=0x2000; buff&=0xBF8F; break; //RX
                  case 3:
                     buff^=0x3000; buff&=0xBF8F; break; //RX
               }
            break;

         case 1: //STALL
               switch (EPStatus)
               {
                  case 0:
                    buff^=0x1000; buff&=0xBF8F; break; //RX
                  case 1:
                    break;
                  case 2:
                     buff^=0x3000; buff&=0xBF8F; break; //RX
                  case 3:
                     buff^=0x2000; buff&=0xBF8F; break; //RX
               }
            break;
               
         case 2: //NAK
               switch (EPStatus)
               {
                  case 0:
                    buff^=0x2000; buff&=0xBF8F; break; //RX
                  case 1:
                     buff^=0x3000; buff&=0xBF8F; break; //RX
                  case 2:
                     break;
                  case 3:
                     buff^=0x1000; buff&=0xBF8F; break; //RX
               }
            break;
   
         case 3: //VALID
               switch (EPStatus)
               {
                  case 0:
                    buff^=0x3000; buff&=0xBF8F; break; //RX
                  case 1:
                     buff^=0x2000; buff&=0xBF8F; break; //RX
                  case 2:
                     buff^=0x1000; buff&=0xBF8F; break; //RX
                  case 3:
                     break;
               }
            break;

        }      
    }
   
  ((uint32_t*)0x40005C00)[EPNum]=buff;
   
 }


const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
{
    0x12, // размер данного дескриптора
    0x01, // тип данного дескриптора - device descriptor
    0x00, 0x02, // 2 байта - версия usb 2.0
    0x02, // класс устройства cdc
    0x00, // подкласс
    0x00, // протокол
    0x40, // USB_MAX_PACKET0, // max размер пакета для нулевой конечной точки
    0x83, 0x04, // 2 байта - VID
    0x40,   0x57,// 2 байта - PID
    0x00, 0x02,// 2 байта - версия (ревизия) устройства
    0x01, // индекс строки с названием производителя
    0x02, // индекс строки с названием устройства
    0x03, // индекс строки с серийным номером устройства
    0x01 // количество поддерживаемых конфигураций
};



   

void MyUSBinit(void)
{

   uint32_t temp2;
   
/*Тактируем ядро*/   
   //RCC->CR |= RCC_CR_HSION; //Включить генератор HSI
   //RCC->CR &= ~RCC_CR_HSEON;
   RCC->CFGR &= ~RCC_CFGR_SW; //Очистка битов выбора источника тактового сигнала
   RCC->CR |= RCC_CR_HSEON;
   
//   FLASH->ACR |= FLASH_ACR_HLFCYA;
  FLASH->ACR |= FLASH_ACR_LATENCY_1;
  FLASH->ACR |= FLASH_ACR_PRFTBE;
   while((FLASH->ACR & FLASH_ACR_PRFTBS)==0) {}
   
  while((RCC->CR & RCC_CR_HSERDY)==0) {} //Ожидание готовности HSE
 
   RCC->CFGR |= RCC_CFGR_PLLSRC; //Источником сигнала для PLL выбран HSE (внешний - кварц на 8 МГц)
  RCC->CR &= ~RCC_CR_PLLON; //Отключить генератор PLL
  RCC->CFGR &= ~RCC_CFGR_PLLMUL; //Очистить PLLMULL
  RCC->CFGR |= RCC_CFGR_PLLMUL_0 | RCC_CFGR_PLLMUL_1 | RCC_CFGR_PLLMUL_2; //Коефициент умножения 9  (будет 72 МГЦ)
  RCC->CFGR |= RCC_CFGR_PPRE1_2;
   RCC->CR |= RCC_CR_PLLON; //Включить генератор PLL
  while((RCC->CR & RCC_CR_PLLRDY)==0) {} //Ожидание готовности PLL
   

      
 
  //Переключиться на тактирование от PLL
    //
   RCC->CFGR |= RCC_CFGR_SW_1 ; //Выбрать источником тактового сигнала PLL
      
  while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1) {} //Ожидание переключения на PLL
   
/*Тактируем периферию*/      
   RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOEEN; // Включаем тактирование портов А и Е
   RCC->CFGR &= ~RCC_CFGR_USBPRE; // Настраиваем частоту USB (= частота ядра / 1.5)
   RCC->APB1ENR |=   RCC_APB1ENR_USBEN; // Включаем тактирование USB от шины APB1
   RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Включаем тактирование SYSCFG (хз что это, но так надо :) )

      /*----------*/
   
/*Настраиваем Порт А*/      
  GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12; // Скорость 50 МГц
   GPIOA->MODER |= GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1; // Режим альтернативной функции (для USB)
   //GPIOA->OTYPER = 0x00000000;
   //GPIOA->PUPDR |= GPIO_PUPDR_PUPDR12_0;
   GPIOA->AFR[1] |= 0x000EE000; // Номер и пины альтернативной фунции (у нас пины 11 и 12 для альтернативной функции номер 14 - USB)
   
/*Настраиваем Порт Е*/         
  GPIOE->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8 | GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10 |
                     GPIO_OSPEEDER_OSPEEDR11 | GPIO_OSPEEDER_OSPEEDR12 | GPIO_OSPEEDER_OSPEEDR13 |
                      GPIO_OSPEEDER_OSPEEDR14 | GPIO_OSPEEDER_OSPEEDR15; // Скорость для указанных пинов 50 МГц
   GPIOE->MODER |= GPIO_MODER_MODER8_0 | GPIO_MODER_MODER9_0 | GPIO_MODER_MODER10_0 |
                   GPIO_MODER_MODER11_0 | GPIO_MODER_MODER12_0 | GPIO_MODER_MODER13_0 |
                   GPIO_MODER_MODER14_0 | GPIO_MODER_MODER15_0; // Указанные пины на выход
   //GPIOE->OTYPER = 0x00000000;
   //GPIOE->PUPDR = 0x00000000;
   //GPIOE->AFR[1] |= 0x00000000;
   
      /*----------*/
                                 
  EXTI->RTSR |= EXTI_RTSR_TR18; // внешнее прерывание №18 (USBWakeUp) по возрастающему фронту
  EXTI->IMR |= EXTI_IMR_MR18; // Включаем прерывание по пинам
  //EXTI->EMR |= EXTI_EMR_MR18; // Включаем прерывание по событию (USBWakeUp - по обнаружению устройства)
      
      /*----------*/
         
   
  //NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 8);   
   NVIC_EnableIRQ(USBWakeUp_IRQn); //   Разрешаем глобально прерывание USBWakeUp
  //NVIC_SetPriority(USBWakeUp_IRQn, 3);   // Приоритет прерывания (не могу определится для USB)
      
      /*----------*/                                                      

//здесь нужно включаить вит подтяжки резистора (но на плате STM32F3Discovery он припаян)

//USB->CNTR = 0x3;

*(__IO uint32_t*)(0x40006100) = 0;

USB->CNTR &= ~USB_CNTR_PDWN;             

for ( temp2=10000000; temp2 != 0; temp2--);

//
USB->CNTR &= ~USB_CNTR_FRES;
//USB->CNTR = 0;
USB->ISTR = 0;

USB->CNTR |= USB_CNTR_RESETM; // | USB_CNTR_ERRM; // | USB_CNTR_CTRM;
//

NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn);

  }

void USB_LP_CAN_RX0_IRQHandler(void)
{
//uint8_t tmp = 0;   


if (USB->ISTR & USB_ISTR_CTR)
{
    //while ((USB->ISTR & USB_ISTR_CTR) != 0)
      // {
   USB->ISTR &= ~USB_ISTR_CTR;
   //test1 = *(__IO uint32_t*)(0x400060C1);
   //test1 = (*(__IO uint32_t*)(USB_EP0R));
   
         
   if ((USB->EP0R & USB_EP_CTR_TX) != 0)
   {         

             test1 = USB->EP0R;
         USB_EP0_BIT[7] = 0; // сброс CTR_TX - бит 7
          test2 = USB->EP0R;

        //  if (FlagAddress){USB_REGISTR->DADDR+=ConfigPacket.wValue;FlagAddress=0;} //назначаем полученный адрес

        SetRXTX(0, 3, 1); //to Valid TX

   }   

 
   if ((USB->EP0R & USB_EP_CTR_RX) != 0)
   {   
      test1 = USB->EP0R;
     USB_EP0_BIT[15] = 0; // сброс CTR_RX
      test2 = USB->EP0R;
   switch    (*(__IO uint32_t*)(0x40006101))
    {
      
      case 0x06:
         test6 = USB->EP0R;
       for (i = 0; i < 18; i+=2) // i = 18
        {
           TXBuff = Virtual_Com_Port_DeviceDescriptor[i] + (Virtual_Com_Port_DeviceDescriptor[i+1] << 8);   
        *(__IO uint16_t*)(0x40006080 + i*2) = TXBuff;
        }
         *(__IO uint32_t*)(0x40006004) = 0x0012; // i = 0x0012
            
         
        test3 = USB->EP0R;
          SetRXTX(0, 3, 1); // to Valid TX
             test5 = USB->EP0R;
          SetRXTX(0, 3, 0); // to Valid RX
            test2 = USB->EP0R;
         break;
     }
   


   }
   i = 0;
  //}   
}



 if (USB->ISTR & USB_ISTR_RESET)
  {
   USB->ISTR = 0;
   USB->CNTR |= USB_CNTR_CTRM | USB_CNTR_RESETM; // | USB_CNTR_ESOFM  | USB_CNTR_SOFM;
   USB->BTABLE = BTableOffset; // таблица начинается с 0x0000
   

   *(__IO uint32_t*)(0x40006000) = (uint16_t)  0x40; // начальный адрес USB_ADDR0_TX (такой адрес позволяет в дальнейшем добавить все 8 возможных контрольных точек, каждая имеет размер 1 байт)
   *(__IO uint32_t*)(0x40006004) = (uint16_t) 0x40; // размер исходящих данных - 64 байта USB_COUNT0TX
   *(__IO uint32_t*)(0x40006008) = (uint16_t) 0x80; // начальный адрес USB_ADDR0_RX
   *(__IO uint32_t*)(0x4000600C) = (uint16_t) 0x8400; // 64 байта входящих данных USB_ USB_COUNT0RX_BL_SIZE


   USB->EP0R   |= USB_EP_CONTROL; // режим - CONTROL
 
  USB->EP0R   |= USB_EP_TX_NAK; // Готовы к передаче, но данных для передачи нет
  USB->EP0R   |= USB_EP_RX_VALID; // К приему готов   
      test4 = *(__IO uint32_t*)(0x40006100);

   USB->DADDR |= USB_DADDR_EF;
 
  //   test1 = *(__IO uint32_t*)(0x40005C00);
   //   *(__IO uint32_t*)(0x420B8004) = 1;
   //   test2 = *(__IO uint32_t*)(0x40005C00);
   //   test3 = *(__IO uint32_t*)(0x40005C00);
   //   test4 = *(__IO uint32_t*)(0x40005C00);
      
}
   
   
///////////////
   
   
   
      
  }


//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
 /*---------- descriptor----------------------------------*/
//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////




// configuration descriptor
const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
{
    /* ============== CONFIGURATION 1 =========== */
    /* Configuration 1 descriptor */
    0x09, // размер дескриптора конфигурации
    0x02, // тип дескриптора - configuration
    0x43, // 2 байта - полный размер дескриптора, включая др. дескрипторы
    0x00, // (CwTotalLength 2 EP + Control)
    0x02, // количество интерфейсов (2 интерфейса для CDC - data и config)
    0x01, // номер данной конфигурации (SET_CONFIGURATION)
    0x00, // индекс строки описывающий данную конфигурацию
    0xC0, // битовое поле, характеризующее конфигурацию
        /*
        Распределение бит:
        D7 – зарезервировано (установлено в 1);
        D6 – признак наличия собственного источника питания;
        D5 – признак разрешения сообщения хосту о выходе
        устройства из режима «сна»;
        D4...D0 – зарезервированы (сброшены в 0)
        */
    0x00, // max потребляемый ток от шины (половина от реального (50 = 100мА))

        /* Communication Class Interface Descriptor Requirement */
        0x09, // длина дескриптора
        0x04, // тип дескриптора - интерфейс
        0x00, // номер данного интерфейса
        0x00, // номер альтернативной установки для интерфейса
        0x01, // количество точек для данной альтернативной установки в данном интерфейсе
        0x02, // код класса(USB-IF)
        0x02, // код подкласса(USB-IF)
        0x00, // код протокола(USB-IF)
        0x01, // индекс строки, описывающей данную альтернативную установку данного интерфейса

    /* Header Functional Descriptor */
    0x05, // bFunction Length
    0x24, // bDescriptor type: CS_INTERFACE
    0x00, // bDescriptor subtype: Header Func Desc
    0x10, // bcdCDC:1.1
    0x01,

    /*Call Management Functional Descriptor */
    0x05, /* bFunctionLength */
    0x24, /* bDescriptorType: CS_INTERFACE */
    0x01, /* bDescriptorSubtype: Call Management Func Desc */
    0x00, /* bmCapabilities: device handles call management */ //!!!!!!!!!!!!!!!!!!1
    0x01, /* bDataInterface: CDC data IF ID */

        /* ACM Functional Descriptor */
        0x04, // bFunctionLength
        0x24, // bDescriptor Type: CS_INTERFACE
        0x02, // bDescriptor Subtype: ACM Func Desc
        0x02, // bmCapabilities

    /* Union Functional Descriptor */
    0x05, // bFunctionLength
    0x24, // bDescriptorType: CS_INTERFACE
    0x06, // bDescriptor Subtype: Union Func Desc
    0x00, // bMasterInterface: Communication Class Interface
    0x01, // bSlaveInterface0: Data Class Interface

        /* Endpoint 1 descriptor */
        0x07, // размер дескриптора
        0x05, // тип дескриптора - endpoint
        0x81, // битовое поле адреса точки // IN
            /*
            D7 – направление передачи данных точкой (1 – IN, 0 – OUT);
            D6...D4 – зарезервированы (сброшены в 0);
            D3...D0 – адрес точки
            */
            0x03, // битовое поле, характеризующее точку
            /*
            D7, D6 – зарезервированы (сброшены в 0);
            D5, D4 – функция, выполняемая точкой:
            00 – точка данных;
            01 – точка обратной связи;
            10 – точка данных с неявной обратной связью;
            11 – зарезервировано
            D3, D2 – тип синхронизации хоста и точки:
            00 – без синхронизации;
            01 – асинхронный;
            10 – адаптивный;
            11 – синхронный
            D1, D0 – тип обмена данными:
            00 – контрольный;
            01 – изохронный;
            10 – bulk;
            11 – interrupt
            */

        64, // 2 байта - битовое поле 
            // характеризующее размер пакета передаваемых данных

        0x00,   /*
            D15…D13 – зарезервированы (сброшены в 0);
            D12, D11 – количество дополнительных передач:
            00 – нет дополнительных передач;
            01 – 1 дополнительная передача (всего 2 передачи),
            10 – 2 дополнительные передачи (всего 3 передачи);
            11 – зарезервировано.
            D10...D0 – размер пакета в байтах
            */
        0xFF, // интервал готовности точки к обмену данными

    /* Data Class Interface Descriptor Requirement */
    0x09, // bLength
    0x04, // bDescriptorType
    0x01, // bInterfaceNumber
    0x00, // bAlternateSetting
    0x02, // bNumEndpoints
    0x0A, // bInterfaceClass
    0x00, // bInterfaceSubclass
    0x00, // bInterfaceProtocol
    0x04, // iInterface


    /* Endpoint 2 descriptor */
    0x07, // bLength
    0x05, // bDescriptorType
    0x02, // bEndpointAddress, Endpoint 01 - OUT
    0x02, // bmAttributes BULK
    64, // wMaxPacketSize
    0x00,
    0x00, // bInterval

    /* Endpoint 3 descriptor */
    0x07, // bLength
    0x05, // bDescriptorType
    0x83, // bEndpointAddress, Endpoint 02 - IN
    0x02, // bmAttributes BULK
    64, // wMaxPacketSize
    0x00,
    0x00 // bInterval
};

/* USB String Descriptors */
const uint8_t Virtual_Com_Port_StringLangID[] =
{
    0x04, // длина дескриптора
    0x03, // тип дескриптора - string desc
    0x09, // N байт индетификатор языка
    0x04 /* LangID = 0x0409: U.S. English */
};

const uint8_t Virtual_Com_Port_StringVendor[] =
{
    10, // длина дескриптра
    0x03, // тип дескриптора - string desc
    /* имя */
    'T', 0,
    'E', 0,
    'S', 0,
    'T', 0
};

const uint8_t Virtual_Com_Port_StringProduct[] =
{
    10, // длина дескриптра
    0x03, // тип дескриптора - string desc
    /* имя */
    'T', 0,
    'E', 0,
    'S', 0,
    'T', 0
};

const uint8_t Virtual_Com_Port_StringSerial[] =
{
    10, // длина дескриптра
    0x03, // тип дескриптора - string desc
    /* имя */
    'T', 0,
    'E', 0,
    'S', 0,
    'T', 0
};




Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Пн июл 25, 2016 12:49:29 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Сидел. Читал. Наткнулся на такой текст:
Цитата:
Хост отправляет токен Setup, говорящий функции, что следующий пакет будет пакет Setup. Поле адреса будет содержать адрес устройства, от которого главный компьютер просит дескриптор. Номер конечной точки должен быть 0, что указывает канал по умолчанию (default pipe). Затем хост отправит пакет DATA0. Он будет содержать 8 байт полезной нагрузки, которая будет являться запросом Device Descriptor Request. Функция USB подтверждает пакет setup, что он был прочитан корректно, без ошибок.

Не значит ли это, что после принятия дескриптора устройства мне нужно как-то сказать хосту о том, что я его получил (типа - отправкой пакета нулевой длины)? Или это подтверждение выполняется на железном уровне самостоятельно?
А еще и вот:
Цитата:
Хост отправляет токен IN, чем говорит устройству, что он может теперь отправить данные для этой конечной точки. Поскольку максимальный размер пакета 8 байт, мы должны для отправки разделить 12 байт дескриптора устройства на кусочки. Каждый кусочек должен быть размером по 8 байт, за исключением последней транзакции. Хост подтверждает каждый пакет, который мы посылаем ему.

Однако, я где-то читал, что для STM32 делить control пакет не нужно. Где всё-таки правда? :dont_know:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Пн июл 25, 2016 18:30:45 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2708
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
isx писал(а):
Не значит ли это, что после принятия дескриптора устройства мне нужно как-то сказать хосту о том, что я его получил
По-моему это значит Вам пора отдохнуть и потом начать все заново. Как устройство может получить дескриптор устройства и зачем это знать хосту?
isx писал(а):
Однако, я где-то читал, что для STM32 делить control пакет не нужно. Где всё-таки правда?
Все управляющие пакеты будут для нулевой точки. Т.е. выделять как-то отдельно обрабатывать управляющие пакеты нет смысла.

Я так понимаю, Вы собрались сделать USB UART. Как я понимаю у Вас два пути. Это сделать полную копию какого-то устройства которое знает Винда, т.е. не только дескрипторы повторить, но и протокол обмена. Или же сделать свое и написать драйвер. Какое у Вас решение?

Можно сделать свое HID устройство. Для этого уже в этом топике все есть. Да я Вам весь код выложил своего устройства, хорош он или плох, но работает.

Читаете теорию снова и на этот раз не один раз, а перечитываете(до меня, например, такие вещи не доходят с первого раза). Читаете данный топик сначала, Вами же созданный и все у Вас получится. С виртуальным COM портом не помогу, не знаю.

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Пн июл 25, 2016 19:26:39 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Z_h_e писал(а):
Как устройство может получить дескриптор устройства и зачем это знать хосту?

Прошу прощения, имел ввиду запрос дескриптора устройства.
Z_h_e писал(а):
Все управляющие пакеты будут для нулевой точки. Т.е. выделять как-то отдельно обрабатывать управляющие пакеты нет смысла.

Не то, чтобы выделять. Просто, как я понял смысл этих строк - пока хост полностью не получит дескриптор устройства, он за раз принимает данные не более 8 байт.
Цитата:
Поскольку максимальный размер пакета 8 байт, мы должны для отправки разделить 12 байт дескриптора устройства на кусочки. Каждый кусочек должен быть размером по 8 байт, за исключением последней транзакции.

Источник вроде нормальный - многие на форумах на него ссылаются (http://microsin.ru/content/view/1107/44/)
Z_h_e писал(а):
Я так понимаю, Вы собрались сделать USB UART.

Я хочу просто запустить USB :))
Z_h_e писал(а):
Какое у Вас решение?

Вообще хочу виртуальный COM порт сделать для начала. Только вот пока не удается даже запрос на второй дескриптор получить, а может и скормить первый.
Единственная причина, по которой сейчас запрос на второй дескриптор может не приходить - это неверный порядок действий после получения первого запроса. Данные в буфер записываются нормально, но вот что происходит дальше - передались ли они или же передача не состоялась - загадка :dont_know: .
Ни на каком ресурсе не могу найти простое описание действий (без SPL, HAL и самопальных библиотек), а я нормально читать чужие огороды загадочных для меня функций пока не получается, хоть тресни :kill:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Вт июл 26, 2016 20:45:49 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
isx писал(а):
Не то, чтобы выделять. Просто, как я понял смысл этих строк - пока хост полностью не получит дескриптор устройства, он за раз принимает данные не более 8 байт.

Похоже нашел правду :) :
Цитата:
The USB driver stack issues a request for the USB Device Descriptor (GET_DESCRIPTOR for Descriptor Type DEVICE), using the default USB address of 0, and a maximum packet size of 8 bytes for low-speed devices and 64 bytes for full and high-speed devices.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Ср июл 27, 2016 12:53:42 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Вот еще вопрос:
Почему мы отправляем на первый запрос дескриптора устройства 18 байт, если хост от нас требует 64?
Цитата:
bmRequestType 0x80
bRequest 0x6
wValue 0x100
wIndex 0x0
wLength 0x40


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Ср июл 27, 2016 12:59:36 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2708
Откуда: г. Чайковский
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
Мы уже обсуждали это здесь и вроде даже не один раз. Хост требует "не более".

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Ср июл 27, 2016 18:46:48 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Сделал что-то типа лога срабатывающих прерываний.
У меня используются 4 флага прерывания:
RESET (тут понятное дело, настройки контрольной точки)
SETUP (просто так, в нем ничего не происходит)
CTR_RX (отправка 18-ти байт дескриптора устройства)
CTR_TX (установка STAT_RX в VALID)
Внутри каждого прерывания поместил строки:
Код:
TestBuff[CountTestBuff] = Х;
CountTestBuff++;

Изначально CountTestBuff = 0. Значение Х зависит от того, по какому флагу произошло прерывание. Так для:
Цитата:
RESET = 9
SETUP = 5
CTR_RX = 8
CTR_TX = 7


В итоге массив заполняется такими значениями:
Цитата:
9,5,8,7, 9,5,8,7, 9,5,8,7, 9,5,8,7, 0.0.0......

а затем вылетает окошко в Windows "Неопознанное устройство"
Почему-то после прерывания по CTR_TX я опять вылетаю в ресет и все шаги повторяются. Во входящем буфере при этом после первого ресета постоянно висит первый запрос дескриптора устройства. :dont_know:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Ср июл 27, 2016 19:58:26 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2708
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Сдался вам этот сетап. У меня сейчас нет возможности проверить, но наверняка флаги сетап и rx устанавливпются одновременно, а вы их поди как два разных события обрабатываете. В этом топике мой код полностью выложен, только в разных постах. Соберите,не поленитесь. Дескрипторы не могу выложить физически, только их и не выкладывал, я на телефоне и долго компа не увижу .

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Ср июл 27, 2016 20:13:49 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Z_h_e писал(а):
но наверняка флаги сетап и rx устанавливаются одновременно, а вы их поди как два разных события обрабатываете

Я SUTUP сегодня только поставил, чисто для проверки. В нем кроме заполнения массива нет ничего.
Z_h_e писал(а):
Дескрипторы не могу выложить физически, только их и не выкладывал, я на телефоне и долго компа не увижу .

В дескрипторах нет необходимости - у меня второй запрос все-равно не приходит, а дескриптор устройства я нашел в статье в интернете, потом сверил с другими форумами и с книгой Агурова. Там все сходится...
Пытаюсь сверяться, с Вашим кодом. Пока вроде все сходится, но не уверен что все правильно трактую. В выходные попробую выкроить время и свести все в одну кучу, может что и прояснится...

P.S. Если у меня происходит прерывание по CTR_TX после CTR_RX (в котором мы отправляли дескриптор устройства), то это значит, что МК осуществил передачу дескриптора хосту, и дальнейшая судьба пакета ему не известна? Или это говорит о том, что дескриптор дошел до хоста и хост сообщил о его принятии?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Ср авг 03, 2016 10:46:51 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Начал собирать Ваш код (Z_h_e). Сразу напоролся на грабли:
Цитата из первой страницы :
Спойлер
Код:
void USB_Reset(void)
{

   USB_REGISTR->BTABLE=0;//адрес таблицы дескрипторов таблицы  в выделенной памяти

//Настройка буфера EP0
   DiscrTable->ADR0TX=0x0040;
   DiscrTable->COUNT0TX=0x0000; //макс 0x80
   DiscrTable->ADR0RX=0x0100;
   DiscrTable->COUNT0RX=0b1011000000000000; //размер буфера 0x80 (128)байт

//Регистры конечных точек 0
   USB_REGISTR->EP0R=0x0|      //номер точки
         bit13|bit12|      //STAT_RX - VALID
//         bit8 |//какой то  статус аут
         bit5|//bit4|      //STAT_TX - NAK
         /*bit10|*/   bit9 ;  /*00 BULK   //10-9 тип точки. в данном случае Контрол
                        01 CONTROL
                        10 ISO
                        11 INTERRUPT*/

   USB_REGISTR->DADDR=bit7;//EF:Enable function, Включение ЮСБ с нулевым адресом

   FlagAddress=0; //устройство не пришла команда установки адреса
//   FlagZLP=0;

}


Имеются две проблемы.
1. Если USB_REGISTR->DADDR=bit7; ставить в конце (после настройки точки 0), то регистр EP0 не меняется и остается не настроенным (EP0 = 0).
2. USB_REGISTR->EP0R у Вас использует какую-то функцию установки битов или просто работает с дефайнами из CMSIS (доступ к битам через |=)? Если второй случай, то происходит вот что:
При первом резете, (когда ещё EP0 = 0) STAT биты ставятся как положено (VALID и NAK), но после второго ресета регистр EP0 не сбрасывается и при повторной обработке через |= происходит сброс STAT битов.
Что я опять не так делаю? :dont_know:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Ср авг 03, 2016 15:54:12 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 651
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2708
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Я уже начал забывать что делал, но все то чтоя выложил рабочее. Инициализацию юсб где то тоже выложил. Обработчик прерывания тоже.

После сброса, регистры сбрасываются. Поэтому я прямо пишу в регистр EPnR, безо всякого |=. Ну это же Вы и так видите.

Почему у Вас они не сбрасываются я не знаю. Может из-за того что мк другой, а может Вы ложно заходите в обработчик сброса.

_________________
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Вт авг 16, 2016 15:02:09 
Открыл глаза
Аватар пользователя

Зарегистрирован: Пн июн 14, 2010 17:09:55
Сообщений: 45
Откуда: Москва
Рейтинг сообщения: 0
isx писал(а):
Сделал что-то типа лога срабатывающих прерываний.
.....
SETUP (просто так, в нем ничего не происходит)
.....
В итоге массив заполняется такими значениями:
Цитата:
9,5,8,7, 9,5,8,7, 9,5,8,7, 9,5,8,7, 0.0.0......

а затем вылетает окошко в Windows "Неопознанное устройство"
Почему-то после прерывания по CTR_TX я опять вылетаю в ресет и все шаги повторяются. Во входящем буфере при этом после первого ресета постоянно висит первый запрос дескриптора устройства. :dont_know:


Э, а как это в SETUP ничего не происходит? Ясен пень "ресет и все шаги повторяются".
Я ж уже скидывал ссылку где расписан процесс энумерации устройства. Давайте по порядку:
1. Reset. Поймали сброс, контроллер готов к приему следующих команд по адресу 0 в нулевую КТ.
2. Получаем пакет типа Setup. Смотрим что это за пакет в полях bRequest wValue - должен быть запрос дескриптора устройства.
2.1 После этого Хост долбит контроллер запросами типа IN. Если мне не изменяет память - тут надо по-моему отправить пакет нулевой длинны, чтоб комп понял, что мы приняли пакет.
3. Загружаем дескриптор в пакетную память и разрешаем отправку установкой соответствующих значений (что отправлять и в каком количестве). Об этом уже говорилось.
4. Получаем от компа пакет нулевой длинны - это значит что комп распознал наш пакет.
5. Должен прийти Setup пакет но с запросом Set address. После этого Хост долбит контроллер запросами типа IN. Контроллер должен отправить пакет нулевой длинны.
6. Отвечаем пакетом нулевой длинны.
7. Устанавливаем полученный адрес от хоста в соотв. региср.
8. Хост опять запрашивает дескриптор..
и так далее.
Вот эти шаги должны быть у вас 100%.
Мой контроллер STM32C8T6 с кварцем на 12 МГц. Если уж сможете в коде разобраться - смогу выслать свою прошивку. Но предупреждаю - я не дошел до логического конца. Завалился на запросе дескриптора конфигурации. Я об этом писал.
Да, выслать смогу не сразу, сейчас нет доступа к прошивке.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Сб авг 20, 2016 08:57:41 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2316
Рейтинг сообщения: 0
Radist_M писал(а):
2.1 После этого Хост долбит контроллер запросами типа IN. Если мне не изменяет память - тут надо по-моему отправить пакет нулевой длинны, чтоб комп понял, что мы приняли пакет.

Вот про это хотелось бы по точнее. Я как-то спрашивал на форуме про ZLP после приема запроса дескриптора, но мне сказали, что делать этого не нужно :dont_know: .
Сегодня может время появится, попробую с ZLP - вариантов все-равно пока других нет....


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 583 ]     ... , , , 8, , , ...  

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y