Ср апр 19, 2017 15:53:38
Чт май 04, 2017 08:55:04
Вс июн 25, 2017 22:48:55
Пн июн 26, 2017 11:51:11
Сб сен 02, 2017 18:22:02
#include "main.h"
#include "stm32f4xx_hal.h"
#include "usb_host.h"
#include "usb_host.h"
#include "usbh_core.h"
#include "ST7735S.h"
//размер буфера приема данных
#define RECEIVE_BUFFER_SIZE 512UL
extern USBH_HandleTypeDef hUsbHostFS;//дескриптор подключения
extern ApplicationTypeDef ApplicationState;//состояние приложения
uint8_t ReceiveBuffer[RECEIVE_BUFFER_SIZE];//буфер приема данных
uint8_t DevicePipe[3];//каналы для приема данных
void RCC_Init(void);
void GPIO_Init(void);
void SPI_Init(void);
void USBH_UserProcess(USBH_HandleTypeDef *phost,uint8_t id);//обработчик событий
long USB_HOST_ControlTransfer(USBH_HandleTypeDef *hUsbHost,uint8_t request_type,uint8_t bRequest,uint16_t wValue,uint16_t wIndex,uint8_t *data,uint16_t wLength);//передать управляющее сообщение
long USB_HOST_Receive(USBH_HandleTypeDef *hUsbHost,uint8_t in_pipe,uint8_t *buffer);//прием данных
//----------
//локальный обработчик ошибок
//----------
void ErrorHandler(void)
{
while(1)
{
}
}
//----------
//глобальный обработчик ошибок
//----------
void _Error_Handler(char * file,int line)
{
ErrorHandler();
}
//----------
//инициализация GPIO
//----------
void GPIO_Init(void)
{
//включаем тактирование портов
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
//GPIO_Pin – номера выводов, которые конфигурируются. Пример для нескольких выводов:
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
//GPIO_Speed – задает скорость для выбранных выводов.
//GPIO_Mode – задает режим работы выводов. Может принимать следующие значения:
//настраиваем параметры порта D
GPIO_InitTypeDef LED_GPIO_Init;
LED_GPIO_Init.Mode=GPIO_MODE_OUTPUT_PP;
LED_GPIO_Init.Pull=GPIO_NOPULL;
LED_GPIO_Init.Pin=GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
LED_GPIO_Init.Speed=GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOD,&LED_GPIO_Init);
}
//----------
//инициализация SPI
//----------
void SPI_Init(void)
{
SPI_HandleTypeDef hspi1;
hspi1.Instance=SPI1;
hspi1.Init.Mode=SPI_MODE_MASTER;
hspi1.Init.Direction=SPI_DIRECTION_2LINES;
hspi1.Init.DataSize=SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity=SPI_POLARITY_LOW;
hspi1.Init.CLKPhase=SPI_PHASE_1EDGE;
hspi1.Init.NSS=SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2;
hspi1.Init.FirstBit=SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode=SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial=10;
if (HAL_SPI_Init(&hspi1)!=HAL_OK) ErrorHandler();
}
//----------
//инициализация тактового генератора
//----------
void RCC_Init(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState=RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState=RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource=RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM=4;
RCC_OscInitStruct.PLL.PLLN=168;
RCC_OscInitStruct.PLL.PLLP=RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ=7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!=HAL_OK) ErrorHandler();
RCC_ClkInitStruct.ClockType=RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider=RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider=RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider=RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct,FLASH_LATENCY_5)!=HAL_OK) ErrorHandler();
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
}
//----------
//передать управляющее сообщение
//----------
long USB_HOST_ControlTransfer(USBH_HandleTypeDef *hUsbHost,uint8_t request_type,uint8_t bRequest,uint16_t wValue,uint16_t wIndex,uint8_t *data,uint16_t wLength)
{
hUsbHost->Control.setup.b.bmRequestType=request_type;
hUsbHost->Control.setup.b.bRequest=bRequest;
hUsbHost->Control.setup.b.wValue.w=wValue;
hUsbHost->Control.setup.b.wIndex.w=wIndex;
hUsbHost->Control.setup.b.wLength.w=wLength;
USBH_StatusTypeDef status=USBH_BUSY;
while(1)
{
status=USBH_CtlReq(hUsbHost,data,wLength);
if (status==USBH_BUSY) continue;
break;
}
if (status!=USBH_OK)
{
hUsbHost->RequestState=CMD_SEND;
return(0);
}
return(wLength);
}
//----------
//прием данных
//----------
long USB_HOST_Receive(USBH_HandleTypeDef *hUsbHost,uint8_t in_pipe,uint8_t *buffer)
{
USBH_URBStateTypeDef URB_Status=USBH_URB_IDLE;
long length=0;
USBH_BulkReceiveData(hUsbHost,buffer,RECEIVE_BUFFER_SIZE,in_pipe);
URB_Status=USBH_LL_GetURBState(hUsbHost,in_pipe);
if(URB_Status==USBH_URB_DONE)
{
length=USBH_LL_GetLastXferSize(hUsbHost,in_pipe);
char str[20];
sprintf(str,"Data:%i",length);
ST7735S_Print(str,ST7735S_YELLOW);
return(length);
}
return(0);
}
//----------
//обработка USB
//----------
void USB_HOST_Processing(void)
{
//состояния программы
typedef enum
{
MODE_WAIT,
MODE_GET_MANUFACTURER,
MODE_GET_PRODUCT,
MODE_INIT_PIPE,
MODE_CONTROL_TRANSFER_STOP_I2,
MODE_CONTROL_TRANSFER_STOP_I1,
MODE_CONTROL_TRANSFER_START_I1,
MODE_CONTROL_TRANSFER_START_I2,
MODE_RECEIVE,
MODE_PAUSE,
MODE_STOP
} MODE;
static long state_pos=0;
//последовательность инициализации
static MODE state[]=
{
MODE_WAIT,
MODE_GET_MANUFACTURER,
MODE_GET_PRODUCT,
MODE_INIT_PIPE,
MODE_CONTROL_TRANSFER_STOP_I2,
MODE_PAUSE,
MODE_CONTROL_TRANSFER_STOP_I1,
MODE_PAUSE,
MODE_CONTROL_TRANSFER_START_I1,
MODE_PAUSE,
MODE_CONTROL_TRANSFER_START_I2,
MODE_PAUSE,
MODE_RECEIVE,
MODE_STOP
};
USBH_Process(&hUsbHostFS);
/*
USBH_UsrLog("PID: %xh", hUsbHostFS.device.DevDesc.idProduct );
USBH_UsrLog("VID: %xh", hUsbHostFS.device.DevDesc.idVendor );
*/
USBH_StatusTypeDef status;
if (hUsbHostFS.gState==HOST_DEV_DISCONNECTED || ApplicationState==APPLICATION_DISCONNECT)//устройство отключено
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12|GPIO_PIN_13,GPIO_PIN_RESET); //отключаем светодиоды
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14|GPIO_PIN_15,GPIO_PIN_RESET); //отключаем светодиоды
state_pos=0;
}
if (hUsbHostFS.gState==HOST_CHECK_CLASS)//определение класса устройства
{
MODE mode=state[state_pos];
//начало подключения
if (mode==MODE_WAIT)
{
//if (USBH_SetCfg(&hUsbHostFS,3)==USBH_OK)
{
//USBH_SelectInterface(&hUsbHostFS,0);
/* ST7735S_Clear();
char str[100];
long interface=USBH_MAX_NUM_INTERFACES;//hUsbHostFS.device.CfgDesc.bNumInterfaces;
for(long n=0;n<interface;n++)
{
long ep=hUsbHostFS.device.CfgDesc.Itf_Desc[n].bNumEndpoints;
//long i=hUsbHostFS.device.CfgDesc.Itf_Desc[n].bInterfaceNumber;
sprintf(str,"Interface:%i EP:%i",n,ep);
ST7735S_Print(str,ST7735S_YELLOW);
for(long m=0;m<ep;m++)
{
long addr=hUsbHostFS.device.CfgDesc.Itf_Desc[n].Ep_Desc[m].bEndpointAddress;
long size=hUsbHostFS.device.CfgDesc.Itf_Desc[n].Ep_Desc[m].wMaxPacketSize;
long attr=hUsbHostFS.device.CfgDesc.Itf_Desc[n].Ep_Desc[m].bmAttributes;
sprintf(str,"EP:%02x S:%i A:%02x",addr,size,attr);
ST7735S_Print(str,ST7735S_YELLOW);
}
HAL_Delay(10000);
ST7735S_Clear();
}
HAL_Delay(10000);
HAL_Delay(10000);
HAL_Delay(10000);
*/
state_pos++;
}
return;
}
//запрос производителя
if (mode==MODE_GET_MANUFACTURER)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14,GPIO_PIN_SET);//включаем светодиоды
status=USBH_Get_StringDesc(&hUsbHostFS,hUsbHostFS.device.DevDesc.iManufacturer,ReceiveBuffer,64);
if (status==USBH_OK)
{
ST7735S_Print((char*)ReceiveBuffer,ST7735S_YELLOW);
//HAL_Delay(1000);
state_pos++;
}
return;
}
//запрос модели
if (mode==MODE_GET_PRODUCT)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_15,GPIO_PIN_SET);//включаем светодиоды
status=USBH_Get_StringDesc(&hUsbHostFS,hUsbHostFS.device.DevDesc.iProduct,ReceiveBuffer,64);
if (status==USBH_OK)
{
ST7735S_Print((char*)ReceiveBuffer,ST7735S_YELLOW);
//HAL_Delay(1000);
state_pos++;
}
return;
}
//инициализация каналов
if (mode==MODE_INIT_PIPE)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_SET);//включаем светодиоды
//создаем каналы для конечных точек
uint8_t end_point[3];
end_point[0]=0x81;
end_point[1]=0x83;
end_point[2]=0x85;
bool ok[3];
ok[0]=false;
ok[1]=false;
ok[2]=false;
bool error=false;
for(long n=0;n<3;n++)
{
DevicePipe[n]=USBH_AllocPipe(&hUsbHostFS,end_point[n]);
status=USBH_OpenPipe(&hUsbHostFS,DevicePipe[n],end_point[n],hUsbHostFS.device.address,hUsbHostFS.device.speed,USB_EP_TYPE_BULK,USBH_MAX_DATA_BUFFER);
if (status==USBH_OK) ok[n]=true;
else error=true;
}
if (error==true)
{
for(long n=0;n<3;n++)
{
if (ok[n]==true) USBH_ClosePipe(&hUsbHostFS,DevicePipe[n]);
USBH_FreePipe(&hUsbHostFS,DevicePipe[n]);
}
return;
}
char str[20];
for(long n=0;n<3;n++)
{
sprintf(str,"Pipe:0x%02x=0x%02x",end_point[n],DevicePipe[n]);
ST7735S_Print(str,ST7735S_YELLOW);
}
state_pos++;
return;
}
/* Flir config
01 0b 01 00 01 00 00 00 c4 d5
0 bmRequestType = 01
1 bRequest = 0b
2 wValue 0001 type (H) index (L) stop=0/start=1 (Alternate Setting)
4 wIndex 01 interface 1/2
5 wLength 00
6 Data 00 00
*/
//передача управляющих сообщений
if (mode==MODE_CONTROL_TRANSFER_STOP_I2)
{
//передаём команду на остановку интерфейса 2
USBH_SetInterface(&hUsbHostFS,2,0);
//USB_HOST_ControlTransfer(&hUsbHostFS,USB_H2D|USB_REQ_RECIPIENT_INTERFACE|USB_REQ_TYPE_STANDARD,USB_REQ_SET_INTERFACE,0x00,0x02,ReceiveBuffer,0);
state_pos++;
return;
}
//передача управляющих сообщений
if (mode==MODE_CONTROL_TRANSFER_STOP_I1)
{
//передаём команду на остановку интерфейса 1
USBH_SetInterface(&hUsbHostFS,1,0);
//USB_HOST_ControlTransfer(&hUsbHostFS,USB_H2D|USB_REQ_RECIPIENT_INTERFACE|USB_REQ_TYPE_STANDARD,USB_REQ_SET_INTERFACE,0x00,0x01,ReceiveBuffer,0);
state_pos++;
return;
}
//передача управляющих сообщений
if (mode==MODE_CONTROL_TRANSFER_START_I1)
{
//передаём команду на включение интерфейса 1
USBH_SetInterface(&hUsbHostFS,1,1);
//USB_HOST_ControlTransfer(&hUsbHostFS,USB_H2D|USB_REQ_RECIPIENT_INTERFACE|USB_REQ_TYPE_STANDARD,USB_REQ_SET_INTERFACE,0x01,0x01,ReceiveBuffer,0);
state_pos++;
return;
}
//передача управляющих сообщений
if (mode==MODE_CONTROL_TRANSFER_START_I2)
{
//передаём команду на включение интерфейса 2
USBH_SetInterface(&hUsbHostFS,2,1);
//USB_HOST_ControlTransfer(&hUsbHostFS,USB_H2D|USB_REQ_RECIPIENT_INTERFACE|USB_REQ_TYPE_STANDARD,USB_REQ_SET_INTERFACE,0x01,0x02,ReceiveBuffer,0);
state_pos++;
return;
}
//пауза
if (mode==MODE_PAUSE)
{
HAL_Delay(1);
state_pos++;
}
//прием даннын со всех конечных точек
if (mode==MODE_RECEIVE)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,GPIO_PIN_SET);//включаем светодиоды
long size=0;
size=USB_HOST_Receive(&hUsbHostFS,DevicePipe[0],ReceiveBuffer);
if (size>0)
{
ST7735S_Print("Data0!",ST7735S_YELLOW);
}
size=USB_HOST_Receive(&hUsbHostFS,DevicePipe[1],ReceiveBuffer);
if (size>0)
{
ST7735S_Print("Data1!",ST7735S_YELLOW);
}
size=USB_HOST_Receive(&hUsbHostFS,DevicePipe[2],ReceiveBuffer);
if (size>0)
{
ST7735S_Print("Data2!",ST7735S_YELLOW);
}
}
}
}
//----------
//главная функция программы
//----------
int main(void)
{
HAL_Init();
RCC_Init();
GPIO_Init();
SPI_Init();
USB_HOST_Init();
ST7735S_Init();
ST7735S_Clear();
while (1)
{
USB_HOST_Processing();
}
}
/* Flir config
01 0b 01 00 01 00 00 00
0 bmRequestType = 01
1 bRequest = 0b
2 wValue 0001 type (H) index (L) stop=0/start=1 (Alternate Setting)
4 wIndex 01 interface 1/2
5 wLength 00
6 Data 00 00
*/
Пн сен 04, 2017 18:47:24
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 240
bInterfaceProtocol 1
iInterface 6 com.flir.rosebud.fileio
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Вт сен 05, 2017 10:53:29
Вт сен 05, 2017 11:10:31
Ср сен 06, 2017 19:55:33
Сб сен 09, 2017 19:34:24
Сб сен 09, 2017 19:58:38
Сб сен 09, 2017 21:48:37
Пн сен 11, 2017 17:26:49
Сб сен 16, 2017 07:41:32
Сб сен 16, 2017 08:50:54
Сб сен 16, 2017 15:44:42
Вс сен 17, 2017 06:52:29
Вс сен 17, 2017 09:13:15
Оказалось всё дело в уровне оптимизации проекта. У меня изначально был 0 и поэтому ничего не работало (странно, почему так?).
Поставил Level 1 и заработало.
Вс сен 17, 2017 09:37:29
Вс сен 17, 2017 11:00:46
USB-совместимый хост предполагает, что все запросы будут обработаны в пределах максимального периода 5 секунд. Также определены более строгие лимиты времени для определенных запросов:
Standard Device request (стандартный запрос к устройству) без стадии данных должен быть завершен в течение 50 мс.
Standard Device request со стадией данных должен начать передавать данные не позже чем через 500 мс после запроса.
Каждый пакет данных должен быть отправлен в течение 500 мс после успешного завершения передачи предыдущего пакета. Стадия состояния должна быть завершена в течение 50 мс после передачи последнего пакета данных.
Команда SetAddress (которая содержит фазу данных) должна быть обработана и вернуть статус в течение 50 мс. Устройство тогда имеет 2 мс, чтобы изменить адрес прежде, чем будет послан следующий запрос.
Эти периоды времени ожидания являются весьма приемлемыми для даже самого медленного из устройств, но могут быть ограничением во время отладки. Невозможно обеспечить 50 мс для многих отладочных символов, отправляемых на скорости 9600 bps через асинхронный последовательный порт, или во внутрисхемных отладчиках/эмуляторах при выполнении программы по шагам или при остановке по точке останова для просмотра внутренних регистров и переменных. Поэтому USB требует специальной техники отладки в отличие от других проектов на микроконтроллерах.
http://microsin.net/programming/arm-wor ... part2.html