После включения d-cache перестали передаваться пакеты длиной больше 64 байт (не работает "ping-pong endpoint"). Для работы с USB использую код из проекта (примеров) для sam7, код в архиве.
Нажмите для просмотра прикрепленного файла
Комментарий к const_flash.c: В SRAM выделена некэшируемая область под буферы PDC SPI, для чего добавлена "грубая" таблица трансляции второго уровня. Таблицы хранятся во встроенной флэш.
CODE
//*----------------------------------------------------------------------------
//* \fn AT91F_CDC_Write
//* \brief Send through endpoint 2
//*----------------------------------------------------------------------------
static uint AT91F_UDP_Write(AT91PS_CDC pCdc, const char *pData, uint length)
{
uint cpt = 0;
while ( (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) );
// Send the first packet
cpt = MIN(length, AT91C_EP_IN_SIZE);
length -= cpt;
while (cpt--) AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *pData++;
SET_CSR(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
while (length) {
// Fill the second bank
cpt = MIN(length, AT91C_EP_IN_SIZE);
length -= cpt;
while (cpt--) AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *pData++;
// Enable interrupt on endpoint
AT91C_BASE_UDP->UDP_IER = 1 << AT91C_EP_IN;
// Wait for the the first bank to be sent
while ( !(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
&& (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) )
if ( !AT91F_UDP_IsConfigured(pCdc) ) return length;
CLEAR_CSR(AT91C_EP_IN, AT91C_UDP_TXCOMP);
SET_CSR(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
}
// Wait for the end of transfer
while ( !(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
&& (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) )
if ( !AT91F_UDP_IsConfigured(pCdc) ) return length;
CLEAR_CSR(AT91C_EP_IN, AT91C_UDP_TXCOMP);
return length;
}
//* \fn AT91F_CDC_Write
//* \brief Send through endpoint 2
//*----------------------------------------------------------------------------
static uint AT91F_UDP_Write(AT91PS_CDC pCdc, const char *pData, uint length)
{
uint cpt = 0;
while ( (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) );
// Send the first packet
cpt = MIN(length, AT91C_EP_IN_SIZE);
length -= cpt;
while (cpt--) AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *pData++;
SET_CSR(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
while (length) {
// Fill the second bank
cpt = MIN(length, AT91C_EP_IN_SIZE);
length -= cpt;
while (cpt--) AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *pData++;
// Enable interrupt on endpoint
AT91C_BASE_UDP->UDP_IER = 1 << AT91C_EP_IN;
// Wait for the the first bank to be sent
while ( !(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
&& (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) )
if ( !AT91F_UDP_IsConfigured(pCdc) ) return length;
CLEAR_CSR(AT91C_EP_IN, AT91C_UDP_TXCOMP);
SET_CSR(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
}
// Wait for the end of transfer
while ( !(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
&& (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) )
if ( !AT91F_UDP_IsConfigured(pCdc) ) return length;
CLEAR_CSR(AT91C_EP_IN, AT91C_UDP_TXCOMP);
return length;
}
Программа зацикливается после заполнения второго банка на проверке while ( !(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP) ).
Со стороны ПК используется драйвер atm6124.sys.
Подскажите, как решить проблему?