Перейти к содержанию
    

Уважаемые форумчане, друзья, братья по увлечению!

В 3-мартовском номере журнала РАДИО за 2010 год на с.25-28 С.Суров из Нижнего Новгорода

 

опубликовал описание демонстрационного USB HID устройства на микроконтроллере ATmega88-20DPI

 

с обменом данными по шине USB 1.1

Меня заинтересовала возможность подключения микроконвертора MSP430А2013 аналогичным образом.

Преимущества - упрощение конструкции (не нужен будет мост USB-COM и драйверы виртуального

 

порта), повышение надёжности.

Препятствия -

1) ограничение по частоте. В режиме LS (low speed) скорость 1.5 Мбит/с означает время

 

передачи одного бита - не более 667 нс.

В описании к MSP430 декларирована максимальная тактовая частота 16 МГц (62.5 нс), но это для

 

процессора. С интерфейсом работает таймер_А, который можно тактировать от SMCLK. Сигнал

 

тактирования SMCLK можно получить от источника с цифровым управлением (DCO).

На обработку одного бита данных будет приходится 667/62.5=10 тактов. Хватит ли их?

В статье Кристиана Старкйогана http://www.obdev.at/developers/articles/00003.html убедительно показано, что для AVR контроллера можно обойтись и восемью тактами.

2) переносимость клиентского кода. В среде визуального программирования С++ Builder 6 можно подключить созданный Робертом Мартином Марквардом компонент TJvHidDeviceController. Есть ли подобные компоненты для среды Delphi?

3) Процессор ATmega88-20DPI существенно и глубоко восьмибитен, преимущественно ли бороться за 16-битность, пытаясь перейти к MSP430? Буду благодарен за информацию, есть ли 16-разрядные процессоры с небольшим количеством терминалов (16-24 pins) с реализованной функцией интерфейса по USB 1.1 типа HID?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

преимущественно ли бороться за 16-битность, пытаясь перейти к MSP430?

Если выбор msp430 не принципиален (нет жёстких требований к потреблению), лучше наверно перескочить через ступень и взяться сразу за ARM.

Тем более что там и USB есть, и ethernet, и SD и много чего ещё. И стоит практически столько же.

Повторить устройство на мсп наверно можно, если оно будет заниматься только прослушкой USB.

Но интереса в этом мало. Лучше уж тогда мост вставить. Хотя, если UART всё равно занимать, можно попробовать принимать в режиме SPI, а такты формировать выходом таймера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если выбор msp430 не принципиален (нет жёстких требований к потреблению), лучше наверно перескочить через ступень и взяться сразу за ARM.

Тем более что там и USB есть, и ethernet, и SD и много чего ещё. И стоит практически столько же.

Повторить устройство на мсп наверно можно, если оно будет заниматься только прослушкой USB.

Но интереса в этом мало. Лучше уж тогда мост вставить. Хотя, если UART всё равно занимать, можно попробовать принимать в режиме SPI, а такты формировать выходом таймера.

за дружелюбный ответ спасибо. Правильно ли я понял, что, взявшись за реализацию USB 1.1 на МСП, я займу таймер, оставив проц свободным для обслуживания нечастых прерываний с АЦП, и если тактирования на проц будет не от DCO, могут быть конфликты в случае одновременной работы приёма или передачи по USB и АЦП или процессора?

Режим SPI - Service Provider Interface? или речь идёт о SPIP (Serial Peripheral Interface Protocol)?

Догадался ли я о Вашем намёке, М-р Юран, на мысль немного подправить программную реализацию USART, уже основанную на работе таймера?.

Выкладываю свой неуклюжий перевод Старкйохана в концептуальной его части

 

"Являясь процессором RISC, MSP430 выполняет большинство инструкций за один цикл тактирования. Поэтому будет справедливой необходимость упаковать в 8 инструкций-команд следующие действия, необходимые для обработки каждого бита –

1) кодирование «1» при отсутствии изменений на входных линиях, «0» при измене

2) кодирование может быть инвертированием операции исключающего или между текущим статусом и статусом 8 циклами ранее

3) Кодирование битстаффинга – для сохранения синхронизации после каждых 6 «1» вставляется незначащий «0», он должен быть удалён после приёма

4) Распознавание конца пакета, обозначаемого состоянием «SE0». Это означает, что обе линии данных (обычно инвертированные друг относительно друга) установлены на уровень логического нуля на удвоенное время передачи одного бит

5) Полученный бит должен быть сохранён с проверкой буфера переполнения каждые 8 бит данных."

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"Являясь процессором RISC, MSP430 выполняет большинство инструкций за один цикл тактирования. Поэтому ...

Это откуда? Я что-то не нашел...

Под SPI я понимаю Serial Peripheral Interface.

То есть подаём сигнал на вход UARTа в режиме SPI, а таймером формируем тактовые клоки.

Задвинули 8 тактов, прерывание от SPI, складываем в буфер.

Вот про SE0 я забыл... Его можно отловить компаратором. То есть если обе линии в одном состоянии - получаем прерывание от компаратора.

Приняли весь пакет - обрабатываем. Декодируем NRZI, выкидываем биты стаффинга и т.д.

 

Хотя можно и исходный алгоритм переработать. Но в этом случае во время обмена контроллер не сможет ни на что отвлекаться. Потому что счёт на такты процессора. То есть все прерывания должны быть запрещены.

В принципе, автор как раз и подчёркивает, что для его реализации не нужна никакая периферия, только опрос порта и 100% занятость процессора в момент обмена.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это откуда? Я что-то не нашел...

Признаю, мой грех. Следует читать "AVR" вместо "MSP430". Слишком велико было желание выдать мечту за действительное.

 

"... То есть подаём сигнал на вход UARTа в режиме SPI, а таймером формируем тактовые клоки.

Задвинули 8 тактов, прерывание от SPI, складываем в буфер."

"...Его можно отловить компаратором. То есть если обе линии в одном состоянии - получаем прерывание от компаратора.

Приняли весь пакет - обрабатываем. Декодируем NRZI, выкидываем биты стаффинга и т.д."

 

Извините, М-р Юран, но в кристалле MSP430F2013 нет аппаратного UART и нет компаратора, там только АЦП16.

 

"Хотя можно и исходный алгоритм переработать. Но в этом случае во время обмена контроллер не сможет ни на что отвлекаться. Потому что счёт на такты процессора. То есть все прерывания должны быть запрещены.

В принципе, автор как раз и подчёркивает, что для его реализации не нужна никакая периферия, только опрос порта и 100% занятость процессора в момент обмена."

 

После чтения и перевода на русский статьи Старкйохана возникли вопросы и сомнения. Конечный вариант кода -

rxbit0:
    in     x1, port;1 цикл на чтение данных из порта ввода\вывода
    andi    x1, mask; 1 цикл на проверку конца пакета передачи SE0
    breq    end_of_packet; 1 цикл (так как переход по ветви не произошёл)
    eor    x2, x1; 1 цикл на декодирование NRZI – без возврата к нулю инверт
    ror    x2; 1 цикл на приём бита из LSB -> carry
    ror     shift; 1 цикл накопление битов данных 
    cpi    shift, 4; 1 цикл на проверку наличия 6-ти последовательных нулей
    brlo    do_unstaff; 1 цикл (так как переход по ветви не произошёл)
rxbit1:
    in     x2, port;1 цикл на чтение данных из порта ввода\вывода
    breq    end_of_packet; 1 цикл (так как переход по ветви не произошёл)
    eor    x1, x2; 1 цикл на декодирование NRZI – без возврата к нулю инверт
    ror    x1; 1 цикл на приём бита из LSB -> carry
    ror     shift; 1 цикл накопление битов данных 
    cpi    shift, 4; 1 цикл на проверку наличия 6-ти последовательных нулей
    brlo    do_unstaff; 1 цикл (так как переход по ветви не произошёл)
    mov    x2, x1; 1 цикл (сохранение ввода для следующего цикла)
итого 16 циклов
Удаление набитого незначащего приткнутого бита.
С первого взгляда разрушение одного бита должно быть простым. Только прикиньтесь манекеном – сделайте чтение и ожидание:
do_unstuff0:    ; 1 цикл (переход из точки ветвления по условию)
    in     x1, port;1 цикл на чтение данных из порта ввода\вывода
    andi    x1, mask; 1 цикл на проверку конца пакета передачи SE0
    breq    end_of_packet; 1 цикл (так как переход по ветви не произошёл)
    nop    ;1 цикл на отсутствие операции – пустая команда
    nop    ;1 цикл на отсутствие операции – пустая команда
    rjmp    rxbit1;2 цикла (переход из точки ветвления по условию)
итого 8 циклов

Впервые у нас два свободных цикла! Делаем необходимые копирование и запись и заменяем проверки конца пакета для управления переходом по петле и готово. Но постойте! Что произойдёт, если за всунутым незначащим битом следует такой же? Наш сдвиговый регистр содержит сохранённые данные и в нём окажется 7 нулей подряд. Следующий бит будет поэтому проигнорирован, хотя вставка незначащего бита была только что отработана. Программная ошибка!
На этот раз всё действительно серьёзно. Нам надо исключить ситуацию, когда в сдвиговом регистре более 5 старших нулей подряд, но в нём данные, которые нам нужны. И мы не можем и не должны их менять. Можно сделать копию регистра и использовать её для обнаружения битстаффинга. Но где взять свободные циклы, чтобы позаботиться о копии. И в конце концов, хранение обширных данных не может быть эффективным. В чём мы действительно нуждаемся, так это в другой Хорошей Идее.
Если решение существует, он должно состоять в изменении содержимого регистра сдвига. Это единственный способ плотно упаковать код для чтения битов, чтобы выжить без изменения. Отлично. Итак, мы должны установить по меньшей мере самый старший значащий бит в сдвиге в ходе do_unstuff. Но как нам тогда восстановить полученный байт?
Ключ к решению – в том, что мы знаем, что мы модифицируем. Мы устанавливаем в «1» бит, про который известно, что его значение - «0». И мы знаем, где они будут приземляться, поскольку петля цикла развёрнута и фиксировано количество операций сдвига, следующих до момента сохранения данных. Мы просто собираем биты, которые мы изменили, в отдельном регистре и возвращаем их назад сразу перед сохранением. К счастью, у нас оставалось два свободных цикла в do_unstuff:
do_unstuff0:    ; 1 цикл (переход из точки ветвления по условию)
    in     x1, port;1 цикл на чтение данных из порта ввода\вывода
    andi    x1, mask; 1 цикл на проверку конца пакета передачи SE0
    breq    end_of_packet; 1 цикл (так как переход по ветви не произошёл)
    ori    shift, 0xfc;1 цикл маскировка 6ти свежих бит подряд
    andi    x3, 0xfe;1 цикл спрятанные нами биты сдвинуты вправо на 7
    rjmp    rxbit1;2 цикла (переход из точки ветвления по условию)

Попытался реализовать в IAR Embedded Workbench IDE 4.21.8.

;*******************************************************************************
;   MSP430F20xx Demo - USB 1.1 Echo, 12MHz SMCLK
;
;   Description: Use data latch
;   to implement USB function @ 1500000 baud. Software directly reads and
;   writes to RX and TX pins, all software activity is stopped besides CPU. 
;   No interrupt is available.
;   After a character has been received, CPU forces echo's back the received character.
;   MCLK = SMCLK = DCO = 12 MHz
;   
;
;                MSP430F20xx
;             -----------------
;         /|\|              XIN|-
;          | |                 | 
;          --|RST          XOUT|-
;            |                 |
;            |   CCI0B/TXD/P1.5|-------->
;            |                 | 1500000 8N1
;            |   CCI0A/RXD/P1.1|<--------
;
;   April 2010
;   Built with IAR Embedded Workbench Version: 4.21.8
;*******************************************************************************
RXD         EQU     002h                  ; RXD on P1.1
TXD         EQU     020h                  ; TXD on P1.5
;
;   CPU Registers Used
#define     Rx1     R4
#define     Rx2     R5
#define     Rx3     R6
;
;   Conditions for 150000 Baud SW USB1.1, SMCLK = 12000000
Bitime_5    EQU     04                    ; ~0.5 bit length
Bitime      EQU     08                ; 667ns bit length ~ 1.5 Mbaud
#include  "msp430x20x3.h"
;-------------------------------------------------------------------------------
            ORG     0F800h                ; Program Reset
;-------------------------------------------------------------------------------
RESET       mov.w   #0280h,SP             ; Initialize stackpointer
StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL; Stop Watchdog Timer
SetupBCS    mov.w   #CALBC1_12MHZ,&BCSCTL1 ; SMCLK, 12MHz
SetupDC0    mov.w   #CALBC0_12MHZ,&DCOCTL  ; DCO = 12MHz
SetupP1     bis.b   #TXD+RXD,&P1SEL    ;
            bis.b   #TXD,&P1DIR        ;
SetupX3     mov.w   0xff,Rx3       
                                          ;
Rxbit0      mov.w   &020h,Rx1              ; read data from I\O port
            cmp.b   msk,RX1                ; check for SE0
            jne     End_of_Packet          ;
            xor.b   Rx2,Rx1                ; NRZI decoding
            rrc.b   Rx2                ; Data bit -> carry
            rrc.b   shift                 ; collect data bits
            cmp.w   shift,4            ; check for 6 consecutieve 0 bits
            jnz     do_unstuff0;          ; Stuffed bit? Will be ignored!
Rxbit1      mov.w   &020h,Rx2              ; read data from I\O port
            cmp.b   msk,RX2                ; check for SE0
            jne     End_of_Packet          ;
            xor.b   Rx1,Rx2                ; NRZI decoding
            rrc.b   Rx1                ; Data bit -> carry
            rrc.b   shift                 ; collect data bits
            cmp.w   shift,4            ; check for 6 consecutieve 0 bits
            jnz     do_unstuff1;          ; Stuffed bit? Will be ignored!
do_unstuff0 mov.w   &020h,Rx1              ; read data from I\O port
            cmp.b   msk,RX1                ; check for SE0
            jne     End_of_Packet          ;
            xor.b   shift,0xfc             ; mask out 6 recently received bits
            cmp.b   Rx3,0xfe                ; shift masked bits right 7
            jnz     rxbit1;                 ; 
do_unstuff1 mov.w   &020h,Rx2              ; read data from I\O port
            cmp.b   msk,RX2                ; check for SE0
            jne     End_of_Packet          ;
            xor.b   shift,0xfc             ; mask out 6 recently received bits
            cmp.b   Rx3,0xfe                ; shift masked bits right 7
            jnz     rxbit0;                 ;             
End_of_Packet
            nop
            
;-------------------------------------------------------------------------------
;           Interrupt Vectors
;-------------------------------------------------------------------------------
            ORG     0FFFEh                ; MSP430 RESET Vector
            DW      RESET                 ;
            ORG     0FFF2h                ; Timer_A0 Vector
            DW      TA0_ISR            ;
            END

При попытке компиляции выскакивает ошибка Error [431] Accessing SFR using incorrect size. На строку SetupBCS. Помогите, пожалуйста, понять, что не так?

Изменено пользователем VVlad

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"Являясь процессором RISC, MSP430 AVR выполняет большинство инструкций за один цикл тактирования. Поэтому будет справедливой необходимость упаковать в 8 инструкций-команд следующие действия, необходимые для обработки каждого бита

"Хотя можно и исходный алгоритм переработать. Но в этом случае во время обмена контроллер не сможет ни на что отвлекаться. Потому что счёт на такты процессора. То есть все прерывания должны быть запрещены.

В принципе, автор как раз и подчёркивает, что для его реализации не нужна никакая периферия, только опрос порта и 100% занятость процессора в момент обмена."

Выделенные нюансы препятствуют реализации желаемого на MSP430. Потому, что, например, вывод в порт

P1OUT=0x01;

у MSP430 занимает 4 такта, вместо одного у AVR. А наложение маски типа

P1OUT|=0x01;

занимает у MSP430 - 5 тактов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Выделенные нюансы препятствуют реализации желаемого на MSP430. Потому, что, например, вывод в порт

P1OUT=0x01;

у MSP430 занимает 4 такта, вместо одного у AVR. А наложение маски типа

P1OUT|=0x01;

занимает у MSP430 - 5 тактов.

Благодаря любезному ответу Резидента мне стало понятно, что без обработки прерываний, только на процессоре MSP, реализовать USB1.1 невозможно.

Если же использовать периферический ТаймерА, тактируя его сигналом SMCLK от DCO, настроенного на 12 МГц, можно успеть обработать пакеты данных?

план такой -

1) отключаем сторожевой таймер, настраиваем порты, систему тактирования, регистр захвата-сравнения таймера А

2) в бесконечной петле цикла происходит запуск АЦП, переход в спящий режим с разрешением прерываний, прерывание от АЦП будит процессор, тот запрещает все прерывания, выполняет усреднение и готовит пакет данных для передачи, кодируя его в NRZI c битстаффингом, включает прерывания и передаёт управление на таймер А. По истечении интервала (0.6 мкс) для передачи очередного бита формируется следующий. Задача передачи данных более простая, чем приём. Не требуется искать фронты сигналов, процессор сам решает, когда передавать данные. Готовая последовательность битов из буферного регистра TxData аппаратно сдвигаются на выход P1.1 при помощи регистра CCR0 таймера А. По окончании передачи происходит переход в начало цикла, следующий запуск АЦП и так далее.

 

Нет ли здесь методических ошибок?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Выделенные нюансы препятствуют реализации желаемого на MSP430. Потому, что, например, вывод в порт

P1OUT=0x01;

у MSP430 занимает 4 такта, вместо одного у AVR. А наложение маски типа

P1OUT|=0x01;

занимает у MSP430 - 5 тактов.

Я ж говорил, надо переработать. Например, тупо складываем в стопочку в ОЗУ принятые с порта байты, а после окончания приёма начинаем разбирать. Конец передачи можно успеть отследить, наложением маски.

Но в целом получается искусство ради искусства.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но в целом получается искусство ради искусства.

Вот именно. В подобных извращениях нет никакого смысла. Для единичных поделок стоимость не критична и можно поставить мост uart или сразу взять проц с usb интерфейсом. Для крупной серии есть дешевые холтеки с аппаратным low speed usb или аналогичные чипы от других производителей. Радиогубительство было уместно когда мк с интерфейсом usb были недоступны а сейчас это дурь в чистом виде.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Порадовали, благодарю м-ра Юрана за конкретные инструкции по переработке, за наложение маски и искусство.

Спасибо __3м_ за знакомство с Холтек, поиск дешёвых аналогов привёл к статье http://www.gaw.ru/pdf/Atmel/app/avr/AVR309.pdf

откуда можно узнать (стр.5 из 23), что в низкоскоростных юсби размер пакета ограничен одним байтом.

Во многих случаях вычислительная мощность микроконтроллеров очень близка к минимальным требованиям, и драйверы пишут на ассемблере. В отличие от UART USB требует синхронизации, что сильно усложняет передачу.

Вы меня убедили, что дурь ради искусства ничем не лучше искусства дури.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

VVlad, когда нам понадобилось дешевое решение с USB (клавиатура из двух кнопок, но именно с USB-интерфейсом), то мы взяли PIC18 (PIC18F14K50-I/SS), стоимостью порядка $2,5 в розницу (сравните с MSP430F2013IPW, который около $3,5 в рознице) с аппаратным USB-device, пример реализации HID от Microchip и человек, не знакомый ранее ни с PIC, ни с USB, через две недели изучения получил вполне работающий вариант устройства. Спрашивается, зачем изобретать велосипеды собственной конструкции, если заранее известно, что даже по стоимости одних только комплектующих он будет стоить больше, чем уже готовый велосипед известной конструкции? :laughing: Если только ради получения удовольствия от самого процесса :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... то мы взяли PIC18 (PIC18F14K50-I/SS), стоимостью порядка $2,5 в розницу...через две недели изучения получил вполне работающий вариант устройства. ...
Если взять CP2103, то можно съэкономить 13 дней.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

VVlad, когда нам понадобилось дешевое решение с USB (клавиатура из двух кнопок, но именно с USB-интерфейсом), то мы взяли PIC18 (PIC18F14K50-I/SS), стоимостью порядка $2,5 в розницу (сравните с MSP430F2013IPW, который около $3,5 в рознице) с аппаратным USB-device, пример реализации HID от Microchip и человек, не знакомый ранее ни с PIC, ни с USB, через две недели изучения получил вполне работающий вариант устройства. Спрашивается, зачем изобретать велосипеды собственной конструкции, если заранее известно, что даже по стоимости одних только комплектующих он будет стоить больше, чем уже готовый велосипед известной конструкции? :laughing: Если только ради получения удовольствия от самого процесса :biggrin:

Согласен с Вами, Резидент. Однако, основное требование заказчика - использовать 16-разрядный процессор, а PIC18F14K50-I/SS - 8миразрядный.

 

Если взять CP2103, то можно съэкономить 13 дней.

Спасибо за совет, IH_, СР2103 хорош, но к нему, наверное, нужны панельки, о которых никто не слышал.

напрямую запаивать в плату слишком миниатюрные выводы - на макете не удалось.

Каков способ монтажа?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

напрямую запаивать в плату слишком миниатюрные выводы - на макете не удалось.

Каков способ монтажа?

Если cp210x слишком мал, можно пробовать ft232/pl2303/tusb3410. Для макета cp210x можно приклеить "на спинку" и жилами многожильного провода распаять выводы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласен с Вами, Резидент. Однако, основное требование заказчика - использовать 16-разрядный процессор, а PIC18F14K50-I/SS - 8миразрядный.

А не все ли равно какой разрядности процессор если требуемую задачу он решает причем с бо-оольшим запасом ??? "неважно какого цвета кошка главное чтобы она ловила мышей".

Хотя если заказчик работает по на-на-технологии то да, проблема.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...