реклама на сайте
подробности

 
 
> Готовность SPI, как определить?
777777
сообщение May 20 2008, 08:00
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Как определить, что в SPDR можно писать очередной байт? SPIF устанавливается после передачи, но после обработки сбрасывается, и при включении там 0. А есть ли какой бит, по которому можно определить, что передача в данный момент не идет? Т.е. который устанавливается сразу после записи в SPDR?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Maik-vs
сообщение May 20 2008, 09:38
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101



Цитата(777777 @ May 20 2008, 12:00) *
Как определить, что в SPDR можно писать очередной байт? SPIF устанавливается после передачи, но после обработки сбрасывается, и при включении там 0. А есть ли какой бит, по которому можно определить, что передача в данный момент не идет? Т.е. который устанавливается сразу после записи в SPDR?

Чего-то напутано. "Сразу после записи в SPDR" передача как раз идёт. Если записать в SPDR пока передача идёт, поднимется флаг WCOL. Писать в SPDR можно через 34 цикла процессора после предыдущей записи (SPCR=0x50). Раньше - синхроимпульсы будут, а данные - нет. Прямо сейчас этим занимаюсь, Мега16. AVR Studio всё правильно симулирует.
Go to the top of the page
 
+Quote Post
777777
сообщение May 20 2008, 10:45
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Maik-vs @ May 20 2008, 13:38) *
Чего-то напутано. "Сразу после записи в SPDR" передача как раз идёт.


Вот я и хочу узнать, когда она закончится. Не используя прерываний, по готовности. Похоже, только читая SPIF и ожидая когда он исчезнет.

А хотелось бы наоборот: перед записью узнать что предыдущая передача уже завершилась, записать SPDR и продолжить заниматься другими делами.

Сообщение отредактировал 777777 - May 20 2008, 11:09
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 20 2008, 13:41
Сообщение #4


Ambidexter
*****

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



Цитата(777777 @ May 20 2008, 09:45) *
Похоже, только читая SPIF и ожидая когда он исчезнет

А по-моему, наоборот, флаг SPIF появится, когда закончится передача текущего байта. Для самого первого раза (после подачи питания) можно передать фиктивную посылку, чтобы взвести флаг SPIF.
Цитата(777777 @ May 20 2008, 09:45) *
А хотелось бы наоборот: перед записью узнать что предыдущая передача уже завершилась, записать SPDR и продолжить заниматься другими делами

Делаете, как описано выше, потом проверяете флаг SPIF, если он установлен, то записываете в SPDR новый байт на передачу, при этом флаг SPIF сбросится.

Цитата(Maik-vs @ May 20 2008, 08:38) *
Писать в SPDR можно через 34 цикла процессора после предыдущей записи (SPCR=0x50). Раньше - синхроимпульсы будут, а данные - нет

Откуда вы взяли про 34 цикла, ссылочкой не поделитесь? И что такое SPCR=0x50, в нём вроде используются только 0, 6 и 7 биты?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 20 2008, 16:26
Сообщение #5


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(=GM= @ May 20 2008, 17:41) *
А по-моему, наоборот, флаг SPIF появится, когда закончится передача текущего байта. Для самого первого раза (после подачи питания) можно передать фиктивную посылку, чтобы взвести флаг SPIF.
конечно после окончания передачи, и поэтому буз внешнего флага здесь не обойтись.
Ну типа так он устроен...
Цитата
Откуда вы взяли про 34 цикла
Ну это почти правда, только там не 34 smile.gif
ну и для других делителей будет другое количество тактов,
сам пробовал в железе только для X2 режима, но с Вами поделюсь инфой только после
того как Вы раскажите/покажите вариант про который мы долго и упорно
спорили(PWM на 24 канала) smile.gif
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 20 2008, 16:55
Сообщение #6


Ambidexter
*****

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



Цитата(singlskv @ May 20 2008, 15:26) *
конечно после окончания передачи, и поэтому без внешнего флага здесь не обойтись. Ну типа так он устроен...
Ну это почти правда, только там не 34

Я и так знаю, что там не 34. Как устроен спи внутри, к сожалению, не знаю. Что такое внешний флаг, не понимаю, о чём вы? То, что я сказал насчёт первого фиктивного байта правильно, но можно обойтись и без его передачи.

Если уж взялись отвечать за другого, так и отвечайте нормально, а не наводите тень на плетень (:-). Повторю ещё раз: "Откуда вы взяли про 34 цикла, ссылочкой не поделитесь? И что такое SPCR=0x50, в нём вроде используются только 0, 6 и 7 биты?"

Цитата(singlskv @ May 20 2008, 15:26) *
сам пробовал в железе только для X2 режима, но с Вами поделюсь инфой только после того как Вы раскажите/покажите вариант про который мы долго и упорно спорили (PWM на 24 канала)

Sulking, are we (:-)? Напомните, подзабыл я, и вроде бы с вами не спорил, тем более долго и упорно, поскольку вы были не в теме.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 20 2008, 17:29
Сообщение #7


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(=GM= @ May 20 2008, 20:55) *
Я и так знаю, что там не 34. Как устроен спи внутри, к сожалению, не знаю.
Что такое внешний флаг, не понимаю, о чём вы?
просто переменная в памяти которая будет говорить всем что SPI в данный момент занят
Цитата
То, что я сказал насчёт первого фиктивного байта правильно, но можно обойтись и без его передачи.
А вот здесь я уже недопонял...
Цитата
Если уж взялись отвечать за другого, так и отвечайте нормально, а не наводите тень на плетень (:-). Повторю ещё раз: "Откуда вы взяли про 34 цикла, ссылочкой не поделитесь? И что такое SPCR=0x50, в нём вроде используются только 0, 6 и 7 биты?"
Sulking, are we (:-)? Напомните, подзабыл я, и вроде бы с вами не спорил, тем более долго и упорно, поскольку вы были не в теме.
Да ни вапрос, в отличии от Вас готов просто показать код... smile.gif
Код
  SPDR = OutHi;                    // старшая часть выходов
758:    6f b8           out    0x0f, r6; 15
    ...
  __asm__ __volatile__ ("nop"); // бездельничаем пока передается байт
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
  __asm__ __volatile__ ("nop");
776:    00 00           nop
  Ch2Hi = SPSR;                    // читаем для сброса флага
778:    2e b0           in    r2, 0x0e; 14
  Ch2Hi = SPDR;                    // читаем старшие 8 бит канала2
77a:    2f b0           in    r2, 0x0f; 15

но это для X2 режима...
Go to the top of the page
 
+Quote Post
Qwertty
сообщение May 20 2008, 19:36
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Цитата(singlskv @ May 20 2008, 21:29) *
Код
    ...
  __asm__ __volatile__ ("nop"); // бездельничаем пока передается байт

но это для X2 режима...

Так весь смысл в том, чтоб вместо бездельничья занять контроллер чем то более полезным. Например при подключении индикатора по SPI, где ответа нет. Я делаю с передачей холостого байта при неактивном /cs. Положил в SPDR и пошел готовить следующие данные. Как обойтись без холостой записи надеюсь подскажет GM. А вообще в этом плане хорошо использовать USART в тех контроллерах, в которых есть этот режим. Там получается буферизация записи и можно по паре байт отправлять за один раз. Ну и с флагами там все не так запущено...
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 22 2008, 17:08
Сообщение #9


Ambidexter
*****

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



Цитата(Qwertty @ May 20 2008, 18:36) *
Я делаю с передачей холостого байта при неактивном /cs. Положил в SPDR и пошел готовить следующие данные. Как обойтись без холостой записи надеюсь подскажет GM

Подсказываю, вот так, например, можно делать обмен по спи по прерываниям
Код
spistc: in     temp3,spdr       ;
        st     x+,temp3         ;
spist1: in     tmpsta,SREG      ;
        cpi    xl,low(eobuf)+1  ;end of buffer?
        breq   spist2           ;yes, it is
        ld     temp3,x          ;send current
        out    spdr,temp3       ;byte
spist2: out    SREG,tmpsta      ;
        reti

Принятые байты замещают в буфере переданные. Инициируется обмен вызовом rcall spist1


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 22 2008, 21:53
Сообщение #10


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(=GM= @ May 22 2008, 21:08) *
Подсказываю, вот так, например, можно делать обмен по спи по прерываниям
Код
spistc: in     temp3,spdr      ;
        st     x+,temp3        ;
spist1: in     tmpsta,SREG     ;
        cpi    xl,low(eobuf)+1 ;end of buffer?
        breq   spist2          ;yes, it is
        ld     temp3,x         ;send current
        out    spdr,temp3      ;byte
spist2: out    SREG,tmpsta     ;
        reti

Принятые байты замещают в буфере переданные. Инициируется обмен вызовом rcall spist1
Повторное использование кода(начало посылки через rcall spist1) выглядит красиво.
Но к сожалению на С неприменимо, нужно писать отдельно старт транзакции.
Ну и для максимума скорости, ИМХО, такое прерывание не очень, при выборе SPI2X(Focs/2)
самым большим тормозом становится время входа/выхода в прерывание
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 22 2008, 23:09
Сообщение #11


Ambidexter
*****

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



Цитата(singlskv @ May 22 2008, 20:53) *
Повторное использование кода (начало посылки через rcall spist1) выглядит красиво

Спасибо, не бог весть что, конечно, но это я сам придумал. Я бы сказал, что это не повторное использование, а именно запуск передачи пакета байт из буфера.
Цитата(singlskv @ May 22 2008, 20:53) *
Но к сожалению на С неприменимо, нужно писать отдельно старт транзакции

На си можно попробовать задействовать оператор свич на две позиции.
Цитата(singlskv @ May 22 2008, 20:53) *
Ну и для максимума скорости, такое прерывание не очень, при выборе SPI2X(Focs/2) самым большим тормозом становится время входа/выхода в прерывание

Да вроде нет, тело прерывания выполняется максимум за 14МЦ + 6-7 на вход, всего 20-21, а на передачу одного байта по спи на максимальной скорости Fclk/2 требуется минимум 17МЦ.

И небольшое увеличение времени передачи пакета окупается большим ПЛЮСОМ: положили данные в буфер, толкнули обмен, занялись другими делами, прошло некое время, проверили указатель буфера, забрали принятые данные и всё. А если не требуется приёма данных, то на прерывание потребуется 17-18МЦ. Так что прерывания будут идти практически непрерывно и проверять ничего не надо (:-).

Кстати, в вашем фрагменте снимать флаг прерывания в конце транзакции совсем не обязательно.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 23 2008, 18:46
Сообщение #12


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(=GM= @ May 23 2008, 03:09) *
Спасибо, не бог весть что, конечно, но это я сам придумал. Я бы сказал, что это не повторное использование, а именно запуск передачи пакета байт из буфера.
Ну здесь как раз понравилось именно повторное использование, такой
запуск вполне стандартен и понятен, но вот то что это удалось красиво
вписать прямо в код прерывания....
Цитата
На си можно попробовать задействовать оператор свич на две позиции.
к сожалению оверхед который при этом будет на С убивает саму идею.
Цитата
Да вроде нет, тело прерывания выполняется максимум за 14МЦ + 6-7 на вход, всего 20-21, а на передачу одного байта по спи на максимальной скорости Fclk/2 требуется минимум 17МЦ.
Я не очень точно выразился говоря про вход/выход из прерывания,
то есть вход/выход это первопричина а в сумме на производительность будет больше
всего влиять разница в тактах между:
in temp3,spdr ;
......
out spdr,temp3 ;byte
для Вашего варианта, при непрерывном трансфере большого куска, на передачу
одного байта будет >20-21 тактов
Цитата
И небольшое увеличение времени передачи пакета окупается большим ПЛЮСОМ: положили данные в буфер, толкнули обмен, занялись другими делами, прошло некое время, проверили указатель буфера, забрали принятые данные и всё. А если не требуется приёма данных, то на прерывание потребуется 17-18МЦ. Так что прерывания будут идти практически непрерывно и проверять ничего не надо (:-).

Для "общих" случаев обмена по SPI Ваш вариант видимо практически идеален...
Для частных, большой вопрос, тот кусочек кода который я привел был частным случаем,
я его привел только для того чтобы показать сколько ТОЧНО длится передача по SPI.
Цитата
Кстати, в вашем фрагменте снимать флаг прерывания в конце транзакции совсем не обязательно.

А вот этот вопрос для меня остается загадкой, дело в том что железки на которой работает этот
код я никогда не видел 07.gif
более того, в моем коде такие куски повторяются несколько раз подряд,
те байтики шлются непрерывно(4 штуки)
ну и первоначально предполагалось войти в прерывание и принять 4 байта, а при
этом сброс флага обязателен.
Ну и в конечном итоге чтение SPSR заменяет всего-лишь еще один "nop" smile.gif
Потом концепция чуть изменилась, НО, я на самом деле не знаю нужно ли читать SPSR
для запуска новой передачи, даташит на этот счет молчит а натурных испытаний не
попалось....

Да, еще добавлю на всякий случай, вход в прерывание для SPI есть суть
чтение SPSR с сбросом SPIF.
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 24 2008, 00:25
Сообщение #13


Ambidexter
*****

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



Цитата(singlskv @ May 23 2008, 17:46) *
Для частных, большой вопрос, тот кусочек кода который я привел был частным случаем,
я его привел только для того чтобы показать сколько ТОЧНО длится передача по SPI

Ну вот, родил специально для вашего частного случая
Код
;Обмен данными по SPI на максимальной скорости Fclk/2
spist1: in   temp1,spdr  ;принятый байт
spistc: out  spdr,temp2  ;передадим текущий байт
        st   x+,temp1    ;запомним принятый байт
        andi xl,0x10     ;коррекция указателя
        ld   temp2,x     ;прочитаем
        nop              ;следующий байт
        nop              ;из циклического
        nop              ;буфера
        nop              ;период выдачи
        nop              ;байт на Fclk/2
        nop              ;должен быть
        nop              ;18 МЦ, необходимо
        nop              ;проверить
        dec  bcounter    ;все байты?
        brne spist1      ;нет
        ret

Здесь две особенности, первая то, что работает точно на Fclk/2, вторая - используется циклический буфер на 16 байт (можно настроить на любой размер кратный степени 2), поэтому не надо задумываться, куда писать или откуда читать. Надо только зарядить bcounter<16 и использовать для чтения из буфера команду ld temp1,-x. Немного непривычно, но когда освоишься, получается компактный код. Можно и нулём останавливать передачу, место есть...

Вызов, как предложил defunct
Код
       ld    temp2,x
       rcall spistc

В железе не проверял, но вроде должно работать.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 777777   Готовность SPI   May 20 2008, 08:00
- - Dog Pawlowa   Цитата(777777 @ May 20 2008, 11:00) Как о...   May 20 2008, 08:12
- - singlskv   Цитата(777777 @ May 20 2008, 12:00) Как о...   May 20 2008, 08:23
|- - Maik-vs   Цитата(777777 @ May 20 2008, 14:45) Вот я...   May 20 2008, 13:01
||- - singlskv   Цитата(Qwertty @ May 20 2008, 23:36) Так ...   May 20 2008, 20:04
|||- - Qwertty   Цитата(singlskv @ May 21 2008, 00:04) А в...   May 20 2008, 21:50
|||- - singlskv   Цитата(Qwertty @ May 21 2008, 01:50) Про ...   May 20 2008, 21:59
||- - =GM=   Цитата(Qwertty @ May 20 2008, 18:36) Я де...   May 21 2008, 12:00
||- - defunct   Цитата(singlskv @ May 23 2008, 21:46) Ну ...   May 23 2008, 19:15
|||- - singlskv   Цитата(defunct @ May 23 2008, 23:15) Что ...   May 23 2008, 19:34
|||- - defunct   Цитата(singlskv @ May 23 2008, 22:34) Ну ...   May 23 2008, 22:24
|- - Maik-vs   Цитата(=GM= @ May 20 2008, 17:41) Откуда ...   May 21 2008, 12:49
- - defunct   SPI генерит прерывание, сигнализирующее о том, что...   May 20 2008, 09:57
- - Qwertty   А ответы нужны?   May 20 2008, 10:59
- - ILYAUL   Не очень понял зачем SREG сохранять   May 22 2008, 17:19
|- - =GM=   Команда cpi портит флаги в прерывании.   May 22 2008, 21:29
- - Qwertty   Отпишусь тут. Сегодня помучал SPI. Узнал много нов...   Nov 13 2008, 16:47
- - Maik-vs   Цитата(Qwertty @ Nov 13 2008, 19:47) Отпи...   Nov 13 2008, 19:45
- - Qwertty   Цитата(Maik-vs @ Nov 13 2008, 22:45)...   Nov 13 2008, 21:16


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 12:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.01574 секунд с 7
ELECTRONIX ©2004-2016