Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Продукция MICROCHIP

Продукция MICROCHIP Технические вопросы по всей продукции Microchip

Ответ
 
Опции темы Опции просмотра
Старый 14.12.2008, 18:26   #1
Petya
Senior Member
 
Регистрация: 30.11.2008
Адрес: SPb
Сообщений: 150
Вес репутации: 238/47
Petya has a spectacular aura aboutPetya has a spectacular aura aboutPetya has a spectacular aura about
Post Модификация usb firmware

Делюсь своим опытом работы с usb на контроллере pic18f4550.

Однажды понадобилось добавить поддержку hid usb в частотомер, сделанный на 18-м пике. Программа этого частотомера уже была написана.
Структура программы — простой цикл, достающий из очереди сообщения и обрабатывающий их. Добавляют сообщения в очередь обработчики прерываний.

После знакомства с usb-библиотекой микрочипа (http://www.microchip.com/stellent/id...param=en534494) стало понятно, что так просто ее прикрутить к проекту не получится.

Убил метод опроса флагов. Я до сих пор не понимаю, почему они не могли сделать нормальные обработчики прерываний. Ведь при опросе флагов в основном потоке программы задержка обработки будет напрямую зависеть от времени исполнения пользовательского кода. И это при том что модуль usb довольно критичен к задержкам в обработчике (не более 100 мкс).

Первая мысль была — сделать в лоб, особенно не разбираясь, — включить таймер 2 и заставить его выполнять USBDeviceTasks() каждые 100 мкс. Вариант оказался вполне рабочим, но очень неэкономичным: на частоте 12 МГц процессор занимался только одним опросом .

Следующая мысль — работать, как и положено, с обработчиками прерываний. К счастью, исправлять микрочиповского кода пришлось не так уж много. Из всей библиотеки изменениям подверглась только сама USBDeviceTasks() из usb_device.c. Все, что требовалось с ней сделать — это вырезать обработчики подключения и отключения устройства:
Код:
    if (USB_BUS_SENSE != 1)
    {
         // Disable module & detach from bus
         U1CON = 0;

         // Mask all USB interrupts
         U1IE = 0;

         //Move to the detached state
         USBDeviceState = DETACHED_STATE;

         //return so that we don't go through the rest of 
         //the state machine
         return;
    }

    //if we are in the detached state
    if(USBDeviceState == DETACHED_STATE)
    {
        U1CON = 0;                           // Disable module & detach from bus

        // Mask all USB interrupts
        U1IE = 0;                                

        // Enable module & attach to bus
        while(!U1CONbits.USBEN){U1CONbits.USBEN = 1;}

        //moved to the attached state
        USBDeviceState = ATTACHED_STATE;

        //Enable/set things like: pull ups, full/low-speed mode, 
        //set the ping pong mode, and set internal transceiver
        SetConfigurationOptions();
    }

    if(USBDeviceState == ATTACHED_STATE)
    {
        /*
         * After enabling the USB module, it takes some time for the
         * voltage on the D+ or D- line to rise high enough to get out
         * of the SE0 condition. The USB Reset interrupt should not be
         * unmasked until the SE0 condition is cleared. This helps
         * prevent the firmware from misinterpreting this unique event
         * as a USB bus reset from the USB host.
         */

        if(!USBSE0Event)
        {
            USBClearInterruptRegister(U1IR);	// Clear all USB interrupts
            U1IE = 0;			// Mask all USB interrupts
            USBResetIE = 1;		// Unmask RESET interrupt
            USBIdleIE = 1;			// Unmask IDLE interrupt
            USBDeviceState = POWERED_STATE;
        }
    }
Здесь три больших условных оператора.

Первый if выполняется периодически, когда кабель usb не подключен. На самом деле, микрочиповцы просто перестраховались, выполнить это при отключении достаточно один раз .
С учетом обслуживания прерываний блок превратился в следующий:
Код:
         // Disable module & detach from bus
         U1CON = 0;
         // Mask all USB interrupts
         U1IE = 0;
         //Move to the detached state
         USBDeviceState = DETACHED_STATE;
         //	выключаем прерывания
         PIE2bits.USBIE = 0;
Этот фрагмент кода надо поместить в обработчик события отключения кабеля, механизм вызова и вид которого зависят уже от конкретной программы. А если устройство питается только от шины, этот фрагмент вообще не нужен.

Следующие 2 if'а задействуются при подключении кабеля. Тут вся сложность в том, что после втыкания кабеля и включения модуля usb нужно подождать, пока не появится напряжение на линии D+ за счет подключения встроенного резистора (см. жирный английский комментарий). Если этого не сделать, модуль usb ошибочно воспримет несимметричный 0 как сигнал сброса от хоста и собьется.
Переходим от итеративной структуры к строго последовательной и добавляем настройку прерываний:
Код:
        U1CON = 0;                           // Disable module & detach from bus
        // Mask all USB interrupts
        U1IE = 0;
        // Enable module & attach to bus
        while(!U1CONbits.USBEN){U1CONbits.USBEN = 1;}
        //moved to the attached state
        USBDeviceState = ATTACHED_STATE;
        //Enable/set things like: pull ups, full/low-speed mode, 
        //set the ping pong mode, and set internal transceiver
        SetConfigurationOptions();
        while(USBSE0Event)
               ;
        USBClearInterruptRegister(U1IR);	// Clear all USB interrupts
        U1IE = 0;			           // Mask all USB interrupts
        USBResetIE = 1;		           // Unmask RESET interrupt
        USBIdleIE = 1;			// Unmask IDLE interrupt
        USBDeviceState = POWERED_STATE;
        //	настраиваем прерывания
        IPR2bits.USBIP = 0;		//	низкий приоритет
        PIE2bits.USBIE = 1;
Роль периодической проверки условия теперь играет цикл, проверяющий USBSE0Event. Недостаток этого простейшего решения — зависание программы, если по каким-то причинам линия D+ окажется замкнутой на землю.
Полученный фрагмент кода надо поместить в обработчик события подключения кабеля. Ну а если устройство питается от шины, этим обработчиком может быть сама main().

Наконец, сам обработчик прерываний низкого приоритета:
Код:
#pragma interruptlow low_isr
void	low_isr()
{
	if(PIR2bits.USBIF)
	{
		PIR2bits.USBIF = 0;
		USBDeviceTasks();
		//  сюда можно добавить обработку любых событий
		//  usb-модуля, например, установки конфигурации,
		//  окончания приема/передачи и т. д.
	}
           //  ...остальные прерывания goes here
}
Основная программа:
Код:
void	main()
{
	RCONbits.IPEN = 1;   //	режим с приоритетами
	INTCONbits.GIEL = 1;//	разрешаем прерывания

	USBDeviceInit();

	// привязка обработчиков и обработка событий
	while(1)...
}
Модифицированная таким образом программа отлично работает совместно с остальным кодом, практически не нагружая процессор.
Подключение надежное, пока ни разу не было сбоев.
Единственное требование: в критической секции или обработчике прерывания нельзя находиться больше 100 мкс.

Пээс:
  1. Компилировалось в c18 версии 3.21.
  2. Все работает и в extended mode.
  3. Проверялось на основе класса hid, для cdc так не заработает, т. к. там есть еще какой-то ...TxService(), который тоже надо куда-то определить.
  4. Могу выложить более подробный текст программы.

Все!

Последний раз редактировалось Petya; 24.04.2009 в 03:17.
Petya вне форума   Ответить с цитированием
Старый 15.12.2008, 13:30   #2
SergeyKN
Senior Member
 
Регистрация: 13.08.2007
Сообщений: 160
Вес репутации: 111/50
SergeyKN will become famous soon enoughSergeyKN will become famous soon enough
По умолчанию Ответ: Модификация usb firmware

респект за работу и ее выкладывание на всеобщее обзирание. но мне кажется это не совсем верно делать вызов USBDeviceTasks(); в обработчике прерывания. теперь время реакции всей системы == времени выполнения всего
if (PIR2bits.USBIF) - блока, покрайней мере по лоу прерываниям. получается USB -- главная и основная задача контроллера. а это не так USB лишь средство передать информацию. я так думаю.
SergeyKN вне форума   Ответить с цитированием
Старый 15.12.2008, 13:33   #3
Petr
Senior Member
 
Аватар для Petr
 
Регистрация: 25.02.2007
Возраст: 49
Сообщений: 1,879
Вес репутации: 3760/105
Petr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond repute
По умолчанию В смысле ???

Цитата:
Сообщение от SergeyKN Посмотреть сообщение
респект за работу и ее выкладывание на всеобщее обзирание. но мне кажется это не совсем верно делать вызов USBDeviceTasks(); в обработчике прерывания. теперь время реакции всей системы == времени выполнения всего
if (PIR2bits.USBIF) - блока, покрайней мере по лоу прерываниям. получается USB -- главная и основная задача контроллера. а это не так USB лишь средство передать информацию. я так думаю.
Это о чем ?
А как по другому ?
Petr вне форума   Ответить с цитированием
Старый 15.12.2008, 13:38   #4
SergeyKN
Senior Member
 
Регистрация: 13.08.2007
Сообщений: 160
Вес репутации: 111/50
SergeyKN will become famous soon enoughSergeyKN will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Сообщение от Petr Посмотреть сообщение
Это о чем ?
А как по другому ?
а что "Это"? и что "как по другому"? и воще про куда?
SergeyKN вне форума   Ответить с цитированием
Старый 15.12.2008, 13:55   #5
Petr
Senior Member
 
Аватар для Petr
 
Регистрация: 25.02.2007
Возраст: 49
Сообщений: 1,879
Вес репутации: 3760/105
Petr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond repute
По умолчанию Автор вырезал из USBDeviceTasks();

Цитата:
Сообщение от SergeyKN Посмотреть сообщение
а что "Это"? и что "как по другому"? и воще про куда?
обработку подключения/отключения и там осталась
обработка

if(USBResetIF && USBResetIE)
if(USBIdleIF && USBIdleIE)
if(USBStallIF && USBStallIE)
if(USBErrorIF && USBErrorIE)
if(USBTransactionCompleteIE)
и т.п.
Это теперь в прерывании.

Вы предлагаете это все не делать ???

Я подобную задачу решил немного по другому, но похоже.
Может потом выложу.
Petr вне форума   Ответить с цитированием
Старый 15.12.2008, 14:09   #6
SergeyKN
Senior Member
 
Регистрация: 13.08.2007
Сообщений: 160
Вес репутации: 111/50
SergeyKN will become famous soon enoughSergeyKN will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Вы предлагаете это все не делать ???
ну при чем здесь "не делать"?... вроде я ясно написал, что считаю неприемлемым (для себя по крайней мере) делать вызов С-функции из обработчика прерываний. я их воще железно на асме пишу, а чтоб еще из него и что-то вызвать, да еще и длинное -- нееее, на это я пойтить не могу. я конечно понимаю что бывают разные задачи, но мне всё как-то встречаются такие где 100мкс реакции неприемлемы.
SergeyKN вне форума   Ответить с цитированием
Старый 15.12.2008, 14:17   #7
Petr
Senior Member
 
Аватар для Petr
 
Регистрация: 25.02.2007
Возраст: 49
Сообщений: 1,879
Вес репутации: 3760/105
Petr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond repute
По умолчанию Все ясно

Цитата:
Сообщение от SergeyKN Посмотреть сообщение
ну при чем здесь "не делать"?... вроде я ясно написал, что считаю неприемлемым (для себя по крайней мере) делать вызов С-функции из обработчика прерываний. я их воще железно на асме пишу, а чтоб еще из него и что-то вызвать, да еще и длинное -- нееее, на это я пойтить не могу. я конечно понимаю что бывают разные задачи, но мне всё как-то встречаются такие где 100мкс реакции неприемлемы.
Асмист, да и еще и не понял о чем разговор.
Сделал бы "красиво и по своему" да выложил.
Был бы разговор.
Тут человек навел порядок в готовой библиотеке,
сделав все разумно и наглядно.
Petr вне форума   Ответить с цитированием
Старый 15.12.2008, 14:30   #8
SergeyKN
Senior Member
 
Регистрация: 13.08.2007
Сообщений: 160
Вес репутации: 111/50
SergeyKN will become famous soon enoughSergeyKN will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Сообщение от Petr Посмотреть сообщение
Асмист, да и еще и не понял о чем разговор.
Сделал бы "красиво и по своему" да выложил.
Был бы разговор.
Тут человек навел порядок в готовой библиотеке,
сделав все разумно и наглядно.
Асмист -- это ругательство? "да и еще и не понял о чем разговор" ну это то ты откуда высосал? вроде как получается, что это ты никак не врубишься, про что я говорю. я использовал микрочиповский текст с минимальными изменениями, и считаю, что там вполне все разумно. так что "Тут человек навел порядок в готовой библиотеке"...
SergeyKN вне форума   Ответить с цитированием
Старый 15.12.2008, 14:37   #9
Petr
Senior Member
 
Аватар для Petr
 
Регистрация: 25.02.2007
Возраст: 49
Сообщений: 1,879
Вес репутации: 3760/105
Petr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond repute
По умолчанию Что ты говориш - я совершенно не понимаю.

Цитата:
Сообщение от SergeyKN Посмотреть сообщение
Асмист -- это ругательство? "да и еще и не понял о чем разговор" ну это то ты откуда высосал? вроде как получается, что это ты никак не врубишься, про что я говорю. я использовал микрочиповский текст с минимальными изменениями, и считаю, что там вполне все разумно. так что "Тут человек навел порядок в готовой библиотеке"...
Потому что каждый раз противоречиш сам себе.
Сначала сказал, что вызывать функцию из прерывания -
это ЧУДОВИЩНОЕ расточительство.
А потом заявил, что вызывать USBDeviceTasks();
в main(); поллингом - это разумно
А ASMист да - ругательство.
Petr вне форума   Ответить с цитированием
Старый 15.12.2008, 14:54   #10
SergeyKN
Senior Member
 
Регистрация: 13.08.2007
Сообщений: 160
Вес репутации: 111/50
SergeyKN will become famous soon enoughSergeyKN will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Потому что каждый раз противоречиш сам себе.
Сначала сказал, что вызывать функцию из прерывания -
это ЧУДОВИЩНОЕ расточительство.
А потом заявил, что вызывать USBDeviceTasks();
в main(); поллингом - это разумно
А ASMист да - ругательство.
Ну ты Сисюк даешь ... в чем же здесь противоречие? все задачи выполнены, все события обработаны -- почему б и не вызвать USBDeviceTasks(); -- никаких противоречий. И самое главное прерывания вызываются и отрабатываются максимально быстро, генерируя новые события, которые будут в полинге обработаны в следующем цикле -- все логично и строго. я никак не пойму, что ты не поймешь? и воще как то это странно для Сисюка ломать класическую стэйт-машину для ввода прерывания -- может ты таки не Сисюк?
SergeyKN вне форума   Ответить с цитированием
Старый 15.12.2008, 15:05   #11
Petr
Senior Member
 
Аватар для Petr
 
Регистрация: 25.02.2007
Возраст: 49
Сообщений: 1,879
Вес репутации: 3760/105
Petr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond reputePetr has a reputation beyond repute
По умолчанию Вот так вот :-)

Цитата:
Сообщение от SergeyKN Посмотреть сообщение
Ну ты Сисюк даешь ... в чем же здесь противоречие? все задачи выполнены, все события обработаны -- почему б и не вызвать USBDeviceTasks(); -- никаких противоречий. И самое главное прерывания вызываются и отрабатываются максимально быстро, генерируя новые события, которые будут в полинге обработаны в следующем цикле -- все логично и строго. я никак не пойму, что ты не поймешь? и воще как то это странно для Сисюка ломать класическую стэйт-машину для ввода прерывания -- может ты таки не Сисюк?
Не нужно оказывается никому перекладывать это в прерывания...
Вредно...
Ну да ладно.

Для cdc я потом выложу модификацию.
В TxService(); ничего особо хитрого нет.
Сразу оговорюсь:
Она будет неинтересна людям, у которых
супер цикл в main(); выполняется менее чем за 100мкС.
А также людям, никогда не использующим ОС.
Да и вообще видимо много чего не использующим
Petr вне форума   Ответить с цитированием
Старый 15.12.2008, 15:28   #12
SergeyKN
Senior Member
 
Регистрация: 13.08.2007
Сообщений: 160
Вес репутации: 111/50
SergeyKN will become famous soon enoughSergeyKN will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Не нужно оказывается никому перекладывать это в прерывания...
Вредно...
ну опять ты перевираешь. не вредно, а увеличивает время реакции системы -- может где-то это будет как раз и полезно, но где не знаю -- просто надо знать этот момент и учитывать.
Цитата:
Сразу оговорюсь:
Она будет неинтересна людям, у которых
супер цикл в main(); выполняется менее чем за 100мкС.
А также людям, никогда не использующим ОС.
Да и вообще видимо много чего не использующим
ути какОООй . слава богу, ко мне это не относится -- у меня-то цикл больше 100мкс ('с' надо писать маленькой). блин, ты так и не понял, про что я говорил .

а как ты узнал что я ОС не использую? вот это проницательность. Да мне ОС хватает (по горло) в разработке программ в ВижуалС++, я хоть в пиках душу отвожу работая на низком уровне.
SergeyKN вне форума   Ответить с цитированием
Старый 15.12.2008, 19:12   #13
Petya
Senior Member
 
Регистрация: 30.11.2008
Адрес: SPb
Сообщений: 150
Вес репутации: 238/47
Petya has a spectacular aura aboutPetya has a spectacular aura aboutPetya has a spectacular aura about
Arrow Асмисты, налетай!

Еще в прошивке микрочипа есть один забавный кусок кода — функция сброса флага прерывания (сама идея уже подозрительна):
Код:
void USBClearInterruptFlag(BYTE* reg, BYTE flag)
{
    #if defined(__18CXX)
        *reg &= ~(0x01<<flag);
    #elif defined(__C30__) || defined(__C32__)
        *reg = (0x01<<flag); 
    #else
        #error "Function not defined for this compiler       
    #endif
}
Она получает указатель на регистр sfr и номер бита в нем, который требуется сбросить.
Сама функция расположена в конце usb_device.c, вызывается из нескольких мест, в том числе и из пресловутой UsbDeviceTasks().

Смотрим, во что превращает ее компилятор, и развеиваем все сомнения:
Код:
2062:              void USBClearInterruptFlag(BYTE* reg, BYTE flag)
  10DC    D8D2     RCALL 0x1282
2063:              {
2064:                  #if defined(__18CXX)
2065:                      *reg &= ~(0x01<<flag);
  10DE    0E01     MOVLW 0x1
  10E0    6EF3     MOVWF 0xff3, ACCESS
  10E2    0EFC     MOVLW 0xfc
  10E4    50DB     MOVF 0xfdb, W, ACCESS
  10E6    E004     BZ 0x10f0
  10E8    90D8     BCF 0xfd8, 0, ACCESS
  10EA    36F3     RLCF 0xff3, F, ACCESS
  10EC    06E8     DECF 0xfe8, F, ACCESS
  10EE    E1FC     BNZ 0x10e8
  10F0    1CF3     COMF 0xff3, W, ACCESS
  10F2    6E00     MOVWF 0, ACCESS
  10F4    0EFD     MOVLW 0xfd
  10F6    CFDB     MOVFF 0xfdb, 0xfe9
  10F8    FFE9     NOP
  10FA    0EFE     MOVLW 0xfe
  10FC    CFDB     MOVFF 0xfdb, 0xfea
  10FE    FFEA     NOP
  1100    5000     MOVF 0, W, ACCESS
  1102    16EF     ANDWF 0xfef, F, ACCESS
2066:                  #elif defined(__C30__) || defined(__C32__)
2067:                      *reg = (0x01<<flag); 
2068:                  #else
2069:                      #error "Function not defined for this compiler       
2070:                  #endif
2071:              }
  1104    D0E3     BRA 0x12cc
...
...
...
  1282    CFD9     MOVFF 0xfd9, 0xfe6
  1284    FFE6     NOP
  1286    CFE1     MOVFF 0xfe1, 0xfd9
  1288    FFD9     NOP
  128A    0012     RETURN 0
...
...
...
  12CC    52E5     MOVF 0xfe5, F, ACCESS
  12CE    CFE7     MOVFF 0xfe7, 0xfd9
  12D0    FFD9     NOP
  12D2    0012     RETURN 0
30 тактов с полностью включенной оптимизацией!

После переноса кода в макрос
Код:
#if defined(__18CXX)
	#define USBClearInterruptFlag(reg_ptr, flag)\
		(*(reg_ptr) &= ~(1 << (flag)));
#elif defined(__C30__) || defined(__C32__)
	#define USBClearInterruptFlag(reg_ptr, flag)\
		(*(reg_ptr) = (1 << (flag)));
#else
	#error "Function not defined for this compiler
#endif
очистка флага, как и положено, происходит за один такт. Макрос надо поместить в usb_device.h вместо строки
Код:
void USBClearInterruptFlag(BYTE* reg, BYTE flag);
Petya вне форума   Ответить с цитированием
Старый 15.12.2008, 19:48   #14
Petya
Senior Member
 
Регистрация: 30.11.2008
Адрес: SPb
Сообщений: 150
Вес репутации: 238/47
Petya has a spectacular aura aboutPetya has a spectacular aura aboutPetya has a spectacular aura about
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Несколько смущает ветка с С30...
Чем же? Посмотрите на исходный вариант.
Petya вне форума   Ответить с цитированием
Старый 15.12.2008, 19:53   #15
DRoVik
Senior Member
 
Регистрация: 26.02.2007
Сообщений: 148
Вес репутации: 103/52
DRoVik will become famous soon enoughDRoVik will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Сообщение от Petya Посмотреть сообщение
Чем же? Посмотрите на исходный вариант.
Да смотрел... Сейчас DS смотрю на эти пики, а то может глупость сморозил

Ага, так и есть

Последний раз редактировалось DRoVik; 15.12.2008 в 20:00.
DRoVik вне форума   Ответить с цитированием
Старый 15.12.2008, 20:31   #16
majorPAE
Super Moderator
 
Аватар для majorPAE
 
Регистрация: 26.02.2007
Возраст: 58
Сообщений: 2,221
Вес репутации: 2214/94
majorPAE has a reputation beyond reputemajorPAE has a reputation beyond reputemajorPAE has a reputation beyond reputemajorPAE has a reputation beyond reputemajorPAE has a reputation beyond reputemajorPAE has a reputation beyond reputemajorPAE has a reputation beyond reputemajorPAE has a reputation beyond reputemajorPAE has a reputation beyond reputemajorPAE has a reputation beyond reputemajorPAE has a reputation beyond repute
Отправить сообщение для majorPAE с помощью ICQ Отправить сообщение для majorPAE с помощью Skype™
Thumbs up Ответ: Асмисты, налетай!

Цитата:
Сообщение от Petya Посмотреть сообщение
...
После переноса кода в макрос
Код:
#if defined(__18CXX)
    #define USBClearInterruptFlag(reg_ptr, flag)\
        (*(reg_ptr) &= ~(1 << (flag)));
#elif defined(__C30__) || defined(__C32__)
    #define USBClearInterruptFlag(reg_ptr, flag)\
        (*(reg_ptr) = (1 << (flag)));
#else
    #error "Function not defined for this compiler
#endif
очистка флага, как и положено, происходит за один такт. Макрос надо поместить в usb_device.h вместо строки
Код:
void USBClearInterruptFlag(BYTE* reg, BYTE flag);
Лихо... Спасибо!
__________________
ЗАКОH ТРУДHОСТЕЙ БИЛЛИHГСА: Большинство тpyдностей пpоисходит оттого, что мы слишком быстpо говоpим ДА и недостаточно быстpо - НЕТ.(с)
"Очередной шаг вперед, как правило, результат хорошего пинка в зад!"(С)
majorPAE вне форума   Ответить с цитированием
Старый 17.12.2008, 10:25   #17
Alex B.
Super Moderator
 
Аватар для Alex B.
 
Регистрация: 25.02.2007
Адрес: Russia, SPb
Сообщений: 1,674
Вес репутации: 1729/83
Alex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant future
Отправить сообщение для Alex B. с помощью Skype™
По умолчанию Ответ: Модификация usb firmware

спасибо, интересно.
__________________
даташит читать до того , а не после
Alex B. вне форума   Ответить с цитированием
Старый 19.01.2009, 11:20   #18
SergeyKN
Senior Member
 
Регистрация: 13.08.2007
Сообщений: 160
Вес репутации: 111/50
SergeyKN will become famous soon enoughSergeyKN will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

решил пока осваиваю PIC24FJ256GB106 проверить его пиковые возможности по передаче по USB, докладываю результаты...

итак -- PIC24FJ256GB106, фирмвэа 2.3, CDC, частота CPU PLL:1 (32MHz, 16MIPS). обкладываю конструкциями типа "bset LATB, #N, bclr LATB, #N" функцию CDCTxService(), внутри нее цикл while(i) в _RAM части, и макрос mUSBUSARTTxRam (от него синхронизируюсь), время смотрю осцилографом. передается структура размером 250 байт (начинал с такого размера) раз в 100мс, Win-программа принимает структуру, отображает некоторые ее элементы.

как, наверно, все знают передаваемый пакет > 64 байт, разбивается на части по 64б и остаток -- в моём случае это 3 пакета по 64 б и 4-ый 58 б. итак при передаче 64 б -ных пакетов CDCTxService выполняется ~70мкс, между пакетами ~130мкс -- т.е. скорость < 500Кб/с (грубо). элементарная модификация цикла while(i) в CDCTxService() на конструкцию типа:
Код:
asm ("repeat W0");
asm ("mov  [W1++], [W2++]");
уменьшает время выполнения CDCTxService() до 10мкс с небольшим, а расстояние между пакетами начинает стремиться к 64 мкс, и следовательно скорость стремится к вожделенному паспортному 1Мб/с. (замечу, что вышеприведенная модификация while -> mov позволяет использовать максимальную скорость USB и на 2-ой доступной частоте CPU PLL:2 (16MHz, 8MIPS).)

на этом хорошее заканчивается, дальше проблемы... ессно 1Мб/с виден на маленьком пакете и лишь в первые секунды (а значит эйфоричного) наблюдения. смотрим подольше и видим, что 64 мкс между пакетами это лишь минимум, обычно поболе, а иногда проскакивают и ~128мкс. чтоб узнать реальную скорость увеличиваю размер передаваемой структуры, а для этого у cdc_tx_len меняем тип с BYTE на WORD. итак увеличиваю размер передаваемой структуры до 1250/2250/3250/4250 байт. сразу при виде "сверху" стала очевидна природа 128мкс-ных "случаев" -- между ними расстояние в 1мс, скорее всего это те 10% милисекундного фрейма (кадра), которые железно резервируются для контрол-пакетов. так, что скорость уменьшилась до 870Кб/с.

окончательно стало ясно что никакого пинг-понга нет (хотя режим включен) -- 2-ой USB-пакет от начала передачи структуры должен бы передаваться сразу же за первым, но это не так. исследование фирмвэа показало, что кое-какие заготовки для пинг-понга есть но по факту он не доделан. сделать его самому пока не удалось, уж больно там намутили (маньяк какой-то писал), в смысле ненужной усложненности кода. что означают и что делают в USBTransferOnePacket строки:
Код:
        //toggle over the to the next buffer for an IN endpoint
        ((BYTE_VAL*)&pBDTEntryIn[ep])->Val ^= USB_NEXT_PING_PONG;
я так и не понял, сегодня попробую с ICD2 разобраться. если у кого есть идеи по пинг-понгу, можете не стесняться.

ну и напоследок самое неприятное... при размере 4250 б, увидел что несколько пакетов передаются после огромной паузы, стал увелчивать размер структуры 5250/6250 -- точно сначала ~4.6мс передаются пакеты, потом пауза, потом передаются оставшиеся пакеты. причем пауза переменная, начинается от ~1мс в течении примерно 5-6 секунд растет до ~2мс, а потом скачком опять на 1мс. если передавать 10250б, то соответственно можно наблюдать 3 группы пакетов две по 4.6мс в последней остаток, и обе паузы ведут себя как описано выше.

совсем что-то непонятное. сначала начал грешить на Win-прогу, ну типа приоритет потока, в котором обмен с устройством идет, слишком низкий, но... чет попробовал вернуться опять к while (т.е. медленный вариант) -- группы увеличились до 8мс с небольшим, а пауза ведет себя как и в "быстром" варианте. такое впечатление, что передается какое-то определенное число пакетов, а потом что-то затыкается. если у кого появятся какие-нить идеи/гипотезы очень буду благодарен.

но окончательный вывод вобщем-то оптимистический -- PIC24FJ256GB106 обладает аппаратными возможностями юзать фул-спид по полной, все упирается в софт, и мелкочиповское фирмфэа требует доработки, по крайней мере для пиковых скоростей обмена.
SergeyKN вне форума   Ответить с цитированием
Старый 19.01.2009, 17:26   #19
-=3m=-
Junior Member
 
Регистрация: 19.01.2009
Сообщений: 14
Вес репутации: 133/44
-=3m=- will become famous soon enough-=3m=- will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Сообщение от SergeyKN Посмотреть сообщение
...
окончательно стало ясно что никакого пинг-понга нет (хотя режим включен) -- 2-ой USB-пакет от начала передачи структуры должен бы передаваться сразу же за первым, но это не так. исследование фирмвэа показало, что кое-какие заготовки для пинг-понга есть но по факту он не доделан. сделать его самому пока не удалось, уж больно там намутили (маньяк какой-то писал), в смысле ненужной усложненности кода. что означают и что делают в USBTransferOnePacket строки:
Код:
        //toggle over the to the next buffer for an IN endpoint
        ((BYTE_VAL*)&pBDTEntryIn[ep])->Val ^= USB_NEXT_PING_PONG;
я так и не понял, сегодня попробую с ICD2 разобраться. если у кого есть идеи по пинг-понгу, можете не стесняться.
Пингпонг в микрочиповском фреймворке явно нерабочий, там дофига еще ковырять.
Удручает необоснованная загроможденность исходника. Что эти индусы там курят???
Мне кажется должно работать так:
у вас есть буфер, где лежат посылаемые данные
вы задаете в BDT Even адрес начала буфера buf, в BDT Odd адрес следующего куска (buf + размер_эндпойнта). Когда первый кусок будет передан автоматически начнет передаваться второй а вы в это время в отработавшем BDT должны быстренько сменить начальный адрес на buf + 2*размер_эндпойнта и так далее пока не будет передан весь буфер.
ICD2 не помогает потому что обмен по USB невозможно тормознуть.
Есть идея подключить uart на 1-2 мегабита и выдавать диагностику на лету.
-=3m=- вне форума   Ответить с цитированием
Старый 20.01.2009, 09:47   #20
SergeyKN
Senior Member
 
Регистрация: 13.08.2007
Сообщений: 160
Вес репутации: 111/50
SergeyKN will become famous soon enoughSergeyKN will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Мне кажется должно работать так:
у вас есть буфер, где лежат посылаемые данные
вы задаете в BDT Even адрес начала буфера buf, в BDT Odd адрес следующего куска (buf + размер_эндпойнта). Когда первый кусок будет передан автоматически начнет передаваться второй а вы в это время в отработавшем BDT должны быстренько сменить начальный адрес на buf + 2*размер_эндпойнта и так далее пока не будет передан весь буфер.
согласен, это пожалуй самый экономичный способ... но, чёт тут есть "нехорошее", пока не знаю что. по крайней мере, для 18-ых получается, что этот буфер надо размещать в USB-RAM. я пока сделал попроще в духе самого фирмвэа -- т.е. добавил еще один буфер cdc_data_tx_ODD[CDC_DATA_IN_EP_SIZE] и намертво (в инициализации) закрепил cdc_data_tx в EP(CDC_DATA_EP,1,0), а cdc_data_tx_ODD в EP(CDC_DATA_EP,1,1). и копирую туда по очереди. в принципе работает, хотя я не до конца всё понимаю как это работает, вот блин намутили черти.

так что, без учета 2-ой проблемы (1-2мс пауза), структуры до 4Кб передаются на скорости 1094-1130Кб/с -- как я понимаю это предел для bulk. еще чуть поковыряю и брошу -- всё-равно у меня не предвидится в ближайшее время задач с необходимостью таких скоростей, пока 150Кб/с и то... будем делать не будем хз?

ПС. а фирмвэа надо конечно переделывать по-крупному...
SergeyKN вне форума   Ответить с цитированием
Старый 20.01.2009, 12:13   #21
-=3m=-
Junior Member
 
Регистрация: 19.01.2009
Сообщений: 14
Вес репутации: 133/44
-=3m=- will become famous soon enough-=3m=- will become famous soon enough
Thumbs up Ответ: Модификация usb firmware для pic18

Цитата:
Сообщение от SergeyKN Посмотреть сообщение
согласен, это пожалуй самый ...
так что, без учета 2-ой проблемы (1-2мс пауза), структуры до 4Кб передаются на скорости 1094-1130Кб/с -- как я понимаю это предел для bulk.
Насчет проблемы 4кб.
Вспомнил что у меня были проблемы с чипами FTDI usb-uart при обмене длинными блоками на высокой скорости (1 и боее мегабит). Там в драйвере есть параметр USB transfer size, по умолчани он равен 4096 байт. При дефолтных настройках блоки данных разбивались на куски по 4кб с паузами бежду блоками.
Почитайте http://support.microsoft.com/kb/832430

On Windows XP and Windows Server 2003, when the maximum size of a transfer for a bulk endpoint is either less than 4 kilobytes (KB) or equal to 4 KB, the port driver splits the transaction into multiple transfers. Theoretically, this behavior makes the maximum size of a USB transfer unlimited for these endpoints. However, Microsoft has not tested very large transfers, and Microsoft does not recommend very large transfers.

Дефолтных значений USB transfer size для bulk transfer я в msdn не нашел, но по поведению похоже это 4096 байт. Используя стандартные дрова лучше этот размер не превышать.
-=3m=- вне форума   Ответить с цитированием
Старый 20.01.2009, 13:30   #22
SergeyKN
Senior Member
 
Регистрация: 13.08.2007
Сообщений: 160
Вес репутации: 111/50
SergeyKN will become famous soon enoughSergeyKN will become famous soon enough
По умолчанию Ответ: Модификация usb firmware для pic18

Цитата:
Сообщение от -=3m=- Посмотреть сообщение
Дефолтных значений USB transfer size для bulk transfer я в msdn не нашел, но по поведению похоже это 4096 байт. Используя стандартные дрова лучше этот размер не превышать.
да, очень похоже на то... я примерно такие гипотезы про себя и выдвигал. спасибо. но воще-то у меня виста, так что я пока еще поищу пути к победе.
SergeyKN вне форума   Ответить с цитированием
Старый 09.09.2010, 13:57   #23
andrewtitoff
Senior Member
 
Регистрация: 19.03.2010
Адрес: СПб
Сообщений: 114
Вес репутации: 145/41
andrewtitoff will become famous soon enoughandrewtitoff will become famous soon enough
По умолчанию Re: Ответ: Модификация usb firmware для pic18

Здравствуйте!, не подскажете как для CDC переделать обработку USB через прерывание, уже который день бьюсь - ничего не нашел, в инете максимум что нашел - это для HID и то не уверен что работает, т.к. все примеры которые я нашел для старого фреймворка, а там все немного по другому... =(((
andrewtitoff вне форума   Ответить с цитированием
Старый 09.12.2010, 03:16   #24
Petya
Senior Member
 
Регистрация: 30.11.2008
Адрес: SPb
Сообщений: 150
Вес репутации: 238/47
Petya has a spectacular aura aboutPetya has a spectacular aura aboutPetya has a spectacular aura about
Arrow Re: Модификация usb firmware для pic18

Дополнение по теме.

В первом сообщении я писал, что для работы usb-фреймворка с прерываниями в режиме CDC потребуются доп. изменения, связанные с функцией CDCTxService().

По замыслу рабработчиков, эта функция должна вызываться в главном цикле на каждой итерации. Её задача - обеспечить удобный для программиста способ отправки данных на хост. Под этим понимается извлечение данных из произвольного участка ОЗУ/флеша, их авторазбиение на пакеты нужной длины + выдача пакета нулевой длины в конце (признак завершения передачи), когда надо.

Алгоритм такой:
  • Программа отправляет данные вызовом putrsUSBUSART()
  • Ссылка на них запоминается для ф-ции CDCTxService() в глобальных переменных
  • За несколько последующих вызовов CDCTxService() отправит нужное число пакетов с этими данными

Понятно, что большая часть вызовов CDCTxService() пройдёт в холостую - это будут только проверки на то, что данных для отправки нет или data endpoint пока занят.
Есть только 2 момента, когда её вызов необходим:
  • сразу после putrsUSBUSART(), чтобы выдать первый пакет
  • После обработки флага TRNIF, для передачи очередного пакета.

Таким образом, если модуль usb обслуживается не в суперцикле, а в обработчике прерывания, операция вывода может выглядеть так:
Код:
if(USBUSARTIsTxTrfReady())
{
    putrsUSBUSART("Button Pressed -- \r\n");
    CDCTxService();
}
а функция обработки событий - так:
Код:
BOOL USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, WORD size)
{
    switch(event)
    {
        ...
        case EVENT_TRANSFER:
            CDCTxService();
            break;
        ...
    }      
    return TRUE; 
}

Если важна скорость или объём кода, можно вообще убрать все эти навороты с CDCTxService(), удалить её, а данные выводить напрямую в data endpoint вызовом
Код:
CDCDataInHandle = USBTxOnePacket(CDC_DATA_EP,(BYTE*)&usb_ram_buffer, length);
, а готовность проверять так:
Код:
USBHandleBusy(CDCDataInHandle)
При этом также можно избежать избыточных копирований буфера, переданного в putrsUSBUSART(), в буфер конечной точки.

Минусы: за один вызов можно будет передать не более CDC_DATA_IN_EP_SIZE (по умолчанию = 64) байт, и только из USB RAM.


ПС: Про "суперцикл VS прерывания":

Я не сторонник того, чтобы всегда использовать обсуждаемый здесь способ программирования. Часто программа сама по себе хорошо реализуется по архитектуре суперцикла. Например, когда логика работы сводится к непрерывной передаче данных (как в примерах микрочипа - usb<-ацп, usb<>uart и пр.).
Другое дело, если нужно использовать ОС или добавить поддержку usb в уже готовую программу, не использующую суперцикл.
Преимущество микрочиповского варианта - простота, а рассмотренного - универсальность. (Недаром же они назвали его именно фреймворком).

Есть мнение, что нехорошо ставить вызов функции USBTasks() в обработчик прерывания, т.к. это замедляет реакцию системы.
В данном случае эта проблема может быть легко решена: прерыванию от usb назначаем низкий приоритет, остальным - высокий.
Petya вне форума   Ответить с цитированием
Старый 24.12.2010, 15:10   #25
vladtv
Senior Member
 
Регистрация: 27.02.2007
Сообщений: 144
Вес репутации: 100/52
vladtv will become famous soon enoughvladtv will become famous soon enough
По умолчанию Re: Модификация usb firmware для pic18

Дабы не плодить темы спрошу о своей проблеме здесь. "Прикручиваю" HID устройство с существующему проекту. Процессор 18F14K50, тактовая 12MHz (основное время прибор питается от батареи и тактовую повышать не хотелось). Пользуюсь mcc18 v3.34 и примером USB Device - HID - Custom Demos из Microchip Solutions v2010-08-04. Пробую работать с USB по прерываниям. В исходной программе есть прерывание от TMR2 которое довольно критично ко времени выполнения (формируется шим для звукового сообщения). USB пока не подключен (физически). После того как в проект "включено" всё необходимое для поддержки USB, выход из прерывания TMR2 "затягивается" почти на 1ms, вернее из прерывания то выходит, но в глобальный while(1) попадает только через 1ms (а это очень долго). Где путешествует программа - не могу вычислить. Если отключить прерывания TMR2 программа честно крутится в глобальном while(1). Прерывание от USB не возникает. Кто что посоветует?

Последний раз редактировалось vladtv; 24.12.2010 в 15:23.
vladtv вне форума   Ответить с цитированием
Ответ

Метки
firmware, interrupt, pic18f4550, polling, usb, usb cdc


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Драйвер для USB Bootloader Evgeniy Продукция MICROCHIP 2 17.10.2008 12:05
Какую RTOS выбрать под PIC18, есть ли замена jacos для MCC18 Максим2008 Инструментарий 20 05.08.2008 09:11
команды для работы с USB Sergey1 Общетехнические вопросы 1 14.06.2007 09:30
Хочу перейти с Asm на Cи для PIC18 crokus Продукция MICROCHIP 12 11.05.2007 15:01
класс для полноценного использования USB? sergikoff Продукция MICROCHIP 6 12.04.2007 18:06


Часовой пояс GMT +3, время: 04:44.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot