Top.Mail.Ru
Перейти к содержанию

DIY контроллер для педалей и кнопок


Рекомендуемые сообщения

Поглядел на код, плохо уже соображаю, поэтому ща буду глупости писать. Вместо неиспользуемых кнопок в статус репорте можно padding использовать, тогда пустые биты не будут отображаться как кнопки. Если SWDIO/SWCLK в кубе повесить на ноги, то connect можно будет делать без ресета, хотя ног доступно будет и меньше.

 

Хотел еще что-нибудь написать, но голова уже выключилась... :turned:

  • Нравится 2
Ссылка на комментарий

Спасибо за комменты по делу )

На самом деле я не завидую любому профессиональному программисту, который набредет на мой код. ))) В свое оправдание скажу, что я там многое собираюсь переписать, например, для конфигурятора пинов всю работу с gpio придется переписать на bare register access, т.е. выкинуть все define. Поэтому я на данном этапе особо к красоте кода не стремился

 

padding, насколько я понимаю, несет чисто эстетическую функцию. Но в дальнейшем при динамически изменяемом кол-ве кнопок он будет мешать. Наоборот, кол-во кнопок в дескрипторе планирую увеличить до 128.

SWDIO/SWCLK отключены специально, они полезную работу выполняют

  • Нравится 1
Ссылка на комментарий
  • 2 недели спустя...

Дима, подскажи, пожалуйста, были какие то проблемы с ADC на 12 МГц? Я вот про это:

 

// PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;

PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;

 

У меня тут трэш-шапито какое то вылезло, пытаюсь разобраться...

 

И вот это:

 

hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;

// hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

//hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

 

Читать по 16 бит не получилось, только по 32?

Ссылка на комментарий
// PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;

PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;

когда я попытался завести АЦП на макс частоте (типа круто) и ADC_SAMPLETIME_1CYCLE_5, скорость обмена по усб упала до 3Hz. Сложно сказать в чем тут была проблема - в самом АЦП (в принципе это ведь штатные для него частоты) и в переполнении какого-ть усб буфера на передачу, но вот факт. Больше всего я грешу, что не хватало пропускной способности самой шины. В итоге я прикинул, что для 1kHz обмена хватит и 9MHz + ADC_SAMPLETIME_13CYCLES_5 для большей точности.

 

// hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

//hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

CubeMx вообще первоначально не хотел 16бит ставить, это я уже пробовал ручками. Но потом внезапно понял, что по 32битной шине что 16 бит, что дефолтные 32 в любом случае пролезут за 1 такт и оставил 32

Ссылка на комментарий

когда я попытался завести АЦП на макс частоте (типа круто) и ADC_SAMPLETIME_1CYCLE_5, скорость обмена по усб упала до 3Hz. Сложно сказать в чем тут была проблема - в самом АЦП (в принципе это ведь штатные для него частоты) и в переполнении какого-ть усб буфера на передачу, но вот факт. Больше всего я грешу, что не хватало пропускной способности самой шины. В итоге я прикинул, что для 1kHz обмена хватит и 9MHz + ADC_SAMPLETIME_13CYCLES_5 для большей точности.

Там скорее всего слишком много прерываний генерировалось после каждого завершения преобразования, из-за этого и скорость упала...

 

CubeMx вообще первоначально не хотел 16бит ставить, это я уже пробовал ручками. Но потом внезапно понял, что по 32битной шине что 16 бит, что дефолтные 32 в любом случае пролезут за 1 такт и оставил 32

Можно в кубе поставить и 16, даже работало, пока я не увеличил количество преобразований за один цикл...

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

 

Можно в кубе поставить и 16, даже работало, пока я не увеличил количество преобразований за один цикл...

16бит там можно выбрать и вроде бы все ок, а потом смотришь в код, а там 8 бит ))) Может только у меня такая фигня, я хз. Куб вроде последний был.

Вообще я крайне разочарован качеством и куба и всего ХАЛа в целом, буду все переписывать постепенно

Ссылка на комментарий

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

После завершения цикла преобразования вызывается callback void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) по прерыванию. У тебя непрерывный цикл преобразования, значит, прерывания генерятся тоже непрерывно :) Так как при этом основной цикл прерывается - это может влиять на скорость опроса.

 

16бит там можно выбрать и вроде бы все ок, а потом смотришь в код, а там 8 бит ))) Может только у меня такая фигня, я хз. Куб вроде последний был.

Вообще я крайне разочарован качеством и куба и всего ХАЛа в целом, буду все переписывать постепенно

Хуже когда добавляешь в код вызов пустой функции и все виснет нахрен :( На ардуине я такого что-то не припомню...

Изменено пользователем RomanST
Ссылка на комментарий
Так как при этом основной цикл прерывается - это может влиять на скорость опроса
насколько я понимаю эту кухню (я так-то ламо ))) ) - не должен, это же отдельный DMA контроллер

вот из референсов

Direct memory access (DMA) is used in order to provide high-speed data transfer between

peripherals and memory as well as memory to memory. Data can be quickly moved by DMA

without any CPU actions. This keeps CPU resources free for other operations.

 

Хуже когда добавляешь в код вызов пустой функции и все виснет нахрен
оптимизатор компилятора не дурит? Если нет, тогда дебаг в руки, благо он тут гораздо лучше, чем на ардуинах
Ссылка на комментарий

насколько я понимаю эту кухню (я так-то ламо ))) ) - не должен, это же отдельный DMA контроллер

HAL_ADC_IRQHandler в stm32f1xx_hal_adc.c посмотри.

 

(#) Optionally, in case of usage of DMA:
	 (++) Configure the DMA (DMA channel, mode normal or circular, ...)
		 using function HAL_DMA_Init().
	 (++) Configure the NVIC for DMA
		 using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn)
	 (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler()
		 into the function of corresponding DMA interruption vector
		 DMAx_Channelx_IRQHandler().

 

HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); - переопределяем вектор 11 в MX_DMA_Init() в main.c, это куб генерит за тебя.

дефолтное значение устанавливается в startup_stm32f103xb.S - DMA1_Channel1_IRQn

 

 .weak DMA1_Channel1_IRQHandler
 .thumb_set DMA1_Channel1_IRQHandler,Default_Handler

текст:

 

void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
/* USER CODE END DMA1_Channel1_IRQn 1 */
}

 

Ну а из HAL_DMA_IRQHandler - вызывается HAL_ADC_ConvCpltCallback()

 

вот из референсов

Код надо смотреть :)

 

оптимизатор компилятора не дурит? Если нет, тогда дебаг в руки, благо он тут гораздо лучше, чем на ардуинах

Дебаг пока не освоил еще, в кукушке он нормально не работает, попробую TrueStudio...

 

Кстати, там еще и half transfer complete callback есть, он на середине буфера вызывается...

Изменено пользователем RomanST
Ссылка на комментарий

Еще интересная тема нашлась, F103 не имеет заводской поддержки DFU (в отличие от, например, F042), но можно реализовать DFU самому, вот тут можно подглядеть реализацию: https://github.com/devanlai/dap42

 

Это на случай если делать мелкосерийный продукт на F103 и обновлять прошивку без st-link'а...

Ссылка на комментарий

да, я в курсе, но поскольку никакой мелкосерийки я не планирую, у меня это где-то очень в дальних планах.

Вот здесь гораздо интереснее, читать со слова Вторичный бутлоадер

Суть - делается вторичный бутлоадер, который представляется как mass storage device, и прошивка заливается как просто копирование файла в эту "флешку". Именно то, что по ссылке, у меня с наскоку не заработало, но имхо направление идеологически верное, так и буду делать, когда дойдут руки

  • Нравится 1
Ссылка на комментарий

Вот здесь гораздо интереснее, читать со слова Вторичный бутлоадер

Суть - делается вторичный бутлоадер, который представляется как mass storage device, и прошивка заливается как просто копирование файла в эту "флешку". Именно то, что по ссылке, у меня с наскоку не заработало, но имхо направление идеологически верное, так и буду делать, когда дойдут руки

Забавный велосипед придумали, DFU наоборот, в "заводской" схеме нормальная прошивка начинается со стандартного адреса, а чтобы первым стартовал загрузчик DFU - меняют таблицу векторов прерываний...

Ссылка на комментарий
  • 1 месяц спустя...

Дима, а ты случайно не изучал вопрос, какие контролы поддерживает iR кроме осей и кнопок. Вот прямо если идти по документу HID Usage Tables:

http://www.usb.org/developers/hidpage/Hut1_12v2.pdf

Ссылка на комментарий
  • 5 месяцев спустя...

Рома, извини, только сейчас увидел твой пост. Не изучал, вроде больше ничего и не поддерживает.

 

 

Не прошло и года, набыдлокодил я прогу-конфигурялку режима работы пинов

 

post-1259-0-38331800-1489175558_thumb.png

 

post-1259-0-77002800-1489175566_thumb.png

 

Not_Used - нога не используется

 

AnalogNoSmooth

AnalogLowSmooth

AnalogMedSmooth

AnalogHighSmooth - различные варианты сглаживания для оси, можно выбрать более подходящий в зависимости от качества потов, всяких эми от осв и т.п.

 

Rotary_PINA

Rotary_PINB - крайние (боковые) пины энкодеров

Rotary_Enc - средний пин энкодеров

 

Button_ROW - строка матрицы кнопок

Button_COLUMN - столбец матрицы кнопок

Button - просто одиночная кнопка (вторая нога на +3.3В)

 

 

 

Кроме этого, еще сделал калибровку осей. Аналог обычной калибровки через DXTweak2 (например), но ее значения хранятся в самом МК - не надо на каждой новой винде делать калибровку заново. Ну и ось, вне зависимости насколько сильно она порезана калибровкой, всегда выдает 4096 шагов.

 

post-1259-0-87140200-1489175572_thumb.png

 

 

По кнопкам:

 

Get config from device

Save config to device прочитать/сохранить сохраненный конфиг с/в МК

 

Load config to file

Save config to file - загрузить/сохранить конфиг из/в файла, если вдруг такое вообще понадобится

 

 

Соответственно, обновлена и прошивка для стм

Прошивка

Прога-конфигурялка

  • Нравится 2
Ссылка на комментарий

Дима, как в DirectX через реестр ось инвертировать? Есть детальное описание полей Attributes и FFAttributes?

 

Должно быть где то тут

https://msdn.microso...4(v=vs.85).aspx

https://msdn.microso...1(v=vs.85).aspx

post-1173-0-54480700-1489220524_thumb.png

Изменено пользователем RomanST
Ссылка на комментарий

Дима, как в DirectX через реестр ось инвертировать? Есть детальное описание полей Attributes и FFAttributes?

 

Я наверно проблему не очень понимаю...

Если мы говорим о потах и он выдает инвертированную ось, то достаточно поменять местами у него питание и землю на ногах, так?

Если о усилителе для LC, то такой фокус наверно не пройдет, я в этом случае использовал бы маппинг значений для их инвертирования (т.к. я маппинг все равно использую для вытягивания оси после калибровки)

 

long map(long x, long in_min, long in_max, long out_min, long out_max)

{

return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

}

  • Нравится 1
Ссылка на комментарий

Если о усилителе для LC, то такой фокус наверно не пройдет, я в этом случае использовал бы маппинг значений для их инвертирования (т.к. я маппинг все равно использую для вытягивания оси после калибровки)

 

long map(long x, long in_min, long in_max, long out_min, long out_max)

{

return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

}

Да, в своем контроллере я бы так и сделал, речь о G27, там поты в минимуме имеют значение 255, в максимуме - 0. Когда втыкаешь LC, получается инвертированная ось. Конечно, игры чаще всего позволяют поставить галку "инвертировать ось", но я не уверен, что эта галка есть в каждой игре.

Ссылка на комментарий

Рома,

понятно, но имхо править реестр тоже как-то слишком в лоб решение, выйдет какой-ть очередной виндовый апдейт и оно перестанет работать..

 

может лучше через логитековский профайлер сделать? типа такого

 

post-1259-0-79911800-1489252326.png

 

post-1259-0-10550600-1489252342.png

 

 

правда, насколько я понял, для этого придется делать профиль под конкретную игру, но тут уж надо выбирать меньшее из двух зол...

 

Счастливые вы люди!

Вроде все есть (для симрейсинга), а продолжаете что-то свое выдумывать

Присоединяйся, это интересно ;)

  • Нравится 1
Ссылка на комментарий
  • 3 недели спустя...

Стандартным виндовым средством аля "Свойства игрового контроллера" можно протестировать работу только 32 кнопок. Если больше, то обычно приходится запускать какую-ть игру, чтобы проверить остальные - неудобно.

Поэтому к OSHStudio добавил третью вкладку, где можно протестить все возможные 64 кнопки

 

post-1259-0-73771500-1490640640_thumb.png

Ссылка на комментарий
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...