STM32 и USB (практика)

Кто любит RISC в жизни, заходим, не стесняемся.
Serg1987
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн июн 13, 2016 10:41:52

Re: STM32 и USB (практика)

Сообщение Serg1987 »

Если не ошибаюсь, то момент соединения с шиной обозначается прерыванием по РЕСЕТ.
У меня в STM32F303 тоже нет бита подтяжки. На плате резистор тупо припаян.


Собрал схему, для проверки достал где-то ещё завалявшуюся плату STM32 H-103.

По поводу событий при подключении..
прерывание по РЕСЕТ.?
Нет, мне кажется, не совсем так. Подробнее. Первое событие RESET - это сброс FRES. Тут мы включаем тактирование, настраиваем флаги и т.д. По первому РЕСЕТу мы только конфигурируем и настраиваем девайс. Но на данном этапе данный RESET никак не свидетельствует о подключении шины.

Об подключении к шине непосредственно свидетельствует второй РЕСЕТ (флаг в ISTR первого РЕСЕТа не забываем очистить), о котором и упомянул Z_h_e, и который отправляется уже хостом. Но до этого хаб определяет наличие подтяжки D+. Тут я и стал.(Схему собрал, но не работает). Какое событие отвечает за обнаружение подтяжки D+. ?

Весь процесс я понимаю, идет так:
- после включения девайса (только девайса, без подключения к шине) (и после конфигурирования модуля)устанавливается событие SUSP (более 3мс отсутствия активности на шине). Контроллер успешно уводит девайс в данный режим. Выставляется флаг. Флаг от первого РЕСЕТа (который по сбросу FRES) очищаем. Ждем второго РЕСЕТа от компа.
- в это время (после установления SUSP) при подключении к шине должно произойти событие WKUP :dont_know: (пробуждение устройства и сброс бита low-power mode). Т.е. тут девайс должен определить наличие подтяжки и дать компу информацию о своем присутствии на шине.

Но последнее (именно событие WKUP) почему-то не проходит. Втыкаю девайс в комп - прерывание по WKUP молчит. Такое на двух платах. И на своей и на заводской от Olimex.
Serg1987
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн июн 13, 2016 10:41:52

Re: STM32 и USB (практика)

Сообщение Serg1987 »

Уже совсем замучился. Девайс стабильно уходит в режим приостановки SUSPEND. Именно это прерывание и срабатывает. :cry:
Serg1987
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн июн 13, 2016 10:41:52

Re: STM32 и USB (практика)

Сообщение Serg1987 »

:cry: В общем вот. Всё перепроверил. Вроде всё верно. Но при подключении шнура USB комп ожидаемый Reset не отдает ну никак. При включении прерывания SUSP (пока закомментил) устройство уходит в приостановленный режим. РЕСЕТа нет.

Код: Выделить всё

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "defusb.h"

void UsbInit();


//Инициализация USB
void UsbInit()
{
   //делитель USB равен 1
   RCC->CFGR |= RCC_CFGR_USBPRE;
   //Разрешаем USB
   RCC->APB1ENR |= RCC_APB1ENR_USBEN;

   //Включаем USB
        USB->CNTR &= ~USB_CNTR_PDWN;
   //Тактируем
   USB->CNTR &= ~USB_CNTR_FRES;

   //Очистка флагов событий USB
   USB->ISTR = 0;

   //Разрешаем прерывания
   NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
   NVIC_SetPriority (USB_LP_CAN1_RX0_IRQn, 2);
   NVIC_EnableIRQ(USBWakeUp_IRQn);

   EXTI->RTSR |= EXTI_RTSR_TR18; // прерывание №18
   EXTI->IMR |= EXTI_IMR_MR18; // прерывание по выводам
   EXTI->EMR |= EXTI_EMR_MR18; // прерывание по WU

   //Настройка масок прерываний
   USB->CNTR |=USB_CNTR_RESETM;
       //| USB_CNTR_CTRM
       //| USB_CNTR_WKUPM
   //| USB_CNTR_PMAOVRM
   //| USB_CNTR_ERRM
   //| USB_CNTR_WKUPM
   //| USB_CNTR_SUSPM
   //| USB_CNTR_RESETM
   //| USB_CNTR_SOFM
   //| USB_CNTR_ESOFM;

}


int main(void)
{
    __enable_irq ();
//*****Настройка тактирования
   //сброс системы тактирования
   RCC_DeInit();

   //Включаем HSE
   RCC->CR |= RCC_CR_HSEON;
   //Ждем готовности HSE
   while((RCC->CR & RCC_CR_HSERDY) == 0) {}
   //Предделитель AHB
   RCC->CFGR |= RCC_CFGR_HPRE_0;
   //Очистка регистра умножителя PLL
   RCC->CFGR &= ~RCC_CFGR_PLLMULL;
   //источник PLL от внешнего кварца
   RCC->CFGR |= RCC_CFGR_PLLSRC_HSE;
   //умножитель PLL x6
   RCC->CFGR |= RCC_CFGR_PLLMULL6;
   //Включаем PLL
   RCC->CR |= RCC_CR_PLLON;
   //Ждем готовности PLL
   while((RCC->CR & RCC_CR_PLLRDY) == 0) {}
   //очистка регистра  SW
   RCC->CFGR &= ~RCC_CFGR_SW;
   //выбор источника тактирования PLL
   RCC->CFGR |= RCC_CFGR_SW_1;
   //Ожидание включения PLL
   while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1) {}

    //Включим тактирование - порт A, B,C и альтернативного режима
   RCC->APB2ENR |= RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN|RCC_APB2ENR_AFIOEN;
   //Очищаем регистр альтернативных функций
    //AFIO->MAPR &= 0xFFFFFFFE;
    // НОЖКА C9
    GPIOC->CRH &= ~GPIO_CRH_CNF12_0 & ~GPIO_CRH_CNF12_1;
    GPIOC->CRH |=  GPIO_CRH_MODE12;
    GPIOC->ODR |=  GPIO_ODR_ODR12;

   UsbInit();

    while(1)
    {
       
    }
}


void USB_LP_CAN1_RX0_IRQHandler(void)
{
   USB->BTABLE=0;
        //Втыкаем и ждем сброса от хоста
   if ((USB->ISTR & USB_ISTR_RESET))
       {
      USB->ISTR &= ~USB_ISTR_RESET;
      USB_Reset();
      return; //выходим из обработчика прерываний
       }

}


Есть мысли? Резистор стоит. Подтяжка внешняя. При выставлении SUSP в CNTR уходит в Suspend (т.е. спячку)
Аватара пользователя
Radist_M
Открыл глаза
Сообщения: 45
Зарегистрирован: Пн июн 14, 2010 17:09:55
Откуда: Москва

Re: STM32 и USB (практика)

Сообщение Radist_M »

А может ну его нафиг эти SUSP и WKUP?
На первых порах мне хватало 2-х событий - RESET и CTR (correct transfer).

Код: Выделить всё

void USB_INIT(void)
{
   RCC->CFGR |=RCC_CFGR_USBPRE;//выставляю делитель на 1 (работаю сразу на 48МГЦ)      
   RCC->APB1ENR |= RCC_APB1ENR_USBEN;//USB clock enabled      
   USB->CNTR &= ~USB_CNTR_PDWN;// включаю USB   
   delay(8);//ждем примерно 1 мкс пока не запустится внутренний ИОН   
   //
   USB->CNTR = 0;//и очищаю FRES   
   delay(1);//ждем немного, чтобы установился флаг резета
   USB->ISTR = 0;//и сбрасываю этот флаг, т.к. всю настройку буду производить уже пофакту резета от компа      
   USB->CNTR = USB_CNTR_RESETM|USB_CNTR_CTRM;//enable reset interrupt, correct transfer
   descr_init();//тут инициализирую таблицу дескрипторов
   NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);// включаю нужное прерывание
   
}


Вот задержка на всякий случай

Код: Выделить всё

void delay(uint32_t val)
{
for(;val!=0;val--)
   {__nop();}
}
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Re: STM32 и USB (практика)

Сообщение isx »

Z_h_e
Скиньте пожалуйста обработчик CTR. Я что-то совсем замучался, не идет второй запрос и все :facepalm:
Serg1987
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн июн 13, 2016 10:41:52

Re: STM32 и USB (практика)

Сообщение Serg1987 »

Продолжу о своих приключениях. Всё разрешилось. На отладочной плате всего-то сгорел буферный транзистор, из-за чего не было подтяжки к D+, и соответственно поэтому не приходил долгожданный RESET. Идем дальше. Сейчас вожусь с контрольными точками и дескрипторами. С первыми вроде всё ясно, но не до конца. Так и не понял, как их настраивать. Перечитал всю ветку. Но так и не понял. :?
Значения скопипастил из постов. :shock:
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Re: STM32 и USB (практика)

Сообщение isx »

Спрашивайте конкретнее что не понятно. У меня уже появилось некоторое представление, может чем и помогу :)
Serg1987
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн июн 13, 2016 10:41:52

Re: STM32 и USB (практика)

Сообщение Serg1987 »

С таблице контрольных точек вроде как разобрался немного. Итак.

Вот.Изображение
Итак. С адресами всё вроде понятно.
Вопрос тут следующий:

Код: Выделить всё

//Настройка буфера 0
   Table->ADR0TX=0x0000;
   //количество данных для передачи хосту (32 байт)
   Table->COUNT0TX=0x0020;
   Table->ADR0RX=0x0100;
   //количество принимаемых данных от хоста(32 байт)
   Table->COUNT0RX=0x00004000;


Значение COUNT0RX взял из вашего примера. Но непонятно до конца.
Как именно хекс 0x00004000 соответствует 32-м байтам?

Следующий вопрос. Не до конца понятно, как получить доступ к принятым данным в буфере.
А именно как его прочесть.
Я правильно понимаю, что в USB_ADDRn_RX хранится адрес буфера.
Это значит что данные, которые придут от компа в МК для конечной точки 0, будут лежать по адресу 0x40006000+0x0100*2.

В данном случае данные будут лежать по адресу 0x40006200?!
Но то адрес!.. Туплю. А как с него данные то толком извлечь? Определяю, что мне приходит SETUP пакет. Как вскрыть его содержимое - пока не дошел.

isx, посмотрел ваш код. Меня тут смущает, что адрес приемного буфера у вас нечетный. (выделил) - 0x400060C1. Как такое получилось?
Спойлерswitch (*(__IO uint32_t*)(0x400060C1))
{
case 0x6:

for (i = 0; i < 18; i+=2)
{
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;
USB->EP0R |= USB_EP_TX_VALID;
test1 = USB->EP0R |= USB_EP_TX_VALID;
USB->EP0R |= USB_EP_RX_VALID;
break;
}


Z_h_e. Поясните, пожалуйста, участок кода при заполнении передающего буфера.

Код: Выделить всё

pTXBuf=*pTXBuf*2+0x40006000;


Почему здесь идет умножение на 2.?
Serg1987
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн июн 13, 2016 10:41:52

Re: STM32 и USB (практика)

Сообщение Serg1987 »

А, всё. Кажись въехал.! :P
Так понимаю, нечетный адрес получается, т.к. мы считываем поле Request из пакета SETUP, а у байта Request собственное смещение = 1?
Правильно?
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Re: STM32 и USB (практика)

Сообщение isx »

Serg1987 писал(а):Почему здесь идет умножение на 2.?

Изображение
Мы берем адреса, которые использует USB, а их значение в два раза меньше.
Serg1987 писал(а):Значение COUNT0RX взял из вашего примера. Но непонятно до конца.
Как именно хекс 0x00004000 соответствует 32-м байтам?

Это значение имеет только одну единицу (в бинарном представлении) в бите номер 14. Посмотрить, что это значит в регистре COUNT0RX, а затем загляните в таблицу, которая под этим регистром в даташите.
Serg1987 писал(а):В данном случае данные будут лежать по адресу 0x40006200?!
Но то адрес!.. Туплю. А как с него данные то толком извлечь?

*(__IO uint16_t*)(0x40006080) = TXBuff;
По каждому значению адреса в памяти хранится 4 байта информации, но 3-й и 4-й байты недоступны. Соответственно в моем примере TXBuff получит два байта из адреса. Делаем цикл и читаем данные как из массива в массив.
Вроде так :) .

P.S. А вообще, значение адреса онлайн можно посмотреть в отладчике в KEIL ) .
Serg1987
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн июн 13, 2016 10:41:52

Re: STM32 и USB (практика)

Сообщение Serg1987 »

разбираю его - все четко:

Код: Выделить всё

0x80
0x06 - вот оно - Запрос дескриптора устройства
0x00
0x01
0x00
0x00
0x40
0x00

Да. Но вообще, если делать грамотно, то первый байт нужно также учитывать. Вообще по спецификации бывает 3 запроса на дескриптор (в основном):
GET_DESC_DEVICE: 0x8006
GET_DESC_INTERFACE: 0x8106
GET_DESC_ENDPOINT: 0x8206
Так что учитывать необходимо 2 байта. Я думаю, до этого сам дойду. Пока для отладки использую мониторинг на 0x06, будучи уверенным, что придет именно GET_DESC_DEVICE.
Serg1987
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн июн 13, 2016 10:41:52

Re: STM32 и USB (практика)

Сообщение Serg1987 »

Код: Выделить всё

Мы берем адреса, которые использует USB, а их значение в два раза меньше.

Спасибо, вроде начал вьезжать.
А, понял. Объем памяти в блоке у нас 2 байта (15 бит равен 0). А в поле NUM_BLOCK записано количество блоков. В данном случае в десятичном представлении - это 0d16. 16*2=32.
Поле COUNTn_RX[9:0] заполняется после прихода данных и содержит информацию о кол-ве принятых байт.
Вроде стало на свои места всё. :hunger:
Serg1987
Встал на лапы
Сообщения: 129
Зарегистрирован: Пн июн 13, 2016 10:41:52

Re: STM32 и USB (практика)

Сообщение Serg1987 »

Все равно где-то что-то не то.. :dont_know:
Итак. По участку кода всё проходит отлично:
На сей раз заодно решил светодиодом поиграть

Код: Выделить всё

 switch    (*(__IO uint32_t*)(0x40006081))
          {
          case 0x06:
            GPIOC->BRR |= GPIO_ODR_ODR12;
             break;
          }

Request 0x06 читается.
Но при попытке прочитать значение из адреса 0x40006080 (самый первый байт. ожидаю там 0x80), то этого значения там нет.
Может чего не так делаю.??

Вот, подрисовал рисунок в файле во вложении.
Если у меня читается второй байт по адресу 0x40006081 (значение 0x06. как и должно быть), то почему не читается первый по адресу 0x40006080??
Вложения
yvmzzyqp8.jpg
(36.19 КБ) 418 скачиваний
Последний раз редактировалось Serg1987 Пт июн 17, 2016 17:16:49, всего редактировалось 1 раз.
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Re: STM32 и USB (практика)

Сообщение isx »

Посмотрите в отладчике, какие там у вас значения по адресам.
Изображение
Здесь в строке адреса указано C0, так как в регистр прописано 60 (в два раза меньше, помним :) ). Так можно посмотреть что на самом деле пришло нам в буфер.

P.S. Проглядел. Посмотрите внимательно, что у вас в CASE записано :) .
Вообще не понятно. У вас по адресу .....81 читается 0x06, хотя должно быть 0x60. Возможно вам приходит что-то не то.... :dont_know:
Аватара пользователя
Radist_M
Открыл глаза
Сообщения: 45
Зарегистрирован: Пн июн 14, 2010 17:09:55
Откуда: Москва

Re: STM32 и USB (практика)

Сообщение Radist_M »

Serg1987, а напишите как считываете значение из 0x40006080 и как узнали что не то?


Мне всю дорогу приходит 0x80 0x06 и т.д. 0x81 не встречал.
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Re: STM32 и USB (практика)

Сообщение isx »

Все испробовал. Понятия не имею почему второй запрос не идет. Как только регистры и адреса уже не вертел, но в приемник залетает только дескриптор устройства. :facepalm: :kill:

Спойлер

Код: Выделить всё

void USB_LP_CAN_RX0_IRQHandler(void)
{
   
if (USB->ISTR & USB_ISTR_CTR)
{
    while ((USB->ISTR & USB_ISTR_CTR) != 0)
       {

         
   if ((USB->EP0R & USB_EP_CTR_RX) != 0)
   {         
    USB->EP0R &= ~USB_EP_CTR_RX;
   
    switch    (*(__IO uint32_t*)(0x40006101))
    {
      case 0x6:
         
           for (i = 0; i < 18; i+=2)
        {
           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;
         USB->EP0R   |= USB_EP_RX_NAK;   
        USB->EP0R   |= USB_EP_TX_VALID;
         test1 = USB->EP0R   |= USB_EP_TX_VALID;
         USB->EP0R   |= USB_EP_RX_VALID;
         
         break;
     }
   }   

     }
      if ((USB->EP0R & USB_EP_CTR_TX) != 0)
   {   
   USB->EP0R   |= USB_EP_RX_VALID;   
   }
   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; // размер исходящих данных - 32 байта USB_COUNT0TX
   *(__IO uint32_t*)(0x40006008) = (uint16_t) 0x80; // начальный адрес USB_ADDR0_RX
   *(__IO uint32_t*)(0x4000600C) = (uint16_t) 0x8400; // 32 байта входящих данных USB_ USB_COUNT0RX_BL_SIZE


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

   USB->DADDR |= USB_DADDR_EF;

}
      
}


Вот дескриптор, который я отправляю (брал в интернете, проверял его, но вреде все нормально):

Спойлер

Код: Выделить всё

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 // количество поддерживаемых конфигураций
};


Подскажите пожалуйста, что делать. Я уже перепробовал все, что в голову пришло.... :dont_know:
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: STM32 и USB (практика)

Сообщение Z_h_e »

Некогда пока мне не в форуме участвовать, ни самому с USB ковыряться. После 21 должно время появится, так как я буду на работе :)) .
isx писал(а): USB->EP0R   |= USB_EP_RX_NAK;   
        USB->EP0R   |= USB_EP_TX_VALID;
         test1 = USB->EP0R   |= USB_EP_TX_VALID;
         USB->EP0R   |= USB_EP_RX_VALID;
Четвертый раз говорю, пройдите по шагам все эти строки чудо кода и мониторьте регистр EP0R (с отключенным МК от USB).
Проверьте флаг успешной отправки, которого я думаю нет и соответственно нет в ответ на него (от хоста к МК) пакета ZLP.
Да, я разрешал прием и передачу поочередно, но возможно это неважно.

Serg1987 писал(а):Да. Но вообще, если делать грамотно, то первый байт нужно также учитывать.
Правильно учитывать все поля запроса и обрабатывать неизвестный запрос тоже.
Serg1987 писал(а):switch (*(__IO uint32_t*)(0x40006081))
{
case 0x06:
GPIOC->BRR |= GPIO_ODR_ODR12;
break;
}
Если Вы считываете один байт, то и указатель тоже должен быть на байт, но не на 32 бита.
isx писал(а):У вас по адресу .....81 читается 0x06, хотя должно быть 0x60. Возможно вам приходит что-то не то.... :dont_know:
Нет, 0x06.
Radist_M писал(а):Мне всю дорогу приходит 0x80 0x06 и т.д. 0x81 не встречал.
Вот запрос дескриптора репорта HID, видимо у Вас не HID

Код: Выделить всё

bmRequestType   0x81
bRequest   0x6
wValue   0x2200
wIndex   0x0
wLength   0x94
Последний раз редактировалось Z_h_e Вс июн 19, 2016 08:30:09, всего редактировалось 1 раз.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Re: STM32 и USB (практика)

Сообщение isx »

Z_h_e писал(а):После 21 должно время появится, так как я буду на работе

Что у Вас за работа такая, на которой есть время сидеть на форумах? :)))
Z_h_e писал(а):Проверьте флаг успешной отправки, которого я думаю нет

Его и нет - прерывание по CTR не возникает. Только вот не ясно почему... Последнее, что удается отследить в отладке - это как USB_EP_TX становится в VALID, а потом в 0. При этом флаг ошибки тоже не срабатывает (тоже включал прерывание по ERR для диагностики).
Буду ждать следующей недели, а пока попробую еще куда-нибудь ковырнуть :) .
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: STM32 и USB (практика)

Сообщение Z_h_e »

Да ёлки-палки,isx :kill: . Пускай есть упрощенный 4х битный регистр EP (r1 r0 t1 t0), начальное состояние 0. Все биты типа тогл. Вы хотите установить прием и передачу в VALID, т.е. 0b1111. Что Вы делаете

Код: Выделить всё

EP|=0b1100;
EP|=0b0011

Результат:

Код: Выделить всё

EP==0//начальное состояние
EP==0b1100
EP==0b0011
Так понятно или написать как работает конструкция |= ??? Ах, да, я же уже писал и это. И не верю я, что в отладке этого не видно.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
isx
Поставщик валерьянки для Кота
Сообщения: 2316
Зарегистрирован: Вс июн 26, 2011 20:03:21

Re: STM32 и USB (практика)

Сообщение isx »

Это понятно, только вот после отработки установленного значения TX/RX они автоматически обнуляются.
Вот скрин. После каждого шага значение регистра EP0 заносится в отдельную переменную. Как видим, все, по какой-то причине, отрабатывается правильно, но тугл так работать не должен :dont_know: .
Изображение
Ответить

Вернуться в «ARM»