Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SPI sam7 можно ли ввести паузу между CS ?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
cebotor
есть SAM7A3 есть чип , которым нужно управлять по SPI.
для работы с этим чипом требуется часто и непериодично дергать чип селектом.

Вопрос:
Можно ли в SAM7 ввести задержку между пропаданием чип селекта и выставлением его заново?

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

Или я чего то не понимаю?
ivstech
На AT91SAM7S можно задавать такую задержку
sergeeff
В регистре SPI_MR есть поле DLYBCS - dalay between chip select.
cebotor
Цитата(ivstech @ Apr 17 2007, 14:39) *
На AT91SAM7S можно задавать такую задержку

каким регистром если не секрет ?

Цитата(sergeeff @ Apr 17 2007, 17:13) *
В регистре SPI_MR есть поле DLYBCS - dalay between chip select.

в датащите написано :

•DLYBCS: Delay Between Chip Selects
This field defines the delay from NPCS inactive to the activation of another NPCS. The DLYBCS time guarantees non-overlapping
chip selects and solves bus contentions in case of peripherals having long data float times.
If DLYBCS is less than or equal to six, six MCK periods will be inserted by default.
Otherwise, the following equation determines the delay:

Delay Between Chip Selects= DLYBCS/MCK

не означает ли это что это пауза между чип селектом и длугим чип селектом (на другой ноге NPCS) ?

я попробовал выставить эту паузу :

AT91C_BASE_SPI0->SPI_MR = 0xff070019; // пауза - 0xff
а при записи я делую так

spi_to_send->SPI_CSR[3] = 0x01000801; // снимать чип селект после передачи
spi_to_send->SPI_TDR = data;
spi_to_send->SPI_CR|= AT91C_SPI_LASTXFER; // это и есть последняя посылка

и не смотря на биты CSAAT(снят ) и LASTXFER(выставлен) - при последовательной передаче нескольких байт чип селект между ними не пропадает ...

почему бы это ?
sergeeff
Если не дождаться окончания передачи данных по SPI, а сразу послать следующий байт, то CS не снимается.
cebotor
Цитата(sergeeff @ Apr 17 2007, 22:30) *
Если не дождаться окончания передачи данных по SPI, а сразу послать следующий байт, то CS не снимается.

а как можно дождаться ? я дожидаюсь по биту TXEMPTY в статусе.
вот:

while((spi_to_send->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // Wait for the transmission to complete
spi_to_send->SPI_CSR[3] = 0x01000801; //rise cs after last transfer
spi_to_send->SPI_TDR = data;
spi_to_send->SPI_CR|= AT91C_SPI_LASTXFER;

чип селект все равно не снимается sad.gif
sergeeff
while(!(*AT91C_SPI_SR & AT91C_SPI_TDRE)); // wait for transmit data register is not empty
*AT91C_SPI_TDR = (WORD)(dwData & 0xFFFF);
while(!(*AT91C_SPI_SR & AT91C_SPI_RDRF)); // wait for received data
cebotor
Цитата(sergeeff @ Apr 18 2007, 12:25) *
while(!(*AT91C_SPI_SR & AT91C_SPI_TDRE)); // wait for transmit data register is not empty
*AT91C_SPI_TDR = (WORD)(dwData & 0xFFFF);
while(!(*AT91C_SPI_SR & AT91C_SPI_RDRF)); // wait for received data

все - разобрался, дело было не в этом а в граблях ревизии атмела..
у меня были примеры от иара где в SPI_MR выставлялся бит делителя на 32 - fdiv.
SPI_MR = ...........9; // 9 - мастер моде и fdiv
так вот к моменту последнего датащита этот fdiv атмел изъял из описания.
Самое смешное , что если его выставить - частота действительно падает в 32 раза , но начинает глючить (пауза DLYBCS точно не отрабатывается, там наверное и еще чтото ).
yura-w
Цитата(cebotor @ Apr 18 2007, 15:15) *
пауза DLYBCS точно не отрабатывается, там наверное и еще чтото ).


подскажите, пожалуста, в чем причина:

на at91sam7x (на 50МГц) настроил DLYBCS = 0, длительность СS =1 мкс.
получаю время от входа в ф-ию передачи по spi до формрования CS ~ 1,2 мкс!!
(такое же время от снятия CS до выхода из ф-ии)

передаю так:
unsigned int SPI0_Send(unsigned int data, unsigned char pcs, unsigned char lastxfer)
{
lastxfer = (unsigned char)lastxfer & (unsigned char)0x1; // get lo 1 bit
// whait for tx register empty & create register content
while(!(SPI0->SPI_SR & AT91C_SPI_TDRE)){};
SPI0->SPI_TDR = (data & 0xffff) | lastxfer << 24 | pcs << 16 ;
// wait for rx register full
while(!(SPI0->SPI_SR & AT91C_SPI_RDRF)){};//do while nonzero
return(0xffff & SPI0->SPI_RDR);
}
prottoss
Цитата(yura-w @ Jan 25 2008, 16:26) *
подскажите, пожалуста, в чем причина:
Почитай вот здесь http://electronix.ru/forum/index.php?showtopic=35141&hl=

Я для себя уяснил одно - не парится с аппаратным дрыганием CS а делать выбор чипа программно
yura-w
Цитата(prottoss @ Jan 25 2008, 15:48) *
Почитай вот здесь http://electronix.ru/forum/index.php?showtopic=35141&hl=
Я для себя уяснил одно - не парится с аппаратным дрыганием CS а делать выбор чипа программно

спасибо, буду разбираться,
в лоб попробовал программно дергать, выигрыш в скорости не увидел
xelax
Цитата(yura-w @ Jan 25 2008, 16:12) *
спасибо, буду разбираться,
в лоб попробовал программно дергать, выигрыш в скорости не увидел


Не в скорости выигрышь, а в работоспособности. smile.gif
Если посмотреть errata на spi, то сами разработчики контроллера рекомендуют в некоторых случаях использовать CS в PIO режиме как Workarround проблемы.
prottoss
Кстати, раз уж снова заговорили об SPI на SAM7. Вот счас появилась задачка подключить два устройства по SPI - одно DataFlash AT45DB161 - работает на 12 МГц, второе - SIPO регистры (в общих чертах) с максимальной тактовой частотой 10 кГц. Вот пока думаю, с какой стороны подъехать:-)

Я так понимаю, что надо при инициализации SPI модуля нужно загрузить требуемые делители частот в массив SPI_CSR[] а потом, перед выборкой чипа, переключать на нужный делитель через SPI Mode Register SPI_MR. Я правильно рассуждаю?
yura-w
Цитата(prottoss @ Jan 25 2008, 16:36) *
а потом, перед выборкой чипа, переключать на нужный делитель через SPI Mode Register SPI_MR. Я правильно рассуждаю?

чип выбирается прямо в регистре передаваемых данных: SPI_TDR


Цитата(xelax @ Jan 25 2008, 16:25) *
-Не в скорости выигрышь
-Если посмотреть errata на spi

-а мне надо в скорости
-пока не нашел, продолжу на след неделе, может дадите ссылку?
prottoss
Цитата(yura-w @ Jan 25 2008, 20:50) *
чип выбирается прямо в регистре передаваемых данных: SPI_TDR
Нет, пока не обнулить соответсвующий линии CS бит в поле PCS регистра SPI_MR - толку нет. А вот если перед выборкой чипа загрузить поле PCS регистра SPI_MR нужным значением, а после передачи в это поле записать все единички. Таким образом на один интерфейс SPI имеем четыре разные частоты ну и девайсов, скока ноХ хватит smile.gif Уже проверил smile.gif
xelax
Цитата(yura-w @ Jan 25 2008, 16:50) *
чип выбирается прямо в регистре передаваемых данных: SPI_TDR
-а мне надо в скорости
-пока не нашел, продолжу на след неделе, может дадите ссылку?


Откровение от Atmela. Стих 41, стр. 640
Код
SPI: LASTXFER (Last Transfer) Behavior
In FIXED Mode, with CSAAT bit set, and in “PDC mode” the Chip Select can rise depending on
the data written in the SPI_TDR when the TX_EMPTY flag is set. If for example, the PDC writes
a “1” in the bit 24 (LASTXFER bit) of the SPI_TDR, the chip select will rise as soon as the
TXEMPTY flag is set.
Problem Fix/Workaround
Use the CS in PIO mode when PDC mode is required and CS has to be maintained between
transfers.


даташит с сайта атмела.
prottoss
Сделал еще лучше, мое мнение. Создал деск, в котором сохраняю, в том числе, настройки для СSR регистра. Настраиваем SPI Mode register (MR) для работы именно с ним. Ну и перед трансфером загружаем этот регистр. Т.е. для каждого устройства в системе делаем деск - и устройств практически можент быть неограниченное количество. Если кому интересно - выкладываю файлы на суд общественности
yura-w
Спасибо, за помощь и разъяснение
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.