|
|
  |
SAM7x256 & USB |
|
|
|
Oct 31 2009, 15:42
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(overloaded @ Oct 31 2009, 17:59)  Вот и интересно где тот вариант встречается). Например вот так в атмеловском Framework: Код /// /// !Macros /// - CLEAR_CSR /// - SET_CSR
/// Bitmap for all status bits in CSR. #define REG_NO_EFFECT_1_ALL UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1 \ |UDP_CSR_STALLSENT | UDP_CSR_RXSETUP \ |UDP_CSR_TXCOMP
/// Clears the specified bit(s) in the UDP_CSR register. /// \param endpoint The endpoint number of the CSR to process. /// \param flags The bitmap to set to 1. #define SET_CSR(endpoint, flags) \ { \ volatile unsigned int reg; \ reg = UDP_CSR(UDP_BASE,endpoint); \ reg |= REG_NO_EFFECT_1_ALL; \ reg |= (flags); \ UDP_CSR(UDP_BASE,endpoint) = reg; \ while ( (UDP_CSR(UDP_BASE,endpoint) & (flags)) != (flags)); \ } SET_CSR(...) вызываемая без запрета всех(или только нужных) прерываний гарантированно когда-нить зависнет...
|
|
|
|
|
Dec 12 2009, 06:36
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Продолжение темы. Решил оптимизировать прием данных от хоста. Ранее я выгребал полностью данные из точки в софтовый ФИФО, а из него задача выгребала данных столько, сколько ей нужно. Решил избавиться от софтового буфера и забирать данные, сколько необходимо, сразу из конечной точки. При этом, если нужно данных меньше, чем находится в буфере точки, то не сбрасывать флаг приема (AT91C_UDP_RX_DATA_BK0/1) а просто запрещать прерывания. Что то опять туплю к выходным, ни как не выходит... Описание конечной точки: Код /* Endpoint status setup */ typedef struct __UDP_EP_STATUS { INT size; /* EP FIFO size */ UINT32 type; /* EP type (for store in CSR register) */ UINT32 imask; /* Interrupt flag in the IMR register (for enable/disable interrupt) */ UINT32 banks; /* Current receive bank for OUT endpoint, number of TX FIFO's for IN endpoint */ P_UINT8 data; /* Data buffer pointer */ INT len; /* Data size in buffer */ INT inbuf; /* For RX data count of buffered data */ void (*fcbk)(void); /* Optional transfer complete callback function */ } UDP_EP_STATUS, *P_UDP_EP_STATUS; Обработчик прерывания по приему Код /* Receive Data from host host complete */ if((AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1) & csr) { DBG_OUT("CSR%d RX: ", ep); if(p_eps->data) /* Endpoint is in read state */ { if(p_eps->inbuf > 0) /* Old EP FIFO not be fully readed */ cnt = p_eps->inbuf; else cnt = (AT91C_UDP_RXBYTECNT & csr) >> 16; /* Get data counter */ if(p_eps->len >= cnt) /* Room for new data exist */ { p_eps->len -= cnt; /* Add data to be readed */ for(i = 0; i < cnt; i++) /* Read new data */ *p_eps->data++ = AT91C_BASE_UDP->UDP_FDR[ep]; p_eps->inbuf = 0; /* No data in FIFO */ ClrRxFlag(ep, p_eps); /* Notify USB peripheral device that data have been read */ } else /* No room for all received bank */ { p_eps->inbuf = cnt - p_eps->len; /* Store number of bytes in EP FIFO */ for(i = 0; i < p_eps->len; i++) /* Read new data */ *p_eps->data++ = AT91C_BASE_UDP->UDP_FDR[ep]; p_eps->len = 0; } /* Check read complete */ if(!p_eps->len || cnt < p_eps->size) /* OK */ { p_eps->data = NULL; AT91C_BASE_UDP->UDP_IDR = p_eps->imask; /* disable interrupt */ if(p_eps->fcbk) /* Call Rx Complete application callback */ p_eps->fcbk(); } } else /* Data buffer not set - application not wating data */ { DBG_OUT("NAK! Data buffer not set.\r\n"); AT91C_BASE_UDP->UDP_IDR = p_eps->imask; } } Собственно попытка чтения Код /******************************************************************************* Read data from endpoint *******************************************************************************/ INT UDP_EP_Read(UINT8 ep, void *data, INT len, void (*fcbk)(void)) { P_UDP_EP_STATUS p_eps; DBG_OUT("UDP_EP%d_Read: ", ep); if(!g_State.curr_cfg) /* Check UDP device state */ { DBG_OUT("Device not configured!\r\n"); return FALSE; /* Not configured */ } if(!ep || ep >= UDP_NUM_EP) /* Check enpoint number */ { DBG_OUT("Invalid number %d!\r\n", ep); return FALSE; } p_eps = g_State.ep[ep]; /* Get endpoint status */ if(!p_eps) /* Check endpoint parameters */ { DBG_OUT("ep not inited!\r\n"); return FALSE; } if(p_eps->data) { DBG_OUT("ep busy!\r\n"); return FALSE; } /* Set data fields */ p_eps->data = data; p_eps->len = len; p_eps->fcbk = fcbk; AT91C_BASE_UDP->UDP_IER = p_eps->imask; /* Enable interrupts from endpoint */ DBG_OUT("\r\n"); return TRUE; /* Success */ }
--------------------
|
|
|
|
|
Dec 12 2009, 15:03
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(aaarrr @ Dec 12 2009, 20:01)  Напишите, как оно по-вашему должно работать, и как работает на самом деле. Спасибо, уже разобрался. Опять косяк с палочками был  . Собственно, то что хотел, описал постом выше. Когда я написал первый вариант драйвера - вычитывал все из буфера точки в буфер драйвера. А из буфера задача читала байт столько, сколько ей нужно было. Теперь решил оптимизировать и убрать буфер между драйвером UDP и задачей. Т.е. драйвер напрямую отдавал из хардварного FIFO конечной точки столько, сколько нужно задаче. Если в FIFO данные кончались, то флаг RX_BK0(1) очищался. Не работало в очередной раз по моей невнимательности. Надеюсь понятно объяснил.
--------------------
|
|
|
|
|
Dec 15 2009, 06:22
|

Любитель
    
Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695

|
Цитата(ZiB @ Dec 15 2009, 07:28)  Если я правильно понимаю, то для режима Bulk максимальная частота опроса (для full speed) составляет 1 кГц, а максимальная длина пакета 64 байта. Устройства "Mass Storage Class Device" используют тип передачи Bulk, каким образом получается "900 килобайт в секунду"? У STM32 High Speed USB? Транзакции bulk могут занимать всю свободную ширину шины USB. За один фрейм (1мс) будет несколько передач. 900 килобайт - это Full Speed. High Speed - это десятки мегабайт/сек.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|