STM32 и USB (практика)

Кто любит RISC в жизни, заходим, не стесняемся.
pinchemierda
Встал на лапы
Сообщения: 130
Зарегистрирован: Ср мар 22, 2017 09:52:52

Re: STM32 и USB (практика)

Сообщение pinchemierda »

Отключение отладочной информации не помогает, если конечно я её правильно отключаю (убираю галку в Flash/Configure Flash Tools/Output с Debug Information). Без неё, кстати, на Level 0 также не работает, причём на любой частоте, но это уже не важно...

Ставлю настройки PLL, как на картинке из Куба, которую oleg110592 прислал:
На частоте 168MHz, при PLL_P = 2 ничего не работает. Стоит только поменять на PLL_P = 4, что соответствует частоте 84MHz, так тут же USB запускается.
Не связано ли это с тем что где-нибудь глубоко в функциях работы USB используются временные задержки реализованные по типу for(i=0; i<delay; i++){......} ?

Вот, кстати, нашёл в файле usb_bsp.c одну какую-то подобную:

Код: Выделить всё

void USB_OTG_BSP_uDelay (const uint32_t usec)
{
  __IO uint32_t count = 0;
  const uint32_t utime = (120 * usec / 7);
  do
  {
    if ( ++count > utime )
    {
      return ;
    }
  }
  while (1);

}
Не знаю, влияет ли она на работу USB, но она точно зависит от системной частоты МК.
Реклама
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Re: STM32 и USB (практика)

Сообщение oleg110592 »

да туповатая задержка - в файле usb_core.c есть вызовы такой задержки:
USB_OTG_BSP_uDelay(3);
Посмотрел - в родных либах присутствует такое же. Индусы четко под 84МГц писали что ли?
Реклама
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: STM32 и USB (практика)

Сообщение Z_h_e »

Доброго времени суток.
Пытаюсь запустить USB в режиме девайс на STM32F107 и что-то конкретно завис (я завис).

Вот такая отладочная плата.

Стартап для серии Connectivity берет кварц на 25МГц, на плате 8. Поправил. На выходе MCO частота 72МГц +0.0003 . Кстати, странная какая-то форма сигнала, я думал там должен быть прямоугольные импульсы. Если до 8МГц еще что-то похоже, то далее, чем выше частота, тем больше постоянная составляющая и меньше размах сигнала. Так например, если частота 40МГц, то размах меньше вольта при постоянной составляющей 1.7В.
А если на выход MCO пустить все 72МГц, то при той же постоянной составляющей размах всего-лишь 400мВ (но тут ладно, выше 50МГц и не должно работать).
Странно как-то, но частота 72МГц есть. Ну можно будет еще какой-нибудь ШИМ с таймера пустить на выход, но вроде как и так 72МГц, что еще проверять.

//-------------------------------------------------------------------

Теперь что касается USB.
Инициализирую так.
Спойлер

Код: Выделить всё

		RCC->AHBENR|=RCC_AHBENR_OTGFSEN;	

	OTG_FS_GENERAL->AHBCFG|=
							OTG_FS_GENERAL_AHBCFG_GINT 			|  
							OTG_FS_GENERAL_AHBCFG_PTXFELVL 	| 
							OTG_FS_GENERAL_AHBCFG_TXFELVL 	|
							0;

	OTG_FS_GENERAL->USBCFG=	
							OTG_FS_GENERAL_USBCFG_FDMOD 	| //Force device mode 
							//OTG_FS_GENERAL_USBCFG_HNPCAP 	| 
							//OTG_FS_GENERAL_USBCFG_SRPCAP	|
							(5<<OTG_FS_GENERAL_USBCFG_TRDT_POS)		| //какое то время 
							(5<<OTG_FS_GENERAL_USBCFG_TOCAL_POS)   |
							0;
	


	OTG_FS_DEVICE->CFG=
			OTG_FS_DEVICE_CFG_DSPD | //48МГц
			//OTG_FS_DEVICE_CFG_NZLSOHSK |  //			
			0;

		
	OTG_FS_GENERAL->INTSTS=0xFFFFFFFF;
		
		OTG_FS_GENERAL->INTMSK =
			OTG_FS_GENERAL_INTMSK_USBRSTM 	|    //– USB reset
			//OTG_FS_GENERAL_INTMSK_ENUMDNEM 	|	 //Enumeration done 
			//OTG_FS_GENERAL_INTMSK_USBSUSPM	|  //USB suspend
			//OTG_FS_GENERAL_INTMSK_SOFM |	
			
			//OTG_FS_GENERAL_INTMSK_RXFLVLM |    //буфер приема не пустой	
			//OTG_FS_GENERAL_INTMSK_OEPM			|   //прерывание от OUT EP
		0;
	
	
	//включаем подтягивающий резистор DP вернее сенсор VbusB
	OTG_FS_GENERAL->CCFG|=
		OTG_FS_GENERAL_CCFG_VBUSBSEN |		
		0;	
	
		NVIC_SetPriority(OTG_FS_IRQn,15);
		NVIC_EnableIRQ(OTG_FS_IRQn);
При подключении шнурка вклчается подтягивающий резистор на линии DP и ловлю резет.
Спойлер

Код: Выделить всё

void USB_Reset(void)
{
//очистка FIFO
	OTG_FS_GENERAL->RSTCTL=OTG_FS_GENERAL_RSTCTL_TXFFLSH | OTG_FS_GENERAL_RSTCTL_TXFNUM ;
	while (OTG_FS_GENERAL->RSTCTL & OTG_FS_GENERAL_RSTCTL_TXFFLSH);
	
	OTG_FS_GENERAL->RSTCTL=OTG_FS_GENERAL_RSTCTL_RXFFLSH;
	while (OTG_FS_GENERAL->RSTCTL & OTG_FS_GENERAL_RSTCTL_RXFFLSH);
	
	
	//------------------------------------------------------------
	/*1. Set the NAK bit for all OUT endpoints
– SNAK = 1 in OTG_FS_DOEPCTLx (for all OUT endpoints)
	*/
	//OTG_FS_DEVICE->OUTEP[0].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
	OTG_FS_DEVICE->OUTEP[0].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_CNAK;
	
	OTG_FS_DEVICE->OUTEP[1].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
	OTG_FS_DEVICE->OUTEP[2].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
	OTG_FS_DEVICE->OUTEP[3].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_SNAK;
	
	//------------------------------------------------------------
	/*
	2. Unmask the following interrupt bits
– INEP0 = 1 in OTG_FS_DAINTMSK (control 0 IN endpoint)
– OUTEP0 = 1 in OTG_FS_DAINTMSK (control 0 OUT endpoint)
– STUP = 1 in DOEPMSK
– XFRC = 1 in DOEPMSK
– XFRC = 1 in DIEPMSK
– TOC = 1 in DIEPMSK
	*/
	OTG_FS_DEVICE->AINTMSK =
			OTG_FS_DEVICE_AINTMSK_IEPINTM_0 | 
			OTG_FS_DEVICE_AINTMSK_OEPINTM_0 |
			0;
	
	OTG_FS_DEVICE->OEPMSK =
			OTG_FS_DEVICE_OEPMSK_STUPM | //SETUP phase done mask
			OTG_FS_DEVICE_OEPMSK_XFRCM | //XFRCM: Transfer completed interrupt mask
			0;
			
	OTG_FS_DEVICE->IEPMSK =
			OTG_FS_DEVICE_IEPMSK_TOCM | //Timeout condition mask (Non-isochronous endpoints)
			OTG_FS_DEVICE_IEPMSK_XFRCM | //XFRCM: Transfer completed interrupt mask
			0;

//----------------------------------------------------------------------
/*
3. Set up the Data FIFO RAM for each of the FIFOs
– Program the OTG_FS_GRXFSIZ register, to be able to receive control OUT data
and setup data. If thresholding is not enabled, at a minimum, this must be equal to
1 max packet size of control endpoint 0 + 2 words (for the status of the control
OUT data packet) + 10 words (for setup packets).
– Program the OTG_FS_TX0FSIZ register (depending on the FIFO number chosen)
to be able to transmit control IN data. At a minimum, this must be equal to 1 max
packet size of control endpoint 0.
*/

OTG_FS_GENERAL->RXFSIZ	=	RX_FIFO_SIZE;//размер буфера для приема 
OTG_FS_GENERAL->TX0FSIZ	=	(TX_EP0_FIFO_SIZE<<16) | RX_FIFO_SIZE;//размер буфера и адрес для передачи точки 0


//---------------------------------------------------------------------------
/*
4. Program the following fields in the endpoint-specific registers for control OUT endpoint
0 to receive a SETUP packet
– STUPCNT = 3 in OTG_FS_DOEPTSIZ0 (to receive up to 3 back-to-back SETUP
packets)
*/
OTG_FS_DEVICE->OUTEP[0].TSIZ = 
					OTG_FS_DEVICE_ENDPOINT_TSIZ_STUPCNT_OUT0 | 
					OTG_FS_DEVICE_ENDPOINT_TSIZ_PKTCNT_OUT0   |
					OTG_FS_DEVICE_ENDPOINT_TSIZ_XFRSIZ_OUT0   |
					0;

OTG_FS_DEVICE->OUTEP[0].CTL=
		
		//OTG_FS_DEVICE_ENDPOINT_CTL_EPENA | //включить точку
		OTG_FS_DEVICE_ENDPOINT_CTL_CNAK		| //сбросить NAK		
		0;

OTG_FS_DEVICE->OUTEP[0].CTL=OTG_FS_DEVICE_ENDPOINT_CTL_EPENA ; //включить точку	

//-------------------------

		OTG_FS_GENERAL->INTMSK|=
			//OTG_FS_GENERAL_INTMSK_USBRSTM 	|    //– USB reset
			OTG_FS_GENERAL_INTMSK_ENUMDNEM 	|	 //Enumeration done 
			//OTG_FS_GENERAL_INTMSK_USBSUSPM	|  //USB suspend
			OTG_FS_GENERAL_INTMSK_SOFM |	
			
			OTG_FS_GENERAL_INTMSK_RXFLVLM |    //буфер приема не пустой	
			OTG_FS_GENERAL_INTMSK_OEPM			|   //прерывание от OUT EP
		0;
//---------------------------------
	OTG_FS_DEVICE->OUTEP[0].CTL|=
				OTG_FS_DEVICE_ENDPOINT_CTL_CNAK		| //сбросить NAK
				0;	

};
Далее я должен поймать запрос дескриптора, хост этот запрос шлет, вижу я его лог. анализатором. Но никаких флагов установленных я не вижу, в том числе не вижу флага SOF.
С меня, за помощь, огромное спасибо. :)
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: STM32 и USB (практика)

Сообщение Reflector »

VBUS подключен?
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: STM32 и USB (практика)

Сообщение Z_h_e »

Ага, без него pullup не включается, даже при установке бита force device mode.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 и USB (практика)

Сообщение VladislavS »

Из рабочего проекта.

Код: Выделить всё

static inline void Init()
{
  otg_device()->DCTL = USB_OTG_DCTL_SDIS; //Отключиться от линии

  otg_global()->GAHBCFG = USB_OTG_GAHBCFG_GINT;
  otg_global()->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | _VAL2FLD(USB_OTG_GUSBCFG_TRDT,6) | USB_OTG_GUSBCFG_PHYSEL;
  otg_global()->GINTMSK =  USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTSTS_RXFLVL;
  otg_global()->GCCFG = USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_VBUSBSEN;
  *otg_pcgcctl() = 0;
  //Задать конфигурацию FIFO
  otg_global()->GRXFSIZ = RX_FIFO_SIZE>>2;
  otg_global()->DIEPTXF0_HNPTXFSIZ = ((TX_EP0_FIFO_SIZE<<14)&0xFFFF0000) | RX_FIFO_SIZE;
  otg_global()->DIEPTXF[0] = ((TX_EP1_FIFO_SIZE<<14)&0xFFFF0000) | (RX_FIFO_SIZE+TX_EP0_FIFO_SIZE);
  otg_global()->DIEPTXF[1] = ((TX_EP2_FIFO_SIZE<<14)&0xFFFF0000) | (RX_FIFO_SIZE+TX_EP0_FIFO_SIZE+TX_EP1_FIFO_SIZE);
  otg_global()->DIEPTXF[2] = ((TX_EP3_FIFO_SIZE<<14)&0xFFFF0000) | (RX_FIFO_SIZE+TX_EP0_FIFO_SIZE+TX_EP1_FIFO_SIZE+TX_EP2_FIFO_SIZE);

  otg_outep<0>()->DOEPTSIZ = _VAL2FLD(USB_OTG_DOEPTSIZ_STUPCNT,3) | _VAL2FLD(USB_OTG_DOEPTSIZ_PKTCNT,1) | _VAL2FLD(USB_OTG_DOEPTSIZ_XFRSIZ,64);
  //Разрешить прерывания от USB    
  if (PUSB_BASE == USB_OTG_FS_PERIPH_BASE) NVIC_EnableIRQ(OTG_FS_IRQn);
#ifdef USB_OTG_HS_PERIPH_BASE
  if (PUSB_BASE == USB_OTG_HS_PERIPH_BASE) NVIC_EnableIRQ(OTG_HS_IRQn);
#endif
     
 otg_device()->DCTL &= ~USB_OTG_DCTL_SDIS;  // Подключиться
}


static inline void Enumerate_Reset()      // Обработчик прерывания RESET
{
  //Разрешить прерывания для EP0 и EP1
  otg_device()->DAINTMSK = _VAL2FLD(USB_OTG_DAINTMSK_IEPM,3) | _VAL2FLD(USB_OTG_DAINTMSK_OEPM,3);
  otg_device()->DOEPMSK  = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM;
  otg_device()->DIEPMSK  = USB_OTG_DIEPMSK_XFRCM;
  //Сбросить все TXFIFO
  otg_global()->GRSTCTL = USB_OTG_GRSTCTL_TXFFLSH | USB_OTG_GRSTCTL_TXFNUM_ALL;
  while (otg_global()->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH);
  //Сбросить RXFIFO
  otg_global()->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
  while (otg_global()->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH);
  //До энумерации адррес = 0
  otg_device()->DCFG  = _VAL2FLD(USB_OTG_DCFG_DAD,0) | USB_OTG_DCFG_DSPD_FSPEED;
}
Дальше ловить прерывания. Там "нежданчик" правда будет.
Реклама
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: STM32 и USB (практика)

Сообщение Z_h_e »

Вот жеж.
Бит CCFG_PWRDWN 0 означает активирован.
Спасибо. Буду дальше потихоньку копать. В буфер что-то упало.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Kellya
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Пн авг 24, 2020 19:13:24

Re: STM32 и USB (практика)

Сообщение Kellya »

Добрый вечер.
Пытаюсь запустить USB на stm32f103c8 и столкнулся со следующей проблемой: после того, как я получаю запрос дескриптора устройства (0x8006_0100_0000_4000), не могу передать сам дескриптор хосту. Долго не мог понять в чём заключается дело, пока не стал проверять значения регистра COUNTn_TX и буфера данных передачи. Как оказалось значения там не во всех случаях такие, которые я пытаюсь туда поместить. Например, если я пишу по адресу 0x6000_4000 + 0*16 + 4 (COUNTn_TX для нулевой точки, btable = 0) значение 0xffff_f1ff, то прочитав этот адрес, в дебаггере получаю значение 0x0000_f1ff (вроде бы всё как и должно быть, поскольку только два первых байта записываются), а вот если я пытаюсь записать туда размер передаваемого дескриптора (0x0000_0012), то получаю в консоле только 3 байта - 0x00, 0x00, 0x00. Возможно это проблема самособранного дебаггера (uart + xxd), но раньше с таким не встречался. Или я плохо разобрался с адресацией PMA, хотя, опять же, получение данных работает корректно. Проверил на двух контроллерах, результат один, значит где-то в софте косяки. Не подскажете, в каком направлении начать искать ошибки? Спасибо
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 и USB (практика)

Сообщение VladislavS »

У f103 PMA "дырявый". Писать надо 32-битными словами, но значащих только 16 бит. В отладчике будешь видеть пакеты в виде: два байта - два нуля - два байта - два нуля и т.д.
Kellya
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Пн авг 24, 2020 19:13:24

Re: STM32 и USB (практика)

Сообщение Kellya »

Ну я так и делаю. Если я пишу по адресу 0x4000_6000 (адрес буфера передачи нулевой точки при btable = 0) значение 0x0000_00040, то потом могу его так же просто считать оттуда и получу свои 0x0040. Если я проделаю ту же самую операцию, но уже для регистра 0x4000_6000 + 4 со значением, например, 0x0000_fff1, потом значение регистра перешлю побайтово через usart, то получу ожидаемый результат - 0x00, 0x00, 0xff, 0xf1. Но если я пытаюсь записать туда размер передаваемых данных (0x0000_0012), то по uart мне приходит уже не 4 байта, как раньше, а почему-то только 3, причем все равны 0. Какие-то проблемы с настройкой интерфейса может быть?
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: STM32 и USB (практика)

Сообщение Z_h_e »

Kellya писал(а): Или я плохо разобрался с адресацией PMA
Тут картинка интуитивно понятная.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Kellya
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Пн авг 24, 2020 19:13:24

Re: STM32 и USB (практика)

Сообщение Kellya »

[uquote="Z_h_e",url="/forum/viewtopic.php?p=3883320#p3883320"]
Kellya писал(а): Или я плохо разобрался с адресацией PMA
Тут картинка интуитивно понятная.[/uquote]

Не, не. Это понял все. С адресом 0x4000_6000 проблем не возникает. А когда я делаю все тоже самое, но с 0x4000_6004, то какая-то ерунда получается
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: STM32 и USB (практика)

Сообщение Z_h_e »

Не уверен, по-моему USB_COUNTn_TX уменьшается по мере отправки данных, или я это "с прямым углом перепутал".
Kellya писал(а): то по uart мне приходит уже не 4 байта, как раньше, а почему-то только 3
Возможно тут вопрос к коду для УАРТ.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 и USB (практика)

Сообщение VladislavS »

[uquote="Kellya",url="/forum/viewtopic.php?p=3883310#p3883310"]Но если я пытаюсь записать туда размер передаваемых данных (0x0000_0012)[/uquote]Зачем? "Войну и мир" туда ещё запишите, польза будет такая же.
[uquote="Kellya",url="/forum/viewtopic.php?p=3883310#p3883310"]то по uart мне приходит уже не 4 байта, как раньше, а почему-то только 3, причем все равны 0.[/uquote]Может для начала с uart разобраться? Рановато с такими скилами за USB браться.
[uquote="Kellya",url="/forum/viewtopic.php?p=3883310#p3883310"]Какие-то проблемы с настройкой интерфейса может быть?[/uquote]Какого интерфейса хоть?

PS: Наводящий вопрос. Где лежат дескрипторы буферов приёма/передачи?
Kellya
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Пн авг 24, 2020 19:13:24

Re: STM32 и USB (практика)

Сообщение Kellya »

[uquote="Z_h_e",url="/forum/viewtopic.php?p=3883329#p3883329"]Не уверен, по-моему USB_COUNTn_TX уменьшается по мере отправки данных, или я это "с прямым углом перепутал".
Kellya писал(а): то по uart мне приходит уже не 4 байта, как раньше, а почему-то только 3
Возможно тут вопрос к коду для УАРТ.[/uquote]

Да я тоже на него думаю, просто странно, что он до этого отрабатывал хорошо, а тут вот такое поведение проявилось.
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 и USB (практика)

Сообщение VladislavS »

Наводящий вопрос. Где лежат дескрипторы буферов приёма/передачи? И как они заполнены?
Kellya
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Пн авг 24, 2020 19:13:24

Re: STM32 и USB (практика)

Сообщение Kellya »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3883334#p3883334"][uquote="Kellya",url="/forum/viewtopic.php?p=3883310#p3883310"]Но если я пытаюсь записать туда размер передаваемых данных (0x0000_0012)[/uquote]Зачем? "Войну и мир" туда ещё запишите, польза будет такая же.[/uquote]
Если Вы про лишние нули, то это я просто так, для полноты картины сюда написал.

[uquote="VladislavS",url="/forum/viewtopic.php?p=3883334#p3883334"][uquote="Kellya",url="/forum/viewtopic.php?p=3883310#p3883310"]то по uart мне приходит уже не 4 байта, как раньше, а почему-то только 3, причем все равны 0.[/uquote]Может для начала с uart разобраться? Рановато с такими скилами за USB браться.[/uquote]
Да просто проблем с ним не возникало до этого, данные пересылал без каких-либо нареканий.

[uquote="VladislavS",url="/forum/viewtopic.php?p=3883334#p3883334"][uquote="Kellya",url="/forum/viewtopic.php?p=3883310#p3883310"]Какие-то проблемы с настройкой интерфейса может быть?[/uquote]Какого интерфейса хоть?[/uquote]
Uart

[uquote="VladislavS",url="/forum/viewtopic.php?p=3883334#p3883334"]PS: Наводящий вопрос. Где лежат дескрипторы буферов приёма/передачи?[/uquote]
Ну если я указал btable = 0, то для нулевой точки: 0x4000_6000 - адрес буфера передачи, 0x4000_6004 - размер передаваемых данных, 0x4000_6008 - адрес буфера приема, 0x4000_600С - размер буфера приема + размер принятых данных. Если я правильно понял Ваш вопрос
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 и USB (практика)

Сообщение VladislavS »

[uquote="Kellya",url="/forum/viewtopic.php?p=3883337#p3883337"]Да просто проблем с ним не возникало до этого, данные пересылал без каких-либо нареканий.[/uquote]Однако, они есть. Отделяем мух от котлет. Для отладки USB не нужен UART, там всё отладчиком видно.
[uquote="Kellya",url="/forum/viewtopic.php?p=3883337#p3883337"]Ну если я указал btable = 0, то для нулевой точки: 0x4000_6000 - адрес буфера передачи, 0x4000_6004 - размер передаваемых данных, 0x4000_6008 - адрес буфера приема, 0x4000_600С - размер буфера приема + размер принятых данных. Если я правильно понял Ваш вопрос[/uquote]Хорошо, тогда пишите "Войну и мир" в буфер передачи и давайте команду на его отправку. Следующая грабля лежит в регистре управления конечной точкой. Там биты статуса меняются операцией XOR.
Kellya
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Пн авг 24, 2020 19:13:24

Re: STM32 и USB (практика)

Сообщение Kellya »

[uquote="VladislavS",url="/forum/viewtopic.php?p=3883341#p3883341"][uquote="Kellya",url="/forum/viewtopic.php?p=3883337#p3883337"]Да просто проблем с ним не возникало до этого, данные пересылал без каких-либо нареканий.[/uquote]Однако, они есть. Отделяем мух от котлет. Для отладки USB не нужен UART, там всё отладчиком видно.
[uquote="Kellya",url="/forum/viewtopic.php?p=3883337#p3883337"]Ну если я указал btable = 0, то для нулевой точки: 0x4000_6000 - адрес буфера передачи, 0x4000_6004 - размер передаваемых данных, 0x4000_6008 - адрес буфера приема, 0x4000_600С - размер буфера приема + размер принятых данных. Если я правильно понял Ваш вопрос[/uquote]Хорошо, тогда пишите "Войну и мир" в буфер передачи и давайте команду на его отправку. Следующая грабля лежит в регистре управления конечной точкой. Там биты статуса меняются операцией XOR.[/uquote]

Вот я сейчас как раз на этом моменте и застрял. Я записываю необходимые данные в буфер передачи, но почему-то данные не записываются. В руководстве к контроллеру в разделе USB я ничего такого не нашел, но может есть какие-то ограничения на запись/чтение PMA? Потому что работу с памятью отдельно я, в общем-то, не изучал
Аватара пользователя
VladislavS
Собутыльник Кота
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Re: STM32 и USB (практика)

Сообщение VladislavS »

[uquote="Kellya",url="/forum/viewtopic.php?p=3883346#p3883346"]Вот я сейчас как раз на этом моменте и застрял.[/uquote]Записываем количество передаваемых данных в дескриптор буфера, сами данные в буфер и ставим статус TX_VALID в регистре управления конечной точкой. После чего ловим прерывания успешной передачи и следом следующий запрос (Set address).

Добавлено after 9 hours 9 minutes 20 seconds:
Вчера спросонья перепутал последовательность. Сначала в буфер кладём, а затем размер указываем.
Спойлер

Код: Выделить всё

 template<uint32_t EPNum>
 static inline void WriteEP(uint8_t *pData, uint32_t cnt)
 {
   if constexpr (EPNum==0)
   { // Очередь отправки только в EP0
     if(cnt>=64)
     {
       WritePAM_TX<0>(pData, 64);
       ep_tx_q_adr=pData+64;
       //Размер очереди делаем на 1 больше, чтобы отправить ZLP в случае кратности 64
       ep_tx_q_cnt=cnt-63;
     }
     else
       WritePAM_TX<0>(pData, cnt);
   }
   else
     WritePAM_TX<EPNum>(pData, cnt);
   EPSetStatus<EPNum>(EP_TX_STAT::VALID);
 }


 template <uint32_t EPNum>
 static inline void WritePAM_TX(uint8_t *pSrcData, const uint32_t cnt)
 {
   volatile PMA_WIDTH *pv = (PMA_WIDTH *) ep_tx_buf_adr[EPNum];
   for(uint32_t n = 0; n < (cnt + 1) / 2; n++, pSrcData += 2)
   {
     if constexpr (sizeof(PMA_WIDTH)==2)
       *pv++ = *(pSrcData) + ((*(pSrcData+1))<<8);
     else
       *pv++ = *((uint16_t *)pSrcData);
   }
   ep_buf_dscr[EPNum].COUNT_TX = cnt;
 }

template<uint32_t EPNum>
static inline void EPSetStatus(EP_TX_STAT tx_stat)
{
   *EPnR<EPNum>() = (*EPnR<EPNum>() ^ uint32_t(tx_stat)) & (USB_EPREG_MASK | USB_EPTX_STAT);
}


template<uint32_t EPNum>
static inline constexpr auto EPnR()
{
  return (volatile uint32_t *)(USB_BASE + 4*EPNum);
}
Для STM32F103 PMA_WIDTH это uint32_t.
Ответить

Вернуться в «ARM»