|
Реально достижимая скорость по SPI, Программно-аппаратные трюки для достижения максимальной скорости перед |
|
|
|
Jul 12 2006, 13:34
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Тема была навеяна $ilent, но она была закрыта прежде, чем я успел в ней поучаствовать :-). Интересует, прежде всего, потенциально достижимая скорость как в аппаратном исполнении, так и в программном. Какие требования в "железном" исполнении? Необходимо передать по SPI nByte байт из буфера txBuffer (ОЗУ МК) и одновременно принять массив байт такой же длины в rxBuffer (ОЗУ МК). Моя программа выполняется за 8МЦ, т.е. ровно один такт на 1 бит. Интересно, можно ли добиться большего? Что скажут эксперты? Программа $ilent работает в полудуплексе, следовательно можно снизить требования к программной реализации SPI, а именно, необходимо программно формировать только биты данных и синхронизацию на передачу ИЛИ принимать биты данных по положительным фронтам импульсов синхронизации на прием. Моя программа передает один байт за 36МЦ, т.е. за 4,5 такта на 1 бит. Как добиться большего? Народ, не воспринимайте топик слишком сурово, это мой первый на этом сайте...
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 32)
|
Jul 12 2006, 14:52
|
Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 5-05-06
Из: Ekaterinburg, Russia
Пользователь №: 16 821

|
А что значит программа выполняется за 8МЦ? Передает все nByte за 8 маш. циклов или я неправильно понял?
--------------------
Чудес не бывает - бывает мало знаний и опыта!
|
|
|
|
|
Jul 12 2006, 16:08
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Может вы имели ввиду не мегагерцы а такты? т.е программа выполняется за 36 тактов ( 4.5 такта на бит) 1 такт на бит не получить аппаратно мин прескалер равен 2 и получится 2 такта на бит пограммно теоретически максимум можно получить тоже 2 такта на бит, но только для отправки и отправлять например константу т.е тупо 16 раз записать в порт (не используя SBI CBI) примерно так Код LDI R16, 1; pin0 - CLK=1 LDI R17, 0; pin0 - CLK=0
OUT PORTA, R16; bit 7 OUT PORTA, R17
OUT PORTA, R16; bit 6 OUT PORTA, R17
; и т.д нужное число бит но ценность этого кода сомнительна можно так, но уже 3 такта на бит Код LDI R17, 0
LDI R16, 1 | ((val>>6) & 2); pin0 - CLK=1 pin1 - MOSI=bit 7 OUT PORTA, R16; bit 7 OUT PORTA, R17
LDI R16, 1 | ((val>>5) & 2); pin0 - CLK=1 pin1 - MOSI=bit 6 OUT PORTA, R16; bit 7 OUT PORTA, R17
; и т.д нужное число бит
|
|
|
|
|
Jul 12 2006, 16:14
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(SpiritDance @ Jul 12 2006, 14:15)  Ничего не понял. Толи у меня башка уже не варит толи одно из двух. GM повторите 2 раза и помедленнее.  Прошу прощения за непонятки(:-). Это я, наверное, туплю. Устал, через неделю ухожу в отпуск. Тем не менее, повторяю. В АВР есть аппаратный SPI. С его помощью надо передать и принять некое количество байт максимально быстро. Т.е. нужна программа, которая в основном цикле выполняет следующее 1) взять байт из буфера 1, сдвинуть указатель, 2) отправить его в регистр SPDR на передачу, 3) прочитать из SPDR принятый по SPI байт, 4) записать принятый байт в буфер 2, сдвинуть указатель, 5) повторить п.п.1-4 для заданного количества байт. Мною написана программа, основной цикл которой выполняется за 8 тактов процессора. (Не хочу публиковать преждевременно. чтобы не смущать народ). Меня интересует, можно ли сделать еще быстрее или это предел? Ну и тоже самое для упрощенного програмного варианта, т.е. программное формирование импульсов синхронизации и бит данных только на передачу. Такая программа тоже написана. Цикл на передачу занимает 36 тактов процессора.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 12 2006, 16:31
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(KRS @ Jul 12 2006, 15:08)  Может вы имели ввиду не мегагерцы а такты? т.е программа выполняется за 36 тактов ( 4.5 такта на бит) МЦ - это сокращение слов Машинный Цикл. Я думал, это общепринято. Цитата(KRS @ Jul 12 2006, 15:08)  1 такт на бит не получить аппаратно мин прескалер равен 2 и получится 2 такта на бит Я в курсе, что максимальная частота клока равна половине тактовой. Скажем для тактовой частоты процессора в 10 МГц, можно получить 5 Мгц частоту сихронизации для SPI, тогда для передачи одного бита требуется 0,2 мкс, т.е. 2 МЦ(машинных цикла или такта), а для передачи байта потребуется 8*0,2=1,6 мкс или 16 МЦ. Все это делается аппаратно, но моя программа сохраняет принятый байт и передает новый байт за 8МЦ, остальные 8МЦ она простаивает. Если бы был второй SPI, можно было бы успеть и его обработать(:-). А так машина тратит 1 такт своего машинного времени на передачу/прием одного бита, ну и работает вхолостую половину времени. Цитата(KRS @ Jul 12 2006, 15:08)  пограммно теоретически максимум можно получить тоже 2 такта на бит, но только для отправки и отправлять например константу т.е тупо 16 раз записать в порт (не используя SBI CBI) Нет, это не интересно. Надо именно произвольные байты гонять туда-сюда.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 13 2006, 15:57
|
Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 5-05-06
Из: Ekaterinburg, Russia
Пользователь №: 16 821

|
А какие ограничения на использование регистров? Обязательно два буфера? Можно ли использовать прерывание SPI? Цитата 2) отправить его в регистр SPDR на передачу, 3) прочитать из SPDR принятый по SPI байт, хм, а не наоборот?
Сообщение отредактировал Yura_K - Jul 13 2006, 16:13
--------------------
Чудес не бывает - бывает мало знаний и опыта!
|
|
|
|
|
Jul 13 2006, 21:51
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(Yura_K @ Jul 13 2006, 14:57)  А какие ограничения на использование регистров? Обязательно два буфера? Можно ли использовать прерывание SPI? Все ресурсы МК в ваших руках, никаких ограничений. Два буфера не обязательно, можно один буфер. Можно использовать любые прерывания. Цитата(Yura_K @ Jul 13 2006, 14:57)  Цитата 2) отправить его в регистр SPDR на передачу, 3) прочитать из SPDR принятый по SPI байт,
хм, а не наоборот? Запись в регистр SPDR инициирует передачу по SPI. После окончания последовательной передачи 8-ми бит можно прочитать принятый байт из регистра SPDR. Можно сначала читать из регистра SPDR, а потом писать в регистр SPDR. Главное, чтобы было четкое понимание, что передается и что принимается. Что-то эксперты тяжело раскачиваются...не хотят делиться секретами мастерства(:-).
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 07:00
|
Частый гость
 
Группа: Участник
Сообщений: 177
Регистрация: 25-08-05
Из: Ставрополь
Пользователь №: 7 964

|
Цитата(Yura_K @ Jul 13 2006, 19:57)  2) отправить его в регистр SPDR на передачу, 3) прочитать из SPDR принятый по SPI байт, хм, а не наоборот? А что вы собственно читать из SPDR собрались до записи в него? Результат предыдущего сдвига? Принцип работы SPI - кольцевой регистр сдвига, пока мастер не инициировал передачу, слэйв ничего сам не отдаст. Поэтому все правильно - сначала пишем в SPDR, потом читаем.
|
|
|
|
|
Jul 14 2006, 11:59
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(ksv198 @ Jul 14 2006, 06:00)  Цитата(Yura_K @ Jul 13 2006, 19:57)  2) отправить его в регистр SPDR на передачу, 3) прочитать из SPDR принятый по SPI байт, хм, а не наоборот?
А что вы собственно читать из SPDR собрались до записи в него? Результат предыдущего сдвига? Принцип работы SPI - кольцевой регистр сдвига, пока мастер не инициировал передачу, слэйв ничего сам не отдаст. Поэтому все правильно - сначала пишем в SPDR, потом читаем. Как я уже сказал, не имеет значения, читать до записи или после, хотя после записи читать надо немедленно иначе данные могут быть переписаны. При чтении до записи самое первое чтение будет пустым, ну сделайте буфер на 1 байт больше и все. Поскольку эксперты не хотят делиться своими тайными приемами и трюками(:-), публикую первый вариант программы для аппаратного скоростного SPI, передача идет на предельно достижимой скорости fCLK/2, fCLK-тактовая частота процессора, один байт передается за 16 машинных циклов (МЦ). Регистровая пара Х указывает на начало передающего буфера, пара Y указывает на байт ПЕРЕД приемным буфером, txByte, rxByte - верхние регистры, скажем r16, r17.
Код spiLoop: <nop x 8 раз или другая задача на 8МЦ> ld txByte,X+ ;подготавливаем байт на передачу in rxByte,SPDR ;читаем принятый байт (первый байт-фиктивный) out SPDR,txByte ;запускаем байт на передачу st Y+,rxByte ;сохраняем принятый байт в приемном буфере rjmp spiLoop ;повторяем цикл
Как вы видите, ничего страшного и сложного. Ну вот, весь огонь принимаю на себя(:-).
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 12:19
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(=GM= @ Jul 14 2006, 17:59)  Поскольку эксперты не хотят делиться своими тайными приемами и трюками(:-), публикую первый вариант программы для аппаратного скоростного SPI, передача идет на предельно достижимой скорости fCLK/2, fCLK-тактовая частота процессора, один байт передается за 16 машинных циклов (МЦ). Регистровая пара Х указывает на начало передающего буфера, пара Y указывает на байт ПЕРЕД приемным буфером, txByte, rxByte - верхние регистры, скажем r16, r17.
Код spiLoop: <nop x 8 раз или другая задача на 8МЦ> ld txByte,X+;подготавливаем байт на передачу in rxByte,SPDR ;читаем принятый байт (первый байт-фиктивный) out SPDR,txByte ;запускаем байт на передачу st Y+,rxByte;сохраняем принятый байт в приемном буфере rjmp spiLoop ;повторяем цикл
Как вы видите, ничего страшного и сложного. Ну вот, весь огонь принимаю на себя(:-). В вашем примере отсутствует проверка готовности буферов приемника и передатчика. Нельзя записывать байт в буфер SPI до того как он освободится и/или не имеет смысла читать байт до того как он запишется в буфер SPI.
|
|
|
|
|
Jul 14 2006, 12:30
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(zltigo @ Jul 14 2006, 11:12)  Цитата(=GM= @ Jul 14 2006, 14:59)  Как я уже сказал, не имеет значения, читать до записи или после, хотя после записи читать надо немедленно иначе данные могут быть переписаны.
как Вам уже сказали, Вы элементарноь не понимаете элементарнейший принцип работы SPI :-( Могу это еще раз подтвердить. Ой, кто это(:-)? Кто же мне это сказал, и когда? Чего я там элементарного не понимаю? Всё я понимаю(:-). Но, учтите, задача стоит - достичь максимально возможной скорости передачи по SPI. Приведите внятное видение вами данной проблемы. Подтверждать не надо, надо доказывать, цифрами, программками, ссылками на документы...А так написать, я считаю, это просто гнилой наезд. Цитата(rezident @ Jul 14 2006, 11:19)  Цитата(=GM= @ Jul 14 2006, 17:59)  Поскольку эксперты не хотят делиться своими тайными приемами и трюками(:-), публикую первый вариант программы для аппаратного скоростного SPI, передача идет на предельно достижимой скорости fCLK/2, fCLK-тактовая частота процессора, один байт передается за 16 машинных циклов (МЦ). Регистровая пара Х указывает на начало передающего буфера, пара Y указывает на байт ПЕРЕД приемным буфером, txByte, rxByte - верхние регистры, скажем r16, r17.
Код spiLoop: <nop x 8 раз или другая задача на 8МЦ> ld txByte,X+;подготавливаем байт на передачу in rxByte,SPDR;читаем принятый байт (первый байт-фиктивный) out SPDR,txByte;запускаем байт на передачу st Y+,rxByte;сохраняем принятый байт в приемном буфере rjmp spiLoop ;повторяем цикл
Как вы видите, ничего страшного и сложного. Ну вот, весь огонь принимаю на себя(:-). В вашем примере отсутствует проверка готовности буферов приемника и передатчика. Нельзя записывать байт в буфер SPI до того как он освободится и/или не имеет смысла читать байт до того как он запишется в буфер SPI. Я привел фрагмент программы, основной цикл, который выполняется точно за то время, как передается (и принимается) байт по SPI. Зачем я его буду проверять на готовность, если я и так знаю, что он готов к приему следующего байта! и терять при этом драгоценные такты. Я НЕ записываю байт до того, как он освободится, я записываю в тот момент, когда он только что стал пустым. Точно также и с принятым байтом.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 12:39
|
Частый гость
 
Группа: Участник
Сообщений: 96
Регистрация: 24-09-05
Пользователь №: 8 901

|
Интересный подход. А остальная программа в момент приёма/передачи пакета ничего неделает. PC. Вафли ловит.
|
|
|
|
|
Jul 14 2006, 12:47
|
Частый гость
 
Группа: Участник
Сообщений: 177
Регистрация: 25-08-05
Из: Ставрополь
Пользователь №: 7 964

|
Цитата(=GM= @ Jul 14 2006, 15:59)  Как я уже сказал, не имеет значения, читать до записи или после, хотя после записи читать надо немедленно иначе данные могут быть переписаны. При чтении до записи самое первое чтение будет пустым, ну сделайте буфер на 1 байт больше и все. Имеет значение. Читать ДО записи нечего, а делать из-за этого буфер на 1 байт больше не имеет никакого смысла. Читать немедленно после записи тоже абсурдно. Зачем изобретать грабли? Порядок работы с SPI описан почти в каждом даташите АВРки имеющей такой модуль: - пишем байт в SPDR; - ждем установку SPIF в SPSR (это говорит нам о том, что процесс передачи байта мастера и приема байта слэйва завершен); - читаем SPDR. В вашем коде нет ожидания флага SPIF, поэтому может возникнуть коллизия (запись в SPDR во время передачи), о чем сигнализирует флаг WCOL регистра SPSR, или вы прочтете недостоверные данные. Еще раз повторюсь - SPI это по сути кольцевой 16 разрядный сдвиговый регистр, 8 бит - регистр мастера, 8 бит регистр слэйва. Сдвиг на один бит регистра мастера влечет за собой сдвиг на один бит регистра слэйва (каждый сдвиг тактируется SCK). И никаких тайных приемов и трюков.... Цитата(=GM= @ Jul 14 2006, 16:30)  Я привел фрагмент программы, основной цикл, который выполняется точно за то время, как передается (и принимается) байт по SPI. Зачем я его буду проверять на готовность, если я и так знаю, что он готов к приему следующего байта! и терять при этом драгоценные такты. Я НЕ записываю байт до того, как он освободится, я записываю в тот момент, когда он только что стал пустым. Точно также и с принятым байтом. Вы привели фрагмент программы которая правильно работать не будет. Не обижайтесь, просто посмотрите в любом даташите диаграмму "SPI Master-slave Interconnection" и вам все сразу станет понятно.
|
|
|
|
|
Jul 14 2006, 13:01
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(=GM= @ Jul 14 2006, 18:30)  Я привел фрагмент программы, основной цикл, который выполняется точно за то время, как передается (и принимается) байт по SPI. Зачем я его буду проверять на готовность, если я и так знаю, что он готов к приему следующего байта! и терять при этом драгоценные такты. Я НЕ записываю байт до того, как он освободится, я записываю в тот момент, когда он только что стал пустым. Точно также и с принятым байтом. Тады, ой! Я не обратил на этот факт внимание. Хотя все равно это чисто теоретический кусок кода, не имеющий практического применения. В реальности нужны еще кое-какие проверки, хотя бы на окончание буфера, выделенного для приемоперадачи или на количество байт заданных для чтения/записи.
|
|
|
|
|
Jul 14 2006, 13:25
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(unichorn @ Jul 14 2006, 11:39)  Интересный подход. А остальная программа в момент приёма/передачи пакета ничего не делает. PC. Вафли ловит. Да, ничего не делает, она сильно занята(:-)! Отсюда вытекает интереснейший вопрос. Щас я его попробую сформулировать, может его надо бы в отдельную ветку вынести, чтобы не перегружать, ну да ладно. Есть некая микроконтроллерная система, состоящая из нескольких МК, обменивающихся между собой, скажем по SPI. Как лучше сделать обмен, с точки зрения экономии производительности МК, по прерываниям или максимально быстрый программно-аппаратный обмен, как описано мною выше? Поясню на примере, что имею ввиду. Хотим передать 128 байт. При программно-аппаратном обмене мы потеряем 16*128=2048 МЦ. При обмене по прерываниям мы должны учесть вызов прерывания, сохранение/восстановление временного регистра и статуса, возврат из прерывания, плюс такое же тело подпрограммы, если ничего не забыл, то получается не менее 22 МЦ (это если регистры указателей закреплены за данным прерыванием!). Все это надо делать для каждого байта, так что, в сумме будет 22*128=2816 МЦ на каждый обмен. Еще надо учесть, что прерывания должны следовать каждые 22 МЦ, значит максимальная скорость передачи будет ниже. чем при программно-аппаратном обмене! Да еще не забыть, что есть запасные 8 МЦ в каждом цикле, стоит ими грамотно распорядиться(:-). Конечно, экономия копеешная, но иногда ее так не хватает! Вот такой философский вопрос по использованию и НЕ использованию прерываний где попало. Думайте сами, решайте сами, прерывать или не прерывать. И еще, маленькая просьба, пжлст, не пишите РС, если нет подписи, это моветон, не обижайтесь. Okey-dokey?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 13:40
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(rezident @ Jul 14 2006, 12:01)  Цитата(=GM= @ Jul 14 2006, 18:30)  Я привел фрагмент программы, основной цикл, который выполняется точно за то время, как передается (и принимается) байт по SPI. Зачем я его буду проверять на готовность, если я и так знаю, что он готов к приему следующего байта! и терять при этом драгоценные такты. Я НЕ записываю байт до того, как он освободится, я записываю в тот момент, когда он только что стал пустым. Точно также и с принятым байтом.
Тады, ой! Я не обратил на этот факт внимание. Хотя все равно это чисто теоретический кусок кода, не имеющий практического применения. В реальности нужны еще кое-какие проверки, хотя бы на окончание буфера, выделенного для приемоперадачи или на количество байт заданных для чтения/записи. Принято. Что касается проверок. Код приведен практически реальный. Можно было бы, конечно, поставить декремент счетчика байт (но считать можно было бы только до 256, а если мне надо передать 300?) и переход по условию, но тогда было бы 9 МЦ, а у меня 8! Кто может написать быстрее(:-)? Ну ладно, это у меня отпускные настроения разыгрались(:-). А по делу так. Устанавливаете таймер на прерывание точно после последнего переданного байта, вот вам и будет выход из цикла, останется только подчистить верхушку стека...Зато 8 МЦ! Кому они нужны, право? Ну скажем, можно сделать хороший джейтаг для отладки, на АВР с тактовой 20 МГц скорость может достигать 10 мбит/с.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 13:53
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Код <nop x 8 раз или другая задача на 8МЦ> spiLoop: ld txByte,X+;подготавливаем байт на передачу in rxByte,SPDR;читаем принятый байт (первый байт-фиктивный) out SPDR,txByte;запускаем байт на передачу st Y+,rxByte;сохраняем принятый байт в приемном буфере <nop x 6 раз или другая задача на 6МЦ> subi r16,1 sbci r17,0 brcc spiLoop;повторяем цикл Так потянет? 6 тактов в запасе. А в Оксфорде учитесь?
Сообщение отредактировал GetSmart - Jul 14 2006, 13:58
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 14 2006, 13:55
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
=GM=, есть несколько нюансов в описываемой вами схеме. Цитата Есть некая микроконтроллерная система, состоящая из нескольких МК, обменивающихся между собой, скажем по SPI. Как лучше сделать обмен, с точки зрения экономии производительности МК, по прерываниям или максимально быстрый программно-аппаратный обмен, как описано мною выше? В чем смысл гонять данные с максимальной скоростью? А обрабатывать их до/во время/после обмена не нужно? Что приоритетней, задача выполняемая МК или обмен данными? А оба МК будут успевать подавать данные на конвейер синхронного интерфейса? Или достоверность данных вас особо не волнует? Отсюда наверное и будет решение по прерыванию или в цикле организовывать обмен по SPI. Я бы не стал столь рискованно (на пределе возможного) организовывать обмен даже двух МК. Вот если МК и DataFlash с аппаратным конвейером SPI, то это пожалуйста. предложенный вами кусок кода вполне можно имплантировать в программу.
|
|
|
|
|
Jul 14 2006, 14:50
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(rezident @ Jul 14 2006, 12:55)  =GM=, есть несколько нюансов в описываемой вами схеме. Цитата Есть некая микроконтроллерная система, состоящая из нескольких МК, обменивающихся между собой, скажем по SPI. Как лучше сделать обмен, с точки зрения экономии производительности МК, по прерываниям или максимально быстрый программно-аппаратный обмен, как описано мною выше? В чем смысл гонять данные с максимальной скоростью? Конечно, нюансы есть везде. Чёрт, как известно, сидит в деталях(:-). А в чем смысл их гонять с минимальной скоростью(:-)? Выше я показал на примере, что при максимальной скорости есть некая экономия производительности МК. Цитата(rezident @ Jul 14 2006, 12:55)  А обрабатывать их до/во время/после обмена не нужно? Что приоритетней, задача выполняемая МК или обмен данными? А оба МК будут успевать подавать данные на конвейер синхронного интерфейса? Или достоверность данных вас особо не волнует? Ну, типовой АВР не потянет обработать на такой скорости, увы. Вопрос в другом, что лучше ИЛИ быстро принять пакет, затрачивая минимум производительности, ведь последовательная передача - это непроизводственные затраты, и затем обработать принятый пакет? Во многих протоколах нельзя обработать пакет, не приняв его целиком. ИЛИ же обрабатывать пакет побайтно, теряя на производительности, и принимая решение на ходу? Цитата(rezident @ Jul 14 2006, 12:55)  А оба МК будут успевать подавать данные на конвейер синхронного интерфейса? Ну вы же видите, что программа успевает и принять байт и передать его. А следующая передача может случиться через секунду. Ну вот скажем, вы делаете систему тестирования, вы принимаете байты из LPT ПК и хотите передать в JTAG, для проверки некой микросхемы или платы, используя пограничное сканирование. Что вы предпочтете, медленно заталкивать биты в последовательные регистры нескольких микросхем или быстро? Ответ очевиден, быстро (насколько позволяет система) затолкнуть скажем 600 бит, подождать процесса установления, затем протестировать... Цитата(rezident @ Jul 14 2006, 12:55)  Отсюда наверное и будет решение по прерыванию или в цикле организовывать обмен по SPI. Я бы не стал столь рискованно (на пределе возможного) организовывать обмен даже двух МК. Вот если МК и DataFlash с аппаратным конвейером SPI, то это пожалуйста. предложенный вами кусок кода вполне можно имплантировать в программу. Спасибо. Пользуйтесь, мне не жалко. Ну я тоже не сторонник работать на пределе. Жизнь иногда заставляет. Проект был - асик с доморощенным интерфейсом 5 Мбит/с с точностью до 10 нс, передается команда, затем переключение на прием, принимается 32 бита данных, что делать? А я еще клювом прощелкал, мог бы поработать с людьми, изменить интерфейс, асик был заказной, под нас делали..Пришлось извиваться. Сейчас из 150 мкс обмен занимает 35 мкс! Да я ДПФ делаю за 70 мкс! Цитата(GetSmart @ Jul 14 2006, 12:53)  Код spiLoop: ld txByte,X+;подготавливаем байт на передачу in rxByte,SPDR;читаем принятый байт (первый байт-фиктивный) out SPDR,txByte;запускаем байт на передачу st Y+,rxByte;сохраняем принятый байт в приемном буфере <nop x 6 раз или другая задача на 6МЦ> subi r16,1 sbci r17,0 brcc spiLoop;повторяем цикл Так потянет? 6 тактов в запасе. Нормально, Григорий(:-). Хотя у вас 10 МЦ, а в исходной проге было 8 МЦ. Цитата(GetSmart @ Jul 14 2006, 12:53)  А в Оксфорде учитесь? Не, работаю. Занесло вот в ЮКей. Не каждый московский голубь долетит до середины Ламанша(:-).
Сообщение отредактировал =GM= - Jul 14 2006, 14:49
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 14:58
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата Нормально, Григорий(:-). Хотя у вас 10 МЦ, а в исходной проге было 8 МЦ. Я всего-то заменил два NOPа на SUBI+SBCI. Может вы сами просчитались? В вашей проге было 16 МЦ и в моей 16. Отлично, Константин.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 14 2006, 15:16
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(GetSmart @ Jul 14 2006, 13:58)  Цитата Нормально, Григорий(:-). Хотя у вас 10 МЦ, а в исходной проге было 8 МЦ. Я всего-то заменил два NOPа на SUBI+SBCI. Может вы сами просчитались? В вашей проге было 16 МЦ и в моей 16. Немного не так. Цикл исполняется за 16 МЦ, эт-да, нельзя ни убавить, ни прибавить. Но сама прога, вместе с командой перехода занимает 8 МЦ, следовательно, я могу что-то сделать полезное в оставшиеся 8 МЦ. Скажем, передаю 16 байт и одновременно осуществляю распределенное деление 16/16 (как часть другой задачи). Ну или умножение 16*16, не важно. Важно, что время даром не пропадает. Еще можно чего-нить по медленному программному RS-232C передавать, да мало ли что. А когда Атмел поставит второй SPI, то можно было бы и его задействовать на такой же скорости, в то же самое время! Цитата(GetSmart @ Jul 14 2006, 13:58)  Отлично, Константин. Очень приятно, Костя, меня зовут Джордж, GM это мои инициалы.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 15:32
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
1. А кто тогда Георгий? 2. А когда у вас в цикле стоит бесконечный цикл, это по-вашему в порядке вещей. И ещё ремарка, что можно даром время не терять, но считать кол-во переданных байт мы не будем из принципа. ЗЫ. Эффект от "извращений" пропорционален скорости проца, ну и его стоимости. Для АВРа как-то мелко получается. Цитата Важно, что время даром не пропадает. Ну так определитесь что будете делать уже. А то я могу ещё 2 МЦ в копилку добавить. А если очень захотите, то и передавать на 8 других процессоров одновременно.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 14 2006, 15:57
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(GetSmart @ Jul 14 2006, 14:32)  1. А кто тогда Георгий? Какой Георгий? А-а, Григорий! Это из юморески ММЖ, вы там просто смайлик не заметили! А вообще у меня Джордж-джуниор, т.е. Георгий, подрастает. Цитата(GetSmart @ Jul 14 2006, 14:32)  2. А когда у вас в цикле стоит бесконечный цикл, это по-вашему в порядке вещей. И ещё ремарка, что можно даром время не терять, но считать кол-во переданных байт мы не будем из принципа. Ну уже ответил, см. пост №19, отвечу здесь. Устанавливаете таймер на прерывание точно после последнего переданного байта, вот вам и будет выход из цикла, останется только подчистить верхушку стека...Вот вам и 8 МЦ, вместо 9 или ваших 10! Цитата(GetSmart @ Jul 14 2006, 14:32)  ЗЫ. Эффект от "извращений" пропорционален скорости проца, ну и его стоимости. Для АВРа как-то мелко получается. Это я не понимаю, это не ко мне. Цитата(GetSmart @ Jul 14 2006, 14:32)  Цитата Важно, что время даром не пропадает. Ну так определитесь что будете делать уже. А то я могу ещё 2 МЦ в копилку добавить. А если очень захотите, то и передавать на 8 других процессоров одновременно. Вот интересно, покажите, как это сделать. На 8 процессоров тоже интересно (теоретически). Но думаю вы шутите, это какое-то чудо передать на 8 процов одновременно на скорости 10 мбит/с. Надеюсь, передается индивидуальная для каждого проца информация?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 16:16
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата Надеюсь, передается индивидуальная для каждого проца информация? Ну разумээтся. Не чудо. Только в одну сторону. Ну и со скоростью 6.666 мбит. Так ведь можно? (делитель 1/3) Ну или 1/4. Подумайте денёк. Может догадаетесь. Цитата Не каждый московский голубь долетит до середины Ламанша(:-) Хммм... Хотя постойте. Принимать-таки можно. Можно с одного. А можно с одного из восьми. Ну или со скольки угодно. Пардон. 6.666 МБАЙТ.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jul 14 2006, 16:27
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(GetSmart @ Jul 14 2006, 15:16)  Цитата Надеюсь, передается индивидуальная для каждого проца информация? Ну разумээтся. Не чудо. Только в одну сторону. Ну и со скоростью 6.666 мбит. Так ведь можно? (делитель 1/3) Ну или 1/4. Подумайте денёк. Может догадаетесь. Пардон. 6.666 МБАЙТ. Прошу пардону. Дайте постановку задачи. Что за делитель, что за 6,(6)Мбайт...
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jul 14 2006, 17:21
|
Частый гость
 
Группа: Свой
Сообщений: 185
Регистрация: 5-05-06
Из: Ekaterinburg, Russia
Пользователь №: 16 821

|
2 ksv198 Цитата Поэтому все правильно - сначала пишем в SPDR, потом читаем. Чего-то я не допираю, счего вдруг сначала писать, а потом читать. Тем не менее мой вариант: Код ld r19,X _spi_loop: in r18,SPDR ;1 out SPDR,r19 ;1 st X+,r18 ;2 ld r19,X ;2 _spi_wait_spif: sbis SPSR,SPIF ;1 2 rjmp _spi_wait_spif;2 dec r16 ;1 brne _spi_loop ;2 1 итого: Замечу, что проверка флага - вышло неудачно. 6 nop у GetSmart эффективнее 2 =GM= Цитата Нормально, Григорий(:-). Хотя у вас 10 МЦ, а в исходной проге было 8 МЦ. Зато у GetSmart с проверкой количества байт. P.S. Приведенный код может содержать ошибки, укажите пожалуйста если таковые будут обнаружены. P.P.S. Мне вообще кажется, что довольно трудно оптимизировать программу на RISC, кроме случаев когда она писалась бездумно  .
--------------------
Чудес не бывает - бывает мало знаний и опыта!
|
|
|
|
|
Jul 15 2006, 06:02
|
Частый гость
 
Группа: Участник
Сообщений: 177
Регистрация: 25-08-05
Из: Ставрополь
Пользователь №: 7 964

|
2'=GM= Пришел домой, подумал внимательно и понял свою ошибку, признаю, извиняюсь. Ваш вариант рабочий 100%. Меня сбили с толку ваши фразы типа ...читать до записи или после.. и ...после записи читать надо немедленно иначе данные могут быть переписаны... Последнюю фразу до сих пор не пойму А что касается прерываний, так ведь никто и не говорил никогда, что с ними всегда быстрее - просто иногда удобнее.
|
|
|
|
|
Jul 15 2006, 17:21
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(ksv198 @ Jul 15 2006, 05:02)  2'=GM= Пришел домой, подумал внимательно и понял свою ошибку, признаю, извиняюсь. Ваш вариант рабочий 100%. Принято. Цитата(ksv198 @ Jul 15 2006, 05:02)  Меня сбили с толку ваши фразы типа ...читать до записи или после.. и ...после записи читать надо немедленно иначе данные могут быть переписаны... Последнюю фразу до сих пор не пойму А что касается прерываний, так ведь никто и не говорил никогда, что с ними всегда быстрее - просто иногда удобнее. Фраза немного туманная, согласен. Понимать её надо так. Непосредственно после записи в порт начнется последовательное выталкивание битов, ну и соответственно вталкивание принимаемых битов. Если нет двойного буферирования (у современных АВРок оно вроде есть), то может случиться потеря принятого байта (сам я не проверял, где-то в даташитах прочитал, может и напутал чего). Короче говоря, у вас гарантированно есть 2 МЦ, чтобы считать предыдущие данные из приемного буфера. Если у кого есть под рукой железяка, можете проверить. Да, с прерываниями удобно, но иногда искусство пограммирования (т.е.скорость исполнения кода(:-) требует жертв.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|