Например TDA7294

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





Текущее время: Вт июн 17, 2025 19:19:12

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


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



Начать новую тему Ответить на тему  [ Сообщений: 37 ]  1,  
Автор Сообщение
Не в сети
 Заголовок сообщения: stm32 USB host
СообщениеДобавлено: Чт ноя 21, 2024 11:35:41 
Встал на лапы

Зарегистрирован: Вт фев 15, 2022 21:28:35
Сообщений: 81
Рейтинг сообщения: 0
Здравствуйте. Не могу установить постоянное подключение контроллера(stm32h745) с мышкой.
Хронология:
1. На прерывании Port connect detected делаю Port reset
2. ядро устанавливает Port enable
3. В GINTSTS прилетает disconnect и сбрасывается Port enable.
и так по кругу с частотой 1-2 гц.
Я должен успеть что-то отправить мышке (например get descriptor) или соединение уже должно быть постоянным?
Мышь low speed-ная, я вижу это в статусе подключения в HPRT. Я уж и фрейм интервал поставил 1мс (резет валуе 1.25) и частоту PHY 48/8=6 сделал. Может мне D+ D- поменять местами?
Пробую отправить get descriptor в момент подключения, в ответ... нифига.
В device режиме все работает, скопировал по дескрипторам мышку, жму кнопку - мышь едет.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Сб ноя 23, 2024 18:59:51 
Встал на лапы

Зарегистрирован: Вт фев 15, 2022 21:28:35
Сообщений: 81
Рейтинг сообщения: 0
Я точно не понял что произошло, но все заработало. Сначала я подключил флешку вместо мышки на FS, потом и мышка стала отвечать на LS.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Вс ноя 24, 2024 00:02:50 
Это не хвост, это антенна

Карма: -10
Рейтинг сообщений: 171
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1482
Рейтинг сообщения: 4
Я точно не понял что произошло, но все заработало. Сначала я подключил флешку вместо мышки на FS, потом и мышка стала отвечать на LS.
Если "не понял", то значит завтра с большой вероятностью снова отвалится. Раз причина не найдена.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Вс ноя 24, 2024 00:36:11 
Друг Кота

Карма: 68
Рейтинг сообщений: 1958
Зарегистрирован: Сб дек 18, 2021 19:25:32
Сообщений: 12867
Рейтинг сообщения: 0
Притом, с большой вероятностью сработает такая же последовательность действий. Я бы проверил цепи питания, на предмет ненужных пульсаций, всплесков/провалов, помех.

danone78 писал(а):
Может мне D+ D- поменять местами?
Эти слова (если не в шутку сказаны) немного пугают и наводят на всякие мысли... это демо-отладочная плата, или что-то самодельное? если последнее, то к схеме и трассировке USB множество вопросов может быть.


Вернуться наверх
 
В продаже новые LED-драйверы XLC компании MEAN WELL с диммингом нового поколения

Компания MEAN WELL пополнила ассортимент своей широкой линейки светодиодных драйверов новым семейством XLC для внутреннего освещения. Главное отличие – поддержка широкого спектра проводных и беспроводных технологий диммирования. Новинки представлены в MEANWELL.market моделями с мощностями 25 Вт, 40 Вт и 60 Вт. В линейке есть модели, работающие как в режиме стабилизации тока (СС), так и в режиме стабилизации напряжения (CV) значением 12, 24 и 48 В.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Вс ноя 24, 2024 23:23:28 
Встал на лапы

Зарегистрирован: Вт фев 15, 2022 21:28:35
Сообщений: 81
Рейтинг сообщения: 0
Не то чтобы все отвалилось, но далеко я не продвинулся. Все что удалось это отправить get descriptor, получить ACK+XFRC одновременно, потом отправить пустой пакет. Пытаюсь отправить токен IN - или ошибка передачи или STALL. Можно принимать ответы на том же канале на котором отправляю запросы? А то с другими каналами совсем плохо, все зависает по непонятным причинам, размаскировываю канал, отправляю пустой пакет или токен IN(то есть FIFO не трогаю) и зависаю, пытаюсь прочитать и очистить его регистр прерывания, а там нули и сбрасывать нечего, но с прерывания не выйти.

Добавлено after 13 minutes 41 second:
В Device режиме можно включить несколько конечных точек одновременно, с каналами видимо, надо выключать канал перед включением другого, хотя они по xfrc должны сами выключатсья, ща залогаю регистр управления каналом гляну что там происходит.

Добавлено after 5 hours 53 minutes 17 seconds:
Лед тронулся. Вот уж такую козу я не ожидал. Отправил get descriptor на CH0, получил АСК+XFRC. При отправке токена IN на CH1 выскакивают прерывания конечных точек! В общем я их замаскал и вуаля, получаю первый дескриптор.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Сб ноя 30, 2024 08:31:04 
Встал на лапы

Зарегистрирован: Вт фев 15, 2022 21:28:35
Сообщений: 81
Рейтинг сообщения: 0
Вообще из всей периферии на stm32, USB самая вредная. Все упирается в прерывания и статусный регистр:
- Некоторые прерывания просто не маскируются вообще
- некоторые маскируются (не срабатывают), но биты в статусном регистре устанавливаются
- есть и такие которые не устанавливают бит, но срабатывают.
- IEPINT срабатывает в принудительном хост режиме при DAINT=0.
Самое веселье начинается, когда переключаешь режим и делаешь core soft reset - карета превращается в ТЫКВУ! :shock:
Весь этот выпендрешь с On-The-Go приводит к глюкам в работе конечных автоматов.


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

По промокоду radiokot скидка 10%
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Сб ноя 30, 2024 11:06:45 
Это не хвост, это антенна

Карма: -10
Рейтинг сообщений: 171
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1482
Рейтинг сообщения: 0
Вообще из всей периферии на stm32, USB самая вредная. Все упирается в прерывания и статусный регистр:
- Некоторые прерывания просто не маскируются вообще
- некоторые маскируются (не срабатывают), но биты в статусном регистре устанавливаются
Вообще-то это и правильно. Странно ожидать другого.

- есть и такие которые не устанавливают бит, но срабатывают.
С stm32h745 не работал, но ваял USB-device в STM32Lxxx. Не Кубом, а самостоятельно. И особенных проблем не встретил. Почти всё работало нормально. Единственный косяк, на который наткнулся - неполная поддержка изохронного режима.

Но у меня был только device-режим. Без всяких host или OTG.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Сб дек 07, 2024 14:54:56 
Встал на лапы

Зарегистрирован: Вт фев 15, 2022 21:28:35
Сообщений: 81
Рейтинг сообщения: 0
Мне повезло, раньше на куб инфы не было вообще, и мне пришлось начинать в Keil. А там есть возможность писать прямо в асме, что меня несказанно радовало. АРМовцы поздно прочухали что такое людям давать нельзя, вся их инфа вместе с архитектурами ядер разлетелась по свету.
STM-щики в своих RM-ах гениально обтекают многие нюансы. Мне вообще кажется, что у них наш Сергей Лавров работает на RM-ах.

Добавлено after 28 minutes 4 seconds:
У меня уже все работает, но вся эта возня с дескрипторами мне кажется не обязательна.
Если я подключаю USB устройство и знаю что это мышь и что она с конечной точки 1 будет слать мне interrupt данные, почему бы просто сразу не открыть ей канал и послать set_configuration, без адресации без ничего?
Я например так реализовал микро веб сервер, все htm страницы умещаются в один сегмент 1420 байт, я просто разворачиваю секвенции и отправляю ответы. Все гениально, просто и работает с любого смартфона через вайфай.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Сб дек 07, 2024 18:10:59 
Это не хвост, это антенна

Карма: -10
Рейтинг сообщений: 171
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1482
Рейтинг сообщения: 0
мне пришлось начинать в Keil. А там есть возможность писать прямо в асме, что меня несказанно радовало. АРМовцы поздно прочухали что такое людям давать нельзя, вся их инфа вместе с архитектурами ядер разлетелась по свету.
Вообще не понял что тут написано... :facepalm:
Как именно ARMовцы мешают вам писать на асме? Что "давать нельзя" и почему?

Или вы - конспиролог? 8)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Сб дек 07, 2024 19:15:34 
Грызет канифоль
Аватар пользователя

Карма: 3
Рейтинг сообщений: 69
Зарегистрирован: Ср сен 02, 2015 07:47:20
Сообщений: 251
Рейтинг сообщения: 0
Мне повезло, раньше на куб инфы не было вообще, и мне пришлось начинать в Keil. А там есть возможность писать прямо в асме, что меня несказанно радовало. АРМовцы поздно прочухали что такое людям давать нельзя, вся их инфа вместе с архитектурами ядер разлетелась по свету.
STM-щики в своих RM-ах гениально обтекают многие нюансы. Мне вообще кажется, что у них наш Сергей Лавров работает на RM-ах.


А мужики то не в курсе! Вот пример моего говнокодинга на асме под Eclipse для ARM EABI:
Спойлер
Код:
// Набор функций для дампинга картриджей Денди

#include "dumper/dendy.h"

// Отключение режима Денди
void Dendy_Off()
{   // Параметры
   GPIO_InitTypeDef   GPIO_InStr;
   // Отключаем шину
   ADR_BUS_Off(); CHR_BUS_Off(); PRG_BUS_Off();
   // Деинит управляющих ног Dendy
   PRG_F2_Off(); PRG_RnW_Rd(); CHR_PRD_Off(); CHR_PWR_Off(); CHR_nPA13_Off();
   RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM5, DISABLE); TIM5->CR1 = 0x0000;
   GPIO_InStr.GPIO_Pin = 0x0001;
   GPIO_InStr.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InStr.GPIO_Speed = GPIO_High_Speed;
   GPIO_InStr.GPIO_OType = GPIO_OType_PP;
   GPIO_InStr.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init( GPIOA, &GPIO_InStr );
   GPIO_ResetBits( GPIOA, 0x0001 );
}

// Включение режима Денди
void Dendy_On()
{   // Параметры
   GPIO_InitTypeDef   GPIO_InStr;
   // Инит общих управляющих ног
   ADR_BUS_On(); CHR_BUS_Off(); PRG_BUS_Off();
   // Инит управляющих ног Dendy
   PRG_F2_Off(); PRG_RnW_Rd(); CHR_PRD_Off(); CHR_PWR_Off(); CHR_nPA13_Off();
   GPIO_InStr.GPIO_Pin = 0x0001;
   GPIO_InStr.GPIO_Mode = GPIO_Mode_AF;
   GPIO_InStr.GPIO_Speed = GPIO_High_Speed;
   GPIO_InStr.GPIO_OType = GPIO_OType_PP;
   GPIO_InStr.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init( GPIOA, &GPIO_InStr );
   GPIO_PinAFConfig( GPIOA, GPIO_PinSource0, GPIO_AF_TIM5 );
   // F2: ____------- 200ns/360ns = 560ns/1.786MHz
   RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM5, ENABLE); TIM5->PSC = 0x0000; TIM5->ARR = 0x0000002E; TIM5->CCR1 = 0x0000001E; TIM5->CCMR1 = 0x0060;
   TIM5->CCMR2 = 0x0000; TIM5->CCER = 0x0001; TIM5->SMCR = 0x0000; TIM5->DIER = 0x0000; TIM5->CR2 = 0x0000; TIM5->CR1 = 0x0001;
   // Сбрасываем картридж
   Dendy_Reset();
}

// Включить программный режим денди
void Dendy_Manual()
{   // Параметры
   GPIO_InitTypeDef   GPIO_InStr;
   // Инит общих управляющих ног
   ADR_BUS_On(); CHR_BUS_Off(); PRG_BUS_Off();
   // Инит управляющих ног Dendy
   PRG_F2_Off(); PRG_RnW_Rd(); CHR_PRD_Off(); CHR_PWR_Off(); CHR_nPA13_Off(); // PRG_ROM_Off();
   GPIO_InStr.GPIO_Pin = 0x0001;
   GPIO_InStr.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InStr.GPIO_Speed = GPIO_High_Speed;
   GPIO_InStr.GPIO_OType = GPIO_OType_PP;
   GPIO_InStr.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init( GPIOA, &GPIO_InStr );
   // Деактивация F2
   GPIO_ResetBits( GPIOA, 0x0001 );
}

// Сброс картриджа
void Dendy_Reset()
{   // Выключаем шину
   ADR_BUS_Off(); Delay( 0x3567DFE );
   GPIOC->ODR &= 0xFF00; GPIOE->ODR = 0x0000;
   ADR_BUS_On(); Delay( 0x3567DFE );
}

// Чтение данных PRG в буфер
__attribute__ ((naked)) void Read_PRG( uint8_t *PBuf, uint32_t Start, uint32_t Size )
{   // Начинаем
   __asm volatile
   (   "PUSH   {R0-R8}\n"
      // R0 = PBuf
      // R1 = Start
      // R2 = Size
      // R3 = GPIOA_IDR (Для чтения F2)
      "MOVW   R3, #0x0010\n"
      "MOVT   R3, #0x4002\n"
      // R4 = GPIOE_ODR (Для вывода адреса)
      "MOVW   R4, #0x1014\n"
      "MOVT   R4, #0x4002\n"
        // R5 = GPIOD_IDR (Для ввода данных)
      "MOVW   R5, #0x0C10\n"
      "MOVT   R5, #0x4002\n"
      // R6 = Маска $0000FFFF
      "MOVW   R6, #0xFFFF\n"
      "MOVT   R6, #0x0000\n"
      // Выделим
      "AND   R1, R1, R6, LSL #0\n"
      "AND   R2, R2, R6, LSL #0\n"
      // Синхронизируемся
      "CPSID   f\n"
      "Read_PRG_Syn0:\n"
      "LDR   R7, [R3, #0]\n"
      "ANDS   R7, R7, #1\n"
      "IT      EQ\n"
      "BEQ   Read_PRG_Syn0\n"
      "Read_PRG_Syn1:\n"
      "LDR   R7, [R3, #0]\n"
      "ANDS   R7, R7, #1\n"
      "IT      NE\n"
      "BNE   Read_PRG_Syn1\n"
        // Цикл чтения
      "Read_PRG_Loop:\n"
      // Выставляем адрес
      "STR   R1, [R4, #0]\n"
      // Ждем F2 = 1
      "Read_PRG_LWt0:\n"
      "LDR   R7, [R3, #0]\n"
      "ANDS   R7, R7, #1\n"
      "IT      EQ\n"
      "BEQ   Read_PRG_LWt0\n"
      // Увеличиваем адрес чтения
      "ADD   R1, R1, #1\n"
      // Ждем F2 = 0
      "Read_PRG_LWt1:\n"
      "LDR   R8, [R5, #0]\n"
      "LDR   R7, [R3, #0]\n"
      "ANDS   R7, R7, #1\n"
      "IT      NE\n"
      "BNE   Read_PRG_LWt1\n"
      // Сохраняем данные
      "AND   R8, R8, #0x00FF\n"
      "STRB   R8, [R0, #0]\n"
      // Следующий байт
      "ADDS   R0, R0, #1\n"
      // Счетчик байт
      "SUB   R2, R2, #1\n"
      "ANDS   R2, R2, R6, LSL #0\n"
      "IT      NE\n"
      "BNE   Read_PRG_Loop\n"
      "CPSIE   f\n"
      // Обнулим адрес
      "MOVW   R6, #0x0000\n"
      "STR   R6, [R4, #0]\n"
      "POP   {R0-R8}\n"
      "BX      LR\n"
   );
}

// Чтение данных из картриджа в буфер
void Dendy_Read( uint8_t *PBuf, uint32_t Start, uint32_t Size )
{   // Переменные
   uint32_t         Delay;
   GPIO_InitTypeDef   GPIO_InStr;
   // Начальные установки
   PRG_RnW_Rd(); CHR_In(); PRG_In(); GPIOC->ODR &= 0xFF00;
   GPIO_InStr.GPIO_Pin = 0xFFFF;
   GPIO_InStr.GPIO_Mode = GPIO_Mode_IN;
   GPIO_InStr.GPIO_Speed = GPIO_High_Speed;
   GPIO_InStr.GPIO_OType = GPIO_OType_PP;
   GPIO_InStr.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init( GPIOD, &GPIO_InStr );
   CHR_BUS_On(); PRG_BUS_On();
   // Это PRG или CHR?
   if ((Start & 0x00FF0000) == 0)
   {
      Read_PRG( PBuf, Start, Size );
   }
   else
   {   // Маски адресов и размеров
      Start &= 0x00003FFF; Size &= 0x00003FFF;
      while ((Size & 0x00003FFF) != 0)
      {   // Выставляем адрес
         GPIOE->ODR = Start & 0x0000FFFF;
         // Активируем строб чтения CHR
         CHR_PRD_On();
         // Ждем
         Delay = 3; while (Delay) { Delay -= 1; }
         // Забираем данные и отключаем строб
         *(PBuf) = (GPIOD->IDR >> 8) & 0x00FF;
         // Деактивируем чтение
         CHR_PRD_Off();
         // Счетчики
         PBuf += 1; Start += 1; Size -= 1;
      }
   }
   CHR_BUS_Off(); PRG_BUS_Off();
}

// Запись данных буфера в PRG
__attribute__ ((naked)) void Write_PRG( uint8_t *PBuf, uint32_t Start, uint32_t Size )
{   // Начинаем
   __asm volatile
   (   "PUSH   {R0-R11}\n"
      // R0 = PBuf
      // R1 = Start
      // R2 = Size
      // R3 = GPIOA_IDR (Для чтения F2)
      "MOVW   R3, #0x0010\n"
      "MOVT   R3, #0x4002\n"
      // R4 = GPIOA_BSRR (Для управления R/W)
      "MOVW   R4, #0x0018\n"
      "MOVT   R4, #0x4002\n"
      // R5 = GPIOE_ODR (Для вывода адреса)
      "MOVW   R5, #0x1014\n"
      "MOVT   R5, #0x4002\n"
      // R6 = GPIOD_ODR (Для вывода данных)
      "MOVW   R6, #0x0C14\n"
      "MOVT   R6, #0x4002\n"
      // R7 = Маска $0000FFFF
      "MOVW   R7, 0xFFFF\n"
      "MOVT   R7, 0x0000\n"
      // R8 = Маска $00020000
      "MOVW   R8, 0x0000\n"
      "MOVT   R8, 0x0002\n"
      // R9 = Маска $00000002
      "MOVW   R9, 0x0002\n"
      "MOVT   R9, 0x0000\n"
      // R10 - данные записи
      "LDRB   R10, [R0, #0]\n"
      "AND   R10, R10, 0x00FF\n"
      // Выделим
      "AND   R1, R1, R7, LSL #0\n"
      "AND   R2, R2, R7, LSL #0\n"
      "CPSID   f\n"
      // Синхронизируемся
      "Write_PRG_Syn0:\n"
      "LDR   R11, [R3, #0]\n"
      "ANDS   R11, R11, #1\n"
      "IT      EQ\n"
      "BEQ   Write_PRG_Syn0\n"
      "Write_PRG_Syn1:\n"
      "LDR   R11, [R3, #0]\n"
      "ANDS   R11, R11, #1\n"
      "IT      NE\n"
      "BNE   Write_PRG_Syn1\n"
      // Выставляем запись
      "STR   R8, [R4, #0]\n"
      // Цикл записи
      "Write_PRG_Loop:\n"
      // Выставляем адрес
      "STR   R1, [R5, #0]\n"
      // Выставляем данные
      "STR   R10, [R6, #0]\n"
      // Ждем F2 = 1
      "Write_PRG_LWt0:\n"
      "LDR   R11, [R3, #0]\n"
      "ANDS   R11, R11, #1\n"
      "IT      EQ\n"
      "BEQ   Write_PRG_LWt0\n"
      // Увеличиваем адрес записи
      "ADD   R1, R1, #1\n"
      // Считываем новые данные
      "ADD   R0, R0, #1\n"
      "LDRB   R10, [R0, #0]\n"
      "AND   R10, R10, 0x00FF\n"
      // Ждем F2 = 0
      "Write_PRG_LWt1:\n"
      "LDR   R11, [R3, #0]\n"
      "ANDS   R11, R11, #1\n"
      "IT      NE\n"
      "BNE   Write_PRG_LWt1\n"
      // Счетчик байт
      "SUB   R2, R2, #1\n"
      "ANDS   R2, R2, R7, LSL #0\n"
      "IT      NE\n"
      "BNE   Write_PRG_Loop\n"
      // Убираем запись
      "STR   R9, [R4, #0]\n"
      "CPSIE   f\n"
      // Обнулим адрес
      "MOVW   R7, 0x0000\n"
      "STR   R7, [R5, #0]\n"
      "POP   {R0-R11}\n"
      "BX      LR\n"
   );
}

// Запись данных из буфера в картридж
void Dendy_Write( uint8_t *PBuf, uint32_t Start, uint32_t Size )
{   // Переменные
   uint32_t         Delay;
   GPIO_InitTypeDef   GPIO_InStr;
   // Начальные установки
   PRG_RnW_Rd(); CHR_Out(); PRG_Out(); GPIOC->ODR &= 0xFF00;
   GPIO_InStr.GPIO_Pin = 0xFFFF;
   GPIO_InStr.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InStr.GPIO_Speed = GPIO_High_Speed;
   GPIO_InStr.GPIO_OType = GPIO_OType_PP;
   GPIO_InStr.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init( GPIOD, &GPIO_InStr );
   CHR_BUS_On(); PRG_BUS_On();
   // Это PRG или CHR?
   if ((Start & 0x00FF0000) == 0)
   {
      Write_PRG( PBuf, Start, Size );
   }
   else
   {   // Маски адресов и размеров
      Start &= 0x00003FFF; Size &= 0x00003FFF;
      while ((Size & 0x00003FFF) != 0)
      {   // Выставляем адрес и данные
         GPIOE->ODR = Start & 0x0000FFFF; GPIOD->ODR = (GPIOD->ODR & 0x00FF) | (*(PBuf) * 0x100);
         // Активируем строб записи CHR
         CHR_PWR_On();
         // Ждем
         Delay = 3; while (Delay) { Delay -= 1; }
         // Деактивируем чтение
         CHR_PWR_Off();
         // Счетчики
         PBuf += 1; Start += 1; Size -= 1;
      }
   }
   // Начальное состояние
   GPIO_InStr.GPIO_Pin = 0xFFFF;
   GPIO_InStr.GPIO_Mode = GPIO_Mode_IN;
   GPIO_InStr.GPIO_Speed = GPIO_High_Speed;
   GPIO_InStr.GPIO_OType = GPIO_OType_PP;
   GPIO_InStr.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init( GPIOD, &GPIO_InStr );
   CHR_BUS_Off(); PRG_BUS_Off(); CHR_In(); PRG_In();
}

// Чтение данных в буфер из картриджа в ручном режиме
void Dendy_ManualRead( uint8_t *PBuf, uint32_t Start, uint32_t Size )
{   // Переменные
   uint32_t         Delay;
   GPIO_InitTypeDef   GPIO_InStr;
   // Начальные установки
   PRG_F2_Off(); PRG_RnW_Rd(); CHR_In(); PRG_In(); GPIOC->ODR &= 0xFF00;
   GPIO_InStr.GPIO_Pin = 0xFFFF;
   GPIO_InStr.GPIO_Mode = GPIO_Mode_IN;
   GPIO_InStr.GPIO_Speed = GPIO_High_Speed;
   GPIO_InStr.GPIO_OType = GPIO_OType_PP;
   GPIO_InStr.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init( GPIOD, &GPIO_InStr );
   CHR_BUS_On(); PRG_BUS_On();
   // Маски адресов и размеров
   Start &= 0x0000FFFF; Size &= 0x0000FFFF;
   while ((Size & 0x0000FFFF) != 0)
   {   // Выставляем адрес
      GPIOE->ODR = Start & 0x0000FFFF;
      // Активируем строб чтения CHR
      PRG_F2_On();
      // Ждем
      Delay = 3; while (Delay) { Delay -= 1; }
      // Забираем данные и отключаем строб
      *(PBuf) = GPIOD->IDR & 0x00FF;
      // Деактивируем чтение
      PRG_F2_Off();
      // Счетчики
      PBuf += 1; Start += 1; Size -= 1;
   }
   // Начальное состояние
   PRG_F2_Off(); CHR_BUS_Off(); PRG_BUS_Off();
}

// Запись данных из буфера в картридж в ручном режиме
void Dendy_ManualWrite( uint8_t *PBuf, uint32_t Start, uint32_t Size )
{   // Переменные
   uint32_t         Delay;
   GPIO_InitTypeDef   GPIO_InStr;
   // Начальные установки
   PRG_F2_Off(); PRG_RnW_Wr(); CHR_Out(); PRG_Out(); GPIOC->ODR &= 0xFF00;
   GPIO_InStr.GPIO_Pin = 0xFFFF;
   GPIO_InStr.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InStr.GPIO_Speed = GPIO_High_Speed;
   GPIO_InStr.GPIO_OType = GPIO_OType_PP;
   GPIO_InStr.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init( GPIOD, &GPIO_InStr );
   CHR_BUS_On(); PRG_BUS_On();
   // Маски адресов и размеров
   Start &= 0x0000FFFF; Size &= 0x0000FFFF;
   while ((Size & 0x0000FFFF) != 0)
   {   // Выставляем адрес и данные
      GPIOE->ODR = Start & 0x0000FFFF; GPIOD->ODR = (GPIOD->ODR & 0xFF00) | *(PBuf);
      // Активируем строб чтения CHR
      PRG_F2_On();
      // Ждем
      Delay = 3; while (Delay) { Delay -= 1; }
      // Деактивируем чтение
      PRG_F2_Off();
      // Счетчики
      PBuf += 1; Start += 1; Size -= 1;
   }
   // Начальное состояние
   PRG_F2_Off(); PRG_RnW_Rd();
   GPIO_InStr.GPIO_Pin = 0xFFFF;
   GPIO_InStr.GPIO_Mode = GPIO_Mode_IN;
   GPIO_InStr.GPIO_Speed = GPIO_High_Speed;
   GPIO_InStr.GPIO_OType = GPIO_OType_PP;
   GPIO_InStr.GPIO_PuPd = GPIO_PuPd_UP;
   GPIO_Init( GPIOD, &GPIO_InStr );
   CHR_BUS_Off(); PRG_BUS_Off(); CHR_In(); PRG_In();
}

_________________
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 16 мая 2025 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Вс дек 08, 2024 00:36:39 
Это не хвост, это антенна

Карма: -10
Рейтинг сообщений: 171
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1482
Рейтинг сообщения: 0
А мужики то не в курсе! Вот пример моего говнокодинга на асме под Eclipse для ARM EABI:
Код:
...
      "IT      EQ\n"
      "BEQ   Read_PRG_Syn0\n"
...
      "IT      NE\n"
      "BNE   Read_PRG_Syn1\n"
...
      "IT      EQ\n"
      "BEQ   Read_PRG_LWt0\n"
...
Ваш код полон таких пар. А какой смысл в них? Зачем??? :dont_know:

PS: Код конечно..... ээээ... :facepalm: как будто главная цель была - сделать как можно более громоздко и медленно. :)))

Добавлено after 1 hour 14 minutes 22 seconds:
А мужики то не в курсе! Вот пример моего говнокодинга на асме под Eclipse для ARM EABI:
Спойлер
Код:
// Запись данных буфера в PRG
__attribute__ ((naked)) void Write_PRG( uint8_t *PBuf, uint32_t Start, uint32_t Size )
{   // Начинаем
   __asm volatile
   (   "PUSH   {R0-R11}\n"
      // R0 = PBuf
      // R1 = Start
      // R2 = Size
      // R3 = GPIOA_IDR (Для чтения F2)
      "MOVW   R3, #0x0010\n"
      "MOVT   R3, #0x4002\n"
      // R4 = GPIOA_BSRR (Для управления R/W)
      "MOVW   R4, #0x0018\n"
      "MOVT   R4, #0x4002\n"
      // R5 = GPIOE_ODR (Для вывода адреса)
      "MOVW   R5, #0x1014\n"
      "MOVT   R5, #0x4002\n"
      // R6 = GPIOD_ODR (Для вывода данных)
      "MOVW   R6, #0x0C14\n"
      "MOVT   R6, #0x4002\n"
      // R7 = Маска $0000FFFF
      "MOVW   R7, 0xFFFF\n"
      "MOVT   R7, 0x0000\n"
      // R8 = Маска $00020000
      "MOVW   R8, 0x0000\n"
      "MOVT   R8, 0x0002\n"
      // R9 = Маска $00000002
      "MOVW   R9, 0x0002\n"
      "MOVT   R9, 0x0000\n"
      // R10 - данные записи
      "LDRB   R10, [R0, #0]\n"
      "AND   R10, R10, 0x00FF\n"
      // Выделим
      "AND   R1, R1, R7, LSL #0\n"
      "AND   R2, R2, R7, LSL #0\n"
      "CPSID   f\n"
      // Синхронизируемся
      "Write_PRG_Syn0:\n"
      "LDR   R11, [R3, #0]\n"
      "ANDS   R11, R11, #1\n"
      "IT      EQ\n"
      "BEQ   Write_PRG_Syn0\n"
      "Write_PRG_Syn1:\n"
      "LDR   R11, [R3, #0]\n"
      "ANDS   R11, R11, #1\n"
      "IT      NE\n"
      "BNE   Write_PRG_Syn1\n"
      // Выставляем запись
      "STR   R8, [R4, #0]\n"
      // Цикл записи
      "Write_PRG_Loop:\n"
      // Выставляем адрес
      "STR   R1, [R5, #0]\n"
      // Выставляем данные
      "STR   R10, [R6, #0]\n"
      // Ждем F2 = 1
      "Write_PRG_LWt0:\n"
      "LDR   R11, [R3, #0]\n"
      "ANDS   R11, R11, #1\n"
      "IT      EQ\n"
      "BEQ   Write_PRG_LWt0\n"
      // Увеличиваем адрес записи
      "ADD   R1, R1, #1\n"
      // Считываем новые данные
      "ADD   R0, R0, #1\n"
      "LDRB   R10, [R0, #0]\n"
      "AND   R10, R10, 0x00FF\n"
      // Ждем F2 = 0
      "Write_PRG_LWt1:\n"
      "LDR   R11, [R3, #0]\n"
      "ANDS   R11, R11, #1\n"
      "IT      NE\n"
      "BNE   Write_PRG_LWt1\n"
      // Счетчик байт
      "SUB   R2, R2, #1\n"
      "ANDS   R2, R2, R7, LSL #0\n"
      "IT      NE\n"
      "BNE   Write_PRG_Loop\n"
      // Убираем запись
      "STR   R9, [R4, #0]\n"
      "CPSIE   f\n"
      // Обнулим адрес
      "MOVW   R7, 0x0000\n"
      "STR   R7, [R5, #0]\n"
      "POP   {R0-R11}\n"
      "BX      LR\n"
   );
}
Если чуток причесать Write_PRG() и перенести её в asm-файл, то получим:
Спойлер
Код:
               SECTION  .text:CODE:NOROOT(2)
               THUMB

IO_GPIOA       EQU    0x40020000
IO_GPIOA_IDR   EQU    0x40020010
IO_GPIOA_BSRR  EQU    0x40020018
IO_GPIOD_ODR   EQU    0x40020C14
IO_GPIOE_ODR   EQU    0x40021014
Write_PRG_2:   PUSH   {R4}
               ;R0 = PBuf
               ;R1 = Start
               ;R2 = Size
               ;R3 = GPIOA_IDR (Для чтения F2)
               LDR    R3, =IO_GPIOA
               ;Выделим
               UXTH   R1, R1
               SUBS   R2, R2, #1
               UXTH   R2, R2
               CPSID  f
               ;Синхронизируемся
p2_Syn0:       LDR    R4, [R3, #IO_GPIOA_IDR - IO_GPIOA]
               LSLS   R4, R4, #31
               BPL    p2_Syn0  ;;;
p2_Syn1:       LDR    R4, [R3, #IO_GPIOA_IDR - IO_GPIOA]
               LSLS   R4, R4, #31
               BMI    p2_Syn1
               ;Выставляем запись
               MOVS   R4, #0x00020000
               STR    R4, [R3, #IO_GPIOA_BSRR - IO_GPIOA]
               ;Цикл записи
p2_Loop:       ;Выставляем адрес
               LDR    R4, =IO_GPIOE_ODR
               STR    R1, [R4]
               ;Выставляем данные
               LDRB   R4, [R0], #1
               STR    R4, [R3, #IO_GPIOD_ODR - IO_GPIOA]
               ;Ждем F2 = 1
p2_LWt0:       LDR    R4, [R3, #IO_GPIOA_IDR - IO_GPIOA]
               LSLS   R4, R4, #31
               BPL    p2_LWt0
               ;Увеличиваем адрес записи
               ADDS   R1, R1, #1
               ;Ждем F2 = 0
p2_LWt1:       LDR    R4, [R3, #IO_GPIOA_IDR - IO_GPIOA]
               LSLS   R4, R4, #31
               BMI    p2_LWt1
               ;Счетчик байт
               SUBS   R2, R2, #1
               BPL    p2_Loop
               ;Убираем запись
               MOVS   R2, #2
               STR    R2, [R3, #IO_GPIOA_BSRR - IO_GPIOA]
               CPSIE  f
               ;Обнулим адрес
               LDR    R2, =IO_GPIOE_ODR
               STR    R4, [R2]
               POP    {R4}
               BX     LR
Итого: размер = 84 байта; вместо исходных 180 байт. Да и быстрее должна быть.
8)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Вс дек 08, 2024 08:49:48 
Грызет канифоль
Аватар пользователя

Карма: 3
Рейтинг сообщений: 69
Зарегистрирован: Ср сен 02, 2015 07:47:20
Сообщений: 251
Рейтинг сообщения: 0
jcxz, именно поэтому это и говнокод, была такая проба пера лет 10+ назад. Смысл послания был в том, что асм РУКИ не только никто не запрещает использовать, но и позволяется оформить __NAKED__ процедуры на, собсно, "голом" асме, если вы знаете т.н. "соглашение о вызове" для своего языка программирования.

Добавлено after 2 minutes 22 seconds:
А мужики то не в курсе! Вот пример моего говнокодинга на асме под Eclipse для ARM EABI:
Код:
...
      "IT      EQ\n"
      "BEQ   Read_PRG_Syn0\n"
...
      "IT      NE\n"
      "BNE   Read_PRG_Syn1\n"
...
      "IT      EQ\n"
      "BEQ   Read_PRG_LWt0\n"
...
Ваш код полон таких пар. А какой смысл в них? Зачем??? :dont_know:

Профдеформация после MCS80, MCS96 и т.д.

_________________
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 16 мая 2025 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Вс дек 08, 2024 12:11:05 
Это не хвост, это антенна

Карма: -10
Рейтинг сообщений: 171
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1482
Рейтинг сообщения: 0
если вы знаете т.н. "соглашение о вызове" для своего языка программирования.
Именно поэтому PUSH/POP-ить регистры R0...R3 на входе/выходе функции не нужно. :)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Вс дек 08, 2024 15:21:30 
Встал на лапы

Зарегистрирован: Вт фев 15, 2022 21:28:35
Сообщений: 81
Рейтинг сообщения: 0
ну да, при входе в прерывания r0-r3 залетают в стек автоматом, такова архитектура ядра. С вложенными прерываниями я пока не разбирался.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Вс дек 08, 2024 16:12:23 
Это не хвост, это антенна

Карма: -10
Рейтинг сообщений: 171
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1482
Рейтинг сообщения: 0
ну да, при входе в прерывания r0-r3 залетают в стек автоматом, такова архитектура ядра. С вложенными прерываниями я пока не разбирался.
Причём тут прерывания? Речь шла о функции. Читайте что такое "соглашения вызова функций". Чтобы понимать о чём идёт речь.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Пн дек 09, 2024 01:58:38 
Встал на лапы

Зарегистрирован: Вт фев 15, 2022 21:28:35
Сообщений: 81
Рейтинг сообщения: 0
Ладно давайте вернемся к USB. Мышь работает не очень хорошо, то halt то nack ответит, через пень колоду короче. Запросы отправляю в начале кадра и только по одному запросу. Че за фигня, кто останавливает канал?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Пн дек 09, 2024 08:35:46 
Грызет канифоль
Аватар пользователя

Карма: 3
Рейтинг сообщений: 69
Зарегистрирован: Ср сен 02, 2015 07:47:20
Сообщений: 251
Рейтинг сообщения: 0
Ладно давайте вернемся к USB. Мышь работает не очень хорошо, то halt то nack ответит, через пень колоду короче. Запросы отправляю в начале кадра и только по одному запросу. Че за фигня, кто останавливает канал?

А что за мышка? У меня есть аппаратный USB сниффер, я бы мог записать нормальный обмен как эталон, например. Для примеру записал обмен от беспроводной мышки, файл лога в аттаче. Софт для просмотра можно взять на сайте производителя, он с файлами логов работает и без самого устройства, есть ангельский язык, программа работает без установки. Брал его, кстати, как раз для отладки таких случаев, при реализации USB хоста на STM.


Вложения:
Комментарий к файлу: Скриншот
Снимок.PNG [241.6 KiB]
Скачиваний: 26
Комментарий к файлу: Wireless Mouse attach log
WirelessMouse.zip [42.13 KiB]
Скачиваний: 20

_________________
Репозиторий STM32: https://cloud.mail.ru/public/2i19/Y4w8kKEiZ
Актуальность репозитория: 16 мая 2025 года
Если чего-то не хватает с сайта st.com - пишите, докачаю.
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Пн дек 09, 2024 11:55:44 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 209
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1517
Рейтинг сообщения: 0
ваял USB-device в STM32Lxxx. Не Кубом, а самостоятельно. И особенных проблем не встретил. Почти всё работало нормально. Единственный косяк, на который наткнулся - неполная поддержка изохронного режима.

Ну да. Не считая наркоманский EPnR, у которых часть битов read-only, часть read-write, часть можно только стереть, причем нулем, а часть инвертировать, причем единицей.
А что за проблема с изохронными точками? У меня аудио-девайс (микрофон + динамик) вполне запустился.
danone78 писал(а):
У меня уже все работает, но вся эта возня с дескрипторами мне кажется не обязательна.
Если я подключаю USB устройство и знаю что это мышь

Так а хосту-то об этом откуда узнать? Как узнать сколько кнопок, какое абсолютное смещение соответствует передаваемым данным?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Пн дек 09, 2024 21:31:21 
Встал на лапы

Зарегистрирован: Вт фев 15, 2022 21:28:35
Сообщений: 81
Рейтинг сообщения: 0
Пробовал на двух мышках, одна Genius вторая Zornwee, одинаково. Разобрался что надо PID чередовать, вот только черный нечетный кадр пробовал менять и разницы не увидел. Получается что раз в милисеунду обязательно на SOF прерывание залетать? И.. я не понял где кнопки? Смещения координат я получаю, а кнопки то куда? Жму кнопку, прилетает пакет с нулями.

Добавлено after 6 minutes 57 seconds:
К стати давно хотел спросить, какая разница между периодическими и непериодическими запросами?

Добавлено after 9 minutes 41 second:
Единственное отличие в работе мышек, в том что Zornwee переподключается если ей после остановки канала ничего не послать, а Genius нет, просто молчит.

Добавлено after 22 minutes 59 seconds:
Простите я наврал, кнопки прилетают.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: stm32 USB host
СообщениеДобавлено: Вт дек 10, 2024 00:23:11 
Это не хвост, это антенна

Карма: -10
Рейтинг сообщений: 171
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1482
Рейтинг сообщения: 0
Ну да. Не считая наркоманский EPnR, у которых часть битов read-only, часть read-write, часть можно только стереть, причем нулем, а часть инвертировать, причем единицей.
Если все биты описаны в мануале, то нормально.

А что за проблема с изохронными точками? У меня аудио-девайс (микрофон + динамик) вполне запустился.
Значит у вас размер точек был маленький.

Проблема в том, что размер USB-памяти сильно ограничен. А так как в этой памяти нужно разместить дескрипторы всех точек, а также разместить память для ep0 и по 2 буфера под каждую изохронную точку, то получается, что максимальный размер изохронной точки может быть немного больше 230 байт (если всего одна точка активна).

Для USB-FS размер изохронных точек может быть - до 1023 байт. А значит - и максимальная скорость изохронной передачи ограничена - менее 1/4 от максимально возможной для USB-FS.
Получается - STM32L не соответствует даже требованиям USB-FS. Или не полностью соответствует.


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

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


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

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


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

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


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