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

 
 
> Готовность 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
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 30)
Dog Pawlowa
сообщение May 20 2008, 08:12
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



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

Код
uchar SpiReadWrite(uchar data)
{    // set data to send into SPI data register
    SPDR = data;
    // Wait for transmission complete
    while(!(SPSR & (1<<SPIF)));
    // return data read from SPI
    return SPDR;
}


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 20 2008, 08:23
Сообщение #3


дятел
*****

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



Цитата(777777 @ May 20 2008, 12:00) *
Как определить, что в SPDR можно писать очередной байт? SPIF устанавливается после передачи, но после обработки сбрасывается, и при включении там 0. А есть ли какой бит, по которому можно определить, что передача в данный момент не идет? Т.е. который устанавливается сразу после записи в SPDR?
ИМХО, ни как, но если очень надо, заведите свой флаг который будете
выставлять перед записью в SPDR и сбрасывать после чтения SPIF из SPSR.
Go to the top of the page
 
+Quote Post
Maik-vs
сообщение May 20 2008, 09:38
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 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
defunct
сообщение May 20 2008, 09:57
Сообщение #5


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



SPI генерит прерывание, сигнализирующее о том, что передача завершена.
Go to the top of the page
 
+Quote Post
777777
сообщение May 20 2008, 10:45
Сообщение #6


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

Группа: Участник
Сообщений: 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
Qwertty
сообщение May 20 2008, 10:59
Сообщение #7


Местный
***

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



А ответы нужны?
Go to the top of the page
 
+Quote Post
Maik-vs
сообщение May 20 2008, 13:01
Сообщение #8


Местный
***

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



Цитата(777777 @ May 20 2008, 14:45) *
Вот я и хочу узнать, когда она закончится. Не используя прерываний, по готовности. Похоже, только читая SPIF и ожидая когда он исчезнет.

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

"перед записью узнать что предыдущая передача уже завершилась" Как? "читая SPIF". Прочитали - узнали - не завершилась. Что делать? "читая SPIF и ожидая когда он исчезнет". Ну или прерывание скажет, когда.
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 20 2008, 13:41
Сообщение #9


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
Сообщение #10


дятел
*****

Группа: Свой
Сообщений: 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
Сообщение #11


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
Сообщение #12


дятел
*****

Группа: Свой
Сообщений: 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
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 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
singlskv
сообщение May 20 2008, 20:04
Сообщение #14


дятел
*****

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



Цитата(Qwertty @ May 20 2008, 23:36) *
Так весь смысл в том, чтоб вместо бездельничья занять контроллер чем то более полезным.
Ну... это был просто пример для разяснения того как работает SPI,
хотя пример был из рабочей проги .... smile.gif Ну типа иногда(если нет других дел), выгоднее просто
ничего не делать...
Цитата
Например при подключении индикатора по SPI, где ответа нет. Я делаю с передачей холостого байта при неактивном /cs.
А вот это мне все-таки кто-нить объясните, что за холостой байт который Многим нужен ?
Go to the top of the page
 
+Quote Post
Qwertty
сообщение May 20 2008, 21:50
Сообщение #15


Местный
***

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



Цитата(singlskv @ May 21 2008, 00:04) *
А вот это мне все-таки кто-нить объясните, что за холостой байт который Многим нужен ?

Про это выше написано - холостая посылка, только для взвода SPIF. Просто записать в SPDR что попало, при неактивных cs. Я пишу сразу после настройки SPI. Далее примерно так:
Код
void TransmitSPI(uint8_t _data_)
{
while(!(SPSR & (1<<SPIF)));
SPDR = _data_;
// Завершения не ждем.
}
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 20 2008, 21:59
Сообщение #16


дятел
*****

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



Цитата(Qwertty @ May 21 2008, 01:50) *
Про это выше написано - холостая посылка, только для взвода SPIF. Просто записать в SPDR что попало, при неактивных cs. Я пишу сразу после настройки SPI. Далее примерно так:
Спасибо, теперь понял о чем речь, просто для меня такой
вариант не очень применим, поэтому и не мог никак въехать про какую такую
холостую посылку речь.
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 21 2008, 12:00
Сообщение #17


Ambidexter
*****

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



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

Рецепта на все случаи нет, чуть позже могу показать один вариант, щас немного занят буду. А для разгона покажите код, где вы выводите данные по эспиай. Вы по прерываниям выводите или по готовности?


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


Местный
***

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



Цитата(=GM= @ May 20 2008, 17:41) *
Откуда вы взяли про 34 цикла, ссылочкой не поделитесь? И что такое SPCR=0x50, в нём вроде используются только 0, 6 и 7 биты?


Ссылочкой не поделюсь, т.к. 34 - число, добытое честным экспериментом. Для SPCR=0x50: SPE и MSTR, остальные биты =0, т.е. коэффициент деления 1. Для других коэффициентов, наверное, не 34, поэтому и привёл значение SPCR. AVR Studio это дело симулирует правильно: если между "out SPDR" 34 цикла, передаются байты с промежуткосм в 1 бит. Если меньше - стробы есть, а на линии данных стоит высокий уровеь. Это видел в осциллографе. Частота кварца 20 МГц, МК mega16.
Да, разумеется, SPIF взводится по концу передачи байта. Не понимаю, в чём проблема у топикстартера - можно работать в прерывании, можно - опрашивая флаг, как всегда...
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 22 2008, 17:08
Сообщение #19


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
ILYAUL
сообщение May 22 2008, 17:19
Сообщение #20


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

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Не очень понял зачем SREG сохранять


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 22 2008, 21:29
Сообщение #21


Ambidexter
*****

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



Команда cpi портит флаги в прерывании.


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


дятел
*****

Группа: Свой
Сообщений: 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
Сообщение #23


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
Сообщение #24


дятел
*****

Группа: Свой
Сообщений: 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
defunct
сообщение May 23 2008, 19:15
Сообщение #25


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(singlskv @ May 23 2008, 21:46) *
Ну здесь как раз понравилось именно повторное использование, такой
запуск вполне стандартен и понятен, но вот то что это удалось красиво
вписать прямо в код прерывания....

Что делает такой вызов небезопасным.
Это хак и ничего красивого в этом нет.

разве такой старт был бы чем-то хуже?
Код
.macro StartSpiTransfer
       ld    temp3,x;send current
       out    spdr,temp3;byte
.end macro
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 23 2008, 19:34
Сообщение #26


дятел
*****

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



Цитата(defunct @ May 23 2008, 23:15) *
Что делает такой вызов небезопасным.
Это хак и ничего красивого в этом нет.

разве такой старт был бы чем-то хуже?
Код
.macro StartSpiTransfer
       ld    temp3,x;send current
       out    spdr,temp3;byte
.end macro
Несомненно это хак, но разьве такие варианты не украшают нашу работу ?
Ну а если действительно присмотреться, объясните чем Ваш вариант с макросом надежнее
чем просто вызов в нужное место ?
повторный вход в любом случае Вы не обеспечили....
Go to the top of the page
 
+Quote Post
defunct
сообщение May 23 2008, 22:24
Сообщение #27


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(singlskv @ May 23 2008, 22:34) *
Ну а если действительно присмотреться, объясните чем Ваш вариант с макросом надежнее
чем просто вызов в нужное место ?
повторный вход в любом случае Вы не обеспечили....

1. он быстрее (меньше тактов занимает).
2. не использует RETI не по месту (определяющее по надежности отличие)
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 24 2008, 00:25
Сообщение #28


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
Qwertty
сообщение Nov 13 2008, 16:47
Сообщение #29


Местный
***

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



Отпишусь тут. Сегодня помучал SPI. Узнал много нового smile.gif
Не ждать готовности SPI можно.
Код
void    SpiMasterTx(uint8_t data)
{
do
  {
   SPDR = data;
  }
  while(SPSR & (1<<WCOL));
}

Такая конструкция оказалась вполне работоспособной. То что писал Maik-vs в 4 сообщении этой темы не подтвердилось - данные в SPDR не портятся. Симулятор студии и реальный осциллограф также это подтверждают.
Ждать приходится только при чтении:
Код
uint8_t    SpiMasterTxRx(uint8_t data)
{
    do
        {
        SPDR = data;
        }
        while(SPSR & (1<<WCOL));
    while(!(SPSR & (1<<SPIF)));
    return SPDR;
}

Оказывается WCOL очень полезный флаг....
Go to the top of the page
 
+Quote Post
Maik-vs
сообщение Nov 13 2008, 19:45
Сообщение #30


Местный
***

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



Цитата(Qwertty @ Nov 13 2008, 19:47) *
Отпишусь тут. Сегодня помучал SPI. Узнал много нового smile.gif
Не ждать готовности SPI можно.
Код
void    SpiMasterTx(uint8_t data)
{
do
  {
   SPDR = data;
  }
  while(SPSR & (1<<WCOL));
}

Такая конструкция оказалась вполне работоспособной. То что писал Maik-vs в 4 сообщении этой темы не подтвердилось - данные в SPDR не портятся. Симулятор студии и реальный осциллограф также это подтверждают.

М-да. Оказывается, "while" теперь переводится "не ждать"... lol.gif
Где я писал, что портятся данные в SPDR? Они НЕ ПЕРЕДАЮТСЯ, если запись в SPDR произошла в течение передачи. Это коллизия называется. А Вы фигачите байт в SPDR пока передача не закончится и с нею коллизия стало быть тоже. Хотя в 6-м посте пеклись, как бы "записать SPDR и продолжить заниматься другими делами." wacko.gif
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Nov 13 2008, 21:16
Сообщение #31


Местный
***

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



Цитата(Maik-vs @ Nov 13 2008, 22:45) *
М-да. Оказывается, "while" теперь переводится "не ждать"... lol.gif

Цель та же - не ждать. Именно это я и получил. Записал в SPDR и пошел гулять, готовить следующие данные. Подготовил быстрее, чем закончилась передача, подожду немного, может пару-тройку тактов. Это лучше, чем например 32. А если данные готовились чуть дольше - вообще ничего не жду. Выигрыш во времени получился вполне ощутимый. И "самосброс" SPIF теперь не помеха.
Цитата(Maik-vs @ Nov 13 2008, 22:45) *
Где я писал, что портятся данные в SPDR? Они НЕ ПЕРЕДАЮТСЯ, если запись в SPDR произошла в течение передачи. Это коллизия называется.

"Писать в SPDR можно через 34 цикла процессора после предыдущей записи (SPCR=0x50). Раньше - синхроимпульсы будут, а данные - нет." Я вот про это. Запись в SPDR во время передачи вызывает только один эффект - взвод WCOL. На передаваемые данные никак не влияет. Когда передача закончится, запись в SPDR вызовет начало новой передачи совершенно обычным способом.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 13:45
Рейтинг@Mail.ru


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