[Open source, Программирование микроконтроллеров, DIY или Сделай сам] USB Host, «Blue Pill», метод деления отрезка пополам и цена на водку в СССР
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Написал недавно программный USB-HOST на esp32 для работы с клавиатурой/мышкой/джойстиком. Процессор быстрый, но нежный, 5 вольт на ножках не выдерживает. Поэтому решил переписать на stm32f103c8t6, широко известную в варианте отладочной платы "Blue Pill". К сожалению , это весьма неторопливый по сегодняшним меркам процессор(72 MHz vs 240 у esp32 ), поэтому были сомнения , смогу ли я обеспечить необходимую точность временного интервала между битами при передаче (1.5 Mbps +/- 1.5%),что соответствует +/- 0.01uS то есть примерно один такт работы процессора. То есть процедура задежки типа :
static inline void cpuDelay(uint32_t ticks)
{
uint32_t stop =_getCycleCount32() + ticks;
while((_getCycleCount32() - stop)&0x80000000u); // соntinue while overflow
}
необходимую точность обеспечивать перестала, поэтому решил перейти к процедуре вида:
void cpuDelay()
{
__asm__ __volatile__("nop");
__asm__ __volatile__("nop");
__asm__ __volatile__("nop");
__asm__ __volatile__("nop");
}
с необходимым числом "nop" - ов. Когда надоело настраивать задержку вручную и перекомпилировать код, решил написать процедуру подбирающую необходимую задержку, работающую в широком интервале частот процессора. Идея в следующем: вместо входа в процедуру с адресом cpuDelay войти в процедуру в середине, по указателю:
#define TNOP1 { __asm__ __volatile__(" nop"); }
#define TNOP2 {TNOP1 TNOP1}
#define TNOP4 {TNOP2 TNOP2}
#define TNOP8 {TNOP4 TNOP4}
#define TNOP16 {TNOP8 TNOP8}
#define TNOP32 {TNOP16 TNOP16}
#define TNOP64 {TNOP32 TNOP32}
__volatile__ void cpuDelayBase()
{
TNOP64;
TNOP64;
TNOP64;
TNOP64;
END_BASE:;
}
void (*delay_pntA)() = &cpuDelayBase;
#define cpuDelay(x) {(*delay_pntA)();}
#define SIZEOF_NOP 2
void setDelay(uint8_t ticks)
{
delay_pntA = (&cpuDelayBase)+((256-ticks)*SIZEOF_NOP);
}
Ну а теперь каждом запуске программы генерируется тестовая последовательность бит на 200,посылается, измеряется затраченное время и методом деления отрезка пополам процедура задержки приводится к требуемой и сохраняется в указателе delay_pntA.Время передачи 6 бит должно составлять точно 4.0uS. 6 бит было удобно замерять на временной диаграмме передачи. В стартовой последовательности присутствует комбинация 6 фронтов , которые хорошо видно на диаграмме:Диаграмма
При калибровке выяснилось, что есть небольшой оверхед на измерениях, и его нормированная величина 0.12uS отсюда целевое время 4.12 uS.А причем здесь ВОДКА!!!???Дело в том , что давным давно, в CCCP водка была универсальной валютой, ею расплачивались за все, включая то , что нельзя было купить за деньги. Например, наш мастер участка по ремонту электроники не мог купить на заводе нужные нам детали официально, однако легко мог поменять ящик водки на ящик нужных нам микросхем , на том же заводе, подойдя к правильному человеку. Цену на водку люди знали лучше числа Пи. В частности, на пивзаводе где я подрабатывал электриком во время учебы, телефон фельдшера был 2-87, а электриков-механиков 3-62, а дирекции 4-12. И никто не забывал эти номера телефонов. Цену в 2.87 я не застал по причине слишком молодого возраста а 3.62 (Русская ) и 4.12 (Столичная) - уже вполне. Цена складывалась из цены собственно водки и залоговой цены бутылки в 12 копеек, поэтому такая и не круглая.Водка русская ,этикетка:
Водка столичная , этикетка:
Это картинки отсюдаИтак 4.0 - содержание и 0.12-емкость итого 4.12 ---- Это цена водки Столичная в 1981 году. результат прогона:
pins 8 9 1 1 is OK!
cpu freq = 72.000000 MHz
TIME_MULT = 43
120 bits in 57.333332 uSec 2.093023 MHz 6 ticks in 2.866667 uS
120 bits in 269.000000 uSec 0.446097 MHz 6 ticks in 13.450000 uS
120 bits in 162.333328 uSec 0.739220 MHz 6 ticks in 8.116667 uS
120 bits in 109.000000 uSec 1.100917 MHz 6 ticks in 5.450000 uS
120 bits in 82.916664 uSec 1.447236 MHz 6 ticks in 4.145833 uS
120 bits in 69.000000 uSec 1.739130 MHz 6 ticks in 3.450000 uS
120 bits in 75.666664 uSec 1.585903 MHz 6 ticks in 3.783333 uS
120 bits in 75.666664 uSec 1.585903 MHz 6 ticks in 3.783333 uS
120 bits in 77.333336 uSec 1.551724 MHz 6 ticks in 3.866667 uS
120 bits in 77.333336 uSec 1.551724 MHz 6 ticks in 3.866667 uS
TRANSMIT_TIME_DELAY = 15 time = 4.145833 error = 0.627029%
USB1: Ack = 0 Nack = 0 20 pcurrent->cb_Cmd = 2 state = 2 epCount = 0
USB2: Ack = 0 Nack = 0 00 pcurrent->cb_Cmd = 0 state = 0 epCount = 0
desc.bDeviceClass = 00
desc.bNumConfigurations = 01
cfg.bLength = 09
cfg.wLength = 59
cfg.bNumIntf = 02
cfg.bCV = 01
cfg.bIndex = 00
cfg.bAttr = a0
cfg.bMaxPower = 50
pcurrent->epCount = 1
pcurrent->epCount = 2
desc.bDeviceClass = 00
desc.bNumConfigurations = 01
cfg.bLength = 09
cfg.wLength = 34
cfg.bNumIntf = 01
cfg.bCV = 01
cfg.bIndex = 00
cfg.bAttr = a0
cfg.bMaxPower = 50
pcurrent->epCount = 1
USB0: Ack = 6 Nack = 0 80 pcurrent->cb_Cmd = 14 state = 100 epCount = 2
USB1: Ack = 6 Nack = 0 20 pcurrent->cb_Cmd = 14 state = 104 epCount = 1
P.S. Водка водкой, у нас в Израиле разрешили коноплю, забыл выложить исходники, вот.P.P.S. не придирайтесь к коду. Это только proof of concept. Будет чиститься.
===========
Источник:
habr.com
===========
Похожие новости:
- [Open source, Git, Agile, DevOps] Приглашаем на Live-Вебинар — GitLab Auto DevOps — 8. апреля 2021, 15:00-16:00 МCK
- [Информационная безопасность, Криптография, Open source, Софт] Опубликованы исходники швейцарского криптомессенджера Threema
- [Open source, C++, Отладка, Разработка под Windows] Полезные скрипты для WinDBG: команда !exccandidates
- [Программирование, Системное программирование, Промышленное программирование, Программирование микроконтроллеров] Добавляем modbus в Embox RTOS и используем на STM32 и не только
- [Open source, JavaScript, Программирование, TypeScript] 5 фактов о том, как Microsoft приватизировала открытый исходный код, убивая JavaScript в процессе (перевод)
- [Разработка под Arduino, Гаджеты, DIY или Сделай сам, Электроника для начинающих] Как я сделал кнопку выхода из Zoom (перевод)
- [Системное программирование, Реверс-инжиниринг, Программирование микроконтроллеров, Интернет вещей, DIY или Сделай сам] Hello NXP JN5169 World
- [Читальный зал, Носимая электроника, DIY или Сделай сам, Здоровье] Третий глаз для незрячих (перевод)
- [Гаджеты, DIY или Сделай сам, Электроника для начинающих] Цифровая паяльная станция своими руками (перевод)
- [DIY или Сделай сам] CCTV на базе Raspberry Pi. Часть первая и, возможно, последняя
Теги для поиска: #_open_source, #_programmirovanie_mikrokontrollerov (Программирование микроконтроллеров), #_diy_ili_sdelaj_sam (DIY или Сделай сам), #_stm32, #_stm32f103, #_opensource, #_open_source, #_programmirovanie_mikrokontrollerov (
Программирование микроконтроллеров
), #_diy_ili_sdelaj_sam (
DIY или Сделай сам
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 08:18
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Написал недавно программный USB-HOST на esp32 для работы с клавиатурой/мышкой/джойстиком. Процессор быстрый, но нежный, 5 вольт на ножках не выдерживает. Поэтому решил переписать на stm32f103c8t6, широко известную в варианте отладочной платы "Blue Pill". К сожалению , это весьма неторопливый по сегодняшним меркам процессор(72 MHz vs 240 у esp32 ), поэтому были сомнения , смогу ли я обеспечить необходимую точность временного интервала между битами при передаче (1.5 Mbps +/- 1.5%),что соответствует +/- 0.01uS то есть примерно один такт работы процессора. То есть процедура задежки типа : static inline void cpuDelay(uint32_t ticks)
{ uint32_t stop =_getCycleCount32() + ticks; while((_getCycleCount32() - stop)&0x80000000u); // соntinue while overflow } void cpuDelay()
{ __asm__ __volatile__("nop"); __asm__ __volatile__("nop"); __asm__ __volatile__("nop"); __asm__ __volatile__("nop"); } #define TNOP1 { __asm__ __volatile__(" nop"); }
#define TNOP2 {TNOP1 TNOP1} #define TNOP4 {TNOP2 TNOP2} #define TNOP8 {TNOP4 TNOP4} #define TNOP16 {TNOP8 TNOP8} #define TNOP32 {TNOP16 TNOP16} #define TNOP64 {TNOP32 TNOP32} __volatile__ void cpuDelayBase() { TNOP64; TNOP64; TNOP64; TNOP64; END_BASE:; } void (*delay_pntA)() = &cpuDelayBase; #define cpuDelay(x) {(*delay_pntA)();} #define SIZEOF_NOP 2 void setDelay(uint8_t ticks) { delay_pntA = (&cpuDelayBase)+((256-ticks)*SIZEOF_NOP); } При калибровке выяснилось, что есть небольшой оверхед на измерениях, и его нормированная величина 0.12uS отсюда целевое время 4.12 uS.А причем здесь ВОДКА!!!???Дело в том , что давным давно, в CCCP водка была универсальной валютой, ею расплачивались за все, включая то , что нельзя было купить за деньги. Например, наш мастер участка по ремонту электроники не мог купить на заводе нужные нам детали официально, однако легко мог поменять ящик водки на ящик нужных нам микросхем , на том же заводе, подойдя к правильному человеку. Цену на водку люди знали лучше числа Пи. В частности, на пивзаводе где я подрабатывал электриком во время учебы, телефон фельдшера был 2-87, а электриков-механиков 3-62, а дирекции 4-12. И никто не забывал эти номера телефонов. Цену в 2.87 я не застал по причине слишком молодого возраста а 3.62 (Русская ) и 4.12 (Столичная) - уже вполне. Цена складывалась из цены собственно водки и залоговой цены бутылки в 12 копеек, поэтому такая и не круглая.Водка русская ,этикетка: Водка столичная , этикетка: Это картинки отсюдаИтак 4.0 - содержание и 0.12-емкость итого 4.12 ---- Это цена водки Столичная в 1981 году. результат прогона: pins 8 9 1 1 is OK!
cpu freq = 72.000000 MHz TIME_MULT = 43 120 bits in 57.333332 uSec 2.093023 MHz 6 ticks in 2.866667 uS 120 bits in 269.000000 uSec 0.446097 MHz 6 ticks in 13.450000 uS 120 bits in 162.333328 uSec 0.739220 MHz 6 ticks in 8.116667 uS 120 bits in 109.000000 uSec 1.100917 MHz 6 ticks in 5.450000 uS 120 bits in 82.916664 uSec 1.447236 MHz 6 ticks in 4.145833 uS 120 bits in 69.000000 uSec 1.739130 MHz 6 ticks in 3.450000 uS 120 bits in 75.666664 uSec 1.585903 MHz 6 ticks in 3.783333 uS 120 bits in 75.666664 uSec 1.585903 MHz 6 ticks in 3.783333 uS 120 bits in 77.333336 uSec 1.551724 MHz 6 ticks in 3.866667 uS 120 bits in 77.333336 uSec 1.551724 MHz 6 ticks in 3.866667 uS TRANSMIT_TIME_DELAY = 15 time = 4.145833 error = 0.627029% USB1: Ack = 0 Nack = 0 20 pcurrent->cb_Cmd = 2 state = 2 epCount = 0 USB2: Ack = 0 Nack = 0 00 pcurrent->cb_Cmd = 0 state = 0 epCount = 0 desc.bDeviceClass = 00 desc.bNumConfigurations = 01 cfg.bLength = 09 cfg.wLength = 59 cfg.bNumIntf = 02 cfg.bCV = 01 cfg.bIndex = 00 cfg.bAttr = a0 cfg.bMaxPower = 50 pcurrent->epCount = 1 pcurrent->epCount = 2 desc.bDeviceClass = 00 desc.bNumConfigurations = 01 cfg.bLength = 09 cfg.wLength = 34 cfg.bNumIntf = 01 cfg.bCV = 01 cfg.bIndex = 00 cfg.bAttr = a0 cfg.bMaxPower = 50 pcurrent->epCount = 1 USB0: Ack = 6 Nack = 0 80 pcurrent->cb_Cmd = 14 state = 100 epCount = 2 USB1: Ack = 6 Nack = 0 20 pcurrent->cb_Cmd = 14 state = 104 epCount = 1 =========== Источник: habr.com =========== Похожие новости:
Программирование микроконтроллеров ), #_diy_ili_sdelaj_sam ( DIY или Сделай сам ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 25-Ноя 08:18
Часовой пояс: UTC + 5