USB Host, "Blue Pill", o método de dividir o segmento pela metade e o preço da vodka na URSS

Escreveu recentemente um software USB-HOST no esp32 para funcionar com teclado / mouse / joystick. O processador é rápido, mas delicado, 5 volts nas pernas não aguento. Portanto, decidi reescrevê-lo para stm32f103c8t6, ​​amplamente conhecido na versão da placa de depuração "Blue Pill" .





Infelizmente, este é um processador muito lento para os padrões atuais (72 MHz vs 240 para esp32), então havia dúvidas se eu poderia fornecer a precisão necessária do intervalo de tempo entre os bits durante a transmissão ( 1,5 Mbps +/- 1,5% ), que corresponde a +/- 0,01uS, que é aproximadamente um ciclo do processador. Ou seja, um procedimento de atraso como:





static inline  void cpuDelay(uint32_t ticks)
{
	uint32_t stop =_getCycleCount32() + ticks;
	while((_getCycleCount32() - stop)&0x80000000u); // ntinue while overflow
}

      
      



Parei de fornecer a precisão necessária, então decidi ir para um procedimento do formulário:





void cpuDelay()
{
__asm__ __volatile__("nop");
__asm__ __volatile__("nop");
__asm__ __volatile__("nop");
__asm__ __volatile__("nop");
}
  
      
      



com o número necessário de "nop" - s. Quando me cansei de ajustar a latência manualmente e recompilar o código, decidi escrever um procedimento que seleciona a latência necessária, trabalhando em uma ampla gama de frequências de processador. A ideia é a seguinte: em vez de inserir o procedimento com o endereço cpuDelay, insira o procedimento no meio, no ponteiro:





#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 , .





Vodka russa, rótulo:
Vodka Stolichnaya, rótulo:

Estas são as fotos daqui





Portanto, 4,0 - conteúdo e 0,12 capacidade total 4,12 ---- Este é o preço da vodka Stolichnaya em 1981.





resultado da corrida:





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

      
      



PS Vodka vodka, nós em Israel permitíamos cânhamo, esqueci de postar a fonte, aqui .





O PPS não encontra falhas no código. Esta é apenas uma prova de conceito. Será limpo.








All Articles