VVlad 0 22 апреля, 2010 Опубликовано 22 апреля, 2010 · Жалоба Уважаемые форумчане, друзья, братья по увлечению! В 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 29 22 апреля, 2010 Опубликовано 22 апреля, 2010 · Жалоба преимущественно ли бороться за 16-битность, пытаясь перейти к MSP430? Если выбор msp430 не принципиален (нет жёстких требований к потреблению), лучше наверно перескочить через ступень и взяться сразу за ARM. Тем более что там и USB есть, и ethernet, и SD и много чего ещё. И стоит практически столько же. Повторить устройство на мсп наверно можно, если оно будет заниматься только прослушкой USB. Но интереса в этом мало. Лучше уж тогда мост вставить. Хотя, если UART всё равно занимать, можно попробовать принимать в режиме SPI, а такты формировать выходом таймера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VVlad 0 22 апреля, 2010 Опубликовано 22 апреля, 2010 · Жалоба Если выбор 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 бит данных." Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 29 22 апреля, 2010 Опубликовано 22 апреля, 2010 · Жалоба "Являясь процессором RISC, MSP430 выполняет большинство инструкций за один цикл тактирования. Поэтому ... Это откуда? Я что-то не нашел... Под SPI я понимаю Serial Peripheral Interface. То есть подаём сигнал на вход UARTа в режиме SPI, а таймером формируем тактовые клоки. Задвинули 8 тактов, прерывание от SPI, складываем в буфер. Вот про SE0 я забыл... Его можно отловить компаратором. То есть если обе линии в одном состоянии - получаем прерывание от компаратора. Приняли весь пакет - обрабатываем. Декодируем NRZI, выкидываем биты стаффинга и т.д. Хотя можно и исходный алгоритм переработать. Но в этом случае во время обмена контроллер не сможет ни на что отвлекаться. Потому что счёт на такты процессора. То есть все прерывания должны быть запрещены. В принципе, автор как раз и подчёркивает, что для его реализации не нужна никакая периферия, только опрос порта и 100% занятость процессора в момент обмена. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VVlad 0 22 апреля, 2010 Опубликовано 22 апреля, 2010 (изменено) · Жалоба Это откуда? Я что-то не нашел... Признаю, мой грех. Следует читать "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. Помогите, пожалуйста, понять, что не так? Изменено 22 апреля, 2010 пользователем VVlad Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 22 апреля, 2010 Опубликовано 22 апреля, 2010 · Жалоба "Являясь процессором RISC, MSP430 AVR выполняет большинство инструкций за один цикл тактирования. Поэтому будет справедливой необходимость упаковать в 8 инструкций-команд следующие действия, необходимые для обработки каждого бита "Хотя можно и исходный алгоритм переработать. Но в этом случае во время обмена контроллер не сможет ни на что отвлекаться. Потому что счёт на такты процессора. То есть все прерывания должны быть запрещены. В принципе, автор как раз и подчёркивает, что для его реализации не нужна никакая периферия, только опрос порта и 100% занятость процессора в момент обмена." Выделенные нюансы препятствуют реализации желаемого на MSP430. Потому, что, например, вывод в порт P1OUT=0x01; у MSP430 занимает 4 такта, вместо одного у AVR. А наложение маски типа P1OUT|=0x01; занимает у MSP430 - 5 тактов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VVlad 0 23 апреля, 2010 Опубликовано 23 апреля, 2010 · Жалоба Выделенные нюансы препятствуют реализации желаемого на 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 таймера А. По окончании передачи происходит переход в начало цикла, следующий запуск АЦП и так далее. Нет ли здесь методических ошибок? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 29 23 апреля, 2010 Опубликовано 23 апреля, 2010 · Жалоба Выделенные нюансы препятствуют реализации желаемого на MSP430. Потому, что, например, вывод в порт P1OUT=0x01; у MSP430 занимает 4 такта, вместо одного у AVR. А наложение маски типа P1OUT|=0x01; занимает у MSP430 - 5 тактов. Я ж говорил, надо переработать. Например, тупо складываем в стопочку в ОЗУ принятые с порта байты, а после окончания приёма начинаем разбирать. Конец передачи можно успеть отследить, наложением маски. Но в целом получается искусство ради искусства. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_3m 9 23 апреля, 2010 Опубликовано 23 апреля, 2010 · Жалоба Но в целом получается искусство ради искусства. Вот именно. В подобных извращениях нет никакого смысла. Для единичных поделок стоимость не критична и можно поставить мост uart или сразу взять проц с usb интерфейсом. Для крупной серии есть дешевые холтеки с аппаратным low speed usb или аналогичные чипы от других производителей. Радиогубительство было уместно когда мк с интерфейсом usb были недоступны а сейчас это дурь в чистом виде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VVlad 0 23 апреля, 2010 Опубликовано 23 апреля, 2010 · Жалоба Порадовали, благодарю м-ра Юрана за конкретные инструкции по переработке, за наложение маски и искусство. Спасибо __3м_ за знакомство с Холтек, поиск дешёвых аналогов привёл к статье http://www.gaw.ru/pdf/Atmel/app/avr/AVR309.pdf откуда можно узнать (стр.5 из 23), что в низкоскоростных юсби размер пакета ограничен одним байтом. Во многих случаях вычислительная мощность микроконтроллеров очень близка к минимальным требованиям, и драйверы пишут на ассемблере. В отличие от UART USB требует синхронизации, что сильно усложняет передачу. Вы меня убедили, что дурь ради искусства ничем не лучше искусства дури. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 23 апреля, 2010 Опубликовано 23 апреля, 2010 · Жалоба VVlad, когда нам понадобилось дешевое решение с USB (клавиатура из двух кнопок, но именно с USB-интерфейсом), то мы взяли PIC18 (PIC18F14K50-I/SS), стоимостью порядка $2,5 в розницу (сравните с MSP430F2013IPW, который около $3,5 в рознице) с аппаратным USB-device, пример реализации HID от Microchip и человек, не знакомый ранее ни с PIC, ни с USB, через две недели изучения получил вполне работающий вариант устройства. Спрашивается, зачем изобретать велосипеды собственной конструкции, если заранее известно, что даже по стоимости одних только комплектующих он будет стоить больше, чем уже готовый велосипед известной конструкции? :laughing: Если только ради получения удовольствия от самого процесса Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ih_ 0 26 апреля, 2010 Опубликовано 26 апреля, 2010 · Жалоба ... то мы взяли PIC18 (PIC18F14K50-I/SS), стоимостью порядка $2,5 в розницу...через две недели изучения получил вполне работающий вариант устройства. ...Если взять CP2103, то можно съэкономить 13 дней. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VVlad 0 26 апреля, 2010 Опубликовано 26 апреля, 2010 · Жалоба VVlad, когда нам понадобилось дешевое решение с USB (клавиатура из двух кнопок, но именно с USB-интерфейсом), то мы взяли PIC18 (PIC18F14K50-I/SS), стоимостью порядка $2,5 в розницу (сравните с MSP430F2013IPW, который около $3,5 в рознице) с аппаратным USB-device, пример реализации HID от Microchip и человек, не знакомый ранее ни с PIC, ни с USB, через две недели изучения получил вполне работающий вариант устройства. Спрашивается, зачем изобретать велосипеды собственной конструкции, если заранее известно, что даже по стоимости одних только комплектующих он будет стоить больше, чем уже готовый велосипед известной конструкции? :laughing: Если только ради получения удовольствия от самого процесса Согласен с Вами, Резидент. Однако, основное требование заказчика - использовать 16-разрядный процессор, а PIC18F14K50-I/SS - 8миразрядный. Если взять CP2103, то можно съэкономить 13 дней. Спасибо за совет, IH_, СР2103 хорош, но к нему, наверное, нужны панельки, о которых никто не слышал. напрямую запаивать в плату слишком миниатюрные выводы - на макете не удалось. Каков способ монтажа? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msalov 0 26 апреля, 2010 Опубликовано 26 апреля, 2010 · Жалоба напрямую запаивать в плату слишком миниатюрные выводы - на макете не удалось. Каков способ монтажа? Если cp210x слишком мал, можно пробовать ft232/pl2303/tusb3410. Для макета cp210x можно приклеить "на спинку" и жилами многожильного провода распаять выводы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_3m 9 26 апреля, 2010 Опубликовано 26 апреля, 2010 · Жалоба Согласен с Вами, Резидент. Однако, основное требование заказчика - использовать 16-разрядный процессор, а PIC18F14K50-I/SS - 8миразрядный. А не все ли равно какой разрядности процессор если требуемую задачу он решает причем с бо-оольшим запасом ??? "неважно какого цвета кошка главное чтобы она ловила мышей". Хотя если заказчик работает по на-на-технологии то да, проблема. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться