Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
template<typename Endpoints>
using EndpointsManager = EndpointsManagerBase<SortedUniqueEndpoints<Endpoints>,
typename Sample<IsBidirectionalOrBulkDoubleBufferedEndpoint, SortedUniqueEndpoints<Endpoints>>::type,
typename Sample<IsOutEndpoint, SortedUniqueEndpoints<Endpoints>>::type,
typename Sample<IsBulkDoubleBufferedTxEndpoint, SortedUniqueEndpoints<Endpoints>>::type>;
using BidirectionalAndBulkDoubleBufferedEndpoints = typename Sample<IsBidirectionalOrBulkDoubleBufferedEndpoint, SortedUniqueEndpoints<Endpoints>>::type;
...
using EndpointsManager = EndpointsManagerBase<Endpoints, BidirectionalAndBulkDoubleBufferedEndpoints , ...>;
using X = Y;Когда отладил и понял, что все правильно, соединяю. В основном писать шаблоны несложно (это обычно связка базовый класс + рекурсивная специализация). Напрягает только раскрытие variadic-ов, но ничего не поделать.Добавлю к нелюбви USB. В реальном изделии необходимо заиметь свои vid/pid. Из-за этого при небольшой серии проще поставить конвертер. И разработка также упрощается.
На гитхабе где-то была репа, где раздают vid/pid бесплатно и совершенно официально
We STMicroelectronics, hereby agree that:
"**** Ltd." company can use the original PID: 0x**** and VID: 0x**** pending to be licensed by USB-IF of "**** Ltd. ***" and solely for the purpose of “**** Ltd. *** using STM32F303VC silicon USB device microcontrollers” This license is revocable and nontransferable and no other rights are granted except those expressly stated here.
static void Init()
{
memset(reinterpret_cast<void*>(BdtBase), 0x00, BdtSize);
(InitTxAddressFieldInDescriptor<AllEndpoints>(), ...);
(InitRxAddressFieldInDescriptor<BidirectionalAndBulkDoubleBufferedEndpoints>(), ...);
(InitRxCountFieldInDescriptor<RxEndpoints>(), ...);
(InitSecondRxCountFieldInDescriptor<BidirectionalAndBulkDoubleBufferedEndpoints>(), ...);
}template<typename Endpoint>
static void InitRxCountFieldInDescriptor()
{
*reinterpret_cast<uint16_t*>(BdtBase + BdtCellOffset<Endpoint> + 2) = CalculateRxCountValue<Endpoint>();
}
Stm32 + USB на шаблонах C++