Кое что выяснилось...
После, как ни странно, трех сбросов шины) обработчику прерываний все таки удается принять управляющий пакет)
выяснил что прерывание поступает от нулевой конечной точки...
дальше пытаюсь выяснить от чего же поступило прерывание...
прерывание поступает по принятию пакета управления...
питаюсь прочитать его из буфера... и вот тут то проблема...
контроллер говорит мне ( по самопально организованному через USART0 порту отладки :-) ) что в буфере 0 байт...
???
могу причести листинг моего обработчика прерываний
Код
#include "ioat91sam7a3.h"
#define UP 0x00000200
#define LEFT 0x00002000
#define DOWN 0x00000100
#define RIGHT 0x00001000
#define BUTTON 0x00004000
#define LED_1 0x00100000
#define LED_2 0x00200000
#define LED_3 0x01000000
#define LED_4 0x02000000
//---Коды стандартных запросов (bRequest)---------------------------------------
#define GET_STATUS 0x00 //Запрос статуса
#define CLEAR_FEATURE 0x01 //Сброс устройства
#define SET_FEATURE 0x03 //Установить устройство
#define SET_ADRESS 0x05 //Установить адрес
#define GET_DESCRIPTOR 0x06 //Получить дескриптор
#define SET_DESCRIPTOR 0x07 //Загрузить дескриптор
#define GET_CONFIGURATION 0x08 //Получить код текущей конфигурации
#define SET_CONFIGURATION 0x09 //Установить конфигурацию
#define GET_INTERFACE 0x0A //Получить код интерфейса
#define SET_INTERFACE 0x0B //Установить интерфейс
#define SYNC_FRAME 0x0C //Кадр синхронизации
//---Структура управляющего пакета----------------------------------------------
struct TSetupPacket
{
unsigned char bmRequestType; //Тип запроса
unsigned char bRequest; //Код запроса
unsigned char ValueL; //Тип дескриптора
unsigned char ValueH; //Индекс дескриптора
unsigned char IndexL; //Номер интерфейса или конечной точки
unsigned char IndexH; //Номер интерфейса или конечной точки
unsigned char LengthL; //Число байт для передачи
unsigned char LengthH; //Число байт для передачи
} TSetupPacket;
//---Структура дескриптора устройства-------------------------------------------
const struct USB_DEVICE_DESCRIPTOR
{
unsigned char bLenth; //длина дескриптора
unsigned char bDescriptorType; //тип дескриптора
unsigned char bcdUSBL; //версия спецификации USB в формате BCD
unsigned char bcdUSBH; //версия спецификации USB в формате BCD
unsigned char bDeviceClass; //код класса устройства USB
unsigned char bDeviceSubclass; //код подкласса устройства USB
unsigned char bDeviceProtocol; //код протокола USB
unsigned char bMaxPacketSize0; //мах размер нулевой конечной точки
unsigned char idVendorL; //идентификатор изготовителя устройства
unsigned char idVendorH; //идентификатор изготовителя устройства
unsigned char idProductL; //идентификатор продукта
unsigned char idProductH; //идентификатор продукта
unsigned char bcdDeviceL; //номер версии устройства в формате BCD
unsigned char bcdDeviceH; //номер версии устройства в формате BCD
unsigned char iManufacture; //индекс дескриптора строки описывающей изготовителя
unsigned char iProduct; //индекс дескриптора строки описывающей продукт
unsigned char iSerialNumber; //индекс дескриптора строки описывающей серийный номер устройства
unsigned char bNumConfigurations; //количество возможных конфигураций устройства
} USB_DEVICE_DESCRIPTOR = {0x12, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x08, 0x14, 0x11, 0x77, 0x77, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x01};
//------------------------------------------------------------------------------
const unsigned short int BUFFER_SIZE_EP[6] = {0x08, 0x40, 0x40, 0x40, 0x100, 0x100};//размер буфера конечных точек
unsigned short int i = 0; //индикатор конечной точки по умолчанию 0
unsigned short int COUNT; //счетчик байтов при загрузке в буфер или сохранинии из буфера
unsigned short int RX_BYTE_COUNT; //колво байтов в буфере приемника
unsigned short int TX_BYTE_COUNT; //колво байтов для передачи
unsigned char *DATA_OUT_ADRESS; //указатель на сегмент памяти, содержащий данные для сохранения в буфер приемопередатчика
unsigned char *DATA_IN_ADRESS; //указатель на сегмент памяти, содержащий сохраненные данные из буфера приемопередатчика
//==============================================================================
//---Блок выгрузки данных в буфер FIFO UDP_FDR[i]-------------------------------
void USB_TRANSMIT_EP() //Функция блока сохранения данных в буфер конечной точки 0
{
while ((AT91C_BASE_UDP -> UDP_CSR[i]) & AT91C_UDP_TXPKTRDY); //ждать пока бит AT91C_UDP_TXPKTRDY станет 0
COUNT = 0; //обнуляем счетчик байтов
while (COUNT < BUFFER_SIZE_EP[i]) //запускаем цикл загрузки байтов в буфер i-ой конечной точки
{
if (TX_BYTE_COUNT > 0)
{
AT91C_BASE_UDP -> UDP_FDR[i] = *DATA_OUT_ADRESS; //загружаем байт в буфер
COUNT++; //инкрементируем счетчик байтов
TX_BYTE_COUNT--; //декрементируем счетчик отправленных байтов
DATA_OUT_ADRESS++; //инкрементируем адрес для записи в буфер следующего байта
}
else
{
AT91C_BASE_UDP -> UDP_FDR[i] = 0x00; //Добисываем оставшиеся нули
COUNT++; //инкрементируем счетчик байтов
}
}
AT91C_BASE_UDP -> UDP_CSR[i] |= AT91C_UDP_TXPKTRDY; //установка бита готовности пакета к передаче
}
//==============================================================================
//==============================================================================
//---Блок загрузки данных из буфера FIFO UDP_FDR[i]-----------------------------
void USB_RECEIVE_EP() //Функция блока сохранения данных из буфера конечной точки 0
{
RX_BYTE_COUNT = (((AT91C_BASE_UDP -> UDP_CSR[i]) & AT91C_UDP_RXBYTECNT) >> 16);//число байтов в буфере
while (!((AT91C_BASE_US0 -> US_CSR) & AT91C_US_TXRDY));
AT91C_BASE_US0 -> US_THR = RX_BYTE_COUNT & 0xFF;
COUNT = 0; //обнуляем счетчик байтов
while (COUNT < RX_BYTE_COUNT) //запускаем цикл сохранения байтов
{
*(DATA_IN_ADRESS + COUNT) = AT91C_BASE_UDP -> UDP_FDR[i]; //сохраняем инфу в память
while (!((AT91C_BASE_US0 -> US_CSR) & AT91C_US_TXRDY));
AT91C_BASE_US0 -> US_THR = *(DATA_IN_ADRESS + COUNT);
COUNT++; //инкрементируем счетчик байтов
}
while (!((AT91C_BASE_US0 -> US_CSR) & AT91C_US_TXRDY));
AT91C_BASE_US0 -> US_THR = 0xA3;
}
//==============================================================================
//==============================================================================
//---Блок обработки прерываний от i-ой конечной точки---------------------------
void USB_EP_INT()
{
//---Обработка управляющего пакета----------------------------------------------
if ((AT91C_BASE_UDP -> UDP_CSR[i]) & AT91C_UDP_RXSETUP) //Если пришел управляющий пакет данных или команда
{
DATA_IN_ADRESS = (unsigned char *) &TSetupPacket; //присваиваем указателю адрес памяти где расположена структура управляющего пакета
USB_RECEIVE_EP(); //переход на функцию сохранения байтов в память
while (1);
switch (TSetupPacket.bRequest) //че комп от меня хочет?
{
case GET_DESCRIPTOR:
{
while (!((AT91C_BASE_US0 -> US_CSR) & AT91C_US_TXRDY));
AT91C_BASE_US0 -> US_THR = 0xA4;
while (1);
DATA_OUT_ADRESS = (unsigned char *) &USB_DEVICE_DESCRIPTOR; //присваиваем указателю адрес памяти где расположена структура дескриптора устройства
TX_BYTE_COUNT = *DATA_OUT_ADRESS; //присваиваем счетчику байтов длинну дескриптора устройства
AT91C_BASE_UDP -> UDP_CSR[i] |= AT91C_UDP_DIR; //меняем направление передачи к хосту
AT91C_BASE_UDP -> UDP_CSR[i] = !(AT91C_UDP_RXSETUP); //Сброс бита RXSetup (данные из буфера прочитал)
USB_TRANSMIT_EP(); //Запись в буфер конечной точки дескриптора устройства
break; //выход из оператора switch
}
case SET_ADRESS:
{
while(1);
}
case GET_STATUS:
{
while(1);
}
case CLEAR_FEATURE:
{
while(1);
}
case SET_FEATURE:
{
while(1);
}
case SET_DESCRIPTOR:
{
while(1);
}
case GET_CONFIGURATION:
{
while(1);
}
case SET_CONFIGURATION:
{
while(1);
}
case GET_INTERFACE:
{
while(1);
}
case SET_INTERFACE:
{
while(1);
}
case SYNC_FRAME:
{
while(1);
}
default: //если запрос не известен то выход из оператора switch
{
while(1);
}
}
//AT91C_BASE_UDP -> UDP_CSR[i] = !(AT91C_UDP_RXSETUP);
while(1);
}
//---Обработка подтверждения приема пакета хстом--------------------------------
if ((AT91C_BASE_UDP -> UDP_CSR[i]) & AT91C_UDP_TXCOMP) //Если пришел пакет подтверждения от хоста доставленых ему байтов
{
while(1);
}
//------------------------------------------------------------------------------
if ((AT91C_BASE_UDP -> UDP_CSR[i]) & AT91C_UDP_RX_DATA_BK0) //Если есть данные в банке данных BK0
{
while(1);
}
//------------------------------------------------------------------------------
if ((AT91C_BASE_UDP -> UDP_CSR[i]) & AT91C_UDP_RX_DATA_BK1) //Если есть данные в банке данных BK1
{
while(1);
}
//------------------------------------------------------------------------------
if ((AT91C_BASE_UDP -> UDP_CSR[i]) & AT91C_UDP_ISOERROR) //Хост принял останов или возникла ошибка CRC
{
while(1);
}
//------------------------------------------------------------------------------
}
//==============================================================================
//==============================================================================
//---Обработчик прерываний USB--------------------------------------------------
usb_main()
{
//------------------------------------------------------------------------------
switch ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_ALL_EP_INT) //выбор конечной точки, которая вызвала прерывание
{
case AT91C_UDP_EPINT0: {i = 0; USB_EP_INT(); break;}
case AT91C_UDP_EPINT1: {i = 1; USB_EP_INT(); break;}
case AT91C_UDP_EPINT2: {i = 2; USB_EP_INT(); break;}
case AT91C_UDP_EPINT3: {i = 3; USB_EP_INT(); break;}
case AT91C_UDP_EPINT4: {i = 4; USB_EP_INT(); break;}
case AT91C_UDP_EPINT5: {i = 5; USB_EP_INT(); break;}
}
//------------------------------------------------------------------------------
if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_RXRSM)
{
while (!((AT91C_BASE_US0 -> US_CSR) & AT91C_US_TXRDY));
AT91C_BASE_US0 -> US_THR = 0xF1;
AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_RXRSM;
}
if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_RXSUSP)
{
while (!((AT91C_BASE_US0 -> US_CSR) & AT91C_US_TXRDY));
AT91C_BASE_US0 -> US_THR = 0xF2;
AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_RXSUSP;
}
if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_SOFINT)
{
while (!((AT91C_BASE_US0 -> US_CSR) & AT91C_US_TXRDY));
AT91C_BASE_US0 -> US_THR = 0xF3;
AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_SOFINT;
}
if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_ENDBUSRES)
{
//---Конфигурация USB при сбросе шины-------------------------------------------
AT91C_BASE_UDP -> UDP_FADDR = AT91C_UDP_FEN;
AT91C_BASE_UDP -> UDP_RSTEP = AT91C_UDP_ALL_EP; //Сброс всех конечных точек
AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_CLEAR_INT & (~AT91C_UDP_ENDBUSRES); //Сброс прерываний кроме прерывания по сбросу шины
AT91C_BASE_UDP -> UDP_IDR = AT91C_UDP_ALL_INT; //Запрещаем все прерывания
AT91C_BASE_UDP -> UDP_IER = AT91C_UDP_EPINT0; //Разрешить прерывание от 0 конечной точки
AT91C_BASE_UDP -> UDP_CSR[AT91C_UDP_EP0] = AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS;//0 конечная контрольная точка
AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_ENDBUSRES;
//while (!((AT91C_BASE_US0 -> US_CSR) & AT91C_US_TXRDY));
//AT91C_BASE_US0 -> US_THR = 0xF4;
}
if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_WAKEUP)
{
while (!((AT91C_BASE_US0 -> US_CSR) & AT91C_US_TXRDY));
AT91C_BASE_US0 -> US_THR = 0xF5;
AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_WAKEUP;
}
//------------------------------------------------------------------------------
AT91C_BASE_AIC -> AIC_EOICR = 0xF1F1F1F1; //Сообщаем AIC прерывание обработал :-)
}
//==============================================================================
причина почему так много While(1), потому как код в стадии отладки)
хотя у меня есть такое предположение что приемопередатчик просто не успевает принять данные...
контроллер тактируется от PLL частота 48 МГц...