Например TDA7294

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





Текущее время: Ср апр 17, 2024 02:28:46

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


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



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

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2310
Рейтинг сообщения: 0
Приветствую форумчан!
Наконец-то появилась возможность продолжить свои практические занятия :beer: . Начал разбираться с USB.
Сделал все как в этой статье: http://microtechnics.ru/stm32-peredacha-dannyx-po-usb/ - работает. Только появились вопросы...
Есть две функции:
/*******************************************************************************/
Код:
void Handle_USBAsynchXfer (void)
{
    if (needToSend == 1)
    {
        uint8_t tempData;
 
   tempData = 0x12;
 
   USB_SIL_Write(EP1_IN, &tempData, 1);
   SetEPTxValid(ENDP1);
    }
}
 
/*******************************************************************************/

и
Код:
/*******************************************************************************/
void EP1_IN_Callback (void)
{
    if (needToSend == 1)
    {
   uint8_t tempData;
 
   tempData = 0x34;
 
   USB_SIL_Write(EP1_IN, &tempData, 1);
   SetEPTxValid(ENDP1);
        needToSend = 0;
    }
}
 
/*******************************************************************************/

Обе передают по 8 байт данных. Почему две передачи разнесены по разным функциям?


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

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2310
Рейтинг сообщения: 0
Никаких мыслей? :solder:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 10:03:02 
Мучитель микросхем

Карма: 11
Рейтинг сообщений: 35
Зарегистрирован: Ср окт 15, 2008 09:33:03
Сообщений: 475
Откуда: Воронеж
Рейтинг сообщения: 0
да без проблем. Наверняка это callback функции к каким либо событиям. Просто по обеим событиям делается одно и то же. Ну а что это за события - добро пожаловать в документацию на USB и библиотеку, даташит, код библиотеки и т.д.


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 12:20:39 
Встал на лапы

Карма: 1
Рейтинг сообщений: 39
Зарегистрирован: Ср фев 01, 2012 10:55:53
Сообщений: 145
Рейтинг сообщения: 2
Эти два события обычно используются для bulk endpoint. Вероятно, если после начала фрейма на первый IN запрос контроллер ответит NAK, то хост больше не будет слать IN запросы какое-то время. Так что в Handle_USBAsynchXfer заряжается буфер для первого IN запроса.
Кстати, в STM примерах для bulk эндпоинта забыли сделать отсылку пакета нулевой длинны если данных больше нет, а последний пакет был равен размеру буфера. Если не отсылать такой пакет, со стороны хоста это будет выглядеть как подвисание при чтении.


Вернуться наверх
 
Организация питания на основе надежных литиевых аккумуляторов EVE и микросхем азиатского производства

Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 12:55:03 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2310
Рейтинг сообщения: 0
Galizin писал(а):
Наверняка это callback функции к каким либо событиям.

Handle_USBAsynchXfer(); Эта функция вызывается из коллбэка SOF:
Код:
void SOF_Callback(void)
{
  static uint32_t FrameCount = 0;
 
  if(bDeviceState == CONFIGURED)
  {
    if (FrameCount++ == VCOMPORT_IN_FRAME_INTERVAL)
    {
      /* Reset the frame counter */
      FrameCount = 0;
     
      /* Check the data to be sent through IN pipe */
      Handle_USBAsynchXfer();
    }
  } 
}

Я сейчас читаю книги и статьи по USB (учусь), но такое количество информации просто разрывает мозг, поэтому могу написать глупость... :facepalm:
Как я понимаю, то пакет SOF отправляется хостом для того чтоб спросить устройство, хочет ли оно нам что-то передать. Приняв такой пакет устройство либо отвечает пустым пакетом, либо осуществляет передачу данных через EndPoint-ы. Но тогда появляется вопрос - какого фига данные, впихнутые через функцию SOF вообще отправляются? :dont_know:

BorisSPB писал(а):
Так что в Handle_USBAsynchXfer заряжается буфер для первого IN запроса.

Если я Вас правильно понял, то только первая партия данных летит через Handle_USBAsynchXfer(), а остальные через EP1_IN_Callback?
Тогда такой вопрос: размер буфера в обоих случаях будет одинаковым (таким каким мы его объявили в дескрипторе)?
И еще вопрос: получается для отправки третьего пакета данных (если мы передаем одну партию данных) нужно только повторно вызвать EP1_IN_Callback (в данном случае) и скормить ему нужные данные?


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 14:01:01 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2690
Откуда: г. Чайковский
Рейтинг сообщения: 2
Медали: 1
Получил миской по аватаре (1)
isx писал(а):
просто разрывает мозг
Согласен, я тоже не нашел легко написанной книги по этому вопросу.
isx писал(а):
какого фига данные, впихнутые через функцию SOF вообще отправляются?
Цитата:
Как я понимаю, то пакет SOF отправляется хостом для того чтоб спросить устройство, хочет ли оно нам что-то передать.
SOF - это начало кадра, и не имеет прямого отношения к устройству.
В STM32 много флагов событий от USB и соответственно прерываний. Я тоже потихоньку мучаю USB (т.е. он меня), только я не использую готовых библиотек. Вроде что-то более-менее получается, конечно с кучей подвисших вопросов в воздухе. Так вот, я использую всего два события, это SE0 (событие подключения устройства к компу) и событие успешного трансфера (в любую сторону). В последнем можно определить направравление передачи и для какой точки.
Смысл такой.
-Сначала инициализируется модуль USB. просто вкючаете, подкючаете генератор и т.д.
- По событию SE0 (воткнули девайс в комп) инициализируете нужные регистры, это событие кстати сбросит их в начальное состояние само.
-Затем устанавливаете в регистре EP0 VALID RX, т.е. МК готов принять данные для нулевой точки.
-Возникает прерывание об успешной транзакции. Расшифровываете и понимаете что что то получили.
- читаете что лежит в буфере приема, там будет запрос дескриптора устройства.
-ложите в буфер отправки дескриптор устройства и выставляете в регистре EP0 VALID TX и контроллер сам все отправит.
-после события об успешной отправки опять переводите МК в состояние в готов принять.

После успешной транзакции состояние VALID само сменится на NACK . Т.е. неготовность принятия или отправки данных. Вы же уже поняли что МК сам ничего не отправит и не примет, только по инициативе хоста. И МК может долго отвечать NACK и хост на это никак не обижается.
Я к тому что мне непонятно зачем отлавливать SOF. Ну пропустили начало кадра, ответит МК NACKом сам, и отвечать будет всегда пока не подготовите данные. Хотя мне непонятно может потом, у что мне в USB много чего еще непонятно.

Если интересно, я в ехселе сделал частичный протокол обменамоего МК по USB/

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


Последний раз редактировалось Z_h_e Чт май 05, 2016 14:04:20, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 14:04:01 
Встал на лапы

Карма: 1
Рейтинг сообщений: 39
Зарегистрирован: Ср фев 01, 2012 10:55:53
Сообщений: 145
Рейтинг сообщения: 0
Если отправлять нечего, то аппаратный буфер будет пустой и контроллер при запросе на этот эндпоинт ответит NAKом. Если размер данных в аппаратном буфере меньше максимального, то хост считает что пачка закончилась и приостанавливает IN запросы.
EP1_IN_Callback вызывается в прерывании USB, если есть данные, заряжаем буфер, если нет - посылаем пакет нулевой длинны и далее ждем до следующего SOF.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 15:06:52 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 7
Зарегистрирован: Чт май 14, 2015 15:11:39
Сообщений: 424
Откуда: Саратов
Рейтинг сообщения: 0
Тоже начал разбираться с USB, правда на STMF3. Хочу отправить данные с датчика (1 байт) данных, но получается вот такое:
СпойлерИзображение

Отправляют так:
Спойлер
Код:
uint8_t data = '\n';
USB_SIL_Write(EP1_IN, &data, 1);
SetEPTxValid(ENDP1);
USBprintNumber((uint32_t)GyroRawData[0]);


Спойлер
Код:
void USBprintNumber(uint32_t x)
{
   uint8_t* value;
   char i = 0;
   
   do
   {
      value[i++] = (char) (x%10) + '0';
      x /= 10;
   }   while(x);
   
   USB_SIL_Write(EP1_IN, value, i);
   SetEPTxValid(ENDP1);
}


Вложения:
Скриншот 2016-05-05 16.10.06.png [35.44 KiB]
Скачиваний: 3044
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 16:23:00 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2310
Рейтинг сообщения: 1
Z_h_e писал(а):
Согласен, я тоже не нашел легко написанной книги по этому вопросу.

Тут не только книги, а еще куча всяких статей. Пока читаешь - вроде все понятно, как только переходишь к делу - ступор полный :) .
Z_h_e писал(а):
SOF - это начало кадра, и не имеет прямого отношения к устройству.

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

Я тоже не сторонник библиотек (до сих пор даже SPL-ом не пользовался), но боюсь не потяну сразу USB на уровне регистров (хотя подумываю об этом)... :solder:
Z_h_e писал(а):
Если интересно, я в ехселе сделал частичный протокол обменамоего МК по USB/

У Вас уже реализован полный обмен данными МК с ПК в обе стороны или пока с дескрипторами разбираетесь? В любом случае, буду признателен если скинете кусок кода с инициализацией и работой USB.
Нужно еще подумать что проще, разбирать код чужой библиотеки, или сразу перейти на регистры... :dont_know:
BorisSPB писал(а):
EP1_IN_Callback вызывается в прерывании USB, если есть данные, заряжаем буфер,

Пока понять еще не могу, как обновляются данные буфера между отправками? Вот зарядили мы первую партию в EP1, затем отправили их, после этого ждем срабатывание SOF, обновляем данные и отправляем - и так по кругу. Я правильно понимаю?
FireProoF писал(а):
правда на STMF3

Я кстати тоже) . В статье (адрес в первом посте) производится отправка на МК 2 байт, с последующим приемом МК 2 байт. Статья из трех частей. Я по ней деле проект - он заработал, но пока не совсем ясно каким образом :) . Посмотрите, может чем поможет....


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 16:39:14 
Мучитель микросхем
Аватар пользователя

Карма: 1
Рейтинг сообщений: 7
Зарегистрирован: Чт май 14, 2015 15:11:39
Сообщений: 424
Откуда: Саратов
Рейтинг сообщения: 0
Я тоже с неё начал)
С отправкой чисел разобрался.
Теперь встал вопрос частоты отправки данных. У меня отправка происходит по переполнению таймера. Эксперементальным путём установил, что при частоте переполнения свыше 150 Гц stm32 перестаёт определяться компьютером. На 100 Гц всё норм.
Добавил задержку перед включением таймера. Вроде подключилось, открыл терминал, а он повис. Подождал чуток, отсоединил стм. На терминале показались данные. Видимо комп не справляется с потоком? :(
Не могли бы Вы проделать такой же эксперимент, дабы убедиться, что при частой отправке данных, линия зависает?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 17:06:31 
Собутыльник Кота
Аватар пользователя

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2690
Откуда: г. Чайковский
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
isx писал(а):
У Вас уже реализован полный обмен данными МК с ПК в обе стороны или пока с дескрипторами разбираетесь?
Вроде как допилить осталось чуток. И в божеский вид привести. Но это вроде. Я сначала через первую точку хотел обмен сделать, даже принял данные через winapi функцией READFILE. Но если данных нет, то там зависнешь. HidD_GetInputReport из библиотеки HID.dll отказалась читать, сейчас уже есть предположение почему.
Решил через Feature репорты обмен делать. Вроде получилось и пока ничего больше не делал, надо пнуть себя и сегодня еще поработать. Вобщем то о своих мытарствах я тут писал, надо будет туда и дописать чем дело кончилось, приведу код в боле менее вид, может и скину. А сама инициализация вот она, она простая. Только радиокот все табуляции кода выкинул, почти все сплошняком.
Спойлер
Цитата:
//Регистры ЮСБ
typedef struct {
volatile uint32_t EP0R;
volatile uint32_t EP1R;
volatile uint32_t EP2R;
volatile uint32_t EP3R;
volatile uint32_t EP4R;
volatile uint32_t EP5R;
volatile uint32_t EP6R;
volatile uint32_t EP7R;
volatile uint8_t reserved[0x20];
volatile uint32_t CNTR;
volatile uint32_t ISTR;
volatile uint32_t FNR;
volatile uint32_t DADDR;
volatile uint32_t BTABLE;

} USB_REGISTR_Type;

#define USB_REGISTR ((USB_REGISTR_Type *) 0x40005C00 ) //базовый адрес регистров ЮСБ

......


//Функция инициализации
void USB_INIT(void){

//очистим массив теста
uint8_t iii;

for ( iii=0;iii<11;iii++){In_Pack[iii]=7;} //тест


//Затактируем модуль ЮСБ
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);

USB_REGISTR->CNTR&=~bit1; //сбросим PWDN. Тем самым включим ЮСБ Этот бит включает внутренний voltage references, который питает usb передатчик.



//тут надо сделать паузу tSTARTUP (1мкс надо)
uint32_t temp;
for ( temp=10000000; temp != 0; temp--);

//выключаем сброс ЮСБ
USB_REGISTR->CNTR&=~bit0; //сбросим FRES

//Очистка флагов событий ЮСБ и разрешение прерываний
USB_REGISTR->ISTR=0;
NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);

//Настройка ЮСБ вроде маска прерываний но регистр не только для прерываний
USB_REGISTR->CNTR|=
bit15| //CTRM:Correct transfer interrupt mask
//bit14 | //PMAOVRM:Packet memory area over / underrun interrupt mask
//bit13 | //ERRM:Error interrupt mask
//bit12 | //WKUPM:Wakeup interrupt mask
// bit11 | //SUSPM:Suspend mode interrupt mask
bit10 |//разрешение прерывание по резету
//bit9 | //SOFM:Start of frame interrupt mask
//bit8 | //ESOFM:Expected start of frame interrupt mask
0;

}
//*****************************************************************************************


Мой контроллер STM32F103C8.

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


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: STM32 и USB (практика)
СообщениеДобавлено: Чт май 05, 2016 21:37:26 
Встал на лапы

Карма: 1
Рейтинг сообщений: 39
Зарегистрирован: Ср фев 01, 2012 10:55:53
Сообщений: 145
Рейтинг сообщения: 1
Данные хосту отправляются автоматически по IN запросу если в аппаратном буфере что-то есть, запись в аппаратный буфер происходит с помощью
Код:
USB_SIL_Write(EP1_IN, &tempData, 1);

Обменом управляет хост, насильно хосту данные не скормить, только по IN запросу.
HID устройство удобно тем что не нужен специальный драйвер, но скорость ограничена 64 кб/сек. Если в дескрипторе HID для типа устройства указать нули, обмен можно производить пакетами с помощью ReadFile/WriteFile, за разбор пакета при этом отвечает приложение.


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

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2310
Рейтинг сообщения: 0
Очередной раз убедился в том, что ковырять чужие библиотеки - для меня проблема... Даже не смог найти выход к регистрам USB через SPL :dont_know:
Решил идти с нуля, чтоб уж точно знать, как оно там работает. По пути буду снабжать код подробными комментариями (может кому в будущем пригодится) ибо для себя я такого примера так и не нашел.
P.S. За пол года перерыва в практике общения с паяльником и кодом многое подзабылось, поэтому не пинайте сильно.

Итак, начинаем с самого начала:

Спойлер
Код:
int main(void)
{
       /*----------*/
   
   RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; //включаем тактирование SYSCFG (хз что это, но так надо :) )
   RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOEEN; //включаем тактирование портов А и Е
   
      /*----------*/
   
  GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR11 | GPIO_OSPEEDR_OSPEEDR12; // Скорость 50 МГц
   GPIOA->MODER |= GPIO_MODER_MODER11_0 | GPIO_MODER_MODER12_0; // Режим альтернативной функции
   //GPIOA->OTYPER = 0x00000000;
   //GPIOA->PUPDR = GPIO_PUPDR_PUPDR11 | GPIO_PUPDR_PUPDR12;
   GPIOA->AFR[1] |= 0x000EE000; // Номер и пины альтернативной фунции (у нас пина 11 и 12 для альтернативной функции номер 14 - USB)
   
      /*----------*/
   
  GPIOE->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR8 | GPIO_OSPEEDR_OSPEEDR9 | GPIO_OSPEEDR_OSPEEDR10 |
                     GPIO_OSPEEDR_OSPEEDR11 | GPIO_OSPEEDR_OSPEEDR12 | GPIO_OSPEEDR_OSPEEDR13 |
                     GPIO_OSPEEDR_OSPEEDR14 | GPIO_OSPEEDR_OSPEEDR15; // Скорость 50 МГц
   GPIOE->MODER |= GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1 |
                   GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1 | GPIO_MODER_MODER13_1 |
                   GPIO_MODER_MODER14_1 | GPIO_MODER_MODER15_1; // Все пины на выход
   //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_EnableIRQ(USBWakeUp_IRQn); //   Разрешаем прерывание USBWakeUp
  //NVIC_SetPriority(USBWakeUp_IRQn, 3);   // Приоритет прерывания (не могу определится для USB)
                                                      
      /*----------*/                                                   
   
   RCC->CR |= RCC_CR_HSION; //Включить генератор HSI
   RCC->CR &= ~RCC_CR_HSEON;
  while((RCC->CR & RCC_CR_HSIRDY)==0) {} //Ожидание готовности HSI
 
      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->CR |= RCC_CR_PLLON; //Включить генератор PLL
  while((RCC->CR & RCC_CR_PLLRDY)==0) {} //Ожидание готовности PLL

  //Переключиться на тактирование от PLL
  RCC->CFGR &= ~RCC_CFGR_SW; //Очистка битов выбора источника тактового сигнала
  RCC->CFGR |= RCC_CFGR_SW_PLL; //Выбрать источником тактового сигнала PLL
  while((RCC->CFGR&RCC_CFGR_SWS)!=0x08){} //Ожидание переключения на PLL

         /*---------- ----------*/      

}   


Делал на основе вскрытия библиотеки USB-FS. Если с GPIO все понятно, то вот докопаться до сути EXTI так и не вышло. С SPL ранее не работал, поэтому так и не нашел на какие регистры воздействуют эти строки:
Код:
  EXTI_InitStructure.EXTI_Line = EXTI_Line18;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

У себя в коде прописал как самому показалось верным. :dont_know:
Итак, Set_System(); разложена, поехал ковырять Set_USBClock();
Прошу поглядеть на код, может где-то напортачил или поставил не соответствующий комментарий... :)


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

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2310
Рейтинг сообщения: 0
Расковырял Set_USBClock();. Добавилось всего 2 строчки. Выносить тактирование USB в отдельный блок не стал, поэтому просто добавил в общий код. Инициализацию переписал немного, заодно уточнил некоторые комментарии:
Спойлер
Код:
int main(void)
{
       
         /*----------*/                                                

/*Тактируем ядро*/   
   RCC->CR |= RCC_CR_HSION; //Включить генератор HSI
   RCC->CR &= ~RCC_CR_HSEON;
  while((RCC->CR & RCC_CR_HSIRDY)==0) {} //Ожидание готовности HSI
 
   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->CR |= RCC_CR_PLLON; //Включить генератор PLL
  while((RCC->CR & RCC_CR_PLLRDY)==0) {} //Ожидание готовности PLL

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

      /*----------*/
   
/*Настраиваем Порт А*/      
  GPIOA->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR11 | GPIO_OSPEEDR_OSPEEDR12; // Скорость 50 МГц
   GPIOA->MODER |= GPIO_MODER_MODER11_0 | GPIO_MODER_MODER12_0; // Режим альтернативной функции (для USB)
   //GPIOA->OTYPER = 0x00000000;
   //GPIOA->PUPDR = GPIO_PUPDR_PUPDR11 | GPIO_PUPDR_PUPDR12;
   GPIOA->AFR[1] |= 0x000EE000; // Номер и пины альтернативной фунции (у нас пины 11 и 12 для альтернативной функции номер 14 - USB)
   
/*Настраиваем Порт Е*/         
  GPIOE->OSPEEDR |= GPIO_OSPEEDR_OSPEEDR8 | GPIO_OSPEEDR_OSPEEDR9 | GPIO_OSPEEDR_OSPEEDR10 |
                     GPIO_OSPEEDR_OSPEEDR11 | GPIO_OSPEEDR_OSPEEDR12 | GPIO_OSPEEDR_OSPEEDR13 |
                      GPIO_OSPEEDR_OSPEEDR14 | GPIO_OSPEEDR_OSPEEDR15; // Скорость для указанных пинов 50 МГц
   GPIOE->MODER |= GPIO_MODER_MODER8_1 | GPIO_MODER_MODER9_1 | GPIO_MODER_MODER10_1 |
                   GPIO_MODER_MODER11_1 | GPIO_MODER_MODER12_1 | GPIO_MODER_MODER13_1 |
                   GPIO_MODER_MODER14_1 | GPIO_MODER_MODER15_1; // Указанные пины на выход
   //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_EnableIRQ(USBWakeUp_IRQn); //   Разрешаем глобально прерывание USBWakeUp
  //NVIC_SetPriority(USBWakeUp_IRQn, 3);   // Приоритет прерывания (не могу определится для USB)
                                                      

}   

Добавил:
Код:
RCC->CFGR |= RCC_CFGR_USBPRE; // Настраиваем частоту USB (= частота ядра / 1.5)
RCC->APB2ENR |=   RCC_APB1ENR_USBEN; // Включаем тактирование USB от шины APB1

Идем к USB_Interrupts_Config(); :kill:

Цитата:
Спустя ХХ минут.


Оказалось, отчасти USB_Interrupts_Config(); уже была мной написано в код. Как я понял, эта функция работает с:

Код:
  NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
 // NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn);   
  NVIC_EnableIRQ(USBWakeUp_IRQn);    
 // NVIC_SetPriority(USBWakeUp_IRQn, 3);

однако, сразу поперли вопросы... :solder:
Помимо USB_LP_CAN1_RX0_IRQn, есть USB_HP_CAN1_TX_IRQn. Почему используется именно она, в чем их разница и вообще, за что они отвечают? :dont_know:
И еще, вопрос по приоритетам. Как их выставлять? Запустил рабочий код с USB (про который я говорил в первом посте), там приоритет USB_LP_CAN1_RX0_IRQn стоит 128, а USBWakeUp_IRQn приоритет 1. Можно конечно и просто подставить эти значения, но хочется таки разобраться....
Пока пойду ковырять самую веселую часть инициализации - USB_Init(); :) .


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

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2310
Рейтинг сообщения: 0
В общем наковырял всю инициализацию и проверил (проект перенес на Keil 5, так как там оказался полезный файлик - stm32f303xc.h, который заменяет stm32f30x.h и имеет дополнительно прописанные регистры USB).
Вот что получилось:
Спойлер
Код:
#include "stm32f303xc.h"

#define USB_MAX_PACKET0 ((uint16_t) 0x02)

void Myinit(void)
{

   
/*Тактируем ядро*/   
   //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_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_PUPDR11 | GPIO_PUPDR_PUPDR12;
   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_EnableIRQ(USB_LP_CAN_RX0_IRQn);
        NVIC_SetPriority(USB_LP_CAN_RX0_IRQn, 8);   
   NVIC_EnableIRQ(USBWakeUp_IRQn); //   Разрешаем глобально прерывание USBWakeUp
  //NVIC_SetPriority(USBWakeUp_IRQn, 3);   // Приоритет прерывания (не могу определится для USB)
}


В отладке все работает правильно. Теперь нужно переходить к самому USB.

Как я понял, раскуривая стандартные библиотеки, начинать нужно с подтяжки D+ к питанию через специальный регистр, но такого я в мануале на свой камень не нашел :dont_know:
Дальше идут следующие действия:

Код:
                                                         
// здесь должна быть подтяжка резистора
USB->CNTR &= ~USB_CNTR_PDWN; //подаем питание
USB->CNTR |= USB_CNTR_FRES; //На всякий случай устанавливаем флаг (хотя он итак должен стоять при включении)
USB->CNTR = 0; // в результате FRES сбрасывается в ноль, происходит ресет и генерируется прерывание USB_LP_IRQHandler.   


В итоге, единственный мост для нашего общения с USB - это прерывание USB_LP_IRQHandler, значит в нем и происходит дальнейшая работа.
С помощью флага определяем - от чего произошло прерывание. Первое прерывание, как я понял, произойдет сразу же, по FRES. Затем, уже в прерывании:

Код:
void USB_LP_IRQHandler(void)
{
 if(USB->ISTR & USB_ISTR_RESET)
    {
USB->ISTR = 0;  // сбрасываем флаги
USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_CTRM; // настраиваем маски и включаем прерывание по завершению передачи
........
}
......
}


Дальнейшее поведение библиотеки отследить не удалось. Скорее всего дальше происходит настройка нулевой контрольной точки, но в какой последовательности все это происходит в камне - не известно. :dont_know:
Перечитываю кучи статей на сайтах, но описания пока не могу найти. Буду признателен, если ткнете на подобную статейку или дадите какую-нибудь подсказку...


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

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2690
Откуда: г. Чайковский
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
Не знаю как там в библиотеке. Вот моя функция, которая вызывается по прерыванию SE0
Спойлер
Код:
void USB_Reset(void)
{

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

//Настройка буфера EP0
   DiscrTable->ADR0TX=0x0040;
   DiscrTable->COUNT0TX=0x0000; //макс 0x80
   DiscrTable->ADR0RX=0x0100;
   DiscrTable->COUNT0RX=0b1011000000000000; //размер буфера 0x80 (128)байт
/*
//Настройка буфера EP1 IN Interupt
   DiscrTable->ADR1TX=0x00210;
   DiscrTable->COUNT1TX=0x000a; //макс 0x80
   DiscrTable->ADR1RX=0x0290;
   DiscrTable->COUNT1RX=bit14; //размер буфера 16 байт
   */
/*
//Настройка буфера EP2 OUT Interupt
   DiscrTable->ADR1TX=0x0090;
   DiscrTable->COUNT1TX=0x0000; //макс 0x40
   DiscrTable->ADR1RX=0x0090;
   DiscrTable->COUNT1RX=bit14; //размер буфера 16 байт
*/

//Регистры конечных точек 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*/


//Регистры конечных точек 1

   USB_REGISTR->EP1R=0x1|      //номер точки1
         bit13|//bit12|      //STAT_RX - NAK
         bit5 |// bit4|      //STAT_TX - NAK (10) Valid (11)
         bit10|bit9 ;  /*00 BULK   //10-9 тип точки. в данном случае Контрол
                        01 CONTROL
                        10 ISO
                        11 INTERRUPT*/
/*
//Регистры конечных точек 2
   USB_REGISTR->EP2R=0x2|      //номер точки2
         bit13|//bit12|      //STAT_RX - NAK
         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;



}
Цитата:
USB->CNTR |= USB_CNTR_FRES; //На всякий случай устанавливаем флаг (хотя он итак должен стоять при включении)
Я FRES наоборот сбросил.Вот корявенький перевод REFERENCE, но мне помог.

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


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

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

Ну у меня сначала устанавливается, а потом сбрасывается (прочитал где-то, что на всякий случай лучше перед сбросом устанавливить флаг).
Z_h_e писал(а):
Вот корявенький перевод REFERENCE, но мне помог

Тоже напал на него час назад. Четвертый раз перечитываю, многое проясняется :) .
Z_h_e писал(а):
//Настройка буфера EP0
   DiscrTable->ADR0TX=0x0040;
   DiscrTable->COUNT0TX=0x0000; //макс 0x80
   DiscrTable->ADR0RX=0x0100;
   DiscrTable->COUNT0RX=0b1011000000000000; //размер буфера 0x80 (128)байт

Вот пока главный вопрос - откуда берутся значения этих адресов?


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

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2690
Откуда: г. Чайковский
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
isx писал(а):
Вот пока главный вопрос - откуда берутся значения этих адресов?
Я их сам определил, т.е. сделал такими какие мне нужны. Есть область памяти
0x4000 6000- 0x4000 63FF. Именно с ней работает USB. Есть хитрый момент, 2 и 3ый байты слова в этой области недоступны (т.е. как 16битнай память). Модуль USB работает как 16 битной памятью с адреса 0, ядро как 32ух с адреса 0x4000 6000. Вы определяете область памяти для каждой конечной точки. Например Вы указали адрес
Код:
DiscrTable->ADR0RX=0x0100;
. Это значит что данные, которые придут от компа в МК для конечной точки 0, будут лежать по адресу 0x40006000+0x0100*2. Регистры с адресами (таблица дескрипторов) лежит в этой же памяти. Адрес таблицы указывается в регистре USB_REGISTR->BTABLE=0. Такая запись указывает что таблица находится по адресу 0x4000 6000+0*2.
Спойлер
Код:
//----------
//дескриптор таблицы буферов
typedef struct {
   volatile  uint32_t ADR0TX;
   volatile  uint32_t COUNT0TX;
   volatile  uint32_t ADR0RX;
   volatile  uint32_t COUNT0RX;

   volatile  uint32_t ADR1TX;
   volatile  uint32_t COUNT1TX;
   volatile  uint32_t ADR1RX;
   volatile  uint32_t COUNT1RX;

   volatile  uint32_t ADR2TX;
   volatile  uint32_t COUNT2TX;
   volatile  uint32_t ADR2RX;
   volatile  uint32_t COUNT2RX;


} DiscrTable_Type;

#define DiscrTable ((DiscrTable_Type *) 0x40006000)


Это еще что, поглядите как устанавливаются биты регистров конечной точки USB_EPnR. Часть битов обычный доступ, часть только чтение, часть стирание 0, а часть типа togle (инвертирование при записи 1). Так что тут конструкция R|=(n<<m) просто так не сработает.

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


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

Карма: 11
Рейтинг сообщений: 26
Зарегистрирован: Вс июн 26, 2011 20:03:21
Сообщений: 2310
Рейтинг сообщения: 0
Наконец-то вернулся к теме :) .
Z_h_e писал(а):
Я их сам определил, т.е. сделал такими какие мне нужны. Есть область памяти
0x4000 6000- 0x4000 63FF. Именно с ней работает USB.

Пока я не могу понять, почему нельзя просто сделать эти адреса друг за другом :dont_know: . Например, указываем адрес для входящих данных EP0 (образно) 0х00, длину - 0х09. Затем указываем для исходящих данных адрес 0х10, длину 0х19 и.т.д. Почему, часто, в дескрипторе эти адреса разбросаны?
Z_h_e писал(а):
Адрес таблицы указывается в регистре USB_REGISTR->BTABLE=0. Такая запись указывает что таблица находится по адресу 0x4000 6000+0*2.

И зачем здесь вообще указывать что-то другое, если можно поставить ноль, и плясать от него? :dont_know:
P.S. Уверен, что эти тупые вопросы от непонимания происходящего :dont_know: . Но это только пока не разберусь. Как разберусь, будут другие тупые вопросы :))) .

Z_h_e писал(а):
Это еще что, поглядите как устанавливаются биты регистров конечной точки USB_EPnR.

Глядел. Пока все прозрачно вроде, но уверен, как только дойду до практики, грабли дадут о себе знать (да и лето как-никак, пора бы им уже поработать :) )

И вот еще понял, что нифига не понимаю что в этой строке происходит:
Код:
USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;

Что за "маски" тут настраиваются? Такой код автоматически разрешает прерывание? Если нет, то что будет если включить прерывание, а маску нет? (то что работать не будет понятно, но что происходит на аппаратном уровне..)


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

Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04
Сообщений: 2690
Откуда: г. Чайковский
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
isx писал(а):
Пока я не могу понять, почему нельзя просто сделать эти адреса друг за другом
Очень даже можно. Только надо помнить, что там же таблица адресов.
isx писал(а):
И зачем здесь вообще указывать что-то другое, если можно поставить ноль, и плясать от него?
Ну можно ж ее в конце памяти разместить, а буфера тогда можно с самого начала или несколько таблиц иметь и переключать их.
isx писал(а):
Глядел. Пока все прозрачно вроде, но уверен,...
Предствате что у Вас биты STAT_TX[1:0] устновлены в 10 (NACK). А Вам надо установить в состояние 11 (VALID) . Тогда такая конструкция EP|= STAT_TX1 | STAT_TX0 не прокатит.
isx писал(а):
Что за "маски" тут настраиваются?
Дык маски ж прерываний. Но я включил только CTRM и RESETM. Мне хватило этого.
Цитата:
Если нет, то что будет если включить прерывание, а маску нет?
Прошел по USB пакет SOF. Тут же в регистре USB_ISTR устанавливается флаг SOF (он так и будет висеть пока не сбросите), но так как у меня маска SOFM не установлена, то прерывание не возникнет.

Прерывание для всех событий USB одно. Вам надо самому разбираться в нем из-за чего прерывание возникло.
Спойлер
Код:
//обработчик прерывания низкого уровня ЮСБ
void USB_LP_CAN1_RX0_IRQHandler(void)
{

   //   SUSPM:Suspend mode interrupt mask
//         if (USB_REGISTR->ISTR&bit11){
//                  USB_REGISTR->ISTR&=~bit11;// сброс флага события
//                  USB_REGISTR->CNTR|=bit1; //установим PWDN. Тем самым вsключим ЮСБ
//                  return; //выходим из обработчика прерываний
//               }


//прерывание изза резета SE0
   if (USB_REGISTR->ISTR & bit10){
      USB_REGISTR->ISTR &=~bit10;// сброс флага события резет
      USB_Reset(); //делаем то что нужно после резета
      return; //выходим из обработчика прерываний
   }
   //CTRM:Correct transfer interrupt mask
   //Конечно точка что то удачно сделала.
   //информация об это в битах DIR и  EP_ID[3:0]
   if (USB_REGISTR->ISTR & bit15){
      //USB_REGISTR->ISTR&=~bit15;// сброс флага события этот флаг только для чтения
      Correct_Transfer();
            return; //выходим из обработчика прерываний
         }
//Ошбика если контроллер вовремя не ответил или ...
//   if (USB_REGISTR->ISTR & bit14){
//         USB_REGISTR->ISTR&=~bit14;// сброс флага события
//         return; //выходим из обработчика прерываний
//      }


////ERRM:Error interrupt mask
//ошибка CRC и прочей хрени. вобщем то можно на нее не реагировать. Нужно для отладки
   //if (USB_REGISTR->ISTR&bit13){
   //               USB_REGISTR->ISTR&=~bit13;// сброс флага события
   //               return; //выходим из обработчика прерываний
   //            }
//Wakeup interrupt mask
//   if (pUSB_REGISTR->USB_ISTR&bit12){
//            pUSB_REGISTR->USB_ISTR&=~bit12;// сброс флага события
//            return; //выходим из обработчика прерываний
//         }

//SOFM:Start of frame interrupt mask
   //if (pUSB_REGISTR->USB_ISTR&bit9){
   //         pUSB_REGISTR->USB_ISTR&=~bit9;// сброс флага события
   //         return; //выходим из обработчика прерываний
   //      }


   //ESOFM:Expected start of frame interrupt mask
   //   if (pUSB_REGISTR->USB_ISTR&bit8){
   //            pUSB_REGISTR->USB_ISTR&=~bit8;// сброс флага события
   //            return; //выходим из обработчика прерываний
   //         }
}

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


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

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


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

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


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

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


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